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' show BoundFastaMessage, FastaMessage; |
8 show | 8 |
9 FastaMessage, | 9 import '../fasta_codes.dart' as fasta; |
10 codeConstFieldWithoutInitializer, | |
11 codeExpectedButGot, | |
12 codeExpectedFunctionBody, | |
13 codeFinalFieldWithoutInitializer; | |
14 | 10 |
15 import '../parser/parser.dart' | 11 import '../parser/parser.dart' |
16 show Assert, FormalParameterType, MemberKind, optional; | 12 show Assert, FormalParameterType, MemberKind, optional; |
17 | 13 |
18 import '../parser/identifier_context.dart' show IdentifierContext; | 14 import '../parser/identifier_context.dart' show IdentifierContext; |
19 | 15 |
20 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; | 16 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
21 | 17 |
22 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; | 18 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; |
23 | 19 |
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 } | 945 } |
950 | 946 |
951 @override | 947 @override |
952 Expression throwNoSuchMethodError( | 948 Expression throwNoSuchMethodError( |
953 Expression receiver, String name, Arguments arguments, int charOffset, | 949 Expression receiver, String name, Arguments arguments, int charOffset, |
954 {bool isSuper: false, | 950 {bool isSuper: false, |
955 bool isGetter: false, | 951 bool isGetter: false, |
956 bool isSetter: false, | 952 bool isSetter: false, |
957 bool isStatic: false}) { | 953 bool isStatic: false}) { |
958 String errorName = isSuper ? "super.$name" : name; | 954 String errorName = isSuper ? "super.$name" : name; |
959 String message; | 955 BoundFastaMessage message; |
960 if (isGetter) { | 956 if (isGetter) { |
961 message = "Getter not found: '$errorName'."; | 957 message = fasta.codeGetterNotFound.bind(errorName); |
962 } else if (isSetter) { | 958 } else if (isSetter) { |
963 message = "Setter not found: '$errorName'."; | 959 message = fasta.codeSetterNotFound.bind(errorName); |
964 } else { | 960 } else { |
965 message = "Method not found: '$errorName'."; | 961 message = fasta.codeMethodNotFound.bind(errorName); |
966 } | 962 } |
967 if (constantExpressionRequired) { | 963 if (constantExpressionRequired) { |
968 // TODO(ahe): Use error below instead of building a compile-time error, | 964 // TODO(ahe): Use error below instead of building a compile-time error, |
969 // should be: | 965 // should be: |
970 // return library.loader.throwCompileConstantError(error, charOffset); | 966 // return library.loader.throwCompileConstantError(error, charOffset); |
971 return deprecated_buildCompileTimeError(message, charOffset); | 967 return deprecated_buildCompileTimeError(message, charOffset); |
972 } else { | 968 } else { |
973 Expression error = library.loader.instantiateNoSuchMethodError( | 969 Expression error = library.loader.instantiateNoSuchMethodError( |
974 receiver, name, arguments, charOffset, | 970 receiver, name, arguments, charOffset, |
975 isMethod: !isGetter && !isSetter, | 971 isMethod: !isGetter && !isSetter, |
976 isGetter: isGetter, | 972 isGetter: isGetter, |
977 isSetter: isSetter, | 973 isSetter: isSetter, |
978 isStatic: isStatic, | 974 isStatic: isStatic, |
979 isTopLevel: !isStatic && !isSuper); | 975 isTopLevel: !isStatic && !isSuper); |
980 deprecated_warning(message, charOffset); | 976 warning(message, charOffset); |
981 return new KernelSyntheticExpression(new Throw(error)); | 977 return new KernelSyntheticExpression(new Throw(error)); |
982 } | 978 } |
983 } | 979 } |
984 | 980 |
985 @override | 981 @override |
986 void warnUnresolvedSuperGet(Name name, int charOffset) { | 982 void warnUnresolvedSuperGet(Name name, int charOffset) { |
987 deprecated_warning( | 983 deprecated_warning( |
988 "Super class has no getter named '${name.name}'.", charOffset); | 984 "Super class has no getter named '${name.name}'.", charOffset); |
989 } | 985 } |
990 | 986 |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1533 void handleLiteralList( | 1529 void handleLiteralList( |
1534 int count, Token beginToken, Token constKeyword, Token endToken) { | 1530 int count, Token beginToken, Token constKeyword, Token endToken) { |
1535 debugEvent("LiteralList"); | 1531 debugEvent("LiteralList"); |
1536 List<Expression> expressions = popListForValue(count); | 1532 List<Expression> expressions = popListForValue(count); |
1537 List<DartType> typeArguments = pop(); | 1533 List<DartType> typeArguments = pop(); |
1538 DartType typeArgument; | 1534 DartType typeArgument; |
1539 if (typeArguments != null) { | 1535 if (typeArguments != null) { |
1540 typeArgument = typeArguments.first; | 1536 typeArgument = typeArguments.first; |
1541 if (typeArguments.length > 1) { | 1537 if (typeArguments.length > 1) { |
1542 typeArgument = null; | 1538 typeArgument = null; |
1543 deprecated_warningNotError( | 1539 warningNotError( |
1544 "Too many type arguments on List literal.", beginToken.charOffset); | 1540 fasta.codeListLiteralTooManyTypeArguments, beginToken.charOffset); |
1545 } | 1541 } |
1546 } | 1542 } |
1547 push(new KernelListLiteral(expressions, | 1543 push(new KernelListLiteral(expressions, |
1548 typeArgument: typeArgument, isConst: constKeyword != null) | 1544 typeArgument: typeArgument, isConst: constKeyword != null) |
1549 ..fileOffset = offsetForToken(constKeyword ?? beginToken)); | 1545 ..fileOffset = offsetForToken(constKeyword ?? beginToken)); |
1550 } | 1546 } |
1551 | 1547 |
1552 @override | 1548 @override |
1553 void handleLiteralBool(Token token) { | 1549 void handleLiteralBool(Token token) { |
1554 debugEvent("LiteralBool"); | 1550 debugEvent("LiteralBool"); |
(...skipping 20 matching lines...) Expand all Loading... |
1575 int count, Token beginToken, Token constKeyword, Token endToken) { | 1571 int count, Token beginToken, Token constKeyword, Token endToken) { |
1576 debugEvent("LiteralMap"); | 1572 debugEvent("LiteralMap"); |
1577 List<MapEntry> entries = popList(count) ?? <MapEntry>[]; | 1573 List<MapEntry> entries = popList(count) ?? <MapEntry>[]; |
1578 List<DartType> typeArguments = pop(); | 1574 List<DartType> typeArguments = pop(); |
1579 DartType keyType; | 1575 DartType keyType; |
1580 DartType valueType; | 1576 DartType valueType; |
1581 if (typeArguments != null) { | 1577 if (typeArguments != null) { |
1582 if (typeArguments.length != 2) { | 1578 if (typeArguments.length != 2) { |
1583 keyType = null; | 1579 keyType = null; |
1584 valueType = null; | 1580 valueType = null; |
1585 deprecated_warningNotError( | 1581 warningNotError( |
1586 "Map literal requires two type arguments.", beginToken.charOffset); | 1582 fasta.codeListLiteralTypeArgumentMismatch, beginToken.charOffset); |
1587 } else { | 1583 } else { |
1588 keyType = typeArguments[0]; | 1584 keyType = typeArguments[0]; |
1589 valueType = typeArguments[1]; | 1585 valueType = typeArguments[1]; |
1590 } | 1586 } |
1591 } | 1587 } |
1592 push(new KernelMapLiteral(entries, | 1588 push(new KernelMapLiteral(entries, |
1593 keyType: keyType, valueType: valueType, isConst: constKeyword != null) | 1589 keyType: keyType, valueType: valueType, isConst: constKeyword != null) |
1594 ..fileOffset = constKeyword?.charOffset ?? offsetForToken(beginToken)); | 1590 ..fileOffset = constKeyword?.charOffset ?? offsetForToken(beginToken)); |
1595 } | 1591 } |
1596 | 1592 |
(...skipping 30 matching lines...) Expand all Loading... |
1627 } | 1623 } |
1628 push( | 1624 push( |
1629 new KernelSymbolLiteral(value)..fileOffset = offsetForToken(hashToken)); | 1625 new KernelSymbolLiteral(value)..fileOffset = offsetForToken(hashToken)); |
1630 } | 1626 } |
1631 | 1627 |
1632 DartType kernelTypeFromString( | 1628 DartType kernelTypeFromString( |
1633 String name, List<DartType> arguments, int charOffset) { | 1629 String name, List<DartType> arguments, int charOffset) { |
1634 Builder builder = scope.lookup(name, charOffset, uri); | 1630 Builder builder = scope.lookup(name, charOffset, uri); |
1635 if (builder == null) { | 1631 if (builder == null) { |
1636 deprecated_warning("Type not found: '$name'.", charOffset); | 1632 deprecated_warning("Type not found: '$name'.", charOffset); |
1637 return const InvalidType(); | 1633 return const DynamicType(); |
1638 } else { | 1634 } else { |
1639 return kernelTypeFromBuilder(builder, arguments, charOffset); | 1635 return kernelTypeFromBuilder(builder, arguments, charOffset); |
1640 } | 1636 } |
1641 } | 1637 } |
1642 | 1638 |
1643 DartType kernelTypeFromBuilder( | 1639 DartType kernelTypeFromBuilder( |
1644 Builder builder, List<DartType> arguments, int charOffset) { | 1640 Builder builder, List<DartType> arguments, int charOffset) { |
1645 if (constantExpressionRequired && builder is TypeVariableBuilder) { | 1641 if (constantExpressionRequired && builder is TypeVariableBuilder) { |
1646 deprecated_addCompileTimeError(charOffset, "Not a constant expression."); | 1642 deprecated_addCompileTimeError(charOffset, "Not a constant expression."); |
1647 } | 1643 } |
1648 if (builder.hasProblem) { | 1644 if (builder.hasProblem) { |
1649 ProblemBuilder problem = builder; | 1645 ProblemBuilder problem = builder; |
1650 deprecated_addCompileTimeError(charOffset, problem.deprecated_message); | 1646 deprecated_addCompileTimeError(charOffset, problem.deprecated_message); |
1651 } else { | 1647 } else { |
1652 deprecated_warningNotError( | 1648 warningNotError( |
1653 "Not a type: '${builder.fullNameForErrors}'.", charOffset); | 1649 fasta.codeNotAType.bind(builder.fullNameForErrors), charOffset); |
1654 } | 1650 } |
1655 // TODO(ahe): Create an error somehow. | 1651 // TODO(ahe): Create an error somehow. |
1656 return const InvalidType(); | 1652 return const InvalidType(); |
1657 } | 1653 } |
1658 | 1654 |
1659 @override | 1655 @override |
1660 void handleType(Token beginToken, Token endToken) { | 1656 void handleType(Token beginToken, Token endToken) { |
1661 // TODO(ahe): The scope is wrong for return types of generic functions. | 1657 // TODO(ahe): The scope is wrong for return types of generic functions. |
1662 debugEvent("Type"); | 1658 debugEvent("Type"); |
1663 List<DartType> arguments = pop(); | 1659 List<DartType> arguments = pop(); |
(...skipping 25 matching lines...) Expand all Loading... |
1689 "Can't be used as a type: '${debugName(prefix, suffix)}'."); | 1685 "Can't be used as a type: '${debugName(prefix, suffix)}'."); |
1690 return; | 1686 return; |
1691 } | 1687 } |
1692 } | 1688 } |
1693 if (name is Identifier) { | 1689 if (name is Identifier) { |
1694 name = name.name; | 1690 name = name.name; |
1695 } | 1691 } |
1696 if (name is TypeDeclarationAccessor) { | 1692 if (name is TypeDeclarationAccessor) { |
1697 push(name.buildType(arguments)); | 1693 push(name.buildType(arguments)); |
1698 } else if (name is FastaAccessor) { | 1694 } else if (name is FastaAccessor) { |
1699 deprecated_warningNotError( | 1695 warningNotError( |
1700 "'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); | 1696 fasta.codeNotAType.bind(beginToken.lexeme), beginToken.charOffset); |
1701 push(const InvalidType()); | 1697 push(const InvalidType()); |
1702 } else if (name is TypeBuilder) { | 1698 } else if (name is TypeBuilder) { |
1703 push(name.build(library)); | 1699 push(name.build(library)); |
1704 } else if (name is Builder) { | 1700 } else if (name is Builder) { |
1705 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset)); | 1701 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset)); |
1706 } else if (name is String) { | 1702 } else if (name is String) { |
1707 push(kernelTypeFromString(name, arguments, beginToken.charOffset)); | 1703 push(kernelTypeFromString(name, arguments, beginToken.charOffset)); |
1708 } else { | 1704 } else { |
1709 deprecated_internalProblem("Unhandled: '${name.runtimeType}'."); | 1705 deprecated_internalProblem("Unhandled: '${name.runtimeType}'."); |
1710 } | 1706 } |
| 1707 // TODO(ahe): Unused code fasta.codeNonInstanceTypeVariableUse. |
1711 } | 1708 } |
1712 | 1709 |
1713 @override | 1710 @override |
1714 void beginFunctionType(Token beginToken) { | 1711 void beginFunctionType(Token beginToken) { |
1715 debugEvent("beginFunctionType"); | 1712 debugEvent("beginFunctionType"); |
1716 enterFunctionTypeScope(); | 1713 enterFunctionTypeScope(); |
1717 } | 1714 } |
1718 | 1715 |
1719 void enterFunctionTypeScope() { | 1716 void enterFunctionTypeScope() { |
1720 List typeVariables = pop(); | 1717 List typeVariables = pop(); |
(...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3017 @override | 3014 @override |
3018 void handleModifiers(int count) { | 3015 void handleModifiers(int count) { |
3019 debugEvent("Modifiers"); | 3016 debugEvent("Modifiers"); |
3020 // TODO(ahe): Copied from outline_builder.dart. | 3017 // TODO(ahe): Copied from outline_builder.dart. |
3021 push(popList(count) ?? NullValue.Modifiers); | 3018 push(popList(count) ?? NullValue.Modifiers); |
3022 } | 3019 } |
3023 | 3020 |
3024 @override | 3021 @override |
3025 void handleRecoverableError(Token token, FastaMessage message) { | 3022 void handleRecoverableError(Token token, FastaMessage message) { |
3026 bool silent = hasParserError || | 3023 bool silent = hasParserError || |
3027 message.code == codeFinalFieldWithoutInitializer || | 3024 message.code == fasta.codeFinalFieldWithoutInitializer || |
3028 message.code == codeConstFieldWithoutInitializer; | 3025 message.code == fasta.codeConstFieldWithoutInitializer; |
3029 deprecated_addCompileTimeError(message.charOffset, message.message, | 3026 deprecated_addCompileTimeError(message.charOffset, message.message, |
3030 silent: silent); | 3027 silent: silent); |
3031 } | 3028 } |
3032 | 3029 |
3033 @override | 3030 @override |
3034 Token handleUnrecoverableError(Token token, FastaMessage message) { | 3031 Token handleUnrecoverableError(Token token, FastaMessage message) { |
3035 if (enableNative && message.code == codeExpectedFunctionBody) { | 3032 if (enableNative && message.code == fasta.codeExpectedFunctionBody) { |
3036 Token recover = library.loader.target.skipNativeClause(token); | 3033 Token recover = library.loader.target.skipNativeClause(token); |
3037 if (recover != null) return recover; | 3034 if (recover != null) return recover; |
3038 } else if (message.code == codeExpectedButGot) { | 3035 } else if (message.code == fasta.codeExpectedButGot) { |
3039 String expected = message.arguments["string"]; | 3036 String expected = message.arguments["string"]; |
3040 const List<String> trailing = const <String>[")", "}", ";", ","]; | 3037 const List<String> trailing = const <String>[")", "}", ";", ","]; |
3041 if (trailing.contains(token.stringValue) && trailing.contains(expected)) { | 3038 if (trailing.contains(token.stringValue) && trailing.contains(expected)) { |
3042 handleRecoverableError(token, message); | 3039 handleRecoverableError(token, message); |
3043 return newSyntheticToken(token); | 3040 return newSyntheticToken(token); |
3044 } | 3041 } |
3045 } | 3042 } |
3046 return super.handleUnrecoverableError(token, message); | 3043 return super.handleUnrecoverableError(token, message); |
3047 } | 3044 } |
3048 | 3045 |
(...skipping 30 matching lines...) Expand all Loading... |
3079 library.loader.coreTypes.fallThroughErrorUrlAndLineConstructor, | 3076 library.loader.coreTypes.fallThroughErrorUrlAndLineConstructor, |
3080 new Arguments(<Expression>[ | 3077 new Arguments(<Expression>[ |
3081 new StringLiteral(location?.file ?? uri.toString()), | 3078 new StringLiteral(location?.file ?? uri.toString()), |
3082 new IntLiteral(location?.line ?? 0) | 3079 new IntLiteral(location?.line ?? 0) |
3083 ]), | 3080 ]), |
3084 charOffset: charOffset)); | 3081 charOffset: charOffset)); |
3085 } | 3082 } |
3086 | 3083 |
3087 Expression buildAbstractClassInstantiationError(String className, | 3084 Expression buildAbstractClassInstantiationError(String className, |
3088 [int charOffset = -1]) { | 3085 [int charOffset = -1]) { |
3089 deprecated_warning( | 3086 warning(fasta.codeAbstractClassInstantiation.bind(className), charOffset); |
3090 "The class '$className' is abstract and can't be instantiated.", | |
3091 charOffset); | |
3092 Builder constructor = library.loader.getAbstractClassInstantiationError(); | 3087 Builder constructor = library.loader.getAbstractClassInstantiationError(); |
3093 return new KernelSyntheticExpression(new Throw(buildStaticInvocation( | 3088 return new KernelSyntheticExpression(new Throw(buildStaticInvocation( |
3094 constructor.target, | 3089 constructor.target, |
3095 new KernelArguments(<Expression>[new StringLiteral(className)])))); | 3090 new KernelArguments(<Expression>[new StringLiteral(className)])))); |
3096 } | 3091 } |
3097 | 3092 |
3098 Statement deprecated_buildCompileTimeErrorStatement(error, | 3093 Statement deprecated_buildCompileTimeErrorStatement(error, |
3099 [int charOffset = -1]) { | 3094 [int charOffset = -1]) { |
3100 return new KernelExpressionStatement( | 3095 return new KernelExpressionStatement( |
3101 deprecated_buildCompileTimeError(error, charOffset)); | 3096 deprecated_buildCompileTimeError(error, charOffset)); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3228 deprecated_addCompileTimeError(charOffset, message); | 3223 deprecated_addCompileTimeError(charOffset, message); |
3229 } else { | 3224 } else { |
3230 super.deprecated_warning(message, charOffset); | 3225 super.deprecated_warning(message, charOffset); |
3231 } | 3226 } |
3232 } | 3227 } |
3233 | 3228 |
3234 void deprecated_warningNotError(String message, [int charOffset = -1]) { | 3229 void deprecated_warningNotError(String message, [int charOffset = -1]) { |
3235 super.deprecated_warning(message, charOffset); | 3230 super.deprecated_warning(message, charOffset); |
3236 } | 3231 } |
3237 | 3232 |
| 3233 void warningNotError(BoundFastaMessage bind, int charOffset) { |
| 3234 super.warning(bind, charOffset); |
| 3235 } |
| 3236 |
3238 @override | 3237 @override |
3239 DartType validatedTypeVariableUse( | 3238 DartType validatedTypeVariableUse( |
3240 TypeParameterType type, int offset, bool nonInstanceAccessIsError) { | 3239 TypeParameterType type, int offset, bool nonInstanceAccessIsError) { |
3241 if (!isInstanceContext && type.parameter.parent is Class) { | 3240 if (!isInstanceContext && type.parameter.parent is Class) { |
3242 String message = "Type variables can't be used in static members."; | 3241 String message = "Type variables can't be used in static members."; |
3243 if (nonInstanceAccessIsError) { | 3242 if (nonInstanceAccessIsError) { |
3244 deprecated_addCompileTimeError(offset, message); | 3243 deprecated_addCompileTimeError(offset, message); |
3245 } else { | 3244 } else { |
3246 deprecated_warning(message, offset); | 3245 deprecated_warning(message, offset); |
3247 } | 3246 } |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3773 if (starToken == null) { | 3772 if (starToken == null) { |
3774 return AsyncMarker.Async; | 3773 return AsyncMarker.Async; |
3775 } else { | 3774 } else { |
3776 assert(identical(starToken.stringValue, "*")); | 3775 assert(identical(starToken.stringValue, "*")); |
3777 return AsyncMarker.AsyncStar; | 3776 return AsyncMarker.AsyncStar; |
3778 } | 3777 } |
3779 } else { | 3778 } else { |
3780 return deprecated_internalProblem("Unknown async modifier: $asyncToken"); | 3779 return deprecated_internalProblem("Unknown async modifier: $asyncToken"); |
3781 } | 3780 } |
3782 } | 3781 } |
OLD | NEW |