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 export 'package:kernel/frontend/accessors.dart' show wrapInvalid; | 7 export 'package:kernel/frontend/accessors.dart' show wrapInvalid; |
8 | 8 |
9 import 'package:kernel/frontend/accessors.dart' | 9 import 'package:kernel/frontend/accessors.dart' |
10 show Accessor, buildIsNull, makeLet; | 10 show Accessor, buildIsNull, makeLet; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 | 81 |
82 Expression makeInvalidRead() { | 82 Expression makeInvalidRead() { |
83 return buildThrowNoSuchMethodError(new Arguments.empty(), isGetter: true); | 83 return buildThrowNoSuchMethodError(new Arguments.empty(), isGetter: true); |
84 } | 84 } |
85 | 85 |
86 Expression makeInvalidWrite(Expression value) { | 86 Expression makeInvalidWrite(Expression value) { |
87 return buildThrowNoSuchMethodError(new Arguments(<Expression>[value]), | 87 return buildThrowNoSuchMethodError(new Arguments(<Expression>[value]), |
88 isSetter: true); | 88 isSetter: true); |
89 } | 89 } |
90 | 90 |
91 /* Expression | FastaAccessor */ doInvocation( | 91 /* Expression | FastaAccessor | Initializer */ doInvocation( |
92 int offset, Arguments arguments); | 92 int offset, Arguments arguments); |
93 | 93 |
94 /* Expression | FastaAccessor */ buildPropertyAccess( | 94 /* Expression | FastaAccessor */ buildPropertyAccess( |
95 IncompleteSend send, bool isNullAware) { | 95 IncompleteSend send, bool isNullAware) { |
96 if (send is SendAccessor) { | 96 if (send is SendAccessor) { |
97 return buildMethodInvocation( | 97 return buildMethodInvocation( |
98 buildSimpleRead(), send.name, send.arguments, send.offset, | 98 buildSimpleRead(), send.name, send.arguments, send.offset, |
99 isNullAware: isNullAware); | 99 isNullAware: isNullAware); |
100 } else { | 100 } else { |
101 return PropertyAccessor.make(helper, send.offset, buildSimpleRead(), | 101 return PropertyAccessor.make(helper, send.offset, buildSimpleRead(), |
102 send.name, null, null, isNullAware); | 102 send.name, null, null, isNullAware); |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 /* Expression | FastaAccessor */ buildThrowNoSuchMethodError( | 106 /* Expression | FastaAccessor */ buildThrowNoSuchMethodError( |
107 Arguments arguments, | 107 Arguments arguments, |
108 {bool isSuper: false, | 108 {bool isSuper: false, |
109 isGetter: false, | 109 bool isGetter: false, |
110 isSetter: false, | 110 bool isSetter: false, |
111 String name, | 111 String name, |
112 int offset}) { | 112 int offset}) { |
113 return helper.throwNoSuchMethodError( | 113 return helper.throwNoSuchMethodError( |
114 name ?? plainNameForWrite, arguments, offset ?? this.offset, | 114 name ?? plainNameForWrite, arguments, offset ?? this.offset, |
115 isGetter: isGetter, isSetter: isSetter, isSuper: isSuper); | 115 isGetter: isGetter, isSetter: isSetter, isSuper: isSuper); |
116 } | 116 } |
117 | 117 |
118 bool get isThisPropertyAccessor => false; | 118 bool get isThisPropertyAccessor => false; |
119 } | 119 } |
120 | 120 |
121 abstract class CompileTimeErrorAccessor implements FastaAccessor { | 121 abstract class ErrorAccessor implements FastaAccessor { |
122 @override | 122 @override |
123 Expression get builtBinary => internalError("Unsupported operation."); | 123 Expression get builtBinary => internalError("Unsupported operation."); |
124 | 124 |
125 @override | 125 @override |
126 void set builtBinary(Expression expression) { | 126 void set builtBinary(Expression expression) { |
127 internalError("Unsupported operation."); | 127 internalError("Unsupported operation."); |
128 } | 128 } |
129 | 129 |
130 @override | 130 @override |
131 Expression get builtGetter => internalError("Unsupported operation."); | 131 Expression get builtGetter => internalError("Unsupported operation."); |
132 | 132 |
133 @override | 133 @override |
134 void set builtGetter(Expression expression) { | 134 void set builtGetter(Expression expression) { |
135 internalError("Unsupported operation."); | 135 internalError("Unsupported operation."); |
136 } | 136 } |
137 | 137 |
138 Expression buildError(); | 138 /// Pass [arguments] that must be evaluated before throwing an error. At |
| 139 /// most one of [isGetter] and [isSetter] should be true and they're passed |
| 140 /// to [BuilderHelper.buildThrowNoSuchMethodError] if it is used. |
| 141 Expression buildError(Arguments arguments, |
| 142 {bool isGetter: false, bool isSetter: false, int offset}); |
139 | 143 |
140 Name get name => internalError("Unsupported operation."); | 144 Name get name => internalError("Unsupported operation."); |
141 | 145 |
| 146 @override |
142 String get plainNameForRead => name.name; | 147 String get plainNameForRead => name.name; |
143 | 148 |
144 withReceiver(Object receiver, {bool isNullAware}) => this; | 149 withReceiver(Object receiver, {bool isNullAware}) => this; |
145 | 150 |
| 151 @override |
146 Initializer buildFieldInitializer( | 152 Initializer buildFieldInitializer( |
147 Map<String, FieldInitializer> initializers) { | 153 Map<String, FieldInitializer> initializers) { |
148 return new LocalInitializer(new VariableDeclaration.forValue(buildError())); | 154 return new LocalInitializer(new VariableDeclaration.forValue( |
| 155 buildError(new Arguments.empty(), isSetter: true))); |
149 } | 156 } |
150 | 157 |
151 doInvocation(int offset, Arguments arguments) => this; | 158 @override |
| 159 doInvocation(int offset, Arguments arguments) { |
| 160 return buildError(arguments, offset: offset); |
| 161 } |
152 | 162 |
| 163 @override |
153 buildPropertyAccess(IncompleteSend send, bool isNullAware) => this; | 164 buildPropertyAccess(IncompleteSend send, bool isNullAware) => this; |
154 | 165 |
| 166 @override |
155 buildThrowNoSuchMethodError(Arguments arguments, | 167 buildThrowNoSuchMethodError(Arguments arguments, |
156 {bool isSuper: false, | 168 {bool isSuper: false, |
157 isGetter: false, | 169 isGetter: false, |
158 isSetter: false, | 170 isSetter: false, |
159 String name, | 171 String name, |
160 int offset}) { | 172 int offset}) { |
161 return this; | 173 return this; |
162 } | 174 } |
163 | 175 |
| 176 @override |
164 Expression buildAssignment(Expression value, {bool voidContext: false}) { | 177 Expression buildAssignment(Expression value, {bool voidContext: false}) { |
165 return buildError(); | 178 return buildError(new Arguments(<Expression>[value]), isSetter: true); |
166 } | 179 } |
167 | 180 |
| 181 @override |
168 Expression buildCompoundAssignment(Name binaryOperator, Expression value, | 182 Expression buildCompoundAssignment(Name binaryOperator, Expression value, |
169 {int offset: TreeNode.noOffset, | 183 {int offset: TreeNode.noOffset, |
170 bool voidContext: false, | 184 bool voidContext: false, |
171 Procedure interfaceTarget}) { | 185 Procedure interfaceTarget}) { |
172 return buildError(); | 186 return buildError(new Arguments(<Expression>[value]), isGetter: true); |
173 } | 187 } |
174 | 188 |
| 189 @override |
175 Expression buildPrefixIncrement(Name binaryOperator, | 190 Expression buildPrefixIncrement(Name binaryOperator, |
176 {int offset: TreeNode.noOffset, | 191 {int offset: TreeNode.noOffset, |
177 bool voidContext: false, | 192 bool voidContext: false, |
178 Procedure interfaceTarget}) { | 193 Procedure interfaceTarget}) { |
179 return buildError(); | 194 return buildError(new Arguments(<Expression>[new IntLiteral(1)]), |
| 195 isGetter: true); |
180 } | 196 } |
181 | 197 |
| 198 @override |
182 Expression buildPostfixIncrement(Name binaryOperator, | 199 Expression buildPostfixIncrement(Name binaryOperator, |
183 {int offset: TreeNode.noOffset, | 200 {int offset: TreeNode.noOffset, |
184 bool voidContext: false, | 201 bool voidContext: false, |
185 Procedure interfaceTarget}) { | 202 Procedure interfaceTarget}) { |
186 return buildError(); | 203 return buildError(new Arguments(<Expression>[new IntLiteral(1)]), |
| 204 isGetter: true); |
187 } | 205 } |
188 | 206 |
| 207 @override |
189 Expression buildNullAwareAssignment(Expression value, DartType type, | 208 Expression buildNullAwareAssignment(Expression value, DartType type, |
190 {bool voidContext: false}) { | 209 {bool voidContext: false}) { |
191 return buildError(); | 210 return buildError(new Arguments(<Expression>[value]), isSetter: true); |
192 } | 211 } |
193 | 212 |
194 Expression buildSimpleRead() => buildError(); | 213 @override |
| 214 Expression buildSimpleRead() => |
| 215 buildError(new Arguments.empty(), isGetter: true); |
195 | 216 |
196 Expression makeInvalidRead() => buildError(); | 217 @override |
| 218 Expression makeInvalidRead() => |
| 219 buildError(new Arguments.empty(), isGetter: true); |
197 | 220 |
198 Expression makeInvalidWrite(Expression value) => buildError(); | 221 @override |
| 222 Expression makeInvalidWrite(Expression value) { |
| 223 return buildError(new Arguments(<Expression>[value]), isSetter: true); |
| 224 } |
199 } | 225 } |
200 | 226 |
201 class ThisAccessor extends FastaAccessor { | 227 class ThisAccessor extends FastaAccessor { |
202 final BuilderHelper helper; | 228 final BuilderHelper helper; |
203 | 229 |
204 final int offset; | 230 final int offset; |
205 | 231 |
206 final bool isInitializer; | 232 final bool isInitializer; |
207 | 233 |
208 final bool isSuper; | 234 final bool isSuper; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 Expression get builtGetter => internalError("Unsupported operation."); | 380 Expression get builtGetter => internalError("Unsupported operation."); |
355 | 381 |
356 @override | 382 @override |
357 void set builtGetter(Expression expression) { | 383 void set builtGetter(Expression expression) { |
358 internalError("Unsupported operation."); | 384 internalError("Unsupported operation."); |
359 } | 385 } |
360 | 386 |
361 withReceiver(Object receiver, {bool isNullAware}); | 387 withReceiver(Object receiver, {bool isNullAware}); |
362 } | 388 } |
363 | 389 |
364 class IncompleteError extends IncompleteSend with CompileTimeErrorAccessor { | 390 class IncompleteError extends IncompleteSend with ErrorAccessor { |
365 final Object error; | 391 final Object error; |
366 | 392 |
367 IncompleteError(BuilderHelper helper, int offset, this.error) | 393 IncompleteError(BuilderHelper helper, int offset, this.error) |
368 : super(helper, offset, null); | 394 : super(helper, offset, null); |
369 | 395 |
370 Expression buildError() { | 396 @override |
371 return helper.buildCompileTimeError(error, offset); | 397 Expression buildError(Arguments arguments, |
| 398 {bool isGetter: false, bool isSetter: false, int offset}) { |
| 399 return helper.buildCompileTimeError(error, offset ?? this.offset); |
372 } | 400 } |
| 401 |
| 402 @override |
| 403 doInvocation(int offset, Arguments arguments) => this; |
373 } | 404 } |
374 | 405 |
375 class SendAccessor extends IncompleteSend { | 406 class SendAccessor extends IncompleteSend { |
376 final Arguments arguments; | 407 final Arguments arguments; |
377 | 408 |
378 SendAccessor(BuilderHelper helper, int offset, Name name, this.arguments) | 409 SendAccessor(BuilderHelper helper, int offset, Name name, this.arguments) |
379 : super(helper, offset, name) { | 410 : super(helper, offset, name) { |
380 assert(arguments != null); | 411 assert(arguments != null); |
381 } | 412 } |
382 | 413 |
(...skipping 18 matching lines...) Expand all Loading... |
401 } | 432 } |
402 if (receiver is PrefixBuilder) { | 433 if (receiver is PrefixBuilder) { |
403 PrefixBuilder prefix = receiver; | 434 PrefixBuilder prefix = receiver; |
404 receiver = helper.builderToFirstExpression( | 435 receiver = helper.builderToFirstExpression( |
405 prefix.exports[name.name], "${prefix.name}.${name.name}", offset); | 436 prefix.exports[name.name], "${prefix.name}.${name.name}", offset); |
406 return helper.finishSend(receiver, arguments, offset); | 437 return helper.finishSend(receiver, arguments, offset); |
407 } | 438 } |
408 Expression result; | 439 Expression result; |
409 if (receiver is KernelClassBuilder) { | 440 if (receiver is KernelClassBuilder) { |
410 Builder builder = receiver.findStaticBuilder(name.name, offset, uri); | 441 Builder builder = receiver.findStaticBuilder(name.name, offset, uri); |
411 if (builder == null) { | 442 if (builder == null || builder is AccessErrorBuilder) { |
412 return buildThrowNoSuchMethodError(arguments); | 443 return buildThrowNoSuchMethodError(arguments); |
413 } | 444 } |
414 if (builder.hasProblem) { | 445 if (builder.hasProblem) { |
415 result = helper.buildProblemExpression(builder, offset); | 446 result = helper.buildProblemExpression(builder, offset); |
416 } else { | 447 } else { |
417 Member target = builder.target; | 448 Member target = builder.target; |
418 if (target != null) { | 449 if (target != null) { |
419 if (target is Field) { | 450 if (target is Field) { |
420 result = buildMethodInvocation(new StaticGet(target), callName, | 451 result = buildMethodInvocation(new StaticGet(target), callName, |
421 arguments, offset + (target.name?.name?.length ?? 0), | 452 arguments, offset + (target.name?.name?.length ?? 0), |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 ParenthesizedExpression( | 826 ParenthesizedExpression( |
796 BuilderHelper helper, Expression expression, int offset) | 827 BuilderHelper helper, Expression expression, int offset) |
797 : super(helper, expression, "<a parenthesized expression>", offset); | 828 : super(helper, expression, "<a parenthesized expression>", offset); |
798 | 829 |
799 Expression makeInvalidWrite(Expression value) { | 830 Expression makeInvalidWrite(Expression value) { |
800 return helper.buildCompileTimeError( | 831 return helper.buildCompileTimeError( |
801 "Can't assign to a parenthesized expression.", offset); | 832 "Can't assign to a parenthesized expression.", offset); |
802 } | 833 } |
803 } | 834 } |
804 | 835 |
| 836 class UnresolvedAccessor extends FastaAccessor with ErrorAccessor { |
| 837 @override |
| 838 final int offset; |
| 839 |
| 840 @override |
| 841 final BuilderHelper helper; |
| 842 |
| 843 @override |
| 844 final Name name; |
| 845 |
| 846 UnresolvedAccessor(this.helper, this.name, this.offset); |
| 847 |
| 848 Expression doInvocation(int charOffset, Arguments arguments) { |
| 849 return buildError(arguments, offset: charOffset); |
| 850 } |
| 851 |
| 852 @override |
| 853 Expression buildError(Arguments arguments, |
| 854 {bool isGetter: false, bool isSetter: false, int offset}) { |
| 855 return helper.throwNoSuchMethodError( |
| 856 plainNameForRead, arguments, offset ?? this.offset, |
| 857 isGetter: isGetter, isSetter: isSetter); |
| 858 } |
| 859 } |
| 860 |
805 bool isFieldOrGetter(Member member) { | 861 bool isFieldOrGetter(Member member) { |
806 return member is Field || (member is Procedure && member.isGetter); | 862 return member is Field || (member is Procedure && member.isGetter); |
807 } | 863 } |
808 | 864 |
809 Expression buildMethodInvocation( | 865 Expression buildMethodInvocation( |
810 Expression receiver, Name name, Arguments arguments, int offset, | 866 Expression receiver, Name name, Arguments arguments, int offset, |
811 {bool isNullAware: false}) { | 867 {bool isNullAware: false}) { |
812 if (isNullAware) { | 868 if (isNullAware) { |
813 VariableDeclaration variable = new VariableDeclaration.forValue(receiver); | 869 VariableDeclaration variable = new VariableDeclaration.forValue(receiver); |
814 return makeLet( | 870 return makeLet( |
815 variable, | 871 variable, |
816 new ConditionalExpression( | 872 new ConditionalExpression( |
817 buildIsNull(new VariableGet(variable)), | 873 buildIsNull(new VariableGet(variable)), |
818 new NullLiteral(), | 874 new NullLiteral(), |
819 new MethodInvocation(new VariableGet(variable), name, arguments) | 875 new MethodInvocation(new VariableGet(variable), name, arguments) |
820 ..fileOffset = offset, | 876 ..fileOffset = offset, |
821 const DynamicType())); | 877 const DynamicType())); |
822 } else { | 878 } else { |
823 return new MethodInvocation(receiver, name, arguments)..fileOffset = offset; | 879 return new MethodInvocation(receiver, name, arguments)..fileOffset = offset; |
824 } | 880 } |
825 } | 881 } |
OLD | NEW |