Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1055573003: Report unused elements in GenerateHintsTask. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 engine.resolver; 5 library engine.resolver;
6 6
7 import "dart:math" as math; 7 import "dart:math" as math;
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/src/generated/utilities_collection.dart'; 10 import 'package:analyzer/src/generated/utilities_collection.dart';
(...skipping 4540 matching lines...) Expand 10 before | Expand all | Expand 10 after
4551 _generateForCompilationUnit(_compilationUnits[i], element.source); 4551 _generateForCompilationUnit(_compilationUnits[i], element.source);
4552 } 4552 }
4553 } 4553 }
4554 } 4554 }
4555 ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter( 4555 ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter(
4556 _errorListener, _compilationUnits[0].element.source); 4556 _errorListener, _compilationUnits[0].element.source);
4557 _importsVerifier 4557 _importsVerifier
4558 .generateDuplicateImportHints(definingCompilationUnitErrorReporter); 4558 .generateDuplicateImportHints(definingCompilationUnitErrorReporter);
4559 _importsVerifier 4559 _importsVerifier
4560 .generateUnusedImportHints(definingCompilationUnitErrorReporter); 4560 .generateUnusedImportHints(definingCompilationUnitErrorReporter);
4561 _library.accept(new _UnusedElementsVerifier( 4561 _library.accept(new UnusedElementsVerifier(
4562 _errorListener, _usedElementsVisitor.usedElements)); 4562 _errorListener, _usedElementsVisitor.usedElements));
4563 }); 4563 });
4564 } 4564 }
4565 4565
4566 void _generateForCompilationUnit(CompilationUnit unit, Source source) { 4566 void _generateForCompilationUnit(CompilationUnit unit, Source source) {
4567 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); 4567 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
4568 unit.accept(_importsVerifier); 4568 unit.accept(_importsVerifier);
4569 // dead code analysis 4569 // dead code analysis
4570 unit.accept(new DeadCodeVerifier(errorReporter)); 4570 unit.accept(new DeadCodeVerifier(errorReporter));
4571 unit.accept(_usedElementsVisitor); 4571 unit.accept(_usedElementsVisitor);
(...skipping 10373 matching lines...) Expand 10 before | Expand all | Expand 10 after
14945 return identical(parent.type, node); 14945 return identical(parent.type, node);
14946 } 14946 }
14947 if (parent is SimpleFormalParameter) { 14947 if (parent is SimpleFormalParameter) {
14948 return identical(parent.type, node); 14948 return identical(parent.type, node);
14949 } 14949 }
14950 return false; 14950 return false;
14951 } 14951 }
14952 } 14952 }
14953 14953
14954 /** 14954 /**
14955 * Instances of the class [UnusedElementsVerifier] traverse an element
14956 * structure looking for cases of [HintCode.UNUSED_ELEMENT] and
14957 * [HintCode.UNUSED_LOCAL_VARIABLE].
14958 */
14959 class UnusedElementsVerifier extends RecursiveElementVisitor {
14960 /**
14961 * The error listener to which errors will be reported.
14962 */
14963 final AnalysisErrorListener _errorListener;
14964
14965 /**
14966 * The elements know to be used.
14967 */
14968 final UsedElements _usedElements;
14969
14970 /**
14971 * Create a new instance of the [UnusedElementsVerifier].
14972 */
14973 UnusedElementsVerifier(this._errorListener, this._usedElements);
14974
14975 @override
14976 visitClassElement(ClassElement element) {
14977 if (!_isUsedElement(element)) {
14978 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
14979 element.kind.displayName,
14980 element.displayName
14981 ]);
14982 }
14983 super.visitClassElement(element);
14984 }
14985
14986 @override
14987 visitFieldElement(FieldElement element) {
14988 if (!_isReadMember(element)) {
14989 _reportErrorForElement(
14990 HintCode.UNUSED_FIELD, element, [element.displayName]);
14991 }
14992 super.visitFieldElement(element);
14993 }
14994
14995 @override
14996 visitFunctionElement(FunctionElement element) {
14997 if (!_isUsedElement(element)) {
14998 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
14999 element.kind.displayName,
15000 element.displayName
15001 ]);
15002 }
15003 super.visitFunctionElement(element);
15004 }
15005
15006 @override
15007 visitLocalVariableElement(LocalVariableElement element) {
15008 if (!_isUsedElement(element) && !_isNamedUnderscore(element)) {
15009 HintCode errorCode;
15010 if (_usedElements.isCatchException(element)) {
15011 errorCode = HintCode.UNUSED_CATCH_CLAUSE;
15012 } else if (_usedElements.isCatchStackTrace(element)) {
15013 errorCode = HintCode.UNUSED_CATCH_STACK;
15014 } else {
15015 errorCode = HintCode.UNUSED_LOCAL_VARIABLE;
15016 }
15017 _reportErrorForElement(errorCode, element, [element.displayName]);
15018 }
15019 }
15020
15021 @override
15022 visitMethodElement(MethodElement element) {
15023 if (!_isUsedMember(element)) {
15024 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
15025 element.kind.displayName,
15026 element.displayName
15027 ]);
15028 }
15029 super.visitMethodElement(element);
15030 }
15031
15032 @override
15033 visitPropertyAccessorElement(PropertyAccessorElement element) {
15034 if (!_isUsedMember(element)) {
15035 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
15036 element.kind.displayName,
15037 element.displayName
15038 ]);
15039 }
15040 super.visitPropertyAccessorElement(element);
15041 }
15042
15043 bool _isNamedUnderscore(LocalVariableElement element) {
15044 String name = element.name;
15045 if (name != null) {
15046 for (int index = name.length - 1; index >= 0; --index) {
15047 if (name.codeUnitAt(index) != 0x5F) {
15048 // 0x5F => '_'
15049 return false;
15050 }
15051 }
15052 return true;
15053 }
15054 return false;
15055 }
15056
15057 bool _isReadMember(Element element) {
15058 if (element.isPublic) {
15059 return true;
15060 }
15061 if (element.isSynthetic) {
15062 return true;
15063 }
15064 return _usedElements.readMembers.contains(element.displayName);
15065 }
15066
15067 bool _isUsedElement(Element element) {
15068 if (element.isSynthetic) {
15069 return true;
15070 }
15071 if (element is LocalVariableElement ||
15072 element is FunctionElement && !element.isStatic) {
15073 // local variable or function
15074 } else {
15075 if (element.isPublic) {
15076 return true;
15077 }
15078 }
15079 return _usedElements.elements.contains(element);
15080 }
15081
15082 bool _isUsedMember(Element element) {
15083 if (element.isPublic) {
15084 return true;
15085 }
15086 if (element.isSynthetic) {
15087 return true;
15088 }
15089 if (_usedElements.members.contains(element.displayName)) {
15090 return true;
15091 }
15092 return _usedElements.elements.contains(element);
15093 }
15094
15095 void _reportErrorForElement(
15096 ErrorCode errorCode, Element element, List<Object> arguments) {
15097 if (element != null) {
15098 _errorListener.onError(new AnalysisError.con2(element.source,
15099 element.nameOffset, element.displayName.length, errorCode,
15100 arguments));
15101 }
15102 }
15103 }
15104
15105 /**
14955 * A container with sets of used [Element]s. 15106 * A container with sets of used [Element]s.
14956 */ 15107 */
14957 class UsedElements { 15108 class UsedElements {
14958 /** 15109 /**
14959 * Resolved, locally defined elements that are used or potentially can be 15110 * Resolved, locally defined elements that are used or potentially can be
14960 * used. 15111 * used.
14961 */ 15112 */
14962 final HashSet<Element> elements = new HashSet<Element>(); 15113 final HashSet<Element> elements = new HashSet<Element>();
14963 15114
14964 /** 15115 /**
(...skipping 13 matching lines...) Expand all
14978 * library. 15129 * library.
14979 */ 15130 */
14980 final HashSet<String> members = new HashSet<String>(); 15131 final HashSet<String> members = new HashSet<String>();
14981 15132
14982 /** 15133 /**
14983 * Names of resolved or unresolved class members that are read in the 15134 * Names of resolved or unresolved class members that are read in the
14984 * library. 15135 * library.
14985 */ 15136 */
14986 final HashSet<String> readMembers = new HashSet<String>(); 15137 final HashSet<String> readMembers = new HashSet<String>();
14987 15138
15139 UsedElements();
15140
15141 factory UsedElements.merge(List<UsedElements> parts) {
15142 UsedElements result = new UsedElements();
15143 for (UsedElements part in parts) {
15144 result.elements.addAll(part.elements);
15145 result.catchExceptionElements.addAll(part.catchExceptionElements);
15146 result.catchStackTraceElements.addAll(part.catchStackTraceElements);
15147 result.members.addAll(part.members);
15148 result.readMembers.addAll(part.readMembers);
15149 }
15150 return result;
15151 }
15152
14988 void addCatchException(LocalVariableElement element) { 15153 void addCatchException(LocalVariableElement element) {
14989 if (element != null) { 15154 if (element != null) {
14990 catchExceptionElements.add(element); 15155 catchExceptionElements.add(element);
14991 } 15156 }
14992 } 15157 }
14993 15158
14994 void addCatchStackTrace(LocalVariableElement element) { 15159 void addCatchStackTrace(LocalVariableElement element) {
14995 if (element != null) { 15160 if (element != null) {
14996 catchStackTraceElements.add(element); 15161 catchStackTraceElements.add(element);
14997 } 15162 }
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
15320 nonFields.add(node); 15485 nonFields.add(node);
15321 return null; 15486 return null;
15322 } 15487 }
15323 15488
15324 @override 15489 @override
15325 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); 15490 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this);
15326 15491
15327 @override 15492 @override
15328 Object visitWithClause(WithClause node) => null; 15493 Object visitWithClause(WithClause node) => null;
15329 } 15494 }
15330
15331 /**
15332 * Instances of the class [_UnusedElementsVerifier] traverse an element
15333 * structure looking for cases of [HintCode.UNUSED_ELEMENT] and
15334 * [HintCode.UNUSED_LOCAL_VARIABLE].
15335 */
15336 class _UnusedElementsVerifier extends RecursiveElementVisitor {
15337 /**
15338 * The error listener to which errors will be reported.
15339 */
15340 final AnalysisErrorListener _errorListener;
15341
15342 /**
15343 * The elements know to be used.
15344 */
15345 final UsedElements _usedElements;
15346
15347 /**
15348 * Create a new instance of the [_UnusedElementsVerifier].
15349 */
15350 _UnusedElementsVerifier(this._errorListener, this._usedElements);
15351
15352 @override
15353 visitClassElement(ClassElement element) {
15354 if (!_isUsedElement(element)) {
15355 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
15356 element.kind.displayName,
15357 element.displayName
15358 ]);
15359 }
15360 super.visitClassElement(element);
15361 }
15362
15363 @override
15364 visitFieldElement(FieldElement element) {
15365 if (!_isReadMember(element)) {
15366 _reportErrorForElement(
15367 HintCode.UNUSED_FIELD, element, [element.displayName]);
15368 }
15369 super.visitFieldElement(element);
15370 }
15371
15372 @override
15373 visitFunctionElement(FunctionElement element) {
15374 if (!_isUsedElement(element)) {
15375 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
15376 element.kind.displayName,
15377 element.displayName
15378 ]);
15379 }
15380 super.visitFunctionElement(element);
15381 }
15382
15383 @override
15384 visitLocalVariableElement(LocalVariableElement element) {
15385 if (!_isUsedElement(element) && !_isNamedUnderscore(element)) {
15386 HintCode errorCode;
15387 if (_usedElements.isCatchException(element)) {
15388 errorCode = HintCode.UNUSED_CATCH_CLAUSE;
15389 } else if (_usedElements.isCatchStackTrace(element)) {
15390 errorCode = HintCode.UNUSED_CATCH_STACK;
15391 } else {
15392 errorCode = HintCode.UNUSED_LOCAL_VARIABLE;
15393 }
15394 _reportErrorForElement(errorCode, element, [element.displayName]);
15395 }
15396 }
15397
15398 @override
15399 visitMethodElement(MethodElement element) {
15400 if (!_isUsedMember(element)) {
15401 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
15402 element.kind.displayName,
15403 element.displayName
15404 ]);
15405 }
15406 super.visitMethodElement(element);
15407 }
15408
15409 @override
15410 visitPropertyAccessorElement(PropertyAccessorElement element) {
15411 if (!_isUsedMember(element)) {
15412 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
15413 element.kind.displayName,
15414 element.displayName
15415 ]);
15416 }
15417 super.visitPropertyAccessorElement(element);
15418 }
15419
15420 bool _isNamedUnderscore(LocalVariableElement element) {
15421 String name = element.name;
15422 if (name != null) {
15423 for (int index = name.length - 1; index >= 0; --index) {
15424 if (name.codeUnitAt(index) != 0x5F) {
15425 // 0x5F => '_'
15426 return false;
15427 }
15428 }
15429 return true;
15430 }
15431 return false;
15432 }
15433
15434 bool _isReadMember(Element element) {
15435 if (element.isPublic) {
15436 return true;
15437 }
15438 if (element.isSynthetic) {
15439 return true;
15440 }
15441 return _usedElements.readMembers.contains(element.displayName);
15442 }
15443
15444 bool _isUsedElement(Element element) {
15445 if (element.isSynthetic) {
15446 return true;
15447 }
15448 if (element is LocalVariableElement ||
15449 element is FunctionElement && !element.isStatic) {
15450 // local variable or function
15451 } else {
15452 if (element.isPublic) {
15453 return true;
15454 }
15455 }
15456 return _usedElements.elements.contains(element);
15457 }
15458
15459 bool _isUsedMember(Element element) {
15460 if (element.isPublic) {
15461 return true;
15462 }
15463 if (element.isSynthetic) {
15464 return true;
15465 }
15466 if (_usedElements.members.contains(element.displayName)) {
15467 return true;
15468 }
15469 return _usedElements.elements.contains(element);
15470 }
15471
15472 void _reportErrorForElement(
15473 ErrorCode errorCode, Element element, List<Object> arguments) {
15474 if (element != null) {
15475 _errorListener.onError(new AnalysisError.con2(element.source,
15476 element.nameOffset, element.displayName.length, errorCode,
15477 arguments));
15478 }
15479 }
15480 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698