| 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.resolver; | 5 library analyzer.src.generated.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 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 } else if (element is PropertyAccessorElement && element.isSynthetic) { | 555 } else if (element is PropertyAccessorElement && element.isSynthetic) { |
| 556 // TODO(brianwilkerson) Why isn't this the implementation for PropertyAc
cessorElement? | 556 // TODO(brianwilkerson) Why isn't this the implementation for PropertyAc
cessorElement? |
| 557 Element variable = element.variable; | 557 Element variable = element.variable; |
| 558 if (variable == null) { | 558 if (variable == null) { |
| 559 return false; | 559 return false; |
| 560 } | 560 } |
| 561 return variable.isDeprecated; | 561 return variable.isDeprecated; |
| 562 } | 562 } |
| 563 return element.isDeprecated; | 563 return element.isDeprecated; |
| 564 } | 564 } |
| 565 |
| 565 if (!inDeprecatedMember && isDeprecated(element)) { | 566 if (!inDeprecatedMember && isDeprecated(element)) { |
| 566 String displayName = element.displayName; | 567 String displayName = element.displayName; |
| 567 if (element is ConstructorElement) { | 568 if (element is ConstructorElement) { |
| 568 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), | 569 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), |
| 569 // or have the logic centralized elsewhere, instead of doing this logic | 570 // or have the logic centralized elsewhere, instead of doing this logic |
| 570 // here. | 571 // here. |
| 571 displayName = element.enclosingElement.displayName; | 572 displayName = element.enclosingElement.displayName; |
| 572 if (!element.displayName.isEmpty) { | 573 if (!element.displayName.isEmpty) { |
| 573 displayName = "$displayName.${element.displayName}"; | 574 displayName = "$displayName.${element.displayName}"; |
| 574 } | 575 } |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) { | 965 if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) { |
| 965 Element methodElement = name.staticElement; | 966 Element methodElement = name.staticElement; |
| 966 Element classElement = methodElement?.enclosingElement; | 967 Element classElement = methodElement?.enclosingElement; |
| 967 return methodElement is MethodElement && | 968 return methodElement is MethodElement && |
| 968 classElement is ClassElement && | 969 classElement is ClassElement && |
| 969 !classElement.type.isObject; | 970 !classElement.type.isObject; |
| 970 } | 971 } |
| 971 } | 972 } |
| 972 return false; | 973 return false; |
| 973 } | 974 } |
| 975 |
| 974 FunctionBody body = node.body; | 976 FunctionBody body = node.body; |
| 975 if (body is ExpressionFunctionBody) { | 977 if (body is ExpressionFunctionBody) { |
| 976 if (isNonObjectNoSuchMethodInvocation(body.expression)) { | 978 if (isNonObjectNoSuchMethodInvocation(body.expression)) { |
| 977 _errorReporter.reportErrorForNode( | 979 _errorReporter.reportErrorForNode( |
| 978 HintCode.UNNECESSARY_NO_SUCH_METHOD, node); | 980 HintCode.UNNECESSARY_NO_SUCH_METHOD, node); |
| 979 return true; | 981 return true; |
| 980 } | 982 } |
| 981 } else if (body is BlockFunctionBody) { | 983 } else if (body is BlockFunctionBody) { |
| 982 List<Statement> statements = body.block.statements; | 984 List<Statement> statements = body.block.statements; |
| 983 if (statements.length == 1) { | 985 if (statements.length == 1) { |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 return null; | 1911 return null; |
| 1910 } | 1912 } |
| 1911 } | 1913 } |
| 1912 } | 1914 } |
| 1913 return super.visitConditionalExpression(node); | 1915 return super.visitConditionalExpression(node); |
| 1914 } | 1916 } |
| 1915 | 1917 |
| 1916 @override | 1918 @override |
| 1917 Object visitExportDirective(ExportDirective node) { | 1919 Object visitExportDirective(ExportDirective node) { |
| 1918 ExportElement exportElement = node.element; | 1920 ExportElement exportElement = node.element; |
| 1919 if (exportElement != null) { | 1921 if (exportElement != null && exportElement.context.exists(node.source)) { |
| 1920 // The element is null when the URI is invalid | 1922 // The element is null when the URI is invalid |
| 1921 LibraryElement library = exportElement.exportedLibrary; | 1923 LibraryElement library = exportElement.exportedLibrary; |
| 1922 if (library != null) { | 1924 if (library != null) { |
| 1923 for (Combinator combinator in node.combinators) { | 1925 for (Combinator combinator in node.combinators) { |
| 1924 _checkCombinator(exportElement.exportedLibrary, combinator); | 1926 _checkCombinator(exportElement.exportedLibrary, combinator); |
| 1925 } | 1927 } |
| 1926 } | 1928 } |
| 1927 } | 1929 } |
| 1928 return super.visitExportDirective(node); | 1930 return super.visitExportDirective(node); |
| 1929 } | 1931 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1953 return null; | 1955 return null; |
| 1954 } | 1956 } |
| 1955 } | 1957 } |
| 1956 } | 1958 } |
| 1957 return super.visitIfStatement(node); | 1959 return super.visitIfStatement(node); |
| 1958 } | 1960 } |
| 1959 | 1961 |
| 1960 @override | 1962 @override |
| 1961 Object visitImportDirective(ImportDirective node) { | 1963 Object visitImportDirective(ImportDirective node) { |
| 1962 ImportElement importElement = node.element; | 1964 ImportElement importElement = node.element; |
| 1963 if (importElement != null) { | 1965 if (importElement != null && importElement.context.exists(node.source)) { |
| 1964 // The element is null when the URI is invalid | 1966 // The element is null when the URI is invalid, but not when the URI is |
| 1967 // valid but refers to a non-existent file. |
| 1965 LibraryElement library = importElement.importedLibrary; | 1968 LibraryElement library = importElement.importedLibrary; |
| 1966 if (library != null) { | 1969 if (library != null) { |
| 1967 for (Combinator combinator in node.combinators) { | 1970 for (Combinator combinator in node.combinators) { |
| 1968 _checkCombinator(library, combinator); | 1971 _checkCombinator(library, combinator); |
| 1969 } | 1972 } |
| 1970 } | 1973 } |
| 1971 } | 1974 } |
| 1972 return super.visitImportDirective(node); | 1975 return super.visitImportDirective(node); |
| 1973 } | 1976 } |
| 1974 | 1977 |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2540 | 2543 |
| 2541 @override | 2544 @override |
| 2542 Object visitMethodDeclaration(MethodDeclaration node) { | 2545 Object visitMethodDeclaration(MethodDeclaration node) { |
| 2543 ExecutableElement outerExecutable = _enclosingExecutable; | 2546 ExecutableElement outerExecutable = _enclosingExecutable; |
| 2544 try { | 2547 try { |
| 2545 Token property = node.propertyKeyword; | 2548 Token property = node.propertyKeyword; |
| 2546 SimpleIdentifier methodName = node.name; | 2549 SimpleIdentifier methodName = node.name; |
| 2547 String nameOfMethod = methodName.name; | 2550 String nameOfMethod = methodName.name; |
| 2548 if (property == null) { | 2551 if (property == null) { |
| 2549 String elementName = nameOfMethod == '-' && | 2552 String elementName = nameOfMethod == '-' && |
| 2550 node.parameters != null && | 2553 node.parameters != null && |
| 2551 node.parameters.parameters.isEmpty ? 'unary-' : nameOfMethod; | 2554 node.parameters.parameters.isEmpty |
| 2555 ? 'unary-' |
| 2556 : nameOfMethod; |
| 2552 _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods, | 2557 _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods, |
| 2553 methodName, elementName, methodName.offset); | 2558 methodName, elementName, methodName.offset); |
| 2554 _expectedElements.remove(_enclosingExecutable); | 2559 _expectedElements.remove(_enclosingExecutable); |
| 2555 methodName.staticElement = _enclosingExecutable; | 2560 methodName.staticElement = _enclosingExecutable; |
| 2556 } else { | 2561 } else { |
| 2557 PropertyAccessorElement accessor; | 2562 PropertyAccessorElement accessor; |
| 2558 if (property.keyword == Keyword.GET) { | 2563 if (property.keyword == Keyword.GET) { |
| 2559 accessor = _findIdentifier(_enclosingClass.accessors, methodName); | 2564 accessor = _findIdentifier(_enclosingClass.accessors, methodName); |
| 2560 } else if (property.keyword == Keyword.SET) { | 2565 } else if (property.keyword == Keyword.SET) { |
| 2561 accessor = _findWithNameAndOffset(_enclosingClass.accessors, | 2566 accessor = _findWithNameAndOffset(_enclosingClass.accessors, |
| (...skipping 1394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3956 bool _recordPrefixMap(SimpleIdentifier identifier, Element element) { | 3961 bool _recordPrefixMap(SimpleIdentifier identifier, Element element) { |
| 3957 bool recordIfTargetIsPrefixElement(Expression target) { | 3962 bool recordIfTargetIsPrefixElement(Expression target) { |
| 3958 if (target is SimpleIdentifier && target.staticElement is PrefixElement) { | 3963 if (target is SimpleIdentifier && target.staticElement is PrefixElement) { |
| 3959 List<Element> prefixedElements = usedElements.prefixMap | 3964 List<Element> prefixedElements = usedElements.prefixMap |
| 3960 .putIfAbsent(target.staticElement, () => <Element>[]); | 3965 .putIfAbsent(target.staticElement, () => <Element>[]); |
| 3961 prefixedElements.add(element); | 3966 prefixedElements.add(element); |
| 3962 return true; | 3967 return true; |
| 3963 } | 3968 } |
| 3964 return false; | 3969 return false; |
| 3965 } | 3970 } |
| 3971 |
| 3966 AstNode parent = identifier.parent; | 3972 AstNode parent = identifier.parent; |
| 3967 if (parent is MethodInvocation && parent.methodName == identifier) { | 3973 if (parent is MethodInvocation && parent.methodName == identifier) { |
| 3968 return recordIfTargetIsPrefixElement(parent.target); | 3974 return recordIfTargetIsPrefixElement(parent.target); |
| 3969 } | 3975 } |
| 3970 if (parent is PrefixedIdentifier && parent.identifier == identifier) { | 3976 if (parent is PrefixedIdentifier && parent.identifier == identifier) { |
| 3971 return recordIfTargetIsPrefixElement(parent.prefix); | 3977 return recordIfTargetIsPrefixElement(parent.prefix); |
| 3972 } | 3978 } |
| 3973 return false; | 3979 return false; |
| 3974 } | 3980 } |
| 3975 | 3981 |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4432 * | 4438 * |
| 4433 * Only call this method after all of the compilation units have been visited
by this visitor. | 4439 * Only call this method after all of the compilation units have been visited
by this visitor. |
| 4434 * | 4440 * |
| 4435 * @param errorReporter the error reporter used to report the set of [HintCode
.UNUSED_IMPORT] | 4441 * @param errorReporter the error reporter used to report the set of [HintCode
.UNUSED_IMPORT] |
| 4436 * hints | 4442 * hints |
| 4437 */ | 4443 */ |
| 4438 void generateUnusedImportHints(ErrorReporter errorReporter) { | 4444 void generateUnusedImportHints(ErrorReporter errorReporter) { |
| 4439 int length = _unusedImports.length; | 4445 int length = _unusedImports.length; |
| 4440 for (int i = 0; i < length; i++) { | 4446 for (int i = 0; i < length; i++) { |
| 4441 ImportDirective unusedImport = _unusedImports[i]; | 4447 ImportDirective unusedImport = _unusedImports[i]; |
| 4442 // Check that the import isn't dart:core | 4448 // Check that the imported URI exists and isn't dart:core |
| 4443 ImportElement importElement = unusedImport.element; | 4449 ImportElement importElement = unusedImport.element; |
| 4444 if (importElement != null) { | 4450 if (importElement != null) { |
| 4445 LibraryElement libraryElement = importElement.importedLibrary; | 4451 LibraryElement libraryElement = importElement.importedLibrary; |
| 4446 if (libraryElement != null && libraryElement.isDartCore) { | 4452 if (libraryElement == null || |
| 4453 libraryElement.isDartCore || |
| 4454 !importElement.context.exists(unusedImport.source)) { |
| 4447 continue; | 4455 continue; |
| 4448 } | 4456 } |
| 4449 } | 4457 } |
| 4450 errorReporter.reportErrorForNode( | 4458 errorReporter.reportErrorForNode( |
| 4451 HintCode.UNUSED_IMPORT, unusedImport.uri); | 4459 HintCode.UNUSED_IMPORT, unusedImport.uri); |
| 4452 } | 4460 } |
| 4453 } | 4461 } |
| 4454 | 4462 |
| 4455 /** | 4463 /** |
| 4456 * Report an [HintCode.UNUSED_SHOWN_NAME] hint for each unused shown name. | 4464 * Report an [HintCode.UNUSED_SHOWN_NAME] hint for each unused shown name. |
| (...skipping 4078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8535 if (typeName.name == voidType.name) { | 8543 if (typeName.name == voidType.name) { |
| 8536 // There is no element for 'void'. | 8544 // There is no element for 'void'. |
| 8537 // if (argumentList != null) { | 8545 // if (argumentList != null) { |
| 8538 // // TODO(brianwilkerson) Report this error | 8546 // // TODO(brianwilkerson) Report this error |
| 8539 // reporter.reportError(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGU
MENTS, node, voidType.getName(), 0, argumentList.getArguments().size()); | 8547 // reporter.reportError(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGU
MENTS, node, voidType.getName(), 0, argumentList.getArguments().size()); |
| 8540 // } | 8548 // } |
| 8541 typeName.staticType = voidType; | 8549 typeName.staticType = voidType; |
| 8542 node.type = voidType; | 8550 node.type = voidType; |
| 8543 return; | 8551 return; |
| 8544 } | 8552 } |
| 8553 if (nameScope.shouldIgnoreUndefined(typeName)) { |
| 8554 typeName.staticType = undefinedType; |
| 8555 node.type = undefinedType; |
| 8556 return; |
| 8557 } |
| 8545 // | 8558 // |
| 8546 // If not, the look to see whether we might have created the wrong AST | 8559 // If not, the look to see whether we might have created the wrong AST |
| 8547 // structure for a constructor name. If so, fix the AST structure and then | 8560 // structure for a constructor name. If so, fix the AST structure and then |
| 8548 // proceed. | 8561 // proceed. |
| 8549 // | 8562 // |
| 8550 AstNode parent = node.parent; | 8563 AstNode parent = node.parent; |
| 8551 if (typeName is PrefixedIdentifier && | 8564 if (typeName is PrefixedIdentifier && |
| 8552 parent is ConstructorName && | 8565 parent is ConstructorName && |
| 8553 argumentList == null) { | 8566 argumentList == null) { |
| 8554 ConstructorName name = parent; | 8567 ConstructorName name = parent; |
| 8555 if (name.name == null) { | 8568 if (name.name == null) { |
| 8556 PrefixedIdentifier prefixedIdentifier = | 8569 PrefixedIdentifier prefixedIdentifier = |
| 8557 typeName as PrefixedIdentifier; | 8570 typeName as PrefixedIdentifier; |
| 8558 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 8571 SimpleIdentifier prefix = prefixedIdentifier.prefix; |
| 8559 element = nameScope.lookup(prefix, definingLibrary); | 8572 element = nameScope.lookup(prefix, definingLibrary); |
| 8560 if (element is PrefixElement) { | 8573 if (element is PrefixElement) { |
| 8574 if (nameScope.shouldIgnoreUndefined(typeName)) { |
| 8575 typeName.staticType = undefinedType; |
| 8576 node.type = undefinedType; |
| 8577 return; |
| 8578 } |
| 8561 AstNode grandParent = parent.parent; | 8579 AstNode grandParent = parent.parent; |
| 8562 if (grandParent is InstanceCreationExpression && | 8580 if (grandParent is InstanceCreationExpression && |
| 8563 grandParent.isConst) { | 8581 grandParent.isConst) { |
| 8564 // If, if this is a const expression, then generate a | 8582 // If, if this is a const expression, then generate a |
| 8565 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. | 8583 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. |
| 8566 reportErrorForNode( | 8584 reportErrorForNode( |
| 8567 CompileTimeErrorCode.CONST_WITH_NON_TYPE, | 8585 CompileTimeErrorCode.CONST_WITH_NON_TYPE, |
| 8568 prefixedIdentifier.identifier, | 8586 prefixedIdentifier.identifier, |
| 8569 [prefixedIdentifier.identifier.name]); | 8587 [prefixedIdentifier.identifier.name]); |
| 8570 } else { | 8588 } else { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 8585 // constructor name. It arbitrarily chooses the former, but in this | 8603 // constructor name. It arbitrarily chooses the former, but in this |
| 8586 // case was wrong. | 8604 // case was wrong. |
| 8587 // | 8605 // |
| 8588 name.name = prefixedIdentifier.identifier; | 8606 name.name = prefixedIdentifier.identifier; |
| 8589 name.period = prefixedIdentifier.period; | 8607 name.period = prefixedIdentifier.period; |
| 8590 node.name = prefix; | 8608 node.name = prefix; |
| 8591 typeName = prefix; | 8609 typeName = prefix; |
| 8592 } | 8610 } |
| 8593 } | 8611 } |
| 8594 } | 8612 } |
| 8613 if (nameScope.shouldIgnoreUndefined(typeName)) { |
| 8614 typeName.staticType = undefinedType; |
| 8615 node.type = undefinedType; |
| 8616 return; |
| 8617 } |
| 8595 } | 8618 } |
| 8596 // check element | 8619 // check element |
| 8597 bool elementValid = element is! MultiplyDefinedElement; | 8620 bool elementValid = element is! MultiplyDefinedElement; |
| 8598 if (elementValid && | 8621 if (elementValid && |
| 8599 element is! ClassElement && | 8622 element is! ClassElement && |
| 8600 _isTypeNameInInstanceCreationExpression(node)) { | 8623 _isTypeNameInInstanceCreationExpression(node)) { |
| 8601 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); | 8624 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); |
| 8602 InstanceCreationExpression creation = | 8625 InstanceCreationExpression creation = |
| 8603 node.parent.parent as InstanceCreationExpression; | 8626 node.parent.parent as InstanceCreationExpression; |
| 8604 if (creation.isConst) { | 8627 if (creation.isConst) { |
| (...skipping 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10406 errorReporter.reportErrorForNode(enumTypeError, typeName); | 10429 errorReporter.reportErrorForNode(enumTypeError, typeName); |
| 10407 return null; | 10430 return null; |
| 10408 } | 10431 } |
| 10409 return type; | 10432 return type; |
| 10410 } | 10433 } |
| 10411 // If the type is not an InterfaceType, then visitTypeName() sets the type | 10434 // If the type is not an InterfaceType, then visitTypeName() sets the type |
| 10412 // to be a DynamicTypeImpl | 10435 // to be a DynamicTypeImpl |
| 10413 Identifier name = typeName.name; | 10436 Identifier name = typeName.name; |
| 10414 if (name.name == Keyword.DYNAMIC.syntax) { | 10437 if (name.name == Keyword.DYNAMIC.syntax) { |
| 10415 errorReporter.reportErrorForNode(dynamicTypeError, name, [name.name]); | 10438 errorReporter.reportErrorForNode(dynamicTypeError, name, [name.name]); |
| 10416 } else { | 10439 } else if (!nameScope.shouldIgnoreUndefined(name)) { |
| 10417 errorReporter.reportErrorForNode(nonTypeError, name, [name.name]); | 10440 errorReporter.reportErrorForNode(nonTypeError, name, [name.name]); |
| 10418 } | 10441 } |
| 10419 return null; | 10442 return null; |
| 10420 } | 10443 } |
| 10421 | 10444 |
| 10422 /** | 10445 /** |
| 10423 * Resolve the types in the given list of type names. | 10446 * Resolve the types in the given list of type names. |
| 10424 * | 10447 * |
| 10425 * @param typeNames the type names to be resolved | 10448 * @param typeNames the type names to be resolved |
| 10426 * @param nonTypeError the error to produce if the type name is defined to be
something other than | 10449 * @param nonTypeError the error to produce if the type name is defined to be
something other than |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11005 return null; | 11028 return null; |
| 11006 } | 11029 } |
| 11007 if (identical(node.staticElement, variable)) { | 11030 if (identical(node.staticElement, variable)) { |
| 11008 if (node.inSetterContext()) { | 11031 if (node.inSetterContext()) { |
| 11009 result = true; | 11032 result = true; |
| 11010 } | 11033 } |
| 11011 } | 11034 } |
| 11012 return null; | 11035 return null; |
| 11013 } | 11036 } |
| 11014 } | 11037 } |
| OLD | NEW |