| 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 |