| 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 services.src.index.index_contributor; | 5 library services.src.index.index_contributor; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/services/correction/namespace.dart'; | 9 import 'package:analysis_server/src/services/correction/namespace.dart'; |
| 10 import 'package:analysis_server/src/services/index/index.dart'; | 10 import 'package:analysis_server/src/services/index/index.dart'; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 return; | 63 return; |
| 64 } | 64 } |
| 65 // do index | 65 // do index |
| 66 store.doneIndex(); | 66 store.doneIndex(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 | 69 |
| 70 /** | 70 /** |
| 71 * Visits a resolved AST and adds relationships into [IndexStore]. | 71 * Visits a resolved AST and adds relationships into [IndexStore]. |
| 72 */ | 72 */ |
| 73 class _IndexContributor extends GeneralizingAstVisitor<Object> { | 73 class _IndexContributor extends GeneralizingAstVisitor { |
| 74 final IndexStore _store; | 74 final IndexStore _store; |
| 75 | 75 |
| 76 LibraryElement _libraryElement; | 76 LibraryElement _libraryElement; |
| 77 | 77 |
| 78 Map<ImportElement, Set<Element>> _importElementsMap = {}; | 78 Map<ImportElement, Set<Element>> _importElementsMap = {}; |
| 79 | 79 |
| 80 /** | 80 /** |
| 81 * A stack whose top element (the element with the largest index) is an elemen
t representing the | 81 * A stack whose top element (the element with the largest index) is an |
| 82 * inner-most enclosing scope. | 82 * element representing the inner-most enclosing scope. |
| 83 */ | 83 */ |
| 84 Queue<Element> _elementStack = new Queue(); | 84 Queue<Element> _elementStack = new Queue(); |
| 85 | 85 |
| 86 _IndexContributor(this._store); | 86 _IndexContributor(this._store); |
| 87 | 87 |
| 88 /** | 88 /** |
| 89 * Enter a new scope represented by the given [Element]. | 89 * Enter a new scope represented by the given [Element]. |
| 90 */ | 90 */ |
| 91 void enterScope(Element element) { | 91 void enterScope(Element element) { |
| 92 _elementStack.addFirst(element); | 92 _elementStack.addFirst(element); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 108 * Record the given relationship between the given [Element] and [Location]. | 108 * Record the given relationship between the given [Element] and [Location]. |
| 109 */ | 109 */ |
| 110 void recordRelationship(Element element, Relationship relationship, | 110 void recordRelationship(Element element, Relationship relationship, |
| 111 Location location) { | 111 Location location) { |
| 112 if (element != null && location != null) { | 112 if (element != null && location != null) { |
| 113 _store.recordRelationship(element, relationship, location); | 113 _store.recordRelationship(element, relationship, location); |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 | 116 |
| 117 @override | 117 @override |
| 118 Object visitAssignmentExpression(AssignmentExpression node) { | 118 visitAssignmentExpression(AssignmentExpression node) { |
| 119 _recordOperatorReference(node.operator, node.bestElement); | 119 _recordOperatorReference(node.operator, node.bestElement); |
| 120 return super.visitAssignmentExpression(node); | 120 super.visitAssignmentExpression(node); |
| 121 } | 121 } |
| 122 | 122 |
| 123 @override | 123 @override |
| 124 Object visitBinaryExpression(BinaryExpression node) { | 124 visitBinaryExpression(BinaryExpression node) { |
| 125 _recordOperatorReference(node.operator, node.bestElement); | 125 _recordOperatorReference(node.operator, node.bestElement); |
| 126 return super.visitBinaryExpression(node); | 126 super.visitBinaryExpression(node); |
| 127 } | 127 } |
| 128 | 128 |
| 129 @override | 129 @override |
| 130 Object visitClassDeclaration(ClassDeclaration node) { | 130 visitClassDeclaration(ClassDeclaration node) { |
| 131 ClassElement element = node.element; | 131 ClassElement element = node.element; |
| 132 enterScope(element); | 132 enterScope(element); |
| 133 try { | 133 try { |
| 134 _recordElementDefinition(element); | 134 _recordElementDefinition(element); |
| 135 { | 135 { |
| 136 ExtendsClause extendsClause = node.extendsClause; | 136 ExtendsClause extendsClause = node.extendsClause; |
| 137 if (extendsClause != null) { | 137 if (extendsClause != null) { |
| 138 TypeName superclassNode = extendsClause.superclass; | 138 TypeName superclassNode = extendsClause.superclass; |
| 139 _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY); | 139 _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY); |
| 140 } else { | 140 } else { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 157 } | 157 } |
| 158 } | 158 } |
| 159 { | 159 { |
| 160 ImplementsClause implementsClause = node.implementsClause; | 160 ImplementsClause implementsClause = node.implementsClause; |
| 161 if (implementsClause != null) { | 161 if (implementsClause != null) { |
| 162 for (TypeName interfaceNode in implementsClause.interfaces) { | 162 for (TypeName interfaceNode in implementsClause.interfaces) { |
| 163 _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY); | 163 _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY); |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 } | 166 } |
| 167 return super.visitClassDeclaration(node); | 167 super.visitClassDeclaration(node); |
| 168 } finally { | 168 } finally { |
| 169 _exitScope(); | 169 _exitScope(); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 @override | 173 @override |
| 174 Object visitClassTypeAlias(ClassTypeAlias node) { | 174 visitClassTypeAlias(ClassTypeAlias node) { |
| 175 ClassElement element = node.element; | 175 ClassElement element = node.element; |
| 176 enterScope(element); | 176 enterScope(element); |
| 177 try { | 177 try { |
| 178 _recordElementDefinition(element); | 178 _recordElementDefinition(element); |
| 179 { | 179 { |
| 180 TypeName superclassNode = node.superclass; | 180 TypeName superclassNode = node.superclass; |
| 181 if (superclassNode != null) { | 181 if (superclassNode != null) { |
| 182 _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY); | 182 _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY); |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 { | 185 { |
| 186 WithClause withClause = node.withClause; | 186 WithClause withClause = node.withClause; |
| 187 if (withClause != null) { | 187 if (withClause != null) { |
| 188 for (TypeName mixinNode in withClause.mixinTypes) { | 188 for (TypeName mixinNode in withClause.mixinTypes) { |
| 189 _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY); | 189 _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY); |
| 190 } | 190 } |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 { | 193 { |
| 194 ImplementsClause implementsClause = node.implementsClause; | 194 ImplementsClause implementsClause = node.implementsClause; |
| 195 if (implementsClause != null) { | 195 if (implementsClause != null) { |
| 196 for (TypeName interfaceNode in implementsClause.interfaces) { | 196 for (TypeName interfaceNode in implementsClause.interfaces) { |
| 197 _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY); | 197 _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY); |
| 198 } | 198 } |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 return super.visitClassTypeAlias(node); | 201 super.visitClassTypeAlias(node); |
| 202 } finally { | 202 } finally { |
| 203 _exitScope(); | 203 _exitScope(); |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 | 206 |
| 207 @override | 207 @override |
| 208 Object visitCompilationUnit(CompilationUnit node) { | 208 visitCompilationUnit(CompilationUnit node) { |
| 209 CompilationUnitElement unitElement = node.element; | 209 CompilationUnitElement unitElement = node.element; |
| 210 if (unitElement != null) { | 210 if (unitElement != null) { |
| 211 _elementStack.add(unitElement); | 211 _elementStack.add(unitElement); |
| 212 _libraryElement = unitElement.enclosingElement; | 212 _libraryElement = unitElement.enclosingElement; |
| 213 if (_libraryElement != null) { | 213 if (_libraryElement != null) { |
| 214 return super.visitCompilationUnit(node); | 214 super.visitCompilationUnit(node); |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 return null; | |
| 218 } | 217 } |
| 219 | 218 |
| 220 @override | 219 @override |
| 221 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 220 visitConstructorDeclaration(ConstructorDeclaration node) { |
| 222 ConstructorElement element = node.element; | 221 ConstructorElement element = node.element; |
| 223 enterScope(element); | 222 enterScope(element); |
| 224 try { | 223 try { |
| 225 return super.visitConstructorDeclaration(node); | 224 super.visitConstructorDeclaration(node); |
| 226 } finally { | 225 } finally { |
| 227 _exitScope(); | 226 _exitScope(); |
| 228 } | 227 } |
| 229 } | 228 } |
| 230 | 229 |
| 231 @override | 230 @override |
| 232 visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 231 visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 233 SimpleIdentifier fieldName = node.fieldName; | 232 SimpleIdentifier fieldName = node.fieldName; |
| 234 Expression expression = node.expression; | 233 Expression expression = node.expression; |
| 235 // field reference is write here | 234 // field reference is write here |
| 236 if (fieldName != null) { | 235 if (fieldName != null) { |
| 237 Element element = fieldName.staticElement; | 236 Element element = fieldName.staticElement; |
| 238 Location location = _createLocationForNode(fieldName); | 237 Location location = _createLocationForNode(fieldName); |
| 239 _store.recordRelationship(element, IndexConstants.IS_WRITTEN_BY, location)
; | 238 _store.recordRelationship( |
| 239 element, |
| 240 IndexConstants.IS_WRITTEN_BY, |
| 241 location); |
| 240 } | 242 } |
| 241 // index expression | 243 // index expression |
| 242 if (expression != null) { | 244 if (expression != null) { |
| 243 expression.accept(this); | 245 expression.accept(this); |
| 244 } | 246 } |
| 245 } | 247 } |
| 246 | 248 |
| 247 @override | 249 @override |
| 248 Object visitConstructorName(ConstructorName node) { | 250 visitConstructorName(ConstructorName node) { |
| 249 ConstructorElement element = node.staticElement; | 251 ConstructorElement element = node.staticElement; |
| 250 // in 'class B = A;' actually A constructors are invoked | 252 // in 'class B = A;' actually A constructors are invoked |
| 251 if (element != null && | 253 if (element != null && |
| 252 element.isSynthetic && | 254 element.isSynthetic && |
| 253 element.redirectedConstructor != null) { | 255 element.redirectedConstructor != null) { |
| 254 element = element.redirectedConstructor; | 256 element = element.redirectedConstructor; |
| 255 } | 257 } |
| 256 // prepare location | 258 // prepare location |
| 257 Location location; | 259 Location location; |
| 258 if (node.name != null) { | 260 if (node.name != null) { |
| 259 int start = node.period.offset; | 261 int start = node.period.offset; |
| 260 int end = node.name.end; | 262 int end = node.name.end; |
| 261 location = _createLocationForOffset(start, end - start); | 263 location = _createLocationForOffset(start, end - start); |
| 262 } else { | 264 } else { |
| 263 int start = node.type.end; | 265 int start = node.type.end; |
| 264 location = _createLocationForOffset(start, 0); | 266 location = _createLocationForOffset(start, 0); |
| 265 } | 267 } |
| 266 // record relationship | 268 // record relationship |
| 267 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); | 269 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); |
| 268 return super.visitConstructorName(node); | 270 super.visitConstructorName(node); |
| 269 } | 271 } |
| 270 | 272 |
| 271 @override | 273 @override |
| 272 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 274 visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 273 LocalVariableElement element = node.element; | 275 LocalVariableElement element = node.element; |
| 274 enterScope(element); | 276 enterScope(element); |
| 275 try { | 277 try { |
| 276 return super.visitDeclaredIdentifier(node); | 278 super.visitDeclaredIdentifier(node); |
| 277 } finally { | 279 } finally { |
| 278 _exitScope(); | 280 _exitScope(); |
| 279 } | 281 } |
| 280 } | 282 } |
| 281 | 283 |
| 282 @override | 284 @override |
| 283 Object visitEnumDeclaration(EnumDeclaration node) { | 285 visitEnumDeclaration(EnumDeclaration node) { |
| 284 ClassElement element = node.element; | 286 ClassElement element = node.element; |
| 285 enterScope(element); | 287 enterScope(element); |
| 286 try { | 288 try { |
| 287 _recordElementDefinition(element); | 289 _recordElementDefinition(element); |
| 288 return super.visitEnumDeclaration(node); | 290 super.visitEnumDeclaration(node); |
| 289 } finally { | 291 } finally { |
| 290 _exitScope(); | 292 _exitScope(); |
| 291 } | 293 } |
| 292 } | 294 } |
| 293 | 295 |
| 294 @override | 296 @override |
| 295 Object visitExportDirective(ExportDirective node) { | 297 visitExportDirective(ExportDirective node) { |
| 296 ExportElement element = node.element; | 298 ExportElement element = node.element; |
| 297 if (element != null) { | 299 if (element != null) { |
| 298 LibraryElement expLibrary = element.exportedLibrary; | 300 LibraryElement expLibrary = element.exportedLibrary; |
| 299 _recordLibraryReference(node, expLibrary); | 301 _recordLibraryReference(node, expLibrary); |
| 300 } | 302 } |
| 301 return super.visitExportDirective(node); | 303 super.visitExportDirective(node); |
| 302 } | 304 } |
| 303 | 305 |
| 304 @override | 306 @override |
| 305 Object visitFormalParameter(FormalParameter node) { | 307 visitFormalParameter(FormalParameter node) { |
| 306 ParameterElement element = node.element; | 308 ParameterElement element = node.element; |
| 307 enterScope(element); | 309 enterScope(element); |
| 308 try { | 310 try { |
| 309 return super.visitFormalParameter(node); | 311 super.visitFormalParameter(node); |
| 310 } finally { | 312 } finally { |
| 311 _exitScope(); | 313 _exitScope(); |
| 312 } | 314 } |
| 313 } | 315 } |
| 314 | 316 |
| 315 @override | 317 @override |
| 316 Object visitFunctionDeclaration(FunctionDeclaration node) { | 318 visitFunctionDeclaration(FunctionDeclaration node) { |
| 317 Element element = node.element; | 319 Element element = node.element; |
| 318 _recordElementDefinition(element); | 320 _recordElementDefinition(element); |
| 319 enterScope(element); | 321 enterScope(element); |
| 320 try { | 322 try { |
| 321 return super.visitFunctionDeclaration(node); | 323 super.visitFunctionDeclaration(node); |
| 322 } finally { | 324 } finally { |
| 323 _exitScope(); | 325 _exitScope(); |
| 324 } | 326 } |
| 325 } | 327 } |
| 326 | 328 |
| 327 @override | 329 @override |
| 328 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 330 visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 329 Element element = node.element; | 331 Element element = node.element; |
| 330 _recordElementDefinition(element); | 332 _recordElementDefinition(element); |
| 331 return super.visitFunctionTypeAlias(node); | 333 super.visitFunctionTypeAlias(node); |
| 332 } | 334 } |
| 333 | 335 |
| 334 @override | 336 @override |
| 335 Object visitImportDirective(ImportDirective node) { | 337 visitImportDirective(ImportDirective node) { |
| 336 ImportElement element = node.element; | 338 ImportElement element = node.element; |
| 337 if (element != null) { | 339 if (element != null) { |
| 338 LibraryElement impLibrary = element.importedLibrary; | 340 LibraryElement impLibrary = element.importedLibrary; |
| 339 _recordLibraryReference(node, impLibrary); | 341 _recordLibraryReference(node, impLibrary); |
| 340 } | 342 } |
| 341 return super.visitImportDirective(node); | 343 super.visitImportDirective(node); |
| 342 } | 344 } |
| 343 | 345 |
| 344 @override | 346 @override |
| 345 Object visitIndexExpression(IndexExpression node) { | 347 visitIndexExpression(IndexExpression node) { |
| 346 MethodElement element = node.bestElement; | 348 MethodElement element = node.bestElement; |
| 347 if (element is MethodElement) { | 349 if (element is MethodElement) { |
| 348 Token operator = node.leftBracket; | 350 Token operator = node.leftBracket; |
| 349 Location location = _createLocationForToken(operator, element != null); | 351 Location location = _createLocationForToken(operator, element != null); |
| 350 recordRelationship(element, IndexConstants.IS_INVOKED_BY, location); | 352 recordRelationship(element, IndexConstants.IS_INVOKED_BY, location); |
| 351 } | 353 } |
| 352 return super.visitIndexExpression(node); | 354 super.visitIndexExpression(node); |
| 353 } | 355 } |
| 354 | 356 |
| 355 @override | 357 @override |
| 356 Object visitMethodDeclaration(MethodDeclaration node) { | 358 visitMethodDeclaration(MethodDeclaration node) { |
| 357 ExecutableElement element = node.element; | 359 ExecutableElement element = node.element; |
| 358 enterScope(element); | 360 enterScope(element); |
| 359 try { | 361 try { |
| 360 return super.visitMethodDeclaration(node); | 362 super.visitMethodDeclaration(node); |
| 361 } finally { | 363 } finally { |
| 362 _exitScope(); | 364 _exitScope(); |
| 363 } | 365 } |
| 364 } | 366 } |
| 365 | 367 |
| 366 @override | 368 @override |
| 367 Object visitMethodInvocation(MethodInvocation node) { | 369 visitMethodInvocation(MethodInvocation node) { |
| 368 SimpleIdentifier name = node.methodName; | 370 SimpleIdentifier name = node.methodName; |
| 369 Location location = _createLocationForNode(name); | 371 Location location = _createLocationForNode(name); |
| 370 // element invocation | 372 // element invocation |
| 371 Element element = name.bestElement; | 373 Element element = name.bestElement; |
| 372 if (element is MethodElement || | 374 if (element is MethodElement || |
| 373 element is PropertyAccessorElement || | 375 element is PropertyAccessorElement || |
| 374 element is FunctionElement || | 376 element is FunctionElement || |
| 375 element is VariableElement) { | 377 element is VariableElement) { |
| 376 recordRelationship(element, IndexConstants.IS_INVOKED_BY, location); | 378 recordRelationship(element, IndexConstants.IS_INVOKED_BY, location); |
| 377 } | 379 } |
| 378 // name invocation | 380 // name invocation |
| 379 { | 381 { |
| 380 Element nameElement = new NameElement(name.name); | 382 Element nameElement = new NameElement(name.name); |
| 381 _store.recordRelationship( | 383 _store.recordRelationship( |
| 382 nameElement, | 384 nameElement, |
| 383 IndexConstants.IS_INVOKED_BY, | 385 IndexConstants.IS_INVOKED_BY, |
| 384 location); | 386 location); |
| 385 } | 387 } |
| 386 _recordImportElementReferenceWithoutPrefix(name); | 388 _recordImportElementReferenceWithoutPrefix(name); |
| 387 return super.visitMethodInvocation(node); | 389 super.visitMethodInvocation(node); |
| 388 } | 390 } |
| 389 | 391 |
| 390 @override | 392 @override |
| 391 Object visitPartDirective(PartDirective node) { | 393 visitPartDirective(PartDirective node) { |
| 392 Element element = node.element; | 394 Element element = node.element; |
| 393 Location location = _createLocationForNode(node.uri); | 395 Location location = _createLocationForNode(node.uri); |
| 394 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); | 396 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); |
| 395 return super.visitPartDirective(node); | 397 super.visitPartDirective(node); |
| 396 } | 398 } |
| 397 | 399 |
| 398 @override | 400 @override |
| 399 Object visitPartOfDirective(PartOfDirective node) { | 401 visitPartOfDirective(PartOfDirective node) { |
| 400 Location location = _createLocationForNode(node.libraryName); | 402 Location location = _createLocationForNode(node.libraryName); |
| 401 recordRelationship(node.element, IndexConstants.IS_REFERENCED_BY, location); | 403 recordRelationship(node.element, IndexConstants.IS_REFERENCED_BY, location); |
| 402 return null; | |
| 403 } | 404 } |
| 404 | 405 |
| 405 @override | 406 @override |
| 406 Object visitPostfixExpression(PostfixExpression node) { | 407 visitPostfixExpression(PostfixExpression node) { |
| 407 _recordOperatorReference(node.operator, node.bestElement); | 408 _recordOperatorReference(node.operator, node.bestElement); |
| 408 return super.visitPostfixExpression(node); | 409 super.visitPostfixExpression(node); |
| 409 } | 410 } |
| 410 | 411 |
| 411 @override | 412 @override |
| 412 Object visitPrefixExpression(PrefixExpression node) { | 413 visitPrefixExpression(PrefixExpression node) { |
| 413 _recordOperatorReference(node.operator, node.bestElement); | 414 _recordOperatorReference(node.operator, node.bestElement); |
| 414 return super.visitPrefixExpression(node); | 415 super.visitPrefixExpression(node); |
| 415 } | 416 } |
| 416 | 417 |
| 417 @override | 418 @override |
| 418 Object | 419 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) { |
| 419 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod
e) { | |
| 420 ConstructorElement element = node.staticElement; | 420 ConstructorElement element = node.staticElement; |
| 421 Location location; | 421 Location location; |
| 422 if (node.constructorName != null) { | 422 if (node.constructorName != null) { |
| 423 int start = node.period.offset; | 423 int start = node.period.offset; |
| 424 int end = node.constructorName.end; | 424 int end = node.constructorName.end; |
| 425 location = _createLocationForOffset(start, end - start); | 425 location = _createLocationForOffset(start, end - start); |
| 426 } else { | 426 } else { |
| 427 int start = node.keyword.end; | 427 int start = node.keyword.end; |
| 428 location = _createLocationForOffset(start, 0); | 428 location = _createLocationForOffset(start, 0); |
| 429 } | 429 } |
| 430 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); | 430 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); |
| 431 return super.visitRedirectingConstructorInvocation(node); | 431 super.visitRedirectingConstructorInvocation(node); |
| 432 } | 432 } |
| 433 | 433 |
| 434 @override | 434 @override |
| 435 Object visitSimpleIdentifier(SimpleIdentifier node) { | 435 visitSimpleIdentifier(SimpleIdentifier node) { |
| 436 Element nameElement = new NameElement(node.name); | 436 Element nameElement = new NameElement(node.name); |
| 437 Location location = _createLocationForNode(node); | 437 Location location = _createLocationForNode(node); |
| 438 // name in declaration | 438 // name in declaration |
| 439 if (node.inDeclarationContext()) { | 439 if (node.inDeclarationContext()) { |
| 440 recordRelationship( | 440 recordRelationship( |
| 441 nameElement, | 441 nameElement, |
| 442 IndexConstants.NAME_IS_DEFINED_BY, | 442 IndexConstants.NAME_IS_DEFINED_BY, |
| 443 location); | 443 location); |
| 444 return null; | 444 return; |
| 445 } | 445 } |
| 446 // prepare information | 446 // prepare information |
| 447 Element element = node.bestElement; | 447 Element element = node.bestElement; |
| 448 // stop if already handled | 448 // stop if already handled |
| 449 if (_isAlreadyHandledName(node)) { | 449 if (_isAlreadyHandledName(node)) { |
| 450 return null; | 450 return; |
| 451 } | 451 } |
| 452 // record name read/write | 452 // record name read/write |
| 453 if (element != null && element.enclosingElement is ClassElement || | 453 if (element != null && element.enclosingElement is ClassElement || |
| 454 element == null && location.isQualified) { | 454 element == null && location.isQualified) { |
| 455 bool inGetterContext = node.inGetterContext(); | 455 bool inGetterContext = node.inGetterContext(); |
| 456 bool inSetterContext = node.inSetterContext(); | 456 bool inSetterContext = node.inSetterContext(); |
| 457 if (inGetterContext && inSetterContext) { | 457 if (inGetterContext && inSetterContext) { |
| 458 _store.recordRelationship( | 458 _store.recordRelationship( |
| 459 nameElement, | 459 nameElement, |
| 460 IndexConstants.IS_READ_WRITTEN_BY, | 460 IndexConstants.IS_READ_WRITTEN_BY, |
| 461 location); | 461 location); |
| 462 } else if (inGetterContext) { | 462 } else if (inGetterContext) { |
| 463 _store.recordRelationship( | 463 _store.recordRelationship( |
| 464 nameElement, | 464 nameElement, |
| 465 IndexConstants.IS_READ_BY, | 465 IndexConstants.IS_READ_BY, |
| 466 location); | 466 location); |
| 467 } else if (inSetterContext) { | 467 } else if (inSetterContext) { |
| 468 _store.recordRelationship( | 468 _store.recordRelationship( |
| 469 nameElement, | 469 nameElement, |
| 470 IndexConstants.IS_WRITTEN_BY, | 470 IndexConstants.IS_WRITTEN_BY, |
| 471 location); | 471 location); |
| 472 } | 472 } |
| 473 } | 473 } |
| 474 // this.field parameter | 474 // this.field parameter |
| 475 if (element is FieldFormalParameterElement) { | 475 if (element is FieldFormalParameterElement) { |
| 476 Relationship relationship = peekElement() == element ? | 476 Relationship relationship = peekElement() == element ? |
| 477 IndexConstants.IS_WRITTEN_BY : | 477 IndexConstants.IS_WRITTEN_BY : |
| 478 IndexConstants.IS_REFERENCED_BY; | 478 IndexConstants.IS_REFERENCED_BY; |
| 479 _store.recordRelationship(element.field, relationship, location); | 479 _store.recordRelationship(element.field, relationship, location); |
| 480 return null; | 480 return; |
| 481 } | 481 } |
| 482 // record specific relations | 482 // record specific relations |
| 483 if (element is ClassElement || | 483 if (element is ClassElement || |
| 484 element is FunctionElement || | 484 element is FunctionElement || |
| 485 element is FunctionTypeAliasElement || | 485 element is FunctionTypeAliasElement || |
| 486 element is LabelElement || | 486 element is LabelElement || |
| 487 element is MethodElement || | 487 element is MethodElement || |
| 488 element is PropertyAccessorElement || | 488 element is PropertyAccessorElement || |
| 489 element is PropertyInducingElement || | 489 element is PropertyInducingElement || |
| 490 element is TypeParameterElement) { | 490 element is TypeParameterElement) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 502 location); | 502 location); |
| 503 } else if (inGetterContext) { | 503 } else if (inGetterContext) { |
| 504 recordRelationship(element, IndexConstants.IS_READ_BY, location); | 504 recordRelationship(element, IndexConstants.IS_READ_BY, location); |
| 505 } else if (inSetterContext) { | 505 } else if (inSetterContext) { |
| 506 recordRelationship(element, IndexConstants.IS_WRITTEN_BY, location); | 506 recordRelationship(element, IndexConstants.IS_WRITTEN_BY, location); |
| 507 } else { | 507 } else { |
| 508 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); | 508 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); |
| 509 } | 509 } |
| 510 } | 510 } |
| 511 _recordImportElementReferenceWithoutPrefix(node); | 511 _recordImportElementReferenceWithoutPrefix(node); |
| 512 return super.visitSimpleIdentifier(node); | 512 super.visitSimpleIdentifier(node); |
| 513 } | 513 } |
| 514 | 514 |
| 515 @override | 515 @override |
| 516 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 516 visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 517 ConstructorElement element = node.staticElement; | 517 ConstructorElement element = node.staticElement; |
| 518 Location location; | 518 Location location; |
| 519 if (node.constructorName != null) { | 519 if (node.constructorName != null) { |
| 520 int start = node.period.offset; | 520 int start = node.period.offset; |
| 521 int end = node.constructorName.end; | 521 int end = node.constructorName.end; |
| 522 location = _createLocationForOffset(start, end - start); | 522 location = _createLocationForOffset(start, end - start); |
| 523 } else { | 523 } else { |
| 524 int start = node.keyword.end; | 524 int start = node.keyword.end; |
| 525 location = _createLocationForOffset(start, 0); | 525 location = _createLocationForOffset(start, 0); |
| 526 } | 526 } |
| 527 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); | 527 recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); |
| 528 return super.visitSuperConstructorInvocation(node); | 528 super.visitSuperConstructorInvocation(node); |
| 529 } | 529 } |
| 530 | 530 |
| 531 @override | 531 @override |
| 532 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 532 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 533 VariableDeclarationList variables = node.variables; | 533 VariableDeclarationList variables = node.variables; |
| 534 for (VariableDeclaration variableDeclaration in variables.variables) { | 534 for (VariableDeclaration variableDeclaration in variables.variables) { |
| 535 Element element = variableDeclaration.element; | 535 Element element = variableDeclaration.element; |
| 536 _recordElementDefinition(element); | 536 _recordElementDefinition(element); |
| 537 } | 537 } |
| 538 return super.visitTopLevelVariableDeclaration(node); | 538 super.visitTopLevelVariableDeclaration(node); |
| 539 } | 539 } |
| 540 | 540 |
| 541 @override | 541 @override |
| 542 Object visitTypeParameter(TypeParameter node) { | 542 visitTypeParameter(TypeParameter node) { |
| 543 TypeParameterElement element = node.element; | 543 TypeParameterElement element = node.element; |
| 544 enterScope(element); | 544 enterScope(element); |
| 545 try { | 545 try { |
| 546 return super.visitTypeParameter(node); | 546 super.visitTypeParameter(node); |
| 547 } finally { | 547 } finally { |
| 548 _exitScope(); | 548 _exitScope(); |
| 549 } | 549 } |
| 550 } | 550 } |
| 551 | 551 |
| 552 @override | 552 @override |
| 553 Object visitVariableDeclaration(VariableDeclaration node) { | 553 visitVariableDeclaration(VariableDeclaration node) { |
| 554 VariableElement element = node.element; | 554 VariableElement element = node.element; |
| 555 // record declaration | 555 // record declaration |
| 556 { | 556 { |
| 557 SimpleIdentifier name = node.name; | 557 SimpleIdentifier name = node.name; |
| 558 Location location = _createLocationForNode(name); | 558 Location location = _createLocationForNode(name); |
| 559 location = _getLocationWithExpressionType(location, node.initializer); | 559 location = _getLocationWithExpressionType(location, node.initializer); |
| 560 recordRelationship(element, IndexConstants.NAME_IS_DEFINED_BY, location); | 560 recordRelationship(element, IndexConstants.NAME_IS_DEFINED_BY, location); |
| 561 } | 561 } |
| 562 // visit | 562 // visit |
| 563 enterScope(element); | 563 enterScope(element); |
| 564 try { | 564 try { |
| 565 return super.visitVariableDeclaration(node); | 565 super.visitVariableDeclaration(node); |
| 566 } finally { | 566 } finally { |
| 567 _exitScope(); | 567 _exitScope(); |
| 568 } | 568 } |
| 569 } | 569 } |
| 570 | 570 |
| 571 @override | 571 @override |
| 572 Object visitVariableDeclarationList(VariableDeclarationList node) { | 572 visitVariableDeclarationList(VariableDeclarationList node) { |
| 573 NodeList<VariableDeclaration> variables = node.variables; | 573 NodeList<VariableDeclaration> variables = node.variables; |
| 574 if (variables != null) { | 574 if (variables != null) { |
| 575 // use first VariableDeclaration as Element for Location(s) in type | 575 // use first VariableDeclaration as Element for Location(s) in type |
| 576 { | 576 { |
| 577 TypeName type = node.type; | 577 TypeName type = node.type; |
| 578 if (type != null) { | 578 if (type != null) { |
| 579 for (VariableDeclaration variableDeclaration in variables) { | 579 for (VariableDeclaration variableDeclaration in variables) { |
| 580 enterScope(variableDeclaration.element); | 580 enterScope(variableDeclaration.element); |
| 581 try { | 581 try { |
| 582 type.accept(this); | 582 type.accept(this); |
| 583 } finally { | 583 } finally { |
| 584 _exitScope(); | 584 _exitScope(); |
| 585 } | 585 } |
| 586 // only one iteration | 586 // only one iteration |
| 587 break; | 587 break; |
| 588 } | 588 } |
| 589 } | 589 } |
| 590 } | 590 } |
| 591 // visit variables | 591 // visit variables |
| 592 variables.accept(this); | 592 variables.accept(this); |
| 593 } | 593 } |
| 594 return null; | |
| 595 } | 594 } |
| 596 | 595 |
| 597 /** | 596 /** |
| 598 * @return the [Location] representing location of the [AstNode]. | 597 * @return the [Location] representing location of the [AstNode]. |
| 599 */ | 598 */ |
| 600 Location _createLocationForNode(AstNode node) { | 599 Location _createLocationForNode(AstNode node) { |
| 601 bool isQualified = _isQualifiedClassMemberAccess(node); | 600 bool isQualified = _isQualifiedClassMemberAccess(node); |
| 602 bool isResolved = true; | 601 bool isResolved = true; |
| 603 if (node is SimpleIdentifier) { | 602 if (node is SimpleIdentifier) { |
| 604 isResolved = node.bestElement != null; | 603 isResolved = node.bestElement != null; |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 } | 818 } |
| 820 | 819 |
| 821 /** | 820 /** |
| 822 * @return `true` if given "node" is part of [PrefixedIdentifier] "prefix.node
". | 821 * @return `true` if given "node" is part of [PrefixedIdentifier] "prefix.node
". |
| 823 */ | 822 */ |
| 824 static bool _isIdentifierInPrefixedIdentifier(SimpleIdentifier node) { | 823 static bool _isIdentifierInPrefixedIdentifier(SimpleIdentifier node) { |
| 825 AstNode parent = node.parent; | 824 AstNode parent = node.parent; |
| 826 return parent is PrefixedIdentifier && parent.identifier == node; | 825 return parent is PrefixedIdentifier && parent.identifier == node; |
| 827 } | 826 } |
| 828 } | 827 } |
| OLD | NEW |