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