| 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.builder_accessors; | 5 library fasta.builder_accessors; |
| 6 | 6 |
| 7 export 'frontend_accessors.dart' show wrapInvalid; | 7 export 'frontend_accessors.dart' show wrapInvalid; |
| 8 | 8 |
| 9 import 'frontend_accessors.dart' show Accessor; | 9 import 'frontend_accessors.dart' show Accessor; |
| 10 | 10 |
| 11 import 'package:kernel/ast.dart'; | 11 import 'package:kernel/ast.dart'; |
| 12 | 12 |
| 13 import 'package:kernel/core_types.dart' show CoreTypes; | 13 import 'package:kernel/core_types.dart' show CoreTypes; |
| 14 | 14 |
| 15 import '../builder/scope.dart' show ProblemBuilder; | 15 import '../builder/scope.dart' show AccessErrorBuilder, ProblemBuilder; |
| 16 | 16 |
| 17 import '../errors.dart' show internalError, printUnexpected; | 17 import '../errors.dart' show internalError, printUnexpected; |
| 18 | 18 |
| 19 import 'frontend_accessors.dart' as kernel | 19 import 'frontend_accessors.dart' as kernel |
| 20 show | 20 show |
| 21 IndexAccessor, | 21 IndexAccessor, |
| 22 NullAwarePropertyAccessor, | 22 NullAwarePropertyAccessor, |
| 23 PropertyAccessor, | 23 PropertyAccessor, |
| 24 StaticAccessor, | 24 StaticAccessor, |
| 25 SuperIndexAccessor, | 25 SuperIndexAccessor, |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 if (receiver is BuilderAccessor) { | 422 if (receiver is BuilderAccessor) { |
| 423 return receiver.buildPropertyAccess(this, isNullAware); | 423 return receiver.buildPropertyAccess(this, isNullAware); |
| 424 } | 424 } |
| 425 if (receiver is PrefixBuilder) { | 425 if (receiver is PrefixBuilder) { |
| 426 PrefixBuilder prefix = receiver; | 426 PrefixBuilder prefix = receiver; |
| 427 return helper.builderToFirstExpression( | 427 return helper.builderToFirstExpression( |
| 428 prefix.exports[name.name], name.name, charOffset); | 428 prefix.exports[name.name], name.name, charOffset); |
| 429 } | 429 } |
| 430 if (receiver is KernelClassBuilder) { | 430 if (receiver is KernelClassBuilder) { |
| 431 Builder builder = receiver.findStaticBuilder(name.name, charOffset, uri); | 431 Builder builder = receiver.findStaticBuilder(name.name, charOffset, uri); |
| 432 Member getter = builder?.target; | |
| 433 Member setter; | |
| 434 if (builder == null) { | 432 if (builder == null) { |
| 435 builder = receiver.findStaticBuilder(name.name, charOffset, uri, | 433 // If we find a setter, [builder] is an [AccessErrorBuilder], not null. |
| 434 return buildThrowNoSuchMethodError(null); |
| 435 } |
| 436 Builder setter; |
| 437 if (builder.isSetter) { |
| 438 setter = builder; |
| 439 } else if (builder.isGetter) { |
| 440 setter = receiver.findStaticBuilder(name.name, charOffset, uri, |
| 436 isSetter: true); | 441 isSetter: true); |
| 437 if (builder == null) { | 442 } else if (builder.isField && !builder.isFinal) { |
| 438 return buildThrowNoSuchMethodError(null); | 443 setter = builder; |
| 439 } | |
| 440 setter = builder.target; | |
| 441 } | 444 } |
| 442 if (builder.hasProblem) { | 445 return new StaticAccessor.fromBuilder( |
| 443 return helper.buildProblemExpression(builder, charOffset); | 446 helper, builder, charOffset, setter); |
| 444 } | |
| 445 if (getter is Field) { | |
| 446 if (!getter.isFinal && !getter.isConst) { | |
| 447 setter = getter; | |
| 448 } | |
| 449 } else if (getter is Procedure) { | |
| 450 if (getter.isGetter) { | |
| 451 builder = receiver.findStaticBuilder(name.name, charOffset, uri, | |
| 452 isSetter: true); | |
| 453 if (builder != null && !builder.hasProblem) { | |
| 454 setter = builder.target; | |
| 455 } | |
| 456 } | |
| 457 } | |
| 458 if (getter == null && setter == null) { | |
| 459 return internalError("No accessor for '$name'."); | |
| 460 } | |
| 461 return new StaticAccessor(helper, charOffset, getter, setter); | |
| 462 } | 447 } |
| 463 return PropertyAccessor.make(helper, charOffset, helper.toValue(receiver), | 448 return PropertyAccessor.make(helper, charOffset, helper.toValue(receiver), |
| 464 name, null, null, isNullAware); | 449 name, null, null, isNullAware); |
| 465 } | 450 } |
| 466 | 451 |
| 467 Expression buildNullAwareAssignment(Expression value, DartType type, | 452 Expression buildNullAwareAssignment(Expression value, DartType type, |
| 468 {bool voidContext: false}) { | 453 {bool voidContext: false}) { |
| 469 return internalError("Unhandled"); | 454 return internalError("Unhandled"); |
| 470 } | 455 } |
| 471 | 456 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 final BuilderHelper helper; | 552 final BuilderHelper helper; |
| 568 | 553 |
| 569 final int charOffset; | 554 final int charOffset; |
| 570 | 555 |
| 571 StaticAccessor( | 556 StaticAccessor( |
| 572 this.helper, this.charOffset, Member readTarget, Member writeTarget) | 557 this.helper, this.charOffset, Member readTarget, Member writeTarget) |
| 573 : super(readTarget, writeTarget) { | 558 : super(readTarget, writeTarget) { |
| 574 assert(readTarget != null || writeTarget != null); | 559 assert(readTarget != null || writeTarget != null); |
| 575 } | 560 } |
| 576 | 561 |
| 562 factory StaticAccessor.fromBuilder(BuilderHelper helper, Builder builder, |
| 563 int charOffset, Builder builderSetter) { |
| 564 if (builder is AccessErrorBuilder) { |
| 565 AccessErrorBuilder error = builder; |
| 566 builder = error.builder; |
| 567 // We should only see an access error here if we've looked up a setter |
| 568 // when not explicitly looking for a setter. |
| 569 assert(builder.isSetter); |
| 570 } else if (builder.target == null) { |
| 571 return internalError("Unhandled: ${builder}"); |
| 572 } |
| 573 Member getter = builder.target.hasGetter ? builder.target : null; |
| 574 Member setter = builder.target.hasSetter ? builder.target : null; |
| 575 if (setter == null) { |
| 576 if (builderSetter?.target?.hasSetter ?? false) { |
| 577 setter = builderSetter.target; |
| 578 } |
| 579 } |
| 580 return new StaticAccessor(helper, charOffset, getter, setter); |
| 581 } |
| 582 |
| 577 String get plainNameForRead => (readTarget ?? writeTarget).name.name; | 583 String get plainNameForRead => (readTarget ?? writeTarget).name.name; |
| 578 | 584 |
| 579 Expression doInvocation(int charOffset, Arguments arguments) { | 585 Expression doInvocation(int charOffset, Arguments arguments) { |
| 580 if (readTarget == null || isFieldOrGetter(readTarget)) { | 586 if (readTarget == null || isFieldOrGetter(readTarget)) { |
| 581 return buildMethodInvocation( | 587 return buildMethodInvocation( |
| 582 buildSimpleRead(), new Name("call"), arguments, charOffset); | 588 buildSimpleRead(), new Name("call"), arguments, charOffset); |
| 583 } else { | 589 } else { |
| 584 return helper.buildStaticInvocation(readTarget, arguments) | 590 return helper.buildStaticInvocation(readTarget, arguments) |
| 585 ..fileOffset = charOffset; | 591 ..fileOffset = charOffset; |
| 586 } | 592 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 return buildMethodInvocation(buildSimpleRead(), new Name("call"), arguments, | 725 return buildMethodInvocation(buildSimpleRead(), new Name("call"), arguments, |
| 720 charOffset + (variable.name?.length ?? 0)); | 726 charOffset + (variable.name?.length ?? 0)); |
| 721 } | 727 } |
| 722 | 728 |
| 723 toString() => "VariableAccessor()"; | 729 toString() => "VariableAccessor()"; |
| 724 } | 730 } |
| 725 | 731 |
| 726 Expression throwNoSuchMethodError(String name, Arguments arguments, Uri uri, | 732 Expression throwNoSuchMethodError(String name, Arguments arguments, Uri uri, |
| 727 int charOffset, CoreTypes coreTypes, | 733 int charOffset, CoreTypes coreTypes, |
| 728 {bool isSuper: false, isGetter: false, isSetter: false}) { | 734 {bool isSuper: false, isGetter: false, isSetter: false}) { |
| 729 printUnexpected(uri, charOffset, "Method not found: '$name'."); | 735 String errorName = name; |
| 736 if (isSuper) { |
| 737 errorName = "super.$name"; |
| 738 } |
| 739 if (isGetter) { |
| 740 printUnexpected(uri, charOffset, "Getter not found: '$errorName'."); |
| 741 } else if (isSetter) { |
| 742 printUnexpected(uri, charOffset, "Setter not found: '$errorName'."); |
| 743 } else { |
| 744 printUnexpected(uri, charOffset, "Method not found: '$name'."); |
| 745 } |
| 730 Constructor constructor = | 746 Constructor constructor = |
| 731 coreTypes.getClass("dart:core", "NoSuchMethodError").constructors.first; | 747 coreTypes.getClass("dart:core", "NoSuchMethodError").constructors.first; |
| 732 return new Throw(new ConstructorInvocation( | 748 return new Throw(new ConstructorInvocation( |
| 733 constructor, | 749 constructor, |
| 734 new Arguments(<Expression>[ | 750 new Arguments(<Expression>[ |
| 735 new NullLiteral(), | 751 new NullLiteral(), |
| 736 new SymbolLiteral(name), | 752 new SymbolLiteral(name), |
| 737 new ListLiteral(arguments.positional), | 753 new ListLiteral(arguments.positional), |
| 738 new MapLiteral(arguments.named.map((arg) { | 754 new MapLiteral(arguments.named.map((arg) { |
| 739 return new MapEntry(new SymbolLiteral(arg.name), arg.value); | 755 return new MapEntry(new SymbolLiteral(arg.name), arg.value); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 757 buildIsNull(new VariableGet(variable)), | 773 buildIsNull(new VariableGet(variable)), |
| 758 new NullLiteral(), | 774 new NullLiteral(), |
| 759 new MethodInvocation(new VariableGet(variable), name, arguments) | 775 new MethodInvocation(new VariableGet(variable), name, arguments) |
| 760 ..fileOffset = charOffset, | 776 ..fileOffset = charOffset, |
| 761 const DynamicType())); | 777 const DynamicType())); |
| 762 } else { | 778 } else { |
| 763 return new MethodInvocation(receiver, name, arguments) | 779 return new MethodInvocation(receiver, name, arguments) |
| 764 ..fileOffset = charOffset; | 780 ..fileOffset = charOffset; |
| 765 } | 781 } |
| 766 } | 782 } |
| OLD | NEW |