| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart2js.resolution.constructors; | 5 library dart2js.resolution.constructors; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../compiler.dart' show | 8 import '../compiler.dart' show |
| 9 Compiler; | 9 Compiler; |
| 10 import '../constants/constructors.dart' show | 10 import '../constants/constructors.dart' show |
| 11 ErroneousConstantConstructor, |
| 11 GenerativeConstantConstructor, | 12 GenerativeConstantConstructor, |
| 12 RedirectingGenerativeConstantConstructor; | 13 RedirectingGenerativeConstantConstructor; |
| 13 import '../constants/expressions.dart'; | 14 import '../constants/expressions.dart'; |
| 14 import '../dart_types.dart'; | 15 import '../dart_types.dart'; |
| 15 import '../elements/elements.dart'; | 16 import '../elements/elements.dart'; |
| 16 import '../elements/modelx.dart' show | 17 import '../elements/modelx.dart' show |
| 17 ConstructorElementX, | 18 ConstructorElementX, |
| 18 ErroneousConstructorElementX, | 19 ErroneousConstructorElementX, |
| 19 ErroneousElementX, | 20 ErroneousElementX, |
| 20 ErroneousFieldElementX, | 21 ErroneousFieldElementX, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); | 125 init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); |
| 125 } | 126 } |
| 126 registry.useElement(init, target); | 127 registry.useElement(init, target); |
| 127 registry.registerStaticUse(target); | 128 registry.registerStaticUse(target); |
| 128 checkForDuplicateInitializers(target, init); | 129 checkForDuplicateInitializers(target, init); |
| 129 // Resolve initializing value. | 130 // Resolve initializing value. |
| 130 ResolutionResult result = visitor.visitInStaticContext( | 131 ResolutionResult result = visitor.visitInStaticContext( |
| 131 init.arguments.head, | 132 init.arguments.head, |
| 132 inConstantInitializer: isConst); | 133 inConstantInitializer: isConst); |
| 133 if (isConst) { | 134 if (isConst) { |
| 134 if (result.isConstant && field != null) { | 135 ConstantExpression constant; |
| 135 // TODO(johnniwinther): Report error if `result.constant` is `null`. | 136 if (result.isConstant) { |
| 136 fieldInitializers[field] = result.constant; | 137 constant = result.constant; |
| 137 } else { | 138 } else { |
| 139 if (field != null) { |
| 140 reporter.reportErrorMessage( |
| 141 init, MessageKind.NOT_A_COMPILE_TIME_CONSTANT); |
| 142 } |
| 143 constant = new ErroneousConstantExpression(); |
| 138 isValidAsConstant = false; | 144 isValidAsConstant = false; |
| 139 } | 145 } |
| 146 if (field != null) { |
| 147 fieldInitializers[field] = constant; |
| 148 } |
| 140 } | 149 } |
| 141 } | 150 } |
| 142 | 151 |
| 143 InterfaceType getSuperOrThisLookupTarget(Node diagnosticNode, | 152 InterfaceType getSuperOrThisLookupTarget(Node diagnosticNode, |
| 144 {bool isSuperCall}) { | 153 {bool isSuperCall}) { |
| 145 if (isSuperCall) { | 154 if (isSuperCall) { |
| 146 // Calculate correct lookup target and constructor name. | 155 // Calculate correct lookup target and constructor name. |
| 147 if (identical(constructor.enclosingClass, visitor.compiler.objectClass)) { | 156 if (identical(constructor.enclosingClass, visitor.compiler.objectClass)) { |
| 148 reporter.reportErrorMessage( | 157 reporter.reportErrorMessage( |
| 149 diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT); | 158 diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 isValidAsConstant = false; | 395 isValidAsConstant = false; |
| 387 } | 396 } |
| 388 }); | 397 }); |
| 389 ResolutionResult result = resolveSuperOrThisForSend(call); | 398 ResolutionResult result = resolveSuperOrThisForSend(call); |
| 390 if (isConst) { | 399 if (isConst) { |
| 391 if (result.isConstant) { | 400 if (result.isConstant) { |
| 392 constructorInvocation = result.constant; | 401 constructorInvocation = result.constant; |
| 393 } else { | 402 } else { |
| 394 isValidAsConstant = false; | 403 isValidAsConstant = false; |
| 395 } | 404 } |
| 396 if (isConst && isValidAsConstant) { | 405 if (isConst) { |
| 397 constructor.constantConstructor = | 406 if (isValidAsConstant) { |
| 398 new RedirectingGenerativeConstantConstructor( | 407 constructor.constantConstructor = |
| 399 defaultValues, | 408 new RedirectingGenerativeConstantConstructor( |
| 400 constructorInvocation); | 409 defaultValues, |
| 410 constructorInvocation); |
| 411 } else { |
| 412 constructor.constantConstructor = |
| 413 const ErroneousConstantConstructor(); |
| 414 } |
| 401 } | 415 } |
| 402 } | 416 } |
| 403 return result.element; | 417 return result.element; |
| 404 } else { | 418 } else { |
| 405 reporter.reportErrorMessage( | 419 reporter.reportErrorMessage( |
| 406 call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); | 420 call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); |
| 407 return null; | 421 return null; |
| 408 } | 422 } |
| 409 } else { | 423 } else { |
| 410 reporter.reportErrorMessage( | 424 reporter.reportErrorMessage( |
| 411 link.head, MessageKind.INVALID_INITIALIZER); | 425 link.head, MessageKind.INVALID_INITIALIZER); |
| 426 isValidAsConstant = false; |
| 412 } | 427 } |
| 413 } | 428 } |
| 414 if (!resolvedSuper) { | 429 if (!resolvedSuper) { |
| 415 constructorInvocation = resolveImplicitSuperConstructorSend(); | 430 constructorInvocation = resolveImplicitSuperConstructorSend(); |
| 416 } | 431 } |
| 417 if (isConst && isValidAsConstant) { | 432 if (isConst) { |
| 418 constructor.constantConstructor = new GenerativeConstantConstructor( | 433 ClassElement enclosingClass = constructor.enclosingClass; |
| 419 constructor.enclosingClass.thisType, | 434 enclosingClass.implementation.forEachInstanceField( |
| 420 defaultValues, | 435 (ClassElement enclosingClass, FieldElementX field) { |
| 421 fieldInitializers, | 436 if (field.isFinal) { |
| 422 constructorInvocation); | 437 if (!fieldInitializers.containsKey(field)) { |
| 438 visitor.compiler.resolver.resolveField(field); |
| 439 Expression initializer = field.initializer; |
| 440 if (initializer != null) { |
| 441 fieldInitializers[field] = field.constant; |
| 442 } else { |
| 443 /*warning(functionNode, MessageKind.UNINITIALIZED_FINAL_FIELD, { |
| 444 'fieldName': field.name, |
| 445 });*/ |
| 446 fieldInitializers[field] = new NullConstantExpression(); |
| 447 } |
| 448 } |
| 449 } else { |
| 450 isValidAsConstant = false; |
| 451 } |
| 452 }); |
| 453 if (isValidAsConstant) { |
| 454 constructor.constantConstructor = new GenerativeConstantConstructor( |
| 455 enclosingClass.thisType, |
| 456 defaultValues, |
| 457 fieldInitializers, |
| 458 constructorInvocation); |
| 459 } else { |
| 460 constructor.constantConstructor = |
| 461 const ErroneousConstantConstructor(); |
| 462 } |
| 423 } | 463 } |
| 424 return null; // If there was no redirection always return null. | 464 return null; // If there was no redirection always return null. |
| 425 } | 465 } |
| 426 } | 466 } |
| 427 | 467 |
| 428 class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> { | 468 class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> { |
| 429 final ResolverVisitor resolver; | 469 final ResolverVisitor resolver; |
| 430 final bool inConstContext; | 470 final bool inConstContext; |
| 431 | 471 |
| 432 ConstructorResolver(Compiler compiler, this.resolver, | 472 ConstructorResolver(Compiler compiler, this.resolver, |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 // constructors. | 790 // constructors. |
| 751 return null; | 791 return null; |
| 752 } | 792 } |
| 753 // TODO(johnniwinther): Use [Name] for lookup. | 793 // TODO(johnniwinther): Use [Name] for lookup. |
| 754 ConstructorElement constructor = cls.lookupConstructor(constructorName); | 794 ConstructorElement constructor = cls.lookupConstructor(constructorName); |
| 755 if (constructor != null) { | 795 if (constructor != null) { |
| 756 constructor = constructor.declaration; | 796 constructor = constructor.declaration; |
| 757 } | 797 } |
| 758 return constructor; | 798 return constructor; |
| 759 } | 799 } |
| OLD | NEW |