| 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 @override | 212 @override |
| 213 Object visitClassTypeAlias(ClassTypeAlias node) { | 213 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 214 resolveMetadata(node); | 214 resolveMetadata(node); |
| 215 return null; | 215 return null; |
| 216 } | 216 } |
| 217 | 217 |
| 218 @override | 218 @override |
| 219 Object visitCommentReference(CommentReference node) { | 219 Object visitCommentReference(CommentReference node) { |
| 220 Identifier identifier = node.identifier; | 220 Identifier identifier = node.identifier; |
| 221 if (identifier is SimpleIdentifier) { | 221 if (identifier is SimpleIdentifier) { |
| 222 SimpleIdentifier simpleIdentifier = identifier; | 222 Element element = _resolveSimpleIdentifier(identifier); |
| 223 Element element = _resolveSimpleIdentifier(simpleIdentifier); | |
| 224 if (element == null) { | 223 if (element == null) { |
| 225 // | 224 // |
| 226 // This might be a reference to an imported name that is missing the | 225 // This might be a reference to an imported name that is missing the |
| 227 // prefix. | 226 // prefix. |
| 228 // | 227 // |
| 229 element = _findImportWithoutPrefix(simpleIdentifier); | 228 element = _findImportWithoutPrefix(identifier); |
| 230 if (element is MultiplyDefinedElement) { | 229 if (element is MultiplyDefinedElement) { |
| 231 // TODO(brianwilkerson) Report this error? | 230 // TODO(brianwilkerson) Report this error? |
| 232 element = null; | 231 element = null; |
| 233 } | 232 } |
| 234 } | 233 } |
| 235 if (element == null) { | 234 if (element == null) { |
| 236 // TODO(brianwilkerson) Report this error? | 235 // TODO(brianwilkerson) Report this error? |
| 237 // resolver.reportError( | 236 // resolver.reportError( |
| 238 // StaticWarningCode.UNDEFINED_IDENTIFIER, | 237 // StaticWarningCode.UNDEFINED_IDENTIFIER, |
| 239 // simpleIdentifier, | 238 // simpleIdentifier, |
| 240 // simpleIdentifier.getName()); | 239 // simpleIdentifier.getName()); |
| 241 } else { | 240 } else { |
| 242 if (element.library == null || element.library != _definingLibrary) { | 241 if (element.library == null || element.library != _definingLibrary) { |
| 243 // TODO(brianwilkerson) Report this error? | 242 // TODO(brianwilkerson) Report this error? |
| 244 } | 243 } |
| 245 simpleIdentifier.staticElement = element; | 244 identifier.staticElement = element; |
| 246 if (node.newKeyword != null) { | 245 if (node.newKeyword != null) { |
| 247 if (element is ClassElement) { | 246 if (element is ClassElement) { |
| 248 ConstructorElement constructor = element.unnamedConstructor; | 247 ConstructorElement constructor = element.unnamedConstructor; |
| 249 if (constructor == null) { | 248 if (constructor == null) { |
| 250 // TODO(brianwilkerson) Report this error. | 249 // TODO(brianwilkerson) Report this error. |
| 251 } else { | 250 } else { |
| 252 simpleIdentifier.staticElement = constructor; | 251 identifier.staticElement = constructor; |
| 253 } | 252 } |
| 254 } else { | 253 } else { |
| 255 // TODO(brianwilkerson) Report this error. | 254 // TODO(brianwilkerson) Report this error. |
| 256 } | 255 } |
| 257 } | 256 } |
| 258 } | 257 } |
| 259 } else if (identifier is PrefixedIdentifier) { | 258 } else if (identifier is PrefixedIdentifier) { |
| 260 PrefixedIdentifier prefixedIdentifier = identifier; | 259 SimpleIdentifier prefix = identifier.prefix; |
| 261 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 260 SimpleIdentifier name = identifier.identifier; |
| 262 SimpleIdentifier name = prefixedIdentifier.identifier; | |
| 263 Element element = _resolveSimpleIdentifier(prefix); | 261 Element element = _resolveSimpleIdentifier(prefix); |
| 264 if (element == null) { | 262 if (element == null) { |
| 265 // resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, p
refix.getName()); | 263 // resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, p
refix.getName()); |
| 266 } else { | 264 } else { |
| 267 prefix.staticElement = element; | 265 prefix.staticElement = element; |
| 268 if (element is PrefixElement) { | 266 if (element is PrefixElement) { |
| 269 // TODO(brianwilkerson) Report this error? | 267 // TODO(brianwilkerson) Report this error? |
| 270 element = _resolver.nameScope.lookup(identifier, _definingLibrary); | 268 element = _resolver.nameScope.lookup(identifier, _definingLibrary); |
| 271 name.staticElement = element; | 269 name.staticElement = element; |
| 272 return null; | 270 return null; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 284 if (element is ClassElement) { | 282 if (element is ClassElement) { |
| 285 Element memberElement = | 283 Element memberElement = |
| 286 _lookupGetterOrMethod(element.type, name.name); | 284 _lookupGetterOrMethod(element.type, name.name); |
| 287 if (memberElement == null) { | 285 if (memberElement == null) { |
| 288 memberElement = element.getNamedConstructor(name.name); | 286 memberElement = element.getNamedConstructor(name.name); |
| 289 if (memberElement == null) { | 287 if (memberElement == null) { |
| 290 memberElement = _lookUpSetter(prefix, element.type, name.name); | 288 memberElement = _lookUpSetter(prefix, element.type, name.name); |
| 291 } | 289 } |
| 292 } | 290 } |
| 293 if (memberElement == null) { | 291 if (memberElement == null) { |
| 294 // reportGetterOrSetterNotFound(prefixedIdentifier, name, element.g
etDisplayName()); | 292 // reportGetterOrSetterNotFound(identifier, name, element.getDispla
yName()); |
| 295 } else { | 293 } else { |
| 296 name.staticElement = memberElement; | 294 name.staticElement = memberElement; |
| 297 } | 295 } |
| 298 } else { | 296 } else { |
| 299 // TODO(brianwilkerson) Report this error. | 297 // TODO(brianwilkerson) Report this error. |
| 300 } | 298 } |
| 301 } else { | 299 } else { |
| 302 if (element is ClassElement) { | 300 if (element is ClassElement) { |
| 303 ConstructorElement constructor = | 301 ConstructorElement constructor = |
| 304 element.getNamedConstructor(name.name); | 302 element.getNamedConstructor(name.name); |
| 305 if (constructor == null) { | 303 if (constructor == null) { |
| 306 // TODO(brianwilkerson) Report this error. | 304 // TODO(brianwilkerson) Report this error. |
| 307 } else { | 305 } else { |
| 308 name.staticElement = constructor; | 306 name.staticElement = constructor; |
| 309 } | 307 } |
| 310 } else { | 308 } else { |
| 311 // TODO(brianwilkerson) Report this error. | 309 // TODO(brianwilkerson) Report this error. |
| 312 } | 310 } |
| 313 } | 311 } |
| 314 } | 312 } |
| 315 } | 313 } |
| 316 return null; | 314 return null; |
| 317 } | 315 } |
| 318 | 316 |
| 319 @override | 317 @override |
| 320 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 318 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 321 super.visitConstructorDeclaration(node); | 319 super.visitConstructorDeclaration(node); |
| 322 ConstructorElement element = node.element; | 320 ConstructorElement element = node.element; |
| 323 if (element is ConstructorElementImpl) { | 321 if (element is ConstructorElementImpl) { |
| 324 ConstructorElementImpl constructorElement = element; | |
| 325 ConstructorName redirectedNode = node.redirectedConstructor; | 322 ConstructorName redirectedNode = node.redirectedConstructor; |
| 326 if (redirectedNode != null) { | 323 if (redirectedNode != null) { |
| 327 // set redirected factory constructor | 324 // set redirected factory constructor |
| 328 ConstructorElement redirectedElement = redirectedNode.staticElement; | 325 ConstructorElement redirectedElement = redirectedNode.staticElement; |
| 329 constructorElement.redirectedConstructor = redirectedElement; | 326 element.redirectedConstructor = redirectedElement; |
| 330 } else { | 327 } else { |
| 331 // set redirected generative constructor | 328 // set redirected generative constructor |
| 332 for (ConstructorInitializer initializer in node.initializers) { | 329 for (ConstructorInitializer initializer in node.initializers) { |
| 333 if (initializer is RedirectingConstructorInvocation) { | 330 if (initializer is RedirectingConstructorInvocation) { |
| 334 ConstructorElement redirectedElement = initializer.staticElement; | 331 ConstructorElement redirectedElement = initializer.staticElement; |
| 335 constructorElement.redirectedConstructor = redirectedElement; | 332 element.redirectedConstructor = redirectedElement; |
| 336 } | 333 } |
| 337 } | 334 } |
| 338 } | 335 } |
| 339 resolveMetadata(node); | 336 resolveMetadata(node); |
| 340 } | 337 } |
| 341 return null; | 338 return null; |
| 342 } | 339 } |
| 343 | 340 |
| 344 @override | 341 @override |
| 345 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 342 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 // The method lookup may have failed because there were multiple | 712 // The method lookup may have failed because there were multiple |
| 716 // incompatible choices. In this case we don't want to generate a hint. | 713 // incompatible choices. In this case we don't want to generate a hint. |
| 717 errorCode = _checkForInvocationError(target, false, propagatedElement); | 714 errorCode = _checkForInvocationError(target, false, propagatedElement); |
| 718 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 715 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 719 ClassElement classElementContext = null; | 716 ClassElement classElementContext = null; |
| 720 if (target == null) { | 717 if (target == null) { |
| 721 classElementContext = _resolver.enclosingClass; | 718 classElementContext = _resolver.enclosingClass; |
| 722 } else { | 719 } else { |
| 723 DartType type = _getBestType(target); | 720 DartType type = _getBestType(target); |
| 724 if (type != null) { | 721 if (type != null) { |
| 725 if (type.element is ClassElement) { | 722 Element element = type.element; |
| 726 classElementContext = type.element as ClassElement; | 723 if (element is ClassElement) { |
| 724 classElementContext = element; |
| 727 } | 725 } |
| 728 } | 726 } |
| 729 } | 727 } |
| 730 if (classElementContext != null) { | 728 if (classElementContext != null) { |
| 731 _subtypeManager.ensureLibraryVisited(_definingLibrary); | 729 _subtypeManager.ensureLibraryVisited(_definingLibrary); |
| 732 HashSet<ClassElement> subtypeElements = | 730 HashSet<ClassElement> subtypeElements = |
| 733 _subtypeManager.computeAllSubtypes(classElementContext); | 731 _subtypeManager.computeAllSubtypes(classElementContext); |
| 734 for (ClassElement subtypeElement in subtypeElements) { | 732 for (ClassElement subtypeElement in subtypeElements) { |
| 735 if (subtypeElement.getMethod(methodName.name) != null) { | 733 if (subtypeElement.getMethod(methodName.name) != null) { |
| 736 errorCode = null; | 734 errorCode = null; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 ErrorCode proxyErrorCode = (generatedWithTypePropagation | 799 ErrorCode proxyErrorCode = (generatedWithTypePropagation |
| 802 ? HintCode.UNDEFINED_METHOD | 800 ? HintCode.UNDEFINED_METHOD |
| 803 : StaticTypeWarningCode.UNDEFINED_METHOD); | 801 : StaticTypeWarningCode.UNDEFINED_METHOD); |
| 804 _recordUndefinedNode(targetType.element, proxyErrorCode, methodName, | 802 _recordUndefinedNode(targetType.element, proxyErrorCode, methodName, |
| 805 [methodName.name, targetTypeName]); | 803 [methodName.name, targetTypeName]); |
| 806 } | 804 } |
| 807 } else if (identical( | 805 } else if (identical( |
| 808 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { | 806 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { |
| 809 // Generate the type name. | 807 // Generate the type name. |
| 810 // The error code will never be generated via type propagation | 808 // The error code will never be generated via type propagation |
| 811 DartType targetType = _getStaticType(target); | 809 DartType getSuperType(DartType type) { |
| 812 if (targetType is InterfaceType && !targetType.isObject) { | 810 if (type is InterfaceType && !type.isObject) { |
| 813 targetType = (targetType as InterfaceType).superclass; | 811 return type.superclass; |
| 812 } |
| 813 return type; |
| 814 } | 814 } |
| 815 String targetTypeName = targetType == null ? null : targetType.name; | 815 DartType targetType = getSuperType(_getStaticType(target)); |
| 816 String targetTypeName = targetType?.name; |
| 816 _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, | 817 _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, |
| 817 methodName, [methodName.name, targetTypeName]); | 818 methodName, [methodName.name, targetTypeName]); |
| 818 } | 819 } |
| 819 return null; | 820 return null; |
| 820 } | 821 } |
| 821 | 822 |
| 822 @override | 823 @override |
| 823 Object visitPartDirective(PartDirective node) { | 824 Object visitPartDirective(PartDirective node) { |
| 824 resolveMetadata(node); | 825 resolveMetadata(node); |
| 825 return null; | 826 return null; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 if (prefixElement is PrefixElement) { | 881 if (prefixElement is PrefixElement) { |
| 881 Element element = _resolver.nameScope.lookup(node, _definingLibrary); | 882 Element element = _resolver.nameScope.lookup(node, _definingLibrary); |
| 882 if (element == null && identifier.inSetterContext()) { | 883 if (element == null && identifier.inSetterContext()) { |
| 883 element = _resolver.nameScope.lookup( | 884 element = _resolver.nameScope.lookup( |
| 884 new SyntheticIdentifier("${node.name}=", node), _definingLibrary); | 885 new SyntheticIdentifier("${node.name}=", node), _definingLibrary); |
| 885 } | 886 } |
| 886 if (element == null) { | 887 if (element == null) { |
| 887 if (identifier.inSetterContext()) { | 888 if (identifier.inSetterContext()) { |
| 888 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_SETTER, | 889 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_SETTER, |
| 889 identifier, [identifier.name, prefixElement.name]); | 890 identifier, [identifier.name, prefixElement.name]); |
| 890 } else if (node.parent is Annotation) { | 891 return null; |
| 891 Annotation annotation = node.parent as Annotation; | 892 } |
| 893 AstNode parent = node.parent; |
| 894 if (parent is Annotation) { |
| 892 _resolver.reportErrorForNode( | 895 _resolver.reportErrorForNode( |
| 893 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); | 896 CompileTimeErrorCode.INVALID_ANNOTATION, parent); |
| 894 return null; | |
| 895 } else { | 897 } else { |
| 896 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_GETTER, | 898 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_GETTER, |
| 897 identifier, [identifier.name, prefixElement.name]); | 899 identifier, [identifier.name, prefixElement.name]); |
| 898 } | 900 } |
| 899 return null; | 901 return null; |
| 900 } | 902 } |
| 901 if (element is PropertyAccessorElement && identifier.inSetterContext()) { | 903 Element accessor = element; |
| 902 PropertyInducingElement variable = | 904 if (accessor is PropertyAccessorElement && identifier.inSetterContext()) { |
| 903 (element as PropertyAccessorElement).variable; | 905 PropertyInducingElement variable = accessor.variable; |
| 904 if (variable != null) { | 906 if (variable != null) { |
| 905 PropertyAccessorElement setter = variable.setter; | 907 PropertyAccessorElement setter = variable.setter; |
| 906 if (setter != null) { | 908 if (setter != null) { |
| 907 element = setter; | 909 element = setter; |
| 908 } | 910 } |
| 909 } | 911 } |
| 910 } | 912 } |
| 911 // TODO(brianwilkerson) The prefix needs to be resolved to the element for | 913 // TODO(brianwilkerson) The prefix needs to be resolved to the element for |
| 912 // the import that defines the prefix, not the prefix's element. | 914 // the import that defines the prefix, not the prefix's element. |
| 913 identifier.staticElement = element; | 915 identifier.staticElement = element; |
| 914 // Validate annotation element. | 916 // Validate annotation element. |
| 915 if (node.parent is Annotation) { | 917 AstNode parent = node.parent; |
| 916 Annotation annotation = node.parent as Annotation; | 918 if (parent is Annotation) { |
| 917 _resolveAnnotationElement(annotation); | 919 _resolveAnnotationElement(parent); |
| 918 return null; | |
| 919 } | 920 } |
| 920 return null; | 921 return null; |
| 921 } | 922 } |
| 922 // May be annotation, resolve invocation of "const" constructor. | 923 // May be annotation, resolve invocation of "const" constructor. |
| 923 if (node.parent is Annotation) { | 924 AstNode parent = node.parent; |
| 924 Annotation annotation = node.parent as Annotation; | 925 if (parent is Annotation) { |
| 925 _resolveAnnotationElement(annotation); | 926 _resolveAnnotationElement(parent); |
| 926 } | 927 } |
| 927 // | 928 // |
| 928 // Otherwise, the prefix is really an expression that happens to be a simple | 929 // Otherwise, the prefix is really an expression that happens to be a simple |
| 929 // identifier and this is really equivalent to a property access node. | 930 // identifier and this is really equivalent to a property access node. |
| 930 // | 931 // |
| 931 _resolvePropertyAccess(prefix, identifier, false); | 932 _resolvePropertyAccess(prefix, identifier, false); |
| 932 return null; | 933 return null; |
| 933 } | 934 } |
| 934 | 935 |
| 935 @override | 936 @override |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 !identical(element, enclosingClass)) { | 1077 !identical(element, enclosingClass)) { |
| 1077 _resolver.reportErrorForNode( | 1078 _resolver.reportErrorForNode( |
| 1078 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); | 1079 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); |
| 1079 element = null; | 1080 element = null; |
| 1080 } else if (element == null || | 1081 } else if (element == null || |
| 1081 (element is PrefixElement && !_isValidAsPrefix(node))) { | 1082 (element is PrefixElement && !_isValidAsPrefix(node))) { |
| 1082 // TODO(brianwilkerson) Recover from this error. | 1083 // TODO(brianwilkerson) Recover from this error. |
| 1083 if (_isConstructorReturnType(node)) { | 1084 if (_isConstructorReturnType(node)) { |
| 1084 _resolver.reportErrorForNode( | 1085 _resolver.reportErrorForNode( |
| 1085 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); | 1086 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); |
| 1086 } else if (node.parent is Annotation) { | |
| 1087 Annotation annotation = node.parent as Annotation; | |
| 1088 _resolver.reportErrorForNode( | |
| 1089 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); | |
| 1090 } else if (element is PrefixElement) { | |
| 1091 _resolver.reportErrorForNode( | |
| 1092 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, | |
| 1093 node, | |
| 1094 [element.name]); | |
| 1095 } else { | 1087 } else { |
| 1096 _recordUndefinedNode(_resolver.enclosingClass, | 1088 AstNode parent = node.parent; |
| 1097 StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); | 1089 if (parent is Annotation) { |
| 1090 _resolver.reportErrorForNode( |
| 1091 CompileTimeErrorCode.INVALID_ANNOTATION, parent); |
| 1092 } else if (element != null) { |
| 1093 _resolver.reportErrorForNode( |
| 1094 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, |
| 1095 node, |
| 1096 [element.name]); |
| 1097 } else { |
| 1098 _recordUndefinedNode(_resolver.enclosingClass, |
| 1099 StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); |
| 1100 } |
| 1098 } | 1101 } |
| 1099 } | 1102 } |
| 1100 node.staticElement = element; | 1103 node.staticElement = element; |
| 1101 if (node.inSetterContext() && | 1104 if (node.inSetterContext() && |
| 1102 node.inGetterContext() && | 1105 node.inGetterContext() && |
| 1103 enclosingClass != null) { | 1106 enclosingClass != null) { |
| 1104 InterfaceType enclosingType = enclosingClass.type; | 1107 InterfaceType enclosingType = enclosingClass.type; |
| 1105 AuxiliaryElements auxiliaryElements = new AuxiliaryElements( | 1108 AuxiliaryElements auxiliaryElements = new AuxiliaryElements( |
| 1106 _lookUpGetter(null, enclosingType, node.name), null); | 1109 _lookUpGetter(null, enclosingType, node.name), null); |
| 1107 node.auxiliaryElements = auxiliaryElements; | 1110 node.auxiliaryElements = auxiliaryElements; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 * error code that should be reported, or `null` if no error should be | 1196 * error code that should be reported, or `null` if no error should be |
| 1194 * reported. The [target] is the target of the invocation, or `null` if there | 1197 * reported. The [target] is the target of the invocation, or `null` if there |
| 1195 * was no target. The flag [useStaticContext] should be `true` if the | 1198 * was no target. The flag [useStaticContext] should be `true` if the |
| 1196 * invocation is in a static constant (does not have access to instance state. | 1199 * invocation is in a static constant (does not have access to instance state. |
| 1197 */ | 1200 */ |
| 1198 ErrorCode _checkForInvocationError( | 1201 ErrorCode _checkForInvocationError( |
| 1199 Expression target, bool useStaticContext, Element element) { | 1202 Expression target, bool useStaticContext, Element element) { |
| 1200 // Prefix is not declared, instead "prefix.id" are declared. | 1203 // Prefix is not declared, instead "prefix.id" are declared. |
| 1201 if (element is PrefixElement) { | 1204 if (element is PrefixElement) { |
| 1202 return CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT; | 1205 return CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT; |
| 1203 } | 1206 } else if (element is PropertyAccessorElement) { |
| 1204 if (element is PropertyAccessorElement) { | |
| 1205 // | 1207 // |
| 1206 // This is really a function expression invocation. | 1208 // This is really a function expression invocation. |
| 1207 // | 1209 // |
| 1208 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. | 1210 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| 1209 FunctionType getterType = element.type; | 1211 FunctionType getterType = element.type; |
| 1210 if (getterType != null) { | 1212 if (getterType != null) { |
| 1211 DartType returnType = getterType.returnType; | 1213 DartType returnType = getterType.returnType; |
| 1212 if (!_isExecutableType(returnType)) { | 1214 if (!_isExecutableType(returnType)) { |
| 1213 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 1215 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 1214 } | 1216 } |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 return staticType; | 1510 return staticType; |
| 1509 } | 1511 } |
| 1510 | 1512 |
| 1511 /** | 1513 /** |
| 1512 * Check for a generic method & apply type arguments if any were passed. | 1514 * Check for a generic method & apply type arguments if any were passed. |
| 1513 */ | 1515 */ |
| 1514 DartType _instantiateGenericMethod( | 1516 DartType _instantiateGenericMethod( |
| 1515 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { | 1517 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { |
| 1516 // TODO(jmesserly): support generic "call" methods on InterfaceType. | 1518 // TODO(jmesserly): support generic "call" methods on InterfaceType. |
| 1517 if (invokeType is FunctionType) { | 1519 if (invokeType is FunctionType) { |
| 1518 FunctionType type = invokeType; | 1520 List<TypeParameterElement> parameters = invokeType.typeFormals; |
| 1519 List<TypeParameterElement> parameters = type.typeFormals; | |
| 1520 | 1521 |
| 1521 NodeList<TypeName> arguments = typeArguments?.arguments; | 1522 NodeList<TypeName> arguments = typeArguments?.arguments; |
| 1522 if (arguments != null && arguments.length != parameters.length) { | 1523 if (arguments != null && arguments.length != parameters.length) { |
| 1523 _resolver.reportErrorForNode( | 1524 _resolver.reportErrorForNode( |
| 1524 StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, | 1525 StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, |
| 1525 node, | 1526 node, |
| 1526 [type, parameters.length, arguments?.length ?? 0]); | 1527 [invokeType, parameters.length, arguments?.length ?? 0]); |
| 1527 | 1528 |
| 1528 // Wrong number of type arguments. Ignore them. | 1529 // Wrong number of type arguments. Ignore them. |
| 1529 arguments = null; | 1530 arguments = null; |
| 1530 } | 1531 } |
| 1531 if (parameters.isNotEmpty) { | 1532 if (parameters.isNotEmpty) { |
| 1532 if (arguments == null) { | 1533 if (arguments == null) { |
| 1533 invokeType = _resolver.typeSystem.instantiateToBounds(type); | 1534 return _resolver.typeSystem.instantiateToBounds(invokeType); |
| 1534 } else { | 1535 } else { |
| 1535 invokeType = type.instantiate(arguments.map((n) => n.type).toList()); | 1536 return invokeType.instantiate(arguments.map((n) => n.type).toList()); |
| 1536 } | 1537 } |
| 1537 } | 1538 } |
| 1538 } | 1539 } |
| 1539 return invokeType; | 1540 return invokeType; |
| 1540 } | 1541 } |
| 1541 | 1542 |
| 1542 /** | 1543 /** |
| 1543 * Return `true` if the given [expression] is a prefix for a deferred import. | 1544 * Return `true` if the given [expression] is a prefix for a deferred import. |
| 1544 */ | 1545 */ |
| 1545 bool _isDeferredPrefix(Expression expression) { | 1546 bool _isDeferredPrefix(Expression expression) { |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 // | 1885 // |
| 1885 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { | 1886 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { |
| 1886 Element element1 = nameNode1.staticElement; | 1887 Element element1 = nameNode1.staticElement; |
| 1887 // CONST | 1888 // CONST |
| 1888 if (element1 is PropertyAccessorElement) { | 1889 if (element1 is PropertyAccessorElement) { |
| 1889 _resolveAnnotationElementGetter(annotation, element1); | 1890 _resolveAnnotationElementGetter(annotation, element1); |
| 1890 return; | 1891 return; |
| 1891 } | 1892 } |
| 1892 // Class(args) | 1893 // Class(args) |
| 1893 if (element1 is ClassElement) { | 1894 if (element1 is ClassElement) { |
| 1894 ClassElement classElement = element1; | 1895 constructor = new InterfaceTypeImpl(element1) |
| 1895 constructor = new InterfaceTypeImpl(classElement) | |
| 1896 .lookUpConstructor(null, _definingLibrary); | 1896 .lookUpConstructor(null, _definingLibrary); |
| 1897 } | 1897 } |
| 1898 } | 1898 } |
| 1899 // | 1899 // |
| 1900 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) | 1900 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) |
| 1901 // | 1901 // |
| 1902 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { | 1902 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { |
| 1903 Element element1 = nameNode1.staticElement; | 1903 Element element1 = nameNode1.staticElement; |
| 1904 Element element2 = nameNode2.staticElement; | 1904 Element element2 = nameNode2.staticElement; |
| 1905 // Class.CONST - not resolved yet | 1905 // Class.CONST - not resolved yet |
| 1906 if (element1 is ClassElement) { | 1906 if (element1 is ClassElement) { |
| 1907 ClassElement classElement = element1; | 1907 element2 = element1.lookUpGetter(nameNode2.name, _definingLibrary); |
| 1908 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary); | |
| 1909 } | 1908 } |
| 1910 // prefix.CONST or Class.CONST | 1909 // prefix.CONST or Class.CONST |
| 1911 if (element2 is PropertyAccessorElement) { | 1910 if (element2 is PropertyAccessorElement) { |
| 1912 nameNode2.staticElement = element2; | 1911 nameNode2.staticElement = element2; |
| 1913 annotation.element = element2; | 1912 annotation.element = element2; |
| 1914 _resolveAnnotationElementGetter(annotation, element2); | 1913 _resolveAnnotationElementGetter(annotation, element2); |
| 1915 return; | 1914 return; |
| 1916 } | 1915 } |
| 1917 // prefix.Class() | 1916 // prefix.Class() |
| 1918 if (element2 is ClassElement) { | 1917 if (element2 is ClassElement) { |
| 1919 constructor = element2.unnamedConstructor; | 1918 constructor = element2.unnamedConstructor; |
| 1920 } | 1919 } |
| 1921 // Class.constructor(args) | 1920 // Class.constructor(args) |
| 1922 if (element1 is ClassElement) { | 1921 if (element1 is ClassElement) { |
| 1923 ClassElement classElement = element1; | 1922 constructor = new InterfaceTypeImpl(element1) |
| 1924 constructor = new InterfaceTypeImpl(classElement) | |
| 1925 .lookUpConstructor(nameNode2.name, _definingLibrary); | 1923 .lookUpConstructor(nameNode2.name, _definingLibrary); |
| 1926 nameNode2.staticElement = constructor; | 1924 nameNode2.staticElement = constructor; |
| 1927 } | 1925 } |
| 1928 } | 1926 } |
| 1929 // | 1927 // |
| 1930 // prefix.Class.CONST or prefix.Class.constructor(args) | 1928 // prefix.Class.CONST or prefix.Class.constructor(args) |
| 1931 // | 1929 // |
| 1932 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { | 1930 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { |
| 1933 Element element2 = nameNode2.staticElement; | 1931 Element element2 = nameNode2.staticElement; |
| 1934 // element2 should be ClassElement | 1932 // element2 should be ClassElement |
| 1935 if (element2 is ClassElement) { | 1933 if (element2 is ClassElement) { |
| 1936 ClassElement classElement = element2; | |
| 1937 String name3 = nameNode3.name; | 1934 String name3 = nameNode3.name; |
| 1938 // prefix.Class.CONST | 1935 // prefix.Class.CONST |
| 1939 PropertyAccessorElement getter = | 1936 PropertyAccessorElement getter = |
| 1940 classElement.lookUpGetter(name3, _definingLibrary); | 1937 element2.lookUpGetter(name3, _definingLibrary); |
| 1941 if (getter != null) { | 1938 if (getter != null) { |
| 1942 nameNode3.staticElement = getter; | 1939 nameNode3.staticElement = getter; |
| 1943 annotation.element = element2; | 1940 annotation.element = element2; |
| 1944 _resolveAnnotationElementGetter(annotation, getter); | 1941 _resolveAnnotationElementGetter(annotation, getter); |
| 1945 return; | 1942 return; |
| 1946 } | 1943 } |
| 1947 // prefix.Class.constructor(args) | 1944 // prefix.Class.constructor(args) |
| 1948 constructor = new InterfaceTypeImpl(classElement) | 1945 constructor = new InterfaceTypeImpl(element2) |
| 1949 .lookUpConstructor(name3, _definingLibrary); | 1946 .lookUpConstructor(name3, _definingLibrary); |
| 1950 nameNode3.staticElement = constructor; | 1947 nameNode3.staticElement = constructor; |
| 1951 } | 1948 } |
| 1952 } | 1949 } |
| 1953 // we need constructor | 1950 // we need constructor |
| 1954 if (constructor == null) { | 1951 if (constructor == null) { |
| 1955 _resolver.reportErrorForNode( | 1952 _resolver.reportErrorForNode( |
| 1956 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); | 1953 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); |
| 1957 return; | 1954 return; |
| 1958 } | 1955 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 new NamespaceBuilder().createExportNamespaceForLibrary(library); | 2074 new NamespaceBuilder().createExportNamespaceForLibrary(library); |
| 2078 for (Combinator combinator in combinators) { | 2075 for (Combinator combinator in combinators) { |
| 2079 NodeList<SimpleIdentifier> names; | 2076 NodeList<SimpleIdentifier> names; |
| 2080 if (combinator is HideCombinator) { | 2077 if (combinator is HideCombinator) { |
| 2081 names = combinator.hiddenNames; | 2078 names = combinator.hiddenNames; |
| 2082 } else { | 2079 } else { |
| 2083 names = (combinator as ShowCombinator).shownNames; | 2080 names = (combinator as ShowCombinator).shownNames; |
| 2084 } | 2081 } |
| 2085 for (SimpleIdentifier name in names) { | 2082 for (SimpleIdentifier name in names) { |
| 2086 String nameStr = name.name; | 2083 String nameStr = name.name; |
| 2087 Element element = namespace.get(nameStr); | 2084 Element element = namespace.get(nameStr) ?? namespace.get("$nameStr="); |
| 2088 if (element == null) { | |
| 2089 element = namespace.get("$nameStr="); | |
| 2090 } | |
| 2091 if (element != null) { | 2085 if (element != null) { |
| 2092 // Ensure that the name always resolves to a top-level variable | 2086 // Ensure that the name always resolves to a top-level variable |
| 2093 // rather than a getter or setter | 2087 // rather than a getter or setter |
| 2094 if (element is PropertyAccessorElement) { | 2088 if (element is PropertyAccessorElement) { |
| 2095 element = (element as PropertyAccessorElement).variable; | 2089 name.staticElement = element.variable; |
| 2090 } else { |
| 2091 name.staticElement = element; |
| 2096 } | 2092 } |
| 2097 name.staticElement = element; | |
| 2098 } | 2093 } |
| 2099 } | 2094 } |
| 2100 } | 2095 } |
| 2101 } | 2096 } |
| 2102 | 2097 |
| 2103 /** | 2098 /** |
| 2104 * Given that we are accessing a property of the given [classElement] with the | 2099 * Given that we are accessing a property of the given [classElement] with the |
| 2105 * given [propertyName], return the element that represents the property. | 2100 * given [propertyName], return the element that represents the property. |
| 2106 */ | 2101 */ |
| 2107 Element _resolveElement( | 2102 Element _resolveElement( |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2291 shouldReportMissingMember_static ? staticType : propagatedType; | 2286 shouldReportMissingMember_static ? staticType : propagatedType; |
| 2292 Element staticOrPropagatedEnclosingElt = staticOrPropagatedType.element; | 2287 Element staticOrPropagatedEnclosingElt = staticOrPropagatedType.element; |
| 2293 bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt); | 2288 bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt); |
| 2294 DartType displayType = staticOrPropagatedType != null | 2289 DartType displayType = staticOrPropagatedType != null |
| 2295 ? staticOrPropagatedType | 2290 ? staticOrPropagatedType |
| 2296 : propagatedType != null ? propagatedType : staticType; | 2291 : propagatedType != null ? propagatedType : staticType; |
| 2297 // Special getter cases. | 2292 // Special getter cases. |
| 2298 if (propertyName.inGetterContext()) { | 2293 if (propertyName.inGetterContext()) { |
| 2299 if (!isStaticProperty && | 2294 if (!isStaticProperty && |
| 2300 staticOrPropagatedEnclosingElt is ClassElement) { | 2295 staticOrPropagatedEnclosingElt is ClassElement) { |
| 2301 ClassElement classElement = staticOrPropagatedEnclosingElt; | 2296 InterfaceType targetType = staticOrPropagatedEnclosingElt.type; |
| 2302 InterfaceType targetType = classElement.type; | |
| 2303 if (!_enableStrictCallChecks && | 2297 if (!_enableStrictCallChecks && |
| 2304 targetType != null && | 2298 targetType != null && |
| 2305 targetType.isDartCoreFunction && | 2299 targetType.isDartCoreFunction && |
| 2306 propertyName.name == FunctionElement.CALL_METHOD_NAME) { | 2300 propertyName.name == FunctionElement.CALL_METHOD_NAME) { |
| 2307 // TODO(brianwilkerson) Can we ever resolve the function being | 2301 // TODO(brianwilkerson) Can we ever resolve the function being |
| 2308 // invoked? | 2302 // invoked? |
| 2309 // resolveArgumentsToParameters(node.getArgumentList(), invokedFuncti
on); | 2303 // resolveArgumentsToParameters(node.getArgumentList(), invokedFuncti
on); |
| 2310 return; | 2304 return; |
| 2311 } else if (classElement.isEnum && propertyName.name == "_name") { | 2305 } else if (staticOrPropagatedEnclosingElt.isEnum && |
| 2306 propertyName.name == "_name") { |
| 2312 _resolver.reportErrorForNode( | 2307 _resolver.reportErrorForNode( |
| 2313 CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, | 2308 CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, |
| 2314 propertyName, | 2309 propertyName, |
| 2315 [propertyName.name]); | 2310 [propertyName.name]); |
| 2316 return; | 2311 return; |
| 2317 } | 2312 } |
| 2318 } | 2313 } |
| 2319 } | 2314 } |
| 2320 Element declaringElement = | 2315 Element declaringElement = |
| 2321 staticType.isVoid ? null : staticOrPropagatedEnclosingElt; | 2316 staticType.isVoid ? null : staticOrPropagatedEnclosingElt; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2451 } | 2446 } |
| 2452 return null; | 2447 return null; |
| 2453 } | 2448 } |
| 2454 | 2449 |
| 2455 /** | 2450 /** |
| 2456 * Given a [node] that can have annotations associated with it, resolve the | 2451 * Given a [node] that can have annotations associated with it, resolve the |
| 2457 * annotations in the element model representing the annotations on the node. | 2452 * annotations in the element model representing the annotations on the node. |
| 2458 */ | 2453 */ |
| 2459 static void resolveMetadata(AnnotatedNode node) { | 2454 static void resolveMetadata(AnnotatedNode node) { |
| 2460 _resolveAnnotations(node.metadata); | 2455 _resolveAnnotations(node.metadata); |
| 2461 if (node is VariableDeclaration && node.parent is VariableDeclarationList) { | 2456 if (node is VariableDeclaration) { |
| 2462 VariableDeclarationList list = node.parent as VariableDeclarationList; | 2457 AstNode parent = node.parent; |
| 2463 _resolveAnnotations(list.metadata); | 2458 if (parent is VariableDeclarationList) { |
| 2464 if (list.parent is FieldDeclaration) { | 2459 _resolveAnnotations(parent.metadata); |
| 2465 FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration; | 2460 AstNode grandParent = parent.parent; |
| 2466 _resolveAnnotations(fieldDeclaration.metadata); | 2461 if (grandParent is FieldDeclaration) { |
| 2467 } else if (list.parent is TopLevelVariableDeclaration) { | 2462 _resolveAnnotations(grandParent.metadata); |
| 2468 TopLevelVariableDeclaration variableDeclaration = | 2463 } else if (grandParent is TopLevelVariableDeclaration) { |
| 2469 list.parent as TopLevelVariableDeclaration; | 2464 _resolveAnnotations(grandParent.metadata); |
| 2470 _resolveAnnotations(variableDeclaration.metadata); | 2465 } |
| 2471 } | 2466 } |
| 2472 } | 2467 } |
| 2473 } | 2468 } |
| 2474 | 2469 |
| 2475 /** | 2470 /** |
| 2476 * Return `true` if the given [identifier] is the return type of a constructor | 2471 * Return `true` if the given [identifier] is the return type of a constructor |
| 2477 * declaration. | 2472 * declaration. |
| 2478 */ | 2473 */ |
| 2479 static bool _isConstructorReturnType(SimpleIdentifier identifier) { | 2474 static bool _isConstructorReturnType(SimpleIdentifier identifier) { |
| 2480 AstNode parent = identifier.parent; | 2475 AstNode parent = identifier.parent; |
| 2481 if (parent is ConstructorDeclaration) { | 2476 if (parent is ConstructorDeclaration) { |
| 2482 return identical(parent.returnType, identifier); | 2477 return identical(parent.returnType, identifier); |
| 2483 } | 2478 } |
| 2484 return false; | 2479 return false; |
| 2485 } | 2480 } |
| 2486 | 2481 |
| 2487 /** | 2482 /** |
| 2488 * Return `true` if the given [identifier] is the return type of a factory | 2483 * Return `true` if the given [identifier] is the return type of a factory |
| 2489 * constructor. | 2484 * constructor. |
| 2490 */ | 2485 */ |
| 2491 static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) { | 2486 static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) { |
| 2492 AstNode parent = identifier.parent; | 2487 AstNode parent = identifier.parent; |
| 2493 if (parent is ConstructorDeclaration) { | 2488 if (parent is ConstructorDeclaration) { |
| 2494 ConstructorDeclaration constructor = parent; | 2489 return identical(parent.returnType, identifier) && |
| 2495 return identical(constructor.returnType, identifier) && | 2490 parent.factoryKeyword != null; |
| 2496 constructor.factoryKeyword != null; | |
| 2497 } | 2491 } |
| 2498 return false; | 2492 return false; |
| 2499 } | 2493 } |
| 2500 | 2494 |
| 2501 /** | 2495 /** |
| 2502 * Return `true` if the given 'super' [expression] is used in a valid context. | 2496 * Return `true` if the given 'super' [expression] is used in a valid context. |
| 2503 */ | 2497 */ |
| 2504 static bool _isSuperInValidContext(SuperExpression expression) { | 2498 static bool _isSuperInValidContext(SuperExpression expression) { |
| 2505 for (AstNode node = expression; node != null; node = node.parent) { | 2499 for (AstNode node = expression; node != null; node = node.parent) { |
| 2506 if (node is CompilationUnit) { | 2500 if (node is CompilationUnit) { |
| 2507 return false; | 2501 return false; |
| 2508 } | 2502 } else if (node is ConstructorDeclaration) { |
| 2509 if (node is ConstructorDeclaration) { | |
| 2510 return node.factoryKeyword == null; | 2503 return node.factoryKeyword == null; |
| 2511 } | 2504 } else if (node is ConstructorFieldInitializer) { |
| 2512 if (node is ConstructorFieldInitializer) { | |
| 2513 return false; | 2505 return false; |
| 2514 } | 2506 } else if (node is MethodDeclaration) { |
| 2515 if (node is MethodDeclaration) { | |
| 2516 return !node.isStatic; | 2507 return !node.isStatic; |
| 2517 } | 2508 } |
| 2518 } | 2509 } |
| 2519 return false; | 2510 return false; |
| 2520 } | 2511 } |
| 2521 | 2512 |
| 2522 /** | 2513 /** |
| 2523 * Resolve each of the annotations in the given list of [annotations]. | 2514 * Resolve each of the annotations in the given list of [annotations]. |
| 2524 */ | 2515 */ |
| 2525 static void _resolveAnnotations(NodeList<Annotation> annotations) { | 2516 static void _resolveAnnotations(NodeList<Annotation> annotations) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2585 | 2576 |
| 2586 @override | 2577 @override |
| 2587 Element get staticElement => null; | 2578 Element get staticElement => null; |
| 2588 | 2579 |
| 2589 @override | 2580 @override |
| 2590 dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) => null; | 2581 dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) => null; |
| 2591 | 2582 |
| 2592 @override | 2583 @override |
| 2593 void visitChildren(AstVisitor visitor) {} | 2584 void visitChildren(AstVisitor visitor) {} |
| 2594 } | 2585 } |
| OLD | NEW |