Chromium Code Reviews| 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.fasta_accessors; | 5 library fasta.fasta_accessors; |
| 6 | 6 |
| 7 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' | 7 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' |
| 8 show KernelArguments; | 8 show KernelArguments; |
| 9 | 9 |
| 10 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; | 10 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 StaticAccessor, | 32 StaticAccessor, |
| 33 SuperIndexAccessor, | 33 SuperIndexAccessor, |
| 34 SuperPropertyAccessor, | 34 SuperPropertyAccessor, |
| 35 ThisIndexAccessor, | 35 ThisIndexAccessor, |
| 36 ThisPropertyAccessor, | 36 ThisPropertyAccessor, |
| 37 VariableAccessor; | 37 VariableAccessor; |
| 38 | 38 |
| 39 import 'kernel_builder.dart' | 39 import 'kernel_builder.dart' |
| 40 show Builder, KernelClassBuilder, PrefixBuilder, TypeDeclarationBuilder; | 40 show Builder, KernelClassBuilder, PrefixBuilder, TypeDeclarationBuilder; |
| 41 | 41 |
| 42 import '../names.dart' show callName; | 42 import '../names.dart' show callName, lengthName; |
| 43 | 43 |
| 44 abstract class BuilderHelper { | 44 abstract class BuilderHelper { |
| 45 Uri get uri; | 45 Uri get uri; |
| 46 | 46 |
| 47 TypePromoter get typePromoter; | 47 TypePromoter get typePromoter; |
| 48 | 48 |
| 49 int get functionNestingLevel; | 49 int get functionNestingLevel; |
| 50 | 50 |
| 51 bool get constantExpressionRequired; | 51 bool get constantExpressionRequired; |
| 52 | 52 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 83 String name, Arguments arguments, int offset, | 83 String name, Arguments arguments, int offset, |
| 84 {bool isSuper, bool isGetter, bool isSetter}); | 84 {bool isSuper, bool isGetter, bool isSetter}); |
| 85 | 85 |
| 86 bool checkArguments(FunctionNode function, Arguments arguments, | 86 bool checkArguments(FunctionNode function, Arguments arguments, |
| 87 List<TypeParameter> typeParameters); | 87 List<TypeParameter> typeParameters); |
| 88 | 88 |
| 89 StaticGet makeStaticGet(Member readTarget, Token token); | 89 StaticGet makeStaticGet(Member readTarget, Token token); |
| 90 | 90 |
| 91 dynamic addCompileTimeError(int charOffset, String message, {bool silent}); | 91 dynamic addCompileTimeError(int charOffset, String message, {bool silent}); |
| 92 | 92 |
| 93 bool isIdentical(Member member); | |
| 94 | |
| 93 Expression buildMethodInvocation( | 95 Expression buildMethodInvocation( |
| 94 Expression receiver, Name name, Arguments arguments, int offset, | 96 Expression receiver, Name name, Arguments arguments, int offset, |
| 95 {bool isConstantExpression, bool isNullAware}); | 97 {bool isConstantExpression, bool isNullAware}); |
| 96 } | 98 } |
| 97 | 99 |
| 98 abstract class FastaAccessor implements Accessor { | 100 abstract class FastaAccessor implements Accessor { |
| 99 BuilderHelper get helper; | 101 BuilderHelper get helper; |
| 100 | 102 |
| 101 String get plainNameForRead; | 103 String get plainNameForRead; |
| 102 | 104 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 131 /* Expression | FastaAccessor | Initializer */ doInvocation( | 133 /* Expression | FastaAccessor | Initializer */ doInvocation( |
| 132 int offset, Arguments arguments); | 134 int offset, Arguments arguments); |
| 133 | 135 |
| 134 /* Expression | FastaAccessor */ buildPropertyAccess( | 136 /* Expression | FastaAccessor */ buildPropertyAccess( |
| 135 IncompleteSend send, bool isNullAware) { | 137 IncompleteSend send, bool isNullAware) { |
| 136 if (send is SendAccessor) { | 138 if (send is SendAccessor) { |
| 137 return helper.buildMethodInvocation(buildSimpleRead(), send.name, | 139 return helper.buildMethodInvocation(buildSimpleRead(), send.name, |
| 138 send.arguments, offsetForToken(send.token), | 140 send.arguments, offsetForToken(send.token), |
| 139 isNullAware: isNullAware); | 141 isNullAware: isNullAware); |
| 140 } else { | 142 } else { |
| 143 if (helper.constantExpressionRequired && send.name != lengthName) { | |
| 144 helper.addCompileTimeError( | |
| 145 offsetForToken(token), "Not a constant expression."); | |
| 146 } | |
| 141 return PropertyAccessor.make(helper, send.token, buildSimpleRead(), | 147 return PropertyAccessor.make(helper, send.token, buildSimpleRead(), |
| 142 send.name, null, null, isNullAware); | 148 send.name, null, null, isNullAware); |
| 143 } | 149 } |
| 144 } | 150 } |
| 145 | 151 |
| 146 /* Expression | FastaAccessor */ buildThrowNoSuchMethodError( | 152 /* Expression | FastaAccessor */ buildThrowNoSuchMethodError( |
| 147 Arguments arguments, | 153 Arguments arguments, |
| 148 {bool isSuper: false, | 154 {bool isSuper: false, |
| 149 bool isGetter: false, | 155 bool isGetter: false, |
| 150 bool isSetter: false, | 156 bool isSetter: false, |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 if (send is SendAccessor) { | 295 if (send is SendAccessor) { |
| 290 // Notice that 'this' or 'super' can't be null. So we can ignore the | 296 // Notice that 'this' or 'super' can't be null. So we can ignore the |
| 291 // value of [isNullAware]. | 297 // value of [isNullAware]. |
| 292 MethodInvocation result = helper.buildMethodInvocation( | 298 MethodInvocation result = helper.buildMethodInvocation( |
| 293 new ThisExpression(), | 299 new ThisExpression(), |
| 294 send.name, | 300 send.name, |
| 295 send.arguments, | 301 send.arguments, |
| 296 offsetForToken(token)); | 302 offsetForToken(token)); |
| 297 return isSuper ? helper.toSuperMethodInvocation(result) : result; | 303 return isSuper ? helper.toSuperMethodInvocation(result) : result; |
| 298 } else { | 304 } else { |
| 305 if (!isInitializer && helper.constantExpressionRequired) { | |
| 306 // TODO(ahe): Remove this? | |
|
ahe
2017/05/30 09:56:28
I've invested the 50-60 minutes it took to answer
| |
| 307 helper.addCompileTimeError( | |
| 308 offsetForToken(token), "Not a constant expression."); | |
| 309 } | |
| 299 if (isSuper) { | 310 if (isSuper) { |
| 300 Member getter = helper.lookupSuperMember(send.name); | 311 Member getter = helper.lookupSuperMember(send.name); |
| 301 Member setter = helper.lookupSuperMember(send.name, isSetter: true); | 312 Member setter = helper.lookupSuperMember(send.name, isSetter: true); |
| 302 return new SuperPropertyAccessor( | 313 return new SuperPropertyAccessor( |
| 303 helper, send.token, send.name, getter, setter); | 314 helper, send.token, send.name, getter, setter); |
| 304 } else { | 315 } else { |
| 305 return new ThisPropertyAccessor( | 316 return new ThisPropertyAccessor( |
| 306 helper, send.token, send.name, null, null); | 317 helper, send.token, send.name, null, null); |
| 307 } | 318 } |
| 308 } | 319 } |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 685 if (builderSetter?.target?.hasSetter ?? false) { | 696 if (builderSetter?.target?.hasSetter ?? false) { |
| 686 setter = builderSetter.target; | 697 setter = builderSetter.target; |
| 687 } | 698 } |
| 688 } | 699 } |
| 689 return new StaticAccessor(helper, token, getter, setter); | 700 return new StaticAccessor(helper, token, getter, setter); |
| 690 } | 701 } |
| 691 | 702 |
| 692 String get plainNameForRead => (readTarget ?? writeTarget).name.name; | 703 String get plainNameForRead => (readTarget ?? writeTarget).name.name; |
| 693 | 704 |
| 694 Expression doInvocation(int offset, Arguments arguments) { | 705 Expression doInvocation(int offset, Arguments arguments) { |
| 706 if (helper.constantExpressionRequired && !helper.isIdentical(readTarget)) { | |
| 707 helper.addCompileTimeError(offset, "Not a constant expression."); | |
| 708 } | |
| 695 if (readTarget == null || isFieldOrGetter(readTarget)) { | 709 if (readTarget == null || isFieldOrGetter(readTarget)) { |
| 696 return helper.buildMethodInvocation(buildSimpleRead(), callName, | 710 return helper.buildMethodInvocation(buildSimpleRead(), callName, |
| 697 arguments, offset + (readTarget?.name?.name?.length ?? 0)); | 711 arguments, offset + (readTarget?.name?.name?.length ?? 0), |
| 712 // This isn't a constant expression, but we have checked if a | |
| 713 // constant expression error should be emitted already. | |
| 714 isConstantExpression: true); | |
| 698 } else { | 715 } else { |
| 699 return helper.buildStaticInvocation(readTarget, arguments) | 716 return helper.buildStaticInvocation(readTarget, arguments) |
| 700 ..fileOffset = offset; | 717 ..fileOffset = offset; |
| 701 } | 718 } |
| 702 } | 719 } |
| 703 | 720 |
| 704 toString() => "StaticAccessor()"; | 721 toString() => "StaticAccessor()"; |
| 705 } | 722 } |
| 706 | 723 |
| 707 class SuperPropertyAccessor extends kernel.SuperPropertyAccessor | 724 class SuperPropertyAccessor extends kernel.SuperPropertyAccessor |
| 708 with FastaAccessor { | 725 with FastaAccessor { |
| 709 SuperPropertyAccessor(BuilderHelper helper, Token token, Name name, | 726 SuperPropertyAccessor(BuilderHelper helper, Token token, Name name, |
| 710 Member getter, Member setter) | 727 Member getter, Member setter) |
| 711 : super(helper, name, getter, setter, token); | 728 : super(helper, name, getter, setter, token); |
| 712 | 729 |
| 713 String get plainNameForRead => name.name; | 730 String get plainNameForRead => name.name; |
| 714 | 731 |
| 715 Expression doInvocation(int offset, Arguments arguments) { | 732 Expression doInvocation(int offset, Arguments arguments) { |
| 733 if (helper.constantExpressionRequired) { | |
| 734 helper.addCompileTimeError(offset, "Not a constant expression."); | |
| 735 } | |
| 716 if (getter == null || isFieldOrGetter(getter)) { | 736 if (getter == null || isFieldOrGetter(getter)) { |
| 717 return helper.buildMethodInvocation( | 737 return helper.buildMethodInvocation( |
| 718 buildSimpleRead(), callName, arguments, offset); | 738 buildSimpleRead(), callName, arguments, offset, |
| 739 // This isn't a constant expression, but we have checked if a | |
| 740 // constant expression error should be emitted already. | |
| 741 isConstantExpression: true); | |
| 719 } else { | 742 } else { |
| 720 return new DirectMethodInvocation(new ThisExpression(), getter, arguments) | 743 return new DirectMethodInvocation(new ThisExpression(), getter, arguments) |
| 721 ..fileOffset = offset; | 744 ..fileOffset = offset; |
| 722 } | 745 } |
| 723 } | 746 } |
| 724 | 747 |
| 725 toString() => "SuperPropertyAccessor()"; | 748 toString() => "SuperPropertyAccessor()"; |
| 726 } | 749 } |
| 727 | 750 |
| 728 class ThisIndexAccessor extends kernel.ThisIndexAccessor with FastaAccessor { | 751 class ThisIndexAccessor extends kernel.ThisIndexAccessor with FastaAccessor { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 {bool isGetter: false, bool isSetter: false, int offset}) { | 888 {bool isGetter: false, bool isSetter: false, int offset}) { |
| 866 return helper.throwNoSuchMethodError( | 889 return helper.throwNoSuchMethodError( |
| 867 plainNameForRead, arguments, offset ?? offsetForToken(this.token), | 890 plainNameForRead, arguments, offset ?? offsetForToken(this.token), |
| 868 isGetter: isGetter, isSetter: isSetter); | 891 isGetter: isGetter, isSetter: isSetter); |
| 869 } | 892 } |
| 870 } | 893 } |
| 871 | 894 |
| 872 bool isFieldOrGetter(Member member) { | 895 bool isFieldOrGetter(Member member) { |
| 873 return member is Field || (member is Procedure && member.isGetter); | 896 return member is Field || (member is Procedure && member.isGetter); |
| 874 } | 897 } |
| OLD | NEW |