| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../closure.dart'; | 7 import '../closure.dart'; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 fieldValues[field] = pop(); | 301 fieldValues[field] = pop(); |
| 302 } | 302 } |
| 303 } | 303 } |
| 304 | 304 |
| 305 return fieldValues; | 305 return fieldValues; |
| 306 } | 306 } |
| 307 | 307 |
| 308 /// Collects field initializers all the way up the inheritance chain. | 308 /// Collects field initializers all the way up the inheritance chain. |
| 309 void _buildInitializers( | 309 void _buildInitializers( |
| 310 ir.Constructor constructor, Map<ir.Field, HInstruction> fieldValues) { | 310 ir.Constructor constructor, Map<ir.Field, HInstruction> fieldValues) { |
| 311 var foundSuperCall = false; | 311 var foundSuperOrRedirectCall = false; |
| 312 for (var initializer in constructor.initializers) { | 312 for (var initializer in constructor.initializers) { |
| 313 if (initializer is ir.SuperInitializer) { | 313 if (initializer is ir.SuperInitializer || |
| 314 foundSuperCall = true; | 314 initializer is ir.RedirectingInitializer) { |
| 315 var superConstructor = initializer.target; | 315 foundSuperOrRedirectCall = true; |
| 316 var superOrRedirectConstructor = initializer.target; |
| 316 var arguments = _normalizeAndBuildArguments( | 317 var arguments = _normalizeAndBuildArguments( |
| 317 superConstructor.function, initializer.arguments); | 318 superOrRedirectConstructor.function, initializer.arguments); |
| 318 _buildInlinedSuperInitializers( | 319 _buildInlinedInitializers( |
| 319 superConstructor, arguments, fieldValues); | 320 superOrRedirectConstructor, arguments, fieldValues); |
| 320 } else if (initializer is ir.FieldInitializer) { | 321 } else if (initializer is ir.FieldInitializer) { |
| 321 initializer.value.accept(this); | 322 initializer.value.accept(this); |
| 322 fieldValues[initializer.field] = pop(); | 323 fieldValues[initializer.field] = pop(); |
| 323 } | 324 } |
| 324 } | 325 } |
| 325 | 326 |
| 326 // TODO(het): does kernel always set the super initializer at the end? | 327 // Kernel always set the super initializer at the end, so if there was no |
| 327 // If there was no super-call initializer, then call the default constructor | 328 // super-call initializer, then the default constructor is called in the |
| 328 // in the superclass. | 329 // superclass. |
| 329 if (!foundSuperCall) { | 330 if (!foundSuperOrRedirectCall) { |
| 330 if (constructor.enclosingClass != astAdapter.objectClass) { | 331 if (constructor.enclosingClass != astAdapter.objectClass) { |
| 331 var superclass = constructor.enclosingClass.superclass; | 332 var superclass = constructor.enclosingClass.superclass; |
| 332 var defaultConstructor = superclass.constructors | 333 var defaultConstructor = superclass.constructors |
| 333 .firstWhere((c) => c.name == '', orElse: () => null); | 334 .firstWhere((c) => c.name.name == '', orElse: () => null); |
| 334 if (defaultConstructor == null) { | 335 if (defaultConstructor == null) { |
| 335 compiler.reporter.internalError( | 336 compiler.reporter.internalError( |
| 336 NO_LOCATION_SPANNABLE, 'Could not find default constructor.'); | 337 NO_LOCATION_SPANNABLE, 'Could not find default constructor.'); |
| 337 } | 338 } |
| 338 _buildInlinedSuperInitializers( | 339 _buildInlinedInitializers( |
| 339 defaultConstructor, <HInstruction>[], fieldValues); | 340 defaultConstructor, <HInstruction>[], fieldValues); |
| 340 } | 341 } |
| 341 } | 342 } |
| 342 } | 343 } |
| 343 | 344 |
| 344 List<HInstruction> _normalizeAndBuildArguments( | 345 List<HInstruction> _normalizeAndBuildArguments( |
| 345 ir.FunctionNode function, ir.Arguments arguments) { | 346 ir.FunctionNode function, ir.Arguments arguments) { |
| 346 var signature = astAdapter.getFunctionSignature(function); | 347 var signature = astAdapter.getFunctionSignature(function); |
| 347 var builtArguments = <HInstruction>[]; | 348 var builtArguments = <HInstruction>[]; |
| 348 var positionalIndex = 0; | 349 var positionalIndex = 0; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 } | 381 } |
| 381 }); | 382 }); |
| 382 } | 383 } |
| 383 | 384 |
| 384 return builtArguments; | 385 return builtArguments; |
| 385 } | 386 } |
| 386 | 387 |
| 387 /// Inlines the given super [constructor]'s initializers by collecting it's | 388 /// Inlines the given super [constructor]'s initializers by collecting it's |
| 388 /// field values and building its constructor initializers. We visit super | 389 /// field values and building its constructor initializers. We visit super |
| 389 /// constructors all the way up to the [Object] constructor. | 390 /// constructors all the way up to the [Object] constructor. |
| 390 void _buildInlinedSuperInitializers(ir.Constructor constructor, | 391 void _buildInlinedInitializers(ir.Constructor constructor, |
| 391 List<HInstruction> arguments, Map<ir.Field, HInstruction> fieldValues) { | 392 List<HInstruction> arguments, Map<ir.Field, HInstruction> fieldValues) { |
| 392 // TODO(het): Handle RTI if class needs it | 393 // TODO(het): Handle RTI if class needs it |
| 393 fieldValues.addAll(_collectFieldValues(constructor.enclosingClass)); | 394 fieldValues.addAll(_collectFieldValues(constructor.enclosingClass)); |
| 394 | 395 |
| 395 var signature = astAdapter.getFunctionSignature(constructor.function); | 396 var signature = astAdapter.getFunctionSignature(constructor.function); |
| 396 var index = 0; | 397 var index = 0; |
| 397 signature.orderedForEachParameter((ParameterElement parameter) { | 398 signature.orderedForEachParameter((ParameterElement parameter) { |
| 398 HInstruction argument = arguments[index++]; | 399 HInstruction argument = arguments[index++]; |
| 399 // Because we are inlining the initializer, we must update | 400 // Because we are inlining the initializer, we must update |
| 400 // what was given as parameter. This will be used in case | 401 // what was given as parameter. This will be used in case |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 constructor = astAdapter.mapLiteralUntypedMaker; | 1192 constructor = astAdapter.mapLiteralUntypedMaker; |
| 1192 } | 1193 } |
| 1193 } else { | 1194 } else { |
| 1194 inputs.addAll(typeInputs); | 1195 inputs.addAll(typeInputs); |
| 1195 } | 1196 } |
| 1196 } | 1197 } |
| 1197 | 1198 |
| 1198 // If runtime type information is needed and the map literal has no type | 1199 // If runtime type information is needed and the map literal has no type |
| 1199 // parameters, 'constructor' is a static function that forwards the call to | 1200 // parameters, 'constructor' is a static function that forwards the call to |
| 1200 // the factory constructor without type parameters. | 1201 // the factory constructor without type parameters. |
| 1201 assert(constructor.kind == ir.ProcedureKind.Factory); | 1202 assert(constructor.kind == ir.ProcedureKind.Method |
| 1203 || constructor.kind == ir.ProcedureKind.Factory); |
| 1202 | 1204 |
| 1203 // The instruction type will always be a subtype of the mapLiteralClass, but | 1205 // The instruction type will always be a subtype of the mapLiteralClass, but |
| 1204 // type inference might discover a more specific type, or find nothing (in | 1206 // type inference might discover a more specific type, or find nothing (in |
| 1205 // dart2js unit tests). | 1207 // dart2js unit tests). |
| 1206 TypeMask mapType = new TypeMask.nonNullSubtype( | 1208 TypeMask mapType = new TypeMask.nonNullSubtype( |
| 1207 astAdapter.getElement(astAdapter.mapLiteralClass), closedWorld); | 1209 astAdapter.getElement(astAdapter.mapLiteralClass), closedWorld); |
| 1208 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( | 1210 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( |
| 1209 astAdapter.getElement(constructor), globalInferenceResults); | 1211 astAdapter.getElement(constructor), globalInferenceResults); |
| 1210 TypeMask instructionType = | 1212 TypeMask instructionType = |
| 1211 mapType.intersection(returnTypeMask, closedWorld); | 1213 mapType.intersection(returnTypeMask, closedWorld); |
| (...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2477 kernelBuilder.open(exitBlock); | 2479 kernelBuilder.open(exitBlock); |
| 2478 enterBlock.setBlockFlow( | 2480 enterBlock.setBlockFlow( |
| 2479 new HTryBlockInformation( | 2481 new HTryBlockInformation( |
| 2480 kernelBuilder.wrapStatementGraph(bodyGraph), | 2482 kernelBuilder.wrapStatementGraph(bodyGraph), |
| 2481 exception, | 2483 exception, |
| 2482 kernelBuilder.wrapStatementGraph(catchGraph), | 2484 kernelBuilder.wrapStatementGraph(catchGraph), |
| 2483 kernelBuilder.wrapStatementGraph(finallyGraph)), | 2485 kernelBuilder.wrapStatementGraph(finallyGraph)), |
| 2484 exitBlock); | 2486 exitBlock); |
| 2485 } | 2487 } |
| 2486 } | 2488 } |
| OLD | NEW |