| 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 '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
| 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
| 9 | 9 |
| 10 import '../parser/parser.dart' show FormalParameterType, optional; | 10 import '../parser/parser.dart' show FormalParameterType, optional; |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 } | 733 } |
| 734 push(new Identifier(name, token.charOffset)); | 734 push(new Identifier(name, token.charOffset)); |
| 735 } | 735 } |
| 736 | 736 |
| 737 /// Look up [name] in [scope] using [charOffset] to report any | 737 /// Look up [name] in [scope] using [charOffset] to report any |
| 738 /// problems. [isQualified] should be true if [name] is a qualified access | 738 /// problems. [isQualified] should be true if [name] is a qualified access |
| 739 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] | 739 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] |
| 740 /// if the name doesn't resolve in the scope). | 740 /// if the name doesn't resolve in the scope). |
| 741 @override | 741 @override |
| 742 scopeLookup(Scope scope, String name, int charOffset, | 742 scopeLookup(Scope scope, String name, int charOffset, |
| 743 {bool isQualified: false}) { | 743 {bool isQualified: false, PrefixBuilder prefix}) { |
| 744 Builder builder = scope.lookup(name, charOffset, uri); | 744 Builder builder = scope.lookup(name, charOffset, uri); |
| 745 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { | 745 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { |
| 746 Name n = new Name(name, library.library); | 746 Name n = new Name(name, library.library); |
| 747 if (!isQualified && isInstanceContext) { | 747 if (prefix != null && |
| 748 prefix.deferred && |
| 749 builder == null && |
| 750 "loadLibrary" == name) { |
| 751 return buildCompileTimeError( |
| 752 "Deferred loading isn't implemented yet.", charOffset); |
| 753 } else if (!isQualified && isInstanceContext) { |
| 748 assert(builder == null); | 754 assert(builder == null); |
| 749 if (constantExpressionRequired) { | 755 if (constantExpressionRequired) { |
| 750 return new UnresolvedAccessor(this, n, charOffset); | 756 return new UnresolvedAccessor(this, n, charOffset); |
| 751 } | 757 } |
| 752 return new ThisPropertyAccessor(this, charOffset, n, null, null); | 758 return new ThisPropertyAccessor(this, charOffset, n, null, null); |
| 753 } else if (isDartLibrary && | 759 } else if (isDartLibrary && |
| 754 name == "main" && | 760 name == "main" && |
| 755 library.uri.path == "_builtin" && | 761 library.uri.path == "_builtin" && |
| 756 member?.name == "_getMainClosure") { | 762 member?.name == "_getMainClosure") { |
| 757 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 | 763 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 772 } else if (builder.isInstanceMember) { | 778 } else if (builder.isInstanceMember) { |
| 773 if (constantExpressionRequired) { | 779 if (constantExpressionRequired) { |
| 774 addCompileTimeError(charOffset, "Not a constant expression."); | 780 addCompileTimeError(charOffset, "Not a constant expression."); |
| 775 } | 781 } |
| 776 return new ThisPropertyAccessor( | 782 return new ThisPropertyAccessor( |
| 777 this, charOffset, new Name(name, library.library), null, null); | 783 this, charOffset, new Name(name, library.library), null, null); |
| 778 } else if (builder.isRegularMethod) { | 784 } else if (builder.isRegularMethod) { |
| 779 assert(builder.isStatic || builder.isTopLevel); | 785 assert(builder.isStatic || builder.isTopLevel); |
| 780 return new StaticAccessor(this, charOffset, builder.target, null); | 786 return new StaticAccessor(this, charOffset, builder.target, null); |
| 781 } else if (builder is PrefixBuilder) { | 787 } else if (builder is PrefixBuilder) { |
| 788 if (constantExpressionRequired && builder.deferred) { |
| 789 addCompileTimeError( |
| 790 charOffset, |
| 791 "'$name' can't be used in a constant expression because it's " |
| 792 "marked as 'deferred' which means it isn't available until " |
| 793 "loaded.\n" |
| 794 "You might try moving the constant to the deferred library, " |
| 795 "or removing 'deferred' from the import."); |
| 796 } |
| 782 return builder; | 797 return builder; |
| 783 } else { | 798 } else { |
| 784 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; | 799 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; |
| 785 Builder setter; | 800 Builder setter; |
| 786 if (builder.isSetter) { | 801 if (builder.isSetter) { |
| 787 setter = builder; | 802 setter = builder; |
| 788 } else if (builder.isGetter) { | 803 } else if (builder.isGetter) { |
| 789 setter = scope.lookupSetter(name, charOffset, uri); | 804 setter = scope.lookupSetter(name, charOffset, uri); |
| 790 } else if (builder.isField && !builder.isFinal) { | 805 } else if (builder.isField && !builder.isFinal) { |
| 791 setter = builder; | 806 setter = builder; |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 suffix = suffix.name; | 1287 suffix = suffix.name; |
| 1273 } | 1288 } |
| 1274 Builder builder; | 1289 Builder builder; |
| 1275 if (prefix is Builder) { | 1290 if (prefix is Builder) { |
| 1276 builder = prefix; | 1291 builder = prefix; |
| 1277 } else { | 1292 } else { |
| 1278 builder = scope.lookup(prefix, beginToken.charOffset, uri); | 1293 builder = scope.lookup(prefix, beginToken.charOffset, uri); |
| 1279 } | 1294 } |
| 1280 if (builder is PrefixBuilder) { | 1295 if (builder is PrefixBuilder) { |
| 1281 name = scopeLookup(builder.exports, suffix, beginToken.charOffset, | 1296 name = scopeLookup(builder.exports, suffix, beginToken.charOffset, |
| 1282 isQualified: true); | 1297 isQualified: true, prefix: builder); |
| 1283 } else { | 1298 } else { |
| 1284 push(const DynamicType()); | 1299 push(const DynamicType()); |
| 1285 addCompileTimeError(beginToken.charOffset, | 1300 addCompileTimeError(beginToken.charOffset, |
| 1286 "Can't be used as a type: '${debugName(prefix, suffix)}'."); | 1301 "Can't be used as a type: '${debugName(prefix, suffix)}'."); |
| 1287 return; | 1302 return; |
| 1288 } | 1303 } |
| 1289 } | 1304 } |
| 1290 if (name is Identifier) { | 1305 if (name is Identifier) { |
| 1291 name = name.name; | 1306 name = name.name; |
| 1292 } | 1307 } |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 // should be handled later. | 1667 // should be handled later. |
| 1653 Identifier suffix = popIfNotNull(periodBeforeName); | 1668 Identifier suffix = popIfNotNull(periodBeforeName); |
| 1654 Identifier identifier; | 1669 Identifier identifier; |
| 1655 List<DartType> typeArguments = pop(); | 1670 List<DartType> typeArguments = pop(); |
| 1656 dynamic type = pop(); | 1671 dynamic type = pop(); |
| 1657 if (type is List) { | 1672 if (type is List) { |
| 1658 var prefix = type[0]; | 1673 var prefix = type[0]; |
| 1659 identifier = type[1]; | 1674 identifier = type[1]; |
| 1660 if (prefix is PrefixBuilder) { | 1675 if (prefix is PrefixBuilder) { |
| 1661 type = scopeLookup(prefix.exports, identifier.name, start.charOffset, | 1676 type = scopeLookup(prefix.exports, identifier.name, start.charOffset, |
| 1662 isQualified: true); | 1677 isQualified: true, prefix: prefix); |
| 1663 identifier = null; | 1678 identifier = null; |
| 1664 } else if (prefix is ClassBuilder) { | 1679 } else if (prefix is ClassBuilder) { |
| 1665 type = prefix; | 1680 type = prefix; |
| 1666 } else { | 1681 } else { |
| 1667 type = new Identifier(start.lexeme, start.charOffset); | 1682 type = new Identifier(start.lexeme, start.charOffset); |
| 1668 } | 1683 } |
| 1669 } | 1684 } |
| 1670 String name; | 1685 String name; |
| 1671 if (identifier != null && suffix != null) { | 1686 if (identifier != null && suffix != null) { |
| 1672 name = "${identifier.name}.${suffix.name}"; | 1687 name = "${identifier.name}.${suffix.name}"; |
| (...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2925 } else if (node is PrefixBuilder) { | 2940 } else if (node is PrefixBuilder) { |
| 2926 return node.name; | 2941 return node.name; |
| 2927 } else if (node is ThisAccessor) { | 2942 } else if (node is ThisAccessor) { |
| 2928 return node.isSuper ? "super" : "this"; | 2943 return node.isSuper ? "super" : "this"; |
| 2929 } else if (node is FastaAccessor) { | 2944 } else if (node is FastaAccessor) { |
| 2930 return node.plainNameForRead; | 2945 return node.plainNameForRead; |
| 2931 } else { | 2946 } else { |
| 2932 return internalError("Unhandled: ${node.runtimeType}"); | 2947 return internalError("Unhandled: ${node.runtimeType}"); |
| 2933 } | 2948 } |
| 2934 } | 2949 } |
| OLD | NEW |