Index: pkg/analyzer/lib/src/generated/resolver.dart |
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart |
index 56c718ddcbb142b5607a9e86e2164a82adf2e6aa..e9b9ff14917f99fa507a75bc0f6f9c92ef77cb01 100644 |
--- a/pkg/analyzer/lib/src/generated/resolver.dart |
+++ b/pkg/analyzer/lib/src/generated/resolver.dart |
@@ -1924,6 +1924,17 @@ class UnusedLocalVariableVerifier extends RecursiveElementVisitor { |
UnusedLocalVariableVerifier(this._errorReporter); |
Brian Wilkerson
2014/11/10 23:34:47
If the class is checking more than local variables
scheglov
2014/11/11 02:57:06
Done.
|
@override |
+ visitClassElement(ClassElement element) { |
+ if (element is ClassElementImpl && !element.isUsed) { |
+ _errorReporter.reportErrorForElement( |
+ HintCode.UNUSED_ELEMENT, |
+ element, |
+ [element.kind.displayName, element.displayName]); |
+ } |
+ element.visitChildren(this); |
+ } |
+ |
+ @override |
visitLocalVariableElement(LocalVariableElement element) { |
if (element is LocalVariableElementImpl && !element.isUsed) { |
_errorReporter.reportErrorForElement( |
@@ -12481,6 +12492,12 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
LabelScope _labelScope; |
/** |
+ * The class containing the AST nodes being visited, |
+ * or `null` if we are not in the scope of a class. |
+ */ |
+ ClassElement _enclosingClass; |
+ |
+ /** |
* Initialize a newly created visitor to resolve the nodes in a compilation unit. |
* |
* @param library the library containing the compilation unit being resolved |
@@ -12616,10 +12633,16 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
new CaughtException(new AnalysisException(), null)); |
super.visitClassDeclaration(node); |
} else { |
- _nameScope = new TypeParameterScope(_nameScope, classElement); |
- visitClassDeclarationInScope(node); |
- _nameScope = new ClassScope(_nameScope, classElement); |
- visitClassMembersInScope(node); |
+ ClassElement outerClass = _enclosingClass; |
+ try { |
+ _enclosingClass = node.element; |
+ _nameScope = new TypeParameterScope(_nameScope, classElement); |
+ visitClassDeclarationInScope(node); |
+ _nameScope = new ClassScope(_nameScope, classElement); |
+ visitClassMembersInScope(node); |
+ } finally { |
+ _enclosingClass = outerClass; |
+ } |
} |
} finally { |
_nameScope = outerScope; |
@@ -15090,6 +15113,7 @@ class TypeResolverVisitor extends ScopedVisitor { |
if (element != null) { |
if (typeName is SimpleIdentifier) { |
typeName.staticElement = element; |
+ _markTypeNameElementUsed(typeName, element); |
} else if (typeName is PrefixedIdentifier) { |
PrefixedIdentifier identifier = typeName; |
identifier.identifier.staticElement = element; |
@@ -15103,6 +15127,31 @@ class TypeResolverVisitor extends ScopedVisitor { |
} |
/** |
+ * Marks [element] as used in its defining library. |
+ */ |
+ void _markTypeNameElementUsed(Identifier typeName, Element element) { |
+ if (identical(element, _enclosingClass)) { |
+ return; |
+ } |
+ // ignore places where the element is not actually used |
+ if (typeName.parent is TypeName) { |
+ AstNode parent2 = typeName.parent.parent; |
+ if (parent2 is IsExpression) { |
+ return; |
+ } |
+ if (parent2 is VariableDeclarationList) { |
+ return; |
+ } |
+ } |
+ // check if the element is a local top-level element |
+ if (element is ElementImpl && |
+ element.enclosingElement is CompilationUnitElement && |
+ identical(element.library, definingLibrary)) { |
+ element.markUsed(); |
+ } |
+ } |
+ |
+ /** |
* Given a parameter element, create a function type based on the given return type and parameter |
* list and associate the created type with the element. |
* |