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 |