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 library fasta.body_builder; | 5 library fasta.body_builder; |
6 | 6 |
7 import 'package:kernel/ast.dart' | 7 import 'package:kernel/ast.dart' |
8 hide InvalidExpression, InvalidInitializer, InvalidStatement; | 8 hide InvalidExpression, InvalidInitializer, InvalidStatement; |
9 | 9 |
10 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; | 10 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 for (KernelFormalParameterBuilder formal in member.formals) { | 501 for (KernelFormalParameterBuilder formal in member.formals) { |
502 if (formal.hasThis) { | 502 if (formal.hasThis) { |
503 Initializer initializer; | 503 Initializer initializer; |
504 if (member.isExternal) { | 504 if (member.isExternal) { |
505 initializer = buildInvalidInitializer( | 505 initializer = buildInvalidInitializer( |
506 deprecated_buildCompileTimeError( | 506 deprecated_buildCompileTimeError( |
507 "An external constructor can't initialize fields.", | 507 "An external constructor can't initialize fields.", |
508 formal.charOffset), | 508 formal.charOffset), |
509 formal.charOffset); | 509 formal.charOffset); |
510 } else { | 510 } else { |
511 initializer = buildFieldInitializer(formal.name, | 511 initializer = buildFieldInitializer(true, formal.name, |
512 formal.charOffset, new VariableGet(formal.declaration)); | 512 formal.charOffset, new VariableGet(formal.declaration)); |
513 } | 513 } |
514 member.addInitializer(initializer); | 514 member.addInitializer(initializer); |
515 } | 515 } |
516 } | 516 } |
517 } | 517 } |
518 } | 518 } |
519 } | 519 } |
520 | 520 |
521 @override | 521 @override |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 debugEvent("endInitializer"); | 554 debugEvent("endInitializer"); |
555 assert(!inInitializer); | 555 assert(!inInitializer); |
556 final member = this.member; | 556 final member = this.member; |
557 var node = pop(); | 557 var node = pop(); |
558 Initializer initializer; | 558 Initializer initializer; |
559 if (node is Initializer) { | 559 if (node is Initializer) { |
560 initializer = node; | 560 initializer = node; |
561 } else if (node is FastaAccessor) { | 561 } else if (node is FastaAccessor) { |
562 initializer = node.buildFieldInitializer(initializedFields); | 562 initializer = node.buildFieldInitializer(initializedFields); |
563 } else if (node is ConstructorInvocation) { | 563 } else if (node is ConstructorInvocation) { |
564 initializer = | 564 initializer = buildSuperInitializer( |
565 buildSuperInitializer(node.target, node.arguments, token.charOffset); | 565 false, node.target, node.arguments, token.charOffset); |
566 } else { | 566 } else { |
567 Expression value = toValue(node); | 567 Expression value = toValue(node); |
568 if (node is! Throw) { | 568 if (node is! Throw) { |
569 value = | 569 value = |
570 wrapInCompileTimeError(value, fasta.messageExpectedAnInitializer); | 570 wrapInCompileTimeError(value, fasta.messageExpectedAnInitializer); |
571 } | 571 } |
572 initializer = buildInvalidInitializer(node, token.charOffset); | 572 initializer = buildInvalidInitializer(node, token.charOffset); |
573 } | 573 } |
574 _typeInferrer.inferInitializer(initializer); | 574 _typeInferrer.inferInitializer(initializer); |
575 if (member is KernelConstructorBuilder && !member.isExternal) { | 575 if (member is KernelConstructorBuilder && !member.isExternal) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 !checkArguments( | 660 !checkArguments( |
661 superTarget.function, arguments, const <TypeParameter>[])) { | 661 superTarget.function, arguments, const <TypeParameter>[])) { |
662 String superclass = classBuilder.supertype.fullNameForErrors; | 662 String superclass = classBuilder.supertype.fullNameForErrors; |
663 String message = superTarget == null | 663 String message = superTarget == null |
664 ? "'$superclass' doesn't have an unnamed constructor." | 664 ? "'$superclass' doesn't have an unnamed constructor." |
665 : "The unnamed constructor in '$superclass' requires arguments."; | 665 : "The unnamed constructor in '$superclass' requires arguments."; |
666 initializer = buildInvalidInitializer( | 666 initializer = buildInvalidInitializer( |
667 deprecated_buildCompileTimeError(message, builder.charOffset), | 667 deprecated_buildCompileTimeError(message, builder.charOffset), |
668 builder.charOffset); | 668 builder.charOffset); |
669 } else { | 669 } else { |
670 initializer = | 670 initializer = buildSuperInitializer( |
671 buildSuperInitializer(superTarget, arguments, builder.charOffset); | 671 true, superTarget, arguments, builder.charOffset); |
672 } | 672 } |
673 constructor.initializers.add(initializer); | 673 constructor.initializers.add(initializer); |
674 } | 674 } |
675 setParents(constructor.initializers, constructor); | 675 setParents(constructor.initializers, constructor); |
676 if (constructor.function.body == null) { | 676 if (constructor.function.body == null) { |
677 /// >If a generative constructor c is not a redirecting constructor | 677 /// >If a generative constructor c is not a redirecting constructor |
678 /// >and no body is provided, then c implicitly has an empty body {}. | 678 /// >and no body is provided, then c implicitly has an empty body {}. |
679 /// We use an empty statement instead. | 679 /// We use an empty statement instead. |
680 constructor.function.body = new EmptyStatement(); | 680 constructor.function.body = new EmptyStatement(); |
681 constructor.function.body.parent = constructor.function; | 681 constructor.function.body.parent = constructor.function; |
(...skipping 2464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3146 deprecated_buildCompileTimeError( | 3146 deprecated_buildCompileTimeError( |
3147 "'$name' has already been initialized.", offset), | 3147 "'$name' has already been initialized.", offset), |
3148 offset); | 3148 offset); |
3149 deprecated_addCompileTimeError( | 3149 deprecated_addCompileTimeError( |
3150 initializedFields[name], "'$name' was initialized here."); | 3150 initializedFields[name], "'$name' was initialized here."); |
3151 return initializer; | 3151 return initializer; |
3152 } | 3152 } |
3153 | 3153 |
3154 @override | 3154 @override |
3155 Initializer buildFieldInitializer( | 3155 Initializer buildFieldInitializer( |
3156 String name, int offset, Expression expression) { | 3156 bool isSynthetic, String name, int offset, Expression expression) { |
3157 Builder builder = classBuilder.scope.local[name]; | 3157 Builder builder = classBuilder.scope.local[name]; |
3158 if (builder is KernelFieldBuilder && builder.isInstanceMember) { | 3158 if (builder is KernelFieldBuilder && builder.isInstanceMember) { |
3159 initializedFields ??= <String, int>{}; | 3159 initializedFields ??= <String, int>{}; |
3160 if (initializedFields.containsKey(name)) { | 3160 if (initializedFields.containsKey(name)) { |
3161 return buildDuplicatedInitializer( | 3161 return buildDuplicatedInitializer( |
3162 name, offset, initializedFields[name]); | 3162 name, offset, initializedFields[name]); |
3163 } | 3163 } |
3164 initializedFields[name] = offset; | 3164 initializedFields[name] = offset; |
3165 if (builder.isFinal && builder.hasInitializer) { | 3165 if (builder.isFinal && builder.hasInitializer) { |
3166 // TODO(ahe): If CL 2843733002 is landed, this becomes a compile-time | 3166 // TODO(ahe): If CL 2843733002 is landed, this becomes a compile-time |
3167 // error. Also, this is a compile-time error in strong mode. | 3167 // error. Also, this is a compile-time error in strong mode. |
3168 warningNotError( | 3168 warningNotError( |
3169 fasta.templateFinalInstanceVariableAlreadyInitialized | 3169 fasta.templateFinalInstanceVariableAlreadyInitialized |
3170 .withArguments(name), | 3170 .withArguments(name), |
3171 offset); | 3171 offset); |
3172 warningNotError( | 3172 warningNotError( |
3173 fasta.templateFinalInstanceVariableAlreadyInitializedCause | 3173 fasta.templateFinalInstanceVariableAlreadyInitializedCause |
3174 .withArguments(name), | 3174 .withArguments(name), |
3175 builder.charOffset); | 3175 builder.charOffset); |
3176 Builder constructor = | 3176 Builder constructor = |
3177 library.loader.getDuplicatedFieldInitializerError(); | 3177 library.loader.getDuplicatedFieldInitializerError(); |
3178 return buildInvalidInitializer( | 3178 return buildInvalidInitializer( |
3179 new Throw(buildStaticInvocation(constructor.target, | 3179 new Throw(buildStaticInvocation(constructor.target, |
3180 new Arguments(<Expression>[new StringLiteral(name)]), | 3180 new Arguments(<Expression>[new StringLiteral(name)]), |
3181 charOffset: offset)), | 3181 charOffset: offset)), |
3182 offset); | 3182 offset); |
3183 } else { | 3183 } else { |
3184 return new FieldInitializer(builder.field, expression) | 3184 return new FieldInitializer(builder.field, expression) |
3185 ..fileOffset = offset; | 3185 ..fileOffset = offset |
| 3186 ..isSynthetic = isSynthetic; |
3186 } | 3187 } |
3187 } else { | 3188 } else { |
3188 return buildInvalidInitializer( | 3189 return buildInvalidInitializer( |
3189 deprecated_buildCompileTimeError( | 3190 deprecated_buildCompileTimeError( |
3190 "'$name' isn't an instance field of this class.", offset), | 3191 "'$name' isn't an instance field of this class.", offset), |
3191 offset); | 3192 offset); |
3192 } | 3193 } |
3193 } | 3194 } |
3194 | 3195 |
3195 @override | 3196 @override |
3196 Initializer buildSuperInitializer( | 3197 Initializer buildSuperInitializer( |
3197 Constructor constructor, Arguments arguments, | 3198 bool isSynthetic, Constructor constructor, Arguments arguments, |
3198 [int charOffset = -1]) { | 3199 [int charOffset = -1]) { |
3199 if (member.isConst && !constructor.isConst) { | 3200 if (member.isConst && !constructor.isConst) { |
3200 return buildInvalidInitializer( | 3201 return buildInvalidInitializer( |
3201 deprecated_buildCompileTimeError( | 3202 deprecated_buildCompileTimeError( |
3202 "Super constructor isn't const.", charOffset), | 3203 "Super constructor isn't const.", charOffset), |
3203 charOffset); | 3204 charOffset); |
3204 } | 3205 } |
3205 needsImplicitSuperInitializer = false; | 3206 needsImplicitSuperInitializer = false; |
3206 return new SuperInitializer(constructor, arguments) | 3207 return new SuperInitializer(constructor, arguments) |
3207 ..fileOffset = charOffset; | 3208 ..fileOffset = charOffset |
| 3209 ..isSynthetic = isSynthetic; |
3208 } | 3210 } |
3209 | 3211 |
3210 @override | 3212 @override |
3211 Initializer buildRedirectingInitializer( | 3213 Initializer buildRedirectingInitializer( |
3212 Constructor constructor, Arguments arguments, | 3214 Constructor constructor, Arguments arguments, |
3213 [int charOffset = -1]) { | 3215 [int charOffset = -1]) { |
3214 needsImplicitSuperInitializer = false; | 3216 needsImplicitSuperInitializer = false; |
3215 return new KernelRedirectingInitializer(constructor, arguments) | 3217 return new KernelRedirectingInitializer(constructor, arguments) |
3216 ..fileOffset = charOffset; | 3218 ..fileOffset = charOffset; |
3217 } | 3219 } |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3511 } | 3513 } |
3512 } | 3514 } |
3513 | 3515 |
3514 @override | 3516 @override |
3515 Initializer buildFieldInitializer(Map<String, int> initializedFields) { | 3517 Initializer buildFieldInitializer(Map<String, int> initializedFields) { |
3516 if (!identical("=", assignmentOperator) || | 3518 if (!identical("=", assignmentOperator) || |
3517 !accessor.isThisPropertyAccessor) { | 3519 !accessor.isThisPropertyAccessor) { |
3518 return accessor.buildFieldInitializer(initializedFields); | 3520 return accessor.buildFieldInitializer(initializedFields); |
3519 } | 3521 } |
3520 return helper.buildFieldInitializer( | 3522 return helper.buildFieldInitializer( |
3521 accessor.plainNameForRead, offsetForToken(token), value); | 3523 false, accessor.plainNameForRead, offsetForToken(token), value); |
3522 } | 3524 } |
3523 } | 3525 } |
3524 | 3526 |
3525 class DelayedPostfixIncrement extends ContextAccessor { | 3527 class DelayedPostfixIncrement extends ContextAccessor { |
3526 final Name binaryOperator; | 3528 final Name binaryOperator; |
3527 | 3529 |
3528 final Procedure interfaceTarget; | 3530 final Procedure interfaceTarget; |
3529 | 3531 |
3530 DelayedPostfixIncrement(BuilderHelper helper, Token token, | 3532 DelayedPostfixIncrement(BuilderHelper helper, Token token, |
3531 FastaAccessor accessor, this.binaryOperator, this.interfaceTarget) | 3533 FastaAccessor accessor, this.binaryOperator, this.interfaceTarget) |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3798 return AsyncMarker.Async; | 3800 return AsyncMarker.Async; |
3799 } else { | 3801 } else { |
3800 assert(identical(starToken.stringValue, "*")); | 3802 assert(identical(starToken.stringValue, "*")); |
3801 return AsyncMarker.AsyncStar; | 3803 return AsyncMarker.AsyncStar; |
3802 } | 3804 } |
3803 } else { | 3805 } else { |
3804 return unhandled(asyncToken.lexeme, "asyncMarkerFromTokens", | 3806 return unhandled(asyncToken.lexeme, "asyncMarkerFromTokens", |
3805 asyncToken.charOffset, null); | 3807 asyncToken.charOffset, null); |
3806 } | 3808 } |
3807 } | 3809 } |
OLD | NEW |