| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 analyzer.src.generated.element_resolver; | 5 library analyzer.src.generated.element_resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 } | 704 } |
| 705 if (propagatedInvokeType != null) { | 705 if (propagatedInvokeType != null) { |
| 706 List<ParameterElement> parameters = | 706 List<ParameterElement> parameters = |
| 707 _computeCorrespondingParameters(argumentList, propagatedInvokeType); | 707 _computeCorrespondingParameters(argumentList, propagatedInvokeType); |
| 708 argumentList.correspondingPropagatedParameters = parameters; | 708 argumentList.correspondingPropagatedParameters = parameters; |
| 709 } | 709 } |
| 710 // | 710 // |
| 711 // Then check for error conditions. | 711 // Then check for error conditions. |
| 712 // | 712 // |
| 713 ErrorCode errorCode = _checkForInvocationError(target, true, staticElement); | 713 ErrorCode errorCode = _checkForInvocationError(target, true, staticElement); |
| 714 if (errorCode != null && |
| 715 target is SimpleIdentifier && |
| 716 target.staticElement is PrefixElement) { |
| 717 Identifier functionName = |
| 718 new PrefixedIdentifierImpl.temp(target, methodName); |
| 719 if (_resolver.nameScope.shouldIgnoreUndefined(functionName)) { |
| 720 return null; |
| 721 } |
| 722 } |
| 714 bool generatedWithTypePropagation = false; | 723 bool generatedWithTypePropagation = false; |
| 715 if (_enableHints && errorCode == null && staticElement == null) { | 724 if (_enableHints && errorCode == null && staticElement == null) { |
| 716 // The method lookup may have failed because there were multiple | 725 // The method lookup may have failed because there were multiple |
| 717 // incompatible choices. In this case we don't want to generate a hint. | 726 // incompatible choices. In this case we don't want to generate a hint. |
| 718 errorCode = _checkForInvocationError(target, false, propagatedElement); | 727 errorCode = _checkForInvocationError(target, false, propagatedElement); |
| 719 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 728 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 720 ClassElement classElementContext = null; | 729 ClassElement classElementContext = null; |
| 721 if (target == null) { | 730 if (target == null) { |
| 722 classElementContext = _resolver.enclosingClass; | 731 classElementContext = _resolver.enclosingClass; |
| 723 } else { | 732 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 743 generatedWithTypePropagation = true; | 752 generatedWithTypePropagation = true; |
| 744 } | 753 } |
| 745 if (errorCode == null) { | 754 if (errorCode == null) { |
| 746 return null; | 755 return null; |
| 747 } | 756 } |
| 748 if (identical( | 757 if (identical( |
| 749 errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) || | 758 errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) || |
| 750 identical(errorCode, | 759 identical(errorCode, |
| 751 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT) || | 760 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT) || |
| 752 identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { | 761 identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { |
| 753 _resolver.errorReporter | 762 if (!_resolver.nameScope.shouldIgnoreUndefined(methodName)) { |
| 754 .reportErrorForNode(errorCode, methodName, [methodName.name]); | 763 _resolver.errorReporter |
| 764 .reportErrorForNode(errorCode, methodName, [methodName.name]); |
| 765 } |
| 755 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 766 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 756 String targetTypeName; | 767 String targetTypeName; |
| 757 if (target == null) { | 768 if (target == null) { |
| 758 ClassElement enclosingClass = _resolver.enclosingClass; | 769 ClassElement enclosingClass = _resolver.enclosingClass; |
| 759 targetTypeName = enclosingClass.displayName; | 770 targetTypeName = enclosingClass.displayName; |
| 760 ErrorCode proxyErrorCode = (generatedWithTypePropagation | 771 ErrorCode proxyErrorCode = (generatedWithTypePropagation |
| 761 ? HintCode.UNDEFINED_METHOD | 772 ? HintCode.UNDEFINED_METHOD |
| 762 : StaticTypeWarningCode.UNDEFINED_METHOD); | 773 : StaticTypeWarningCode.UNDEFINED_METHOD); |
| 763 _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode, | 774 _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode, |
| 764 methodName, [methodName.name, targetTypeName]); | 775 methodName, [methodName.name, targetTypeName]); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 } else if (identical( | 821 } else if (identical( |
| 811 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { | 822 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { |
| 812 // Generate the type name. | 823 // Generate the type name. |
| 813 // The error code will never be generated via type propagation | 824 // The error code will never be generated via type propagation |
| 814 DartType getSuperType(DartType type) { | 825 DartType getSuperType(DartType type) { |
| 815 if (type is InterfaceType && !type.isObject) { | 826 if (type is InterfaceType && !type.isObject) { |
| 816 return type.superclass; | 827 return type.superclass; |
| 817 } | 828 } |
| 818 return type; | 829 return type; |
| 819 } | 830 } |
| 831 |
| 820 DartType targetType = getSuperType(_getStaticType(target)); | 832 DartType targetType = getSuperType(_getStaticType(target)); |
| 821 String targetTypeName = targetType?.name; | 833 String targetTypeName = targetType?.name; |
| 822 _resolver.errorReporter.reportErrorForNode( | 834 _resolver.errorReporter.reportErrorForNode( |
| 823 StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, | 835 StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, |
| 824 methodName, | 836 methodName, |
| 825 [methodName.name, targetTypeName]); | 837 [methodName.name, targetTypeName]); |
| 826 } | 838 } |
| 827 return null; | 839 return null; |
| 828 } | 840 } |
| 829 | 841 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 Element prefixElement = prefix.staticElement; | 899 Element prefixElement = prefix.staticElement; |
| 888 if (prefixElement is PrefixElement) { | 900 if (prefixElement is PrefixElement) { |
| 889 Element element = _resolver.nameScope.lookup(node, _definingLibrary); | 901 Element element = _resolver.nameScope.lookup(node, _definingLibrary); |
| 890 if (element == null && identifier.inSetterContext()) { | 902 if (element == null && identifier.inSetterContext()) { |
| 891 Identifier setterName = new PrefixedIdentifierImpl.temp( | 903 Identifier setterName = new PrefixedIdentifierImpl.temp( |
| 892 node.prefix, | 904 node.prefix, |
| 893 new SimpleIdentifierImpl(new StringToken(TokenType.STRING, | 905 new SimpleIdentifierImpl(new StringToken(TokenType.STRING, |
| 894 "${node.identifier.name}=", node.identifier.offset - 1))); | 906 "${node.identifier.name}=", node.identifier.offset - 1))); |
| 895 element = _resolver.nameScope.lookup(setterName, _definingLibrary); | 907 element = _resolver.nameScope.lookup(setterName, _definingLibrary); |
| 896 } | 908 } |
| 909 if (element == null && _resolver.nameScope.shouldIgnoreUndefined(node)) { |
| 910 return null; |
| 911 } |
| 897 if (element == null) { | 912 if (element == null) { |
| 898 if (identifier.inSetterContext()) { | 913 if (identifier.inSetterContext()) { |
| 899 _resolver.errorReporter.reportErrorForNode( | 914 _resolver.errorReporter.reportErrorForNode( |
| 900 StaticWarningCode.UNDEFINED_SETTER, | 915 StaticWarningCode.UNDEFINED_SETTER, |
| 901 identifier, | 916 identifier, |
| 902 [identifier.name, prefixElement.name]); | 917 [identifier.name, prefixElement.name]); |
| 903 return null; | 918 return null; |
| 904 } | 919 } |
| 905 AstNode parent = node.parent; | 920 AstNode parent = node.parent; |
| 906 if (parent is Annotation) { | 921 if (parent is Annotation) { |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 _resolver.errorReporter.reportErrorForNode( | 1120 _resolver.errorReporter.reportErrorForNode( |
| 1106 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, | 1121 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, |
| 1107 node, | 1122 node, |
| 1108 [element.name]); | 1123 [element.name]); |
| 1109 } else if (node.name == "await" && _resolver.enclosingFunction != null) { | 1124 } else if (node.name == "await" && _resolver.enclosingFunction != null) { |
| 1110 _recordUndefinedNode( | 1125 _recordUndefinedNode( |
| 1111 _resolver.enclosingClass, | 1126 _resolver.enclosingClass, |
| 1112 StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT, | 1127 StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT, |
| 1113 node, | 1128 node, |
| 1114 [_resolver.enclosingFunction.displayName]); | 1129 [_resolver.enclosingFunction.displayName]); |
| 1115 } else { | 1130 } else if (!_resolver.nameScope.shouldIgnoreUndefined(node)) { |
| 1116 _recordUndefinedNode(_resolver.enclosingClass, | 1131 _recordUndefinedNode(_resolver.enclosingClass, |
| 1117 StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); | 1132 StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); |
| 1118 } | 1133 } |
| 1119 } | 1134 } |
| 1120 node.staticElement = element; | 1135 node.staticElement = element; |
| 1121 if (node.inSetterContext() && | 1136 if (node.inSetterContext() && |
| 1122 node.inGetterContext() && | 1137 node.inGetterContext() && |
| 1123 enclosingClass != null) { | 1138 enclosingClass != null) { |
| 1124 InterfaceType enclosingType = enclosingClass.type; | 1139 InterfaceType enclosingType = enclosingClass.type; |
| 1125 AuxiliaryElements auxiliaryElements = new AuxiliaryElements( | 1140 AuxiliaryElements auxiliaryElements = new AuxiliaryElements( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 } else { | 1185 } else { |
| 1171 if (element.isFactory) { | 1186 if (element.isFactory) { |
| 1172 _resolver.errorReporter.reportErrorForNode( | 1187 _resolver.errorReporter.reportErrorForNode( |
| 1173 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]); | 1188 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]); |
| 1174 } | 1189 } |
| 1175 } | 1190 } |
| 1176 if (name != null) { | 1191 if (name != null) { |
| 1177 name.staticElement = element; | 1192 name.staticElement = element; |
| 1178 } | 1193 } |
| 1179 node.staticElement = element; | 1194 node.staticElement = element; |
| 1195 // TODO(brianwilkerson) Defer this check until we know there's an error (by |
| 1196 // in-lining _resolveArgumentsToFunction below). |
| 1197 ClassDeclaration declaration = |
| 1198 node.getAncestor((AstNode node) => node is ClassDeclaration); |
| 1199 Identifier superclassName = declaration.extendsClause?.superclass?.name; |
| 1200 if (superclassName != null && |
| 1201 _resolver.nameScope.shouldIgnoreUndefined(superclassName)) { |
| 1202 return null; |
| 1203 } |
| 1180 ArgumentList argumentList = node.argumentList; | 1204 ArgumentList argumentList = node.argumentList; |
| 1181 List<ParameterElement> parameters = _resolveArgumentsToFunction( | 1205 List<ParameterElement> parameters = _resolveArgumentsToFunction( |
| 1182 isInConstConstructor, argumentList, element); | 1206 isInConstConstructor, argumentList, element); |
| 1183 if (parameters != null) { | 1207 if (parameters != null) { |
| 1184 argumentList.correspondingStaticParameters = parameters; | 1208 argumentList.correspondingStaticParameters = parameters; |
| 1185 } | 1209 } |
| 1186 return null; | 1210 return null; |
| 1187 } | 1211 } |
| 1188 | 1212 |
| 1189 @override | 1213 @override |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1205 Object visitVariableDeclaration(VariableDeclaration node) { | 1229 Object visitVariableDeclaration(VariableDeclaration node) { |
| 1206 resolveMetadata(node); | 1230 resolveMetadata(node); |
| 1207 return null; | 1231 return null; |
| 1208 } | 1232 } |
| 1209 | 1233 |
| 1210 /** | 1234 /** |
| 1211 * Given that we have found code to invoke the given [element], return the | 1235 * Given that we have found code to invoke the given [element], return the |
| 1212 * error code that should be reported, or `null` if no error should be | 1236 * error code that should be reported, or `null` if no error should be |
| 1213 * reported. The [target] is the target of the invocation, or `null` if there | 1237 * reported. The [target] is the target of the invocation, or `null` if there |
| 1214 * was no target. The flag [useStaticContext] should be `true` if the | 1238 * was no target. The flag [useStaticContext] should be `true` if the |
| 1215 * invocation is in a static constant (does not have access to instance state. | 1239 * invocation is in a static constant (does not have access to instance state)
. |
| 1216 */ | 1240 */ |
| 1217 ErrorCode _checkForInvocationError( | 1241 ErrorCode _checkForInvocationError( |
| 1218 Expression target, bool useStaticContext, Element element) { | 1242 Expression target, bool useStaticContext, Element element) { |
| 1219 // Prefix is not declared, instead "prefix.id" are declared. | 1243 // Prefix is not declared, instead "prefix.id" are declared. |
| 1220 if (element is PrefixElement) { | 1244 if (element is PrefixElement) { |
| 1221 return CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT; | 1245 return CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT; |
| 1222 } else if (element is PropertyAccessorElement) { | 1246 } else if (element is PropertyAccessorElement) { |
| 1223 // | 1247 // |
| 1224 // This is really a function expression invocation. | 1248 // This is really a function expression invocation. |
| 1225 // | 1249 // |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 DartType targetType; | 1300 DartType targetType; |
| 1277 if (useStaticContext) { | 1301 if (useStaticContext) { |
| 1278 targetType = _getStaticType(target); | 1302 targetType = _getStaticType(target); |
| 1279 } else { | 1303 } else { |
| 1280 // Compute and use the propagated type, if it is null, then it may | 1304 // Compute and use the propagated type, if it is null, then it may |
| 1281 // be the case that static type is some type, in which the static | 1305 // be the case that static type is some type, in which the static |
| 1282 // type should be used. | 1306 // type should be used. |
| 1283 targetType = _getBestType(target); | 1307 targetType = _getBestType(target); |
| 1284 } | 1308 } |
| 1285 if (targetType == null) { | 1309 if (targetType == null) { |
| 1310 if (target is Identifier && |
| 1311 _resolver.nameScope.shouldIgnoreUndefined(target)) { |
| 1312 return null; |
| 1313 } |
| 1286 return StaticTypeWarningCode.UNDEFINED_FUNCTION; | 1314 return StaticTypeWarningCode.UNDEFINED_FUNCTION; |
| 1287 } else if (!targetType.isDynamic && !targetType.isBottom) { | 1315 } else if (!targetType.isDynamic && !targetType.isBottom) { |
| 1288 // Proxy-conditional warning, based on state of | 1316 // Proxy-conditional warning, based on state of |
| 1289 // targetType.getElement() | 1317 // targetType.getElement() |
| 1290 return StaticTypeWarningCode.UNDEFINED_METHOD; | 1318 return StaticTypeWarningCode.UNDEFINED_METHOD; |
| 1291 } | 1319 } |
| 1292 } | 1320 } |
| 1293 } | 1321 } |
| 1294 } | 1322 } |
| 1295 return null; | 1323 return null; |
| (...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2592 | 2620 |
| 2593 @override | 2621 @override |
| 2594 Element get staticElement => null; | 2622 Element get staticElement => null; |
| 2595 | 2623 |
| 2596 @override | 2624 @override |
| 2597 dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) => null; | 2625 dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) => null; |
| 2598 | 2626 |
| 2599 @override | 2627 @override |
| 2600 void visitChildren(AstVisitor visitor) {} | 2628 void visitChildren(AstVisitor visitor) {} |
| 2601 } | 2629 } |
| OLD | NEW |