| 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 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 4326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4337 */ | 4337 */ |
| 4338 void _defineTypeParameters() { | 4338 void _defineTypeParameters() { |
| 4339 Scope typeParameterScope = enclosingScope; | 4339 Scope typeParameterScope = enclosingScope; |
| 4340 for (TypeParameterElement typeParameter in _typeElement.typeParameters) { | 4340 for (TypeParameterElement typeParameter in _typeElement.typeParameters) { |
| 4341 typeParameterScope.define(typeParameter); | 4341 typeParameterScope.define(typeParameter); |
| 4342 } | 4342 } |
| 4343 } | 4343 } |
| 4344 } | 4344 } |
| 4345 | 4345 |
| 4346 /** | 4346 /** |
| 4347 * An [AstVisitor] that fills [UsedElements]. |
| 4348 */ |
| 4349 class GatherUsedElementsVisitor extends RecursiveAstVisitor { |
| 4350 final UsedElements usedElements = new UsedElements(); |
| 4351 |
| 4352 final LibraryElement _enclosingLibrary; |
| 4353 ClassElement _enclosingClass; |
| 4354 ExecutableElement _enclosingExec; |
| 4355 |
| 4356 GatherUsedElementsVisitor(this._enclosingLibrary); |
| 4357 |
| 4358 @override |
| 4359 visitCatchClause(CatchClause node) { |
| 4360 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
| 4361 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; |
| 4362 if (exceptionParameter != null) { |
| 4363 Element element = exceptionParameter.staticElement; |
| 4364 usedElements.addCatchException(element); |
| 4365 if (stackTraceParameter != null || node.onKeyword == null) { |
| 4366 usedElements.addElement(element); |
| 4367 } |
| 4368 } |
| 4369 if (stackTraceParameter != null) { |
| 4370 Element element = stackTraceParameter.staticElement; |
| 4371 usedElements.addCatchStackTrace(element); |
| 4372 } |
| 4373 super.visitCatchClause(node); |
| 4374 } |
| 4375 |
| 4376 @override |
| 4377 visitClassDeclaration(ClassDeclaration node) { |
| 4378 ClassElement enclosingClassOld = _enclosingClass; |
| 4379 try { |
| 4380 _enclosingClass = node.element; |
| 4381 super.visitClassDeclaration(node); |
| 4382 } finally { |
| 4383 _enclosingClass = enclosingClassOld; |
| 4384 } |
| 4385 } |
| 4386 |
| 4387 @override |
| 4388 visitFunctionDeclaration(FunctionDeclaration node) { |
| 4389 ExecutableElement enclosingExecOld = _enclosingExec; |
| 4390 try { |
| 4391 _enclosingExec = node.element; |
| 4392 super.visitFunctionDeclaration(node); |
| 4393 } finally { |
| 4394 _enclosingExec = enclosingExecOld; |
| 4395 } |
| 4396 } |
| 4397 |
| 4398 @override |
| 4399 visitFunctionExpression(FunctionExpression node) { |
| 4400 if (node.parent is! FunctionDeclaration) { |
| 4401 usedElements.addElement(node.element); |
| 4402 } |
| 4403 super.visitFunctionExpression(node); |
| 4404 } |
| 4405 |
| 4406 @override |
| 4407 visitMethodDeclaration(MethodDeclaration node) { |
| 4408 ExecutableElement enclosingExecOld = _enclosingExec; |
| 4409 try { |
| 4410 _enclosingExec = node.element; |
| 4411 super.visitMethodDeclaration(node); |
| 4412 } finally { |
| 4413 _enclosingExec = enclosingExecOld; |
| 4414 } |
| 4415 } |
| 4416 |
| 4417 @override |
| 4418 visitSimpleIdentifier(SimpleIdentifier node) { |
| 4419 if (node.inDeclarationContext()) { |
| 4420 return; |
| 4421 } |
| 4422 Element element = node.staticElement; |
| 4423 bool isIdentifierRead = _isReadIdentifier(node); |
| 4424 if (element is LocalVariableElement) { |
| 4425 if (isIdentifierRead) { |
| 4426 usedElements.addElement(element); |
| 4427 } |
| 4428 } else { |
| 4429 _useIdentifierElement(node); |
| 4430 if (element == null || |
| 4431 element is! LocalElement && !identical(element, _enclosingExec)) { |
| 4432 usedElements.members.add(node.name); |
| 4433 if (isIdentifierRead) { |
| 4434 usedElements.readMembers.add(node.name); |
| 4435 } |
| 4436 } |
| 4437 } |
| 4438 } |
| 4439 |
| 4440 @override |
| 4441 visitTypeName(TypeName node) { |
| 4442 _useIdentifierElement(node.name); |
| 4443 } |
| 4444 |
| 4445 /** |
| 4446 * Marks an [Element] of [node] as used in the library. |
| 4447 */ |
| 4448 void _useIdentifierElement(Identifier node) { |
| 4449 Element element = node.staticElement; |
| 4450 if (element == null) { |
| 4451 return; |
| 4452 } |
| 4453 // check if a local element |
| 4454 if (!identical(element.library, _enclosingLibrary)) { |
| 4455 return; |
| 4456 } |
| 4457 // ignore references to an element from itself |
| 4458 if (identical(element, _enclosingClass)) { |
| 4459 return; |
| 4460 } |
| 4461 if (identical(element, _enclosingExec)) { |
| 4462 return; |
| 4463 } |
| 4464 // ignore places where the element is not actually used |
| 4465 if (node.parent is TypeName) { |
| 4466 AstNode parent2 = node.parent.parent; |
| 4467 if (parent2 is IsExpression) { |
| 4468 return; |
| 4469 } |
| 4470 if (parent2 is VariableDeclarationList) { |
| 4471 return; |
| 4472 } |
| 4473 } |
| 4474 // OK |
| 4475 usedElements.addElement(element); |
| 4476 } |
| 4477 |
| 4478 static bool _isReadIdentifier(SimpleIdentifier node) { |
| 4479 // not reading at all |
| 4480 if (!node.inGetterContext()) { |
| 4481 return false; |
| 4482 } |
| 4483 // check if useless reading |
| 4484 AstNode parent = node.parent; |
| 4485 if (parent.parent is ExpressionStatement && |
| 4486 (parent is PrefixExpression || |
| 4487 parent is PostfixExpression || |
| 4488 parent is AssignmentExpression && parent.leftHandSide == node)) { |
| 4489 // v++; |
| 4490 // ++v; |
| 4491 // v += 2; |
| 4492 return false; |
| 4493 } |
| 4494 // OK |
| 4495 return true; |
| 4496 } |
| 4497 } |
| 4498 |
| 4499 /** |
| 4347 * Instances of the class `HintGenerator` traverse a library's worth of dart cod
e at a time to | 4500 * Instances of the class `HintGenerator` traverse a library's worth of dart cod
e at a time to |
| 4348 * generate hints over the set of sources. | 4501 * generate hints over the set of sources. |
| 4349 * | 4502 * |
| 4350 * See [HintCode]. | 4503 * See [HintCode]. |
| 4351 */ | 4504 */ |
| 4352 class HintGenerator { | 4505 class HintGenerator { |
| 4353 final List<CompilationUnit> _compilationUnits; | 4506 final List<CompilationUnit> _compilationUnits; |
| 4354 | 4507 |
| 4355 final InternalAnalysisContext _context; | 4508 final InternalAnalysisContext _context; |
| 4356 | 4509 |
| 4357 final AnalysisErrorListener _errorListener; | 4510 final AnalysisErrorListener _errorListener; |
| 4358 | 4511 |
| 4359 LibraryElement _library; | 4512 LibraryElement _library; |
| 4360 | 4513 |
| 4361 ImportsVerifier _importsVerifier; | 4514 ImportsVerifier _importsVerifier; |
| 4362 | 4515 |
| 4363 bool _enableDart2JSHints = false; | 4516 bool _enableDart2JSHints = false; |
| 4364 | 4517 |
| 4365 /** | 4518 /** |
| 4366 * The inheritance manager used to find overridden methods. | 4519 * The inheritance manager used to find overridden methods. |
| 4367 */ | 4520 */ |
| 4368 InheritanceManager _manager; | 4521 InheritanceManager _manager; |
| 4369 | 4522 |
| 4370 _GatherUsedElementsVisitor _usedElementsVisitor; | 4523 GatherUsedElementsVisitor _usedElementsVisitor; |
| 4371 | 4524 |
| 4372 HintGenerator(this._compilationUnits, this._context, this._errorListener) { | 4525 HintGenerator(this._compilationUnits, this._context, this._errorListener) { |
| 4373 _library = _compilationUnits[0].element.library; | 4526 _library = _compilationUnits[0].element.library; |
| 4374 _importsVerifier = new ImportsVerifier(_library); | 4527 _importsVerifier = new ImportsVerifier(_library); |
| 4375 _enableDart2JSHints = _context.analysisOptions.dart2jsHint; | 4528 _enableDart2JSHints = _context.analysisOptions.dart2jsHint; |
| 4376 _manager = new InheritanceManager(_compilationUnits[0].element.library); | 4529 _manager = new InheritanceManager(_compilationUnits[0].element.library); |
| 4377 _usedElementsVisitor = new _GatherUsedElementsVisitor(_library); | 4530 _usedElementsVisitor = new GatherUsedElementsVisitor(_library); |
| 4378 } | 4531 } |
| 4379 | 4532 |
| 4380 void generateForLibrary() { | 4533 void generateForLibrary() { |
| 4381 PerformanceStatistics.hints.makeCurrentWhile(() { | 4534 PerformanceStatistics.hints.makeCurrentWhile(() { |
| 4382 for (int i = 0; i < _compilationUnits.length; i++) { | 4535 for (int i = 0; i < _compilationUnits.length; i++) { |
| 4383 CompilationUnitElement element = _compilationUnits[i].element; | 4536 CompilationUnitElement element = _compilationUnits[i].element; |
| 4384 if (element != null) { | 4537 if (element != null) { |
| 4385 if (i == 0) { | 4538 if (i == 0) { |
| 4386 _importsVerifier.inDefiningCompilationUnit = true; | 4539 _importsVerifier.inDefiningCompilationUnit = true; |
| 4387 _generateForCompilationUnit(_compilationUnits[i], element.source); | 4540 _generateForCompilationUnit(_compilationUnits[i], element.source); |
| (...skipping 10383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14771 return identical(parent.type, node); | 14924 return identical(parent.type, node); |
| 14772 } | 14925 } |
| 14773 if (parent is SimpleFormalParameter) { | 14926 if (parent is SimpleFormalParameter) { |
| 14774 return identical(parent.type, node); | 14927 return identical(parent.type, node); |
| 14775 } | 14928 } |
| 14776 return false; | 14929 return false; |
| 14777 } | 14930 } |
| 14778 } | 14931 } |
| 14779 | 14932 |
| 14780 /** | 14933 /** |
| 14934 * A container with sets of used [Element]s. |
| 14935 */ |
| 14936 class UsedElements { |
| 14937 /** |
| 14938 * Resolved, locally defined elements that are used or potentially can be |
| 14939 * used. |
| 14940 */ |
| 14941 final HashSet<Element> elements = new HashSet<Element>(); |
| 14942 |
| 14943 /** |
| 14944 * [LocalVariableElement]s that represent exceptions in [CatchClause]s. |
| 14945 */ |
| 14946 final HashSet<LocalVariableElement> catchExceptionElements = |
| 14947 new HashSet<LocalVariableElement>(); |
| 14948 |
| 14949 /** |
| 14950 * [LocalVariableElement]s that represent stack traces in [CatchClause]s. |
| 14951 */ |
| 14952 final HashSet<LocalVariableElement> catchStackTraceElements = |
| 14953 new HashSet<LocalVariableElement>(); |
| 14954 |
| 14955 /** |
| 14956 * Names of resolved or unresolved class members that are referenced in the |
| 14957 * library. |
| 14958 */ |
| 14959 final HashSet<String> members = new HashSet<String>(); |
| 14960 |
| 14961 /** |
| 14962 * Names of resolved or unresolved class members that are read in the |
| 14963 * library. |
| 14964 */ |
| 14965 final HashSet<String> readMembers = new HashSet<String>(); |
| 14966 |
| 14967 void addCatchException(LocalVariableElement element) { |
| 14968 if (element != null) { |
| 14969 catchExceptionElements.add(element); |
| 14970 } |
| 14971 } |
| 14972 |
| 14973 void addCatchStackTrace(LocalVariableElement element) { |
| 14974 if (element != null) { |
| 14975 catchStackTraceElements.add(element); |
| 14976 } |
| 14977 } |
| 14978 |
| 14979 void addElement(Element element) { |
| 14980 if (element != null) { |
| 14981 elements.add(element); |
| 14982 } |
| 14983 } |
| 14984 |
| 14985 bool isCatchException(LocalVariableElement element) { |
| 14986 return catchExceptionElements.contains(element); |
| 14987 } |
| 14988 |
| 14989 bool isCatchStackTrace(LocalVariableElement element) { |
| 14990 return catchStackTraceElements.contains(element); |
| 14991 } |
| 14992 } |
| 14993 |
| 14994 /** |
| 14781 * Instances of the class `VariableResolverVisitor` are used to resolve | 14995 * Instances of the class `VariableResolverVisitor` are used to resolve |
| 14782 * [SimpleIdentifier]s to local variables and formal parameters. | 14996 * [SimpleIdentifier]s to local variables and formal parameters. |
| 14783 */ | 14997 */ |
| 14784 class VariableResolverVisitor extends ScopedVisitor { | 14998 class VariableResolverVisitor extends ScopedVisitor { |
| 14785 /** | 14999 /** |
| 14786 * The method or function that we are currently visiting, or `null` if we are
not inside a | 15000 * The method or function that we are currently visiting, or `null` if we are
not inside a |
| 14787 * method or function. | 15001 * method or function. |
| 14788 */ | 15002 */ |
| 14789 ExecutableElement _enclosingFunction; | 15003 ExecutableElement _enclosingFunction; |
| 14790 | 15004 |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14996 @override | 15210 @override |
| 14997 Object visitMethodDeclaration(MethodDeclaration node) { | 15211 Object visitMethodDeclaration(MethodDeclaration node) { |
| 14998 nonFields.add(node); | 15212 nonFields.add(node); |
| 14999 return null; | 15213 return null; |
| 15000 } | 15214 } |
| 15001 | 15215 |
| 15002 @override | 15216 @override |
| 15003 Object visitNode(AstNode node) => node.accept(builder); | 15217 Object visitNode(AstNode node) => node.accept(builder); |
| 15004 } | 15218 } |
| 15005 | 15219 |
| 15006 class _GatherUsedElementsVisitor extends RecursiveAstVisitor { | |
| 15007 final _UsedElements usedElements = new _UsedElements(); | |
| 15008 | |
| 15009 final LibraryElement _enclosingLibrary; | |
| 15010 ClassElement _enclosingClass; | |
| 15011 ExecutableElement _enclosingExec; | |
| 15012 | |
| 15013 _GatherUsedElementsVisitor(this._enclosingLibrary); | |
| 15014 | |
| 15015 @override | |
| 15016 visitCatchClause(CatchClause node) { | |
| 15017 SimpleIdentifier exceptionParameter = node.exceptionParameter; | |
| 15018 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | |
| 15019 if (exceptionParameter != null) { | |
| 15020 Element element = exceptionParameter.staticElement; | |
| 15021 usedElements.addCatchException(element); | |
| 15022 if (stackTraceParameter != null || node.onKeyword == null) { | |
| 15023 _useElement(element); | |
| 15024 } | |
| 15025 } | |
| 15026 if (stackTraceParameter != null) { | |
| 15027 Element element = stackTraceParameter.staticElement; | |
| 15028 usedElements.addCatchStackTrace(element); | |
| 15029 } | |
| 15030 super.visitCatchClause(node); | |
| 15031 } | |
| 15032 | |
| 15033 @override | |
| 15034 visitClassDeclaration(ClassDeclaration node) { | |
| 15035 ClassElement enclosingClassOld = _enclosingClass; | |
| 15036 try { | |
| 15037 _enclosingClass = node.element; | |
| 15038 super.visitClassDeclaration(node); | |
| 15039 } finally { | |
| 15040 _enclosingClass = enclosingClassOld; | |
| 15041 } | |
| 15042 } | |
| 15043 | |
| 15044 @override | |
| 15045 visitFunctionDeclaration(FunctionDeclaration node) { | |
| 15046 ExecutableElement enclosingExecOld = _enclosingExec; | |
| 15047 try { | |
| 15048 _enclosingExec = node.element; | |
| 15049 super.visitFunctionDeclaration(node); | |
| 15050 } finally { | |
| 15051 _enclosingExec = enclosingExecOld; | |
| 15052 } | |
| 15053 } | |
| 15054 | |
| 15055 @override | |
| 15056 visitFunctionExpression(FunctionExpression node) { | |
| 15057 if (node.parent is! FunctionDeclaration) { | |
| 15058 _useElement(node.element); | |
| 15059 } | |
| 15060 super.visitFunctionExpression(node); | |
| 15061 } | |
| 15062 | |
| 15063 @override | |
| 15064 visitMethodDeclaration(MethodDeclaration node) { | |
| 15065 ExecutableElement enclosingExecOld = _enclosingExec; | |
| 15066 try { | |
| 15067 _enclosingExec = node.element; | |
| 15068 super.visitMethodDeclaration(node); | |
| 15069 } finally { | |
| 15070 _enclosingExec = enclosingExecOld; | |
| 15071 } | |
| 15072 } | |
| 15073 | |
| 15074 @override | |
| 15075 visitSimpleIdentifier(SimpleIdentifier node) { | |
| 15076 if (node.inDeclarationContext()) { | |
| 15077 return; | |
| 15078 } | |
| 15079 Element element = node.staticElement; | |
| 15080 bool isIdentifierRead = _isReadIdentifier(node); | |
| 15081 if (element is LocalVariableElement) { | |
| 15082 if (isIdentifierRead) { | |
| 15083 _useElement(element); | |
| 15084 } | |
| 15085 // } else if (element is PropertyAccessorElement && | |
| 15086 // element.isSynthetic && | |
| 15087 // element.isPrivate) { | |
| 15088 // PropertyInducingElement variable = element.variable; | |
| 15089 // if (node.inGetterContext()) { | |
| 15090 // AstNode parent = node.parent; | |
| 15091 // if (parent.parent is ExpressionStatement && | |
| 15092 // (parent is PrefixExpression || | |
| 15093 // parent is PostfixExpression || | |
| 15094 // parent is AssignmentExpression && parent.leftHandSide == node)) { | |
| 15095 // // f++; | |
| 15096 // // ++f; | |
| 15097 // // f += 2; | |
| 15098 // } else { | |
| 15099 // _useElement(variable); | |
| 15100 // } | |
| 15101 // } | |
| 15102 } else { | |
| 15103 _useIdentifierElement(node); | |
| 15104 if (element == null || | |
| 15105 element is! LocalElement && !identical(element, _enclosingExec)) { | |
| 15106 usedElements.members.add(node.name); | |
| 15107 if (isIdentifierRead) { | |
| 15108 usedElements.readMembers.add(node.name); | |
| 15109 } | |
| 15110 } | |
| 15111 } | |
| 15112 } | |
| 15113 | |
| 15114 @override | |
| 15115 visitTypeName(TypeName node) { | |
| 15116 _useIdentifierElement(node.name); | |
| 15117 } | |
| 15118 | |
| 15119 _useElement(Element element) { | |
| 15120 if (element != null) { | |
| 15121 usedElements.elements.add(element); | |
| 15122 } | |
| 15123 } | |
| 15124 | |
| 15125 /** | |
| 15126 * Marks an [Element] of [node] as used in the library. | |
| 15127 */ | |
| 15128 void _useIdentifierElement(Identifier node) { | |
| 15129 Element element = node.staticElement; | |
| 15130 if (element == null) { | |
| 15131 return; | |
| 15132 } | |
| 15133 // check if a local element | |
| 15134 if (!identical(element.library, _enclosingLibrary)) { | |
| 15135 return; | |
| 15136 } | |
| 15137 // ignore references to an element from itself | |
| 15138 if (identical(element, _enclosingClass)) { | |
| 15139 return; | |
| 15140 } | |
| 15141 if (identical(element, _enclosingExec)) { | |
| 15142 return; | |
| 15143 } | |
| 15144 // ignore places where the element is not actually used | |
| 15145 if (node.parent is TypeName) { | |
| 15146 AstNode parent2 = node.parent.parent; | |
| 15147 if (parent2 is IsExpression) { | |
| 15148 return; | |
| 15149 } | |
| 15150 if (parent2 is VariableDeclarationList) { | |
| 15151 return; | |
| 15152 } | |
| 15153 } | |
| 15154 // OK | |
| 15155 _useElement(element); | |
| 15156 } | |
| 15157 | |
| 15158 static bool _isReadIdentifier(SimpleIdentifier node) { | |
| 15159 // not reading at all | |
| 15160 if (!node.inGetterContext()) { | |
| 15161 return false; | |
| 15162 } | |
| 15163 // check if useless reading | |
| 15164 AstNode parent = node.parent; | |
| 15165 if (parent.parent is ExpressionStatement && | |
| 15166 (parent is PrefixExpression || | |
| 15167 parent is PostfixExpression || | |
| 15168 parent is AssignmentExpression && parent.leftHandSide == node)) { | |
| 15169 // v++; | |
| 15170 // ++v; | |
| 15171 // v += 2; | |
| 15172 return false; | |
| 15173 } | |
| 15174 // OK | |
| 15175 return true; | |
| 15176 } | |
| 15177 } | |
| 15178 | |
| 15179 class _ResolverVisitor_isVariableAccessedInClosure | 15220 class _ResolverVisitor_isVariableAccessedInClosure |
| 15180 extends RecursiveAstVisitor<Object> { | 15221 extends RecursiveAstVisitor<Object> { |
| 15181 final Element variable; | 15222 final Element variable; |
| 15182 | 15223 |
| 15183 bool result = false; | 15224 bool result = false; |
| 15184 | 15225 |
| 15185 bool _inClosure = false; | 15226 bool _inClosure = false; |
| 15186 | 15227 |
| 15187 _ResolverVisitor_isVariableAccessedInClosure(this.variable); | 15228 _ResolverVisitor_isVariableAccessedInClosure(this.variable); |
| 15188 | 15229 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15273 */ | 15314 */ |
| 15274 class _UnusedElementsVerifier extends RecursiveElementVisitor { | 15315 class _UnusedElementsVerifier extends RecursiveElementVisitor { |
| 15275 /** | 15316 /** |
| 15276 * The error listener to which errors will be reported. | 15317 * The error listener to which errors will be reported. |
| 15277 */ | 15318 */ |
| 15278 final AnalysisErrorListener _errorListener; | 15319 final AnalysisErrorListener _errorListener; |
| 15279 | 15320 |
| 15280 /** | 15321 /** |
| 15281 * The elements know to be used. | 15322 * The elements know to be used. |
| 15282 */ | 15323 */ |
| 15283 final _UsedElements _usedElements; | 15324 final UsedElements _usedElements; |
| 15284 | 15325 |
| 15285 /** | 15326 /** |
| 15286 * Create a new instance of the [_UnusedElementsVerifier]. | 15327 * Create a new instance of the [_UnusedElementsVerifier]. |
| 15287 */ | 15328 */ |
| 15288 _UnusedElementsVerifier(this._errorListener, this._usedElements); | 15329 _UnusedElementsVerifier(this._errorListener, this._usedElements); |
| 15289 | 15330 |
| 15290 @override | 15331 @override |
| 15291 visitClassElement(ClassElement element) { | 15332 visitClassElement(ClassElement element) { |
| 15292 if (!_isUsedElement(element)) { | 15333 if (!_isUsedElement(element)) { |
| 15293 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [ | 15334 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [ |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15408 | 15449 |
| 15409 void _reportErrorForElement( | 15450 void _reportErrorForElement( |
| 15410 ErrorCode errorCode, Element element, List<Object> arguments) { | 15451 ErrorCode errorCode, Element element, List<Object> arguments) { |
| 15411 if (element != null) { | 15452 if (element != null) { |
| 15412 _errorListener.onError(new AnalysisError.con2(element.source, | 15453 _errorListener.onError(new AnalysisError.con2(element.source, |
| 15413 element.nameOffset, element.displayName.length, errorCode, | 15454 element.nameOffset, element.displayName.length, errorCode, |
| 15414 arguments)); | 15455 arguments)); |
| 15415 } | 15456 } |
| 15416 } | 15457 } |
| 15417 } | 15458 } |
| 15418 | |
| 15419 class _UsedElements { | |
| 15420 /** | |
| 15421 * Resolved, locally defined elements that are used or potentially can be | |
| 15422 * used. | |
| 15423 */ | |
| 15424 final HashSet<Element> elements = new HashSet<Element>(); | |
| 15425 | |
| 15426 /** | |
| 15427 * [LocalVariableElement]s that represent exceptions in [CatchClause]s. | |
| 15428 */ | |
| 15429 final HashSet<LocalVariableElement> catchExceptionElements = | |
| 15430 new HashSet<LocalVariableElement>(); | |
| 15431 | |
| 15432 /** | |
| 15433 * [LocalVariableElement]s that represent stack traces in [CatchClause]s. | |
| 15434 */ | |
| 15435 final HashSet<LocalVariableElement> catchStackTraceElements = | |
| 15436 new HashSet<LocalVariableElement>(); | |
| 15437 | |
| 15438 /** | |
| 15439 * Names of resolved or unresolved class members that are referenced in the | |
| 15440 * library. | |
| 15441 */ | |
| 15442 final HashSet<String> members = new HashSet<String>(); | |
| 15443 | |
| 15444 /** | |
| 15445 * Names of resolved or unresolved class members that are read in the | |
| 15446 * library. | |
| 15447 */ | |
| 15448 final HashSet<String> readMembers = new HashSet<String>(); | |
| 15449 | |
| 15450 void addCatchException(LocalVariableElement element) { | |
| 15451 if (element != null) { | |
| 15452 catchExceptionElements.add(element); | |
| 15453 } | |
| 15454 } | |
| 15455 | |
| 15456 void addCatchStackTrace(LocalVariableElement element) { | |
| 15457 if (element != null) { | |
| 15458 catchStackTraceElements.add(element); | |
| 15459 } | |
| 15460 } | |
| 15461 | |
| 15462 bool isCatchException(LocalVariableElement element) { | |
| 15463 return catchExceptionElements.contains(element); | |
| 15464 } | |
| 15465 | |
| 15466 bool isCatchStackTrace(LocalVariableElement element) { | |
| 15467 return catchStackTraceElements.contains(element); | |
| 15468 } | |
| 15469 } | |
| OLD | NEW |