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 |