| 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.dart.element.builder; | 5 library analyzer.src.dart.element.builder; |
| 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 } | 197 } |
| 198 } | 198 } |
| 199 } | 199 } |
| 200 return null; | 200 return null; |
| 201 } | 201 } |
| 202 | 202 |
| 203 @override | 203 @override |
| 204 Object visitImportDirective(ImportDirective node) { | 204 Object visitImportDirective(ImportDirective node) { |
| 205 // Remove previous element. (It will remain null if the target is missing.) | 205 // Remove previous element. (It will remain null if the target is missing.) |
| 206 node.element = null; | 206 node.element = null; |
| 207 | |
| 208 String uriContent = node.uriContent; | |
| 209 if (DartUriResolver.isDartExtUri(uriContent)) { | |
| 210 libraryElement.hasExtUri = true; | |
| 211 } | |
| 212 Source importedSource = node.source; | 207 Source importedSource = node.source; |
| 213 if (importedSource != null && context.exists(importedSource)) { | 208 if (importedSource != null && context.exists(importedSource)) { |
| 214 // The imported source will be null if the URI in the import | 209 // The imported source will be null if the URI in the import |
| 215 // directive was invalid. | 210 // directive was invalid. |
| 216 LibraryElement importedLibrary = importLibraryMap[importedSource]; | 211 LibraryElement importedLibrary = importLibraryMap[importedSource]; |
| 217 if (importedLibrary != null) { | 212 if (importedLibrary != null) { |
| 218 if (importedLibrary.isDartCore) { | 213 if (importedLibrary.isDartCore) { |
| 219 explicitlyImportsCore = true; | 214 explicitlyImportsCore = true; |
| 220 } | 215 } |
| 221 ImportElementImpl importElement = new ImportElementImpl(node.offset); | 216 ImportElementImpl importElement = new ImportElementImpl(node.offset); |
| 222 importElement.metadata = _getElementAnnotations(node.metadata); | 217 importElement.metadata = _getElementAnnotations(node.metadata); |
| 223 StringLiteral uriLiteral = node.uri; | 218 StringLiteral uriLiteral = node.uri; |
| 224 if (uriLiteral != null) { | 219 if (uriLiteral != null) { |
| 225 importElement.uriOffset = uriLiteral.offset; | 220 importElement.uriOffset = uriLiteral.offset; |
| 226 importElement.uriEnd = uriLiteral.end; | 221 importElement.uriEnd = uriLiteral.end; |
| 227 } | 222 } |
| 228 importElement.uri = uriContent; | 223 importElement.uri = node.uriContent; |
| 229 importElement.deferred = node.deferredKeyword != null; | 224 importElement.deferred = node.deferredKeyword != null; |
| 230 importElement.combinators = _buildCombinators(node); | 225 importElement.combinators = _buildCombinators(node); |
| 231 importElement.importedLibrary = importedLibrary; | 226 importElement.importedLibrary = importedLibrary; |
| 232 setElementDocumentationComment(importElement, node); | 227 setElementDocumentationComment(importElement, node); |
| 233 SimpleIdentifier prefixNode = node.prefix; | 228 SimpleIdentifier prefixNode = node.prefix; |
| 234 if (prefixNode != null) { | 229 if (prefixNode != null) { |
| 235 importElement.prefixOffset = prefixNode.offset; | 230 importElement.prefixOffset = prefixNode.offset; |
| 236 String prefixName = prefixNode.name; | 231 String prefixName = prefixNode.name; |
| 237 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; | 232 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; |
| 238 if (prefix == null) { | 233 if (prefix == null) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 | 300 |
| 306 /** | 301 /** |
| 307 * Instances of the class `ElementBuilder` traverse an AST structure and build t
he element | 302 * Instances of the class `ElementBuilder` traverse an AST structure and build t
he element |
| 308 * model representing the AST structure. | 303 * model representing the AST structure. |
| 309 */ | 304 */ |
| 310 class ElementBuilder extends RecursiveAstVisitor<Object> { | 305 class ElementBuilder extends RecursiveAstVisitor<Object> { |
| 311 /** | 306 /** |
| 312 * The compilation unit element into which the elements being built will be | 307 * The compilation unit element into which the elements being built will be |
| 313 * stored. | 308 * stored. |
| 314 */ | 309 */ |
| 315 final CompilationUnitElement compilationUnitElement; | 310 final CompilationUnitElementImpl compilationUnitElement; |
| 316 | 311 |
| 317 /** | 312 /** |
| 318 * The element holder associated with the element that is currently being buil
t. | 313 * The element holder associated with the element that is currently being buil
t. |
| 319 */ | 314 */ |
| 320 ElementHolder _currentHolder; | 315 ElementHolder _currentHolder; |
| 321 | 316 |
| 322 /** | 317 /** |
| 323 * A flag indicating whether a variable declaration is within the body of a me
thod or function. | 318 * A flag indicating whether a variable declaration is within the body of a me
thod or function. |
| 324 */ | 319 */ |
| 325 bool _inFunction = false; | 320 bool _inFunction = false; |
| 326 | 321 |
| 327 /** | 322 /** |
| 328 * A collection holding the elements defined in a class that need to have | 323 * A collection holding the elements defined in a class that need to have |
| 329 * their function type fixed to take into account type parameters of the | 324 * their function type fixed to take into account type parameters of the |
| 330 * enclosing class, or `null` if we are not currently processing nodes within | 325 * enclosing class, or `null` if we are not currently processing nodes within |
| 331 * a class. | 326 * a class. |
| 332 */ | 327 */ |
| 333 List<ExecutableElementImpl> _functionTypesToFix = null; | 328 List<ExecutableElementImpl> _functionTypesToFix = null; |
| 334 | 329 |
| 335 /** | 330 /** |
| 336 * A table mapping field names to field elements for the fields defined in the
current class, or | 331 * A table mapping field names to field elements for the fields defined in the
current class, or |
| 337 * `null` if we are not in the scope of a class. | 332 * `null` if we are not in the scope of a class. |
| 338 */ | 333 */ |
| 339 HashMap<String, FieldElement> _fieldMap; | 334 HashMap<String, FieldElement> _fieldMap; |
| 340 | 335 |
| 341 /** | 336 /** |
| 342 * Initialize a newly created element builder to build the elements for a comp
ilation unit. | 337 * Initialize a newly created element builder to build the elements for a |
| 343 * | 338 * compilation unit. The [initialHolder] is the element holder to which the |
| 344 * @param initialHolder the element holder associated with the compilation uni
t being built | 339 * children of the visited compilation unit node will be added. |
| 345 */ | 340 */ |
| 346 ElementBuilder(ElementHolder initialHolder, this.compilationUnitElement) { | 341 ElementBuilder(ElementHolder initialHolder, this.compilationUnitElement) { |
| 347 _currentHolder = initialHolder; | 342 _currentHolder = initialHolder; |
| 348 } | 343 } |
| 349 | 344 |
| 350 @override | 345 @override |
| 351 Object visitAnnotation(Annotation node) { | 346 Object visitAnnotation(Annotation node) { |
| 352 // Although it isn't valid to do so because closures are not constant | 347 // Although it isn't valid to do so because closures are not constant |
| 353 // expressions, it's possible for one of the arguments to the constructor to | 348 // expressions, it's possible for one of the arguments to the constructor to |
| 354 // contain a closure. Wrapping the processing of the annotation this way | 349 // contain a closure. Wrapping the processing of the annotation this way |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 setElementDocumentationComment(element, node); | 472 setElementDocumentationComment(element, node); |
| 478 _currentHolder.addType(element); | 473 _currentHolder.addType(element); |
| 479 className.staticElement = element; | 474 className.staticElement = element; |
| 480 holder.validate(); | 475 holder.validate(); |
| 481 return null; | 476 return null; |
| 482 } | 477 } |
| 483 | 478 |
| 484 @override | 479 @override |
| 485 Object visitCompilationUnit(CompilationUnit node) { | 480 Object visitCompilationUnit(CompilationUnit node) { |
| 486 if (compilationUnitElement is ElementImpl) { | 481 if (compilationUnitElement is ElementImpl) { |
| 487 _setCodeRange(compilationUnitElement as ElementImpl, node); | 482 _setCodeRange(compilationUnitElement, node); |
| 488 } | 483 } |
| 489 return super.visitCompilationUnit(node); | 484 return super.visitCompilationUnit(node); |
| 490 } | 485 } |
| 491 | 486 |
| 492 @override | 487 @override |
| 493 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 488 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 494 ElementHolder holder = new ElementHolder(); | 489 ElementHolder holder = new ElementHolder(); |
| 495 bool wasInFunction = _inFunction; | 490 bool wasInFunction = _inFunction; |
| 496 _inFunction = true; | 491 _inFunction = true; |
| 497 try { | 492 try { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 // to subclass, mix-in, implement, or explicitly instantiate an enum). So | 621 // to subclass, mix-in, implement, or explicitly instantiate an enum). So |
| 627 // we represent this as having no constructors. | 622 // we represent this as having no constructors. |
| 628 enumElement.constructors = ConstructorElement.EMPTY_LIST; | 623 enumElement.constructors = ConstructorElement.EMPTY_LIST; |
| 629 _currentHolder.addEnum(enumElement); | 624 _currentHolder.addEnum(enumElement); |
| 630 enumName.staticElement = enumElement; | 625 enumName.staticElement = enumElement; |
| 631 return super.visitEnumDeclaration(node); | 626 return super.visitEnumDeclaration(node); |
| 632 } | 627 } |
| 633 | 628 |
| 634 @override | 629 @override |
| 635 Object visitExportDirective(ExportDirective node) { | 630 Object visitExportDirective(ExportDirective node) { |
| 636 _createElementAnnotations(node.metadata); | 631 List<ElementAnnotation> annotations = |
| 632 _createElementAnnotations(node.metadata); |
| 633 compilationUnitElement.setAnnotations(node.offset, annotations); |
| 637 return super.visitExportDirective(node); | 634 return super.visitExportDirective(node); |
| 638 } | 635 } |
| 639 | 636 |
| 640 @override | 637 @override |
| 641 Object visitFieldFormalParameter(FieldFormalParameter node) { | 638 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 642 if (node.parent is! DefaultFormalParameter) { | 639 if (node.parent is! DefaultFormalParameter) { |
| 643 SimpleIdentifier parameterName = node.identifier; | 640 SimpleIdentifier parameterName = node.identifier; |
| 644 FieldElement field = | 641 FieldElement field = |
| 645 _fieldMap == null ? null : _fieldMap[parameterName.name]; | 642 _fieldMap == null ? null : _fieldMap[parameterName.name]; |
| 646 FieldFormalParameterElementImpl parameter = | 643 FieldFormalParameterElementImpl parameter = |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 ParameterElementImpl element = node.element; | 885 ParameterElementImpl element = node.element; |
| 889 element.metadata = _createElementAnnotations(node.metadata); | 886 element.metadata = _createElementAnnotations(node.metadata); |
| 890 element.parameters = holder.parameters; | 887 element.parameters = holder.parameters; |
| 891 element.typeParameters = holder.typeParameters; | 888 element.typeParameters = holder.typeParameters; |
| 892 holder.validate(); | 889 holder.validate(); |
| 893 return null; | 890 return null; |
| 894 } | 891 } |
| 895 | 892 |
| 896 @override | 893 @override |
| 897 Object visitImportDirective(ImportDirective node) { | 894 Object visitImportDirective(ImportDirective node) { |
| 898 _createElementAnnotations(node.metadata); | 895 List<ElementAnnotation> annotations = |
| 896 _createElementAnnotations(node.metadata); |
| 897 compilationUnitElement.setAnnotations(node.offset, annotations); |
| 899 return super.visitImportDirective(node); | 898 return super.visitImportDirective(node); |
| 900 } | 899 } |
| 901 | 900 |
| 902 @override | 901 @override |
| 903 Object visitLabeledStatement(LabeledStatement node) { | 902 Object visitLabeledStatement(LabeledStatement node) { |
| 904 bool onSwitchStatement = node.statement is SwitchStatement; | 903 bool onSwitchStatement = node.statement is SwitchStatement; |
| 905 for (Label label in node.labels) { | 904 for (Label label in node.labels) { |
| 906 SimpleIdentifier labelName = label.label; | 905 SimpleIdentifier labelName = label.label; |
| 907 LabelElementImpl element = | 906 LabelElementImpl element = |
| 908 new LabelElementImpl.forNode(labelName, onSwitchStatement, false); | 907 new LabelElementImpl.forNode(labelName, onSwitchStatement, false); |
| 909 _setCodeRange(element, node); | 908 _setCodeRange(element, node); |
| 910 _currentHolder.addLabel(element); | 909 _currentHolder.addLabel(element); |
| 911 labelName.staticElement = element; | 910 labelName.staticElement = element; |
| 912 } | 911 } |
| 913 return super.visitLabeledStatement(node); | 912 return super.visitLabeledStatement(node); |
| 914 } | 913 } |
| 915 | 914 |
| 916 @override | 915 @override |
| 917 Object visitLibraryDirective(LibraryDirective node) { | 916 Object visitLibraryDirective(LibraryDirective node) { |
| 918 _createElementAnnotations(node.metadata); | 917 List<ElementAnnotation> annotations = |
| 918 _createElementAnnotations(node.metadata); |
| 919 compilationUnitElement.setAnnotations(node.offset, annotations); |
| 919 return super.visitLibraryDirective(node); | 920 return super.visitLibraryDirective(node); |
| 920 } | 921 } |
| 921 | 922 |
| 922 @override | 923 @override |
| 923 Object visitMethodDeclaration(MethodDeclaration node) { | 924 Object visitMethodDeclaration(MethodDeclaration node) { |
| 924 try { | 925 try { |
| 925 ElementHolder holder = new ElementHolder(); | 926 ElementHolder holder = new ElementHolder(); |
| 926 bool wasInFunction = _inFunction; | 927 bool wasInFunction = _inFunction; |
| 927 _inFunction = true; | 928 _inFunction = true; |
| 928 try { | 929 try { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 buffer.toString(), | 1072 buffer.toString(), |
| 1072 new CaughtException( | 1073 new CaughtException( |
| 1073 new AnalysisException(buffer.toString()), null)); | 1074 new AnalysisException(buffer.toString()), null)); |
| 1074 } | 1075 } |
| 1075 } | 1076 } |
| 1076 return null; | 1077 return null; |
| 1077 } | 1078 } |
| 1078 | 1079 |
| 1079 @override | 1080 @override |
| 1080 Object visitPartDirective(PartDirective node) { | 1081 Object visitPartDirective(PartDirective node) { |
| 1081 _createElementAnnotations(node.metadata); | 1082 List<ElementAnnotation> annotations = |
| 1083 _createElementAnnotations(node.metadata); |
| 1084 compilationUnitElement.setAnnotations(node.offset, annotations); |
| 1082 return super.visitPartDirective(node); | 1085 return super.visitPartDirective(node); |
| 1083 } | 1086 } |
| 1084 | 1087 |
| 1085 @override | 1088 @override |
| 1086 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 1089 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 1087 if (node.parent is! DefaultFormalParameter) { | 1090 if (node.parent is! DefaultFormalParameter) { |
| 1088 SimpleIdentifier parameterName = node.identifier; | 1091 SimpleIdentifier parameterName = node.identifier; |
| 1089 ParameterElementImpl parameter = | 1092 ParameterElementImpl parameter = |
| 1090 new ParameterElementImpl.forNode(parameterName); | 1093 new ParameterElementImpl.forNode(parameterName); |
| 1091 _setCodeRange(parameter, node); | 1094 _setCodeRange(parameter, node); |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1454 return null; | 1457 return null; |
| 1455 } | 1458 } |
| 1456 | 1459 |
| 1457 /** | 1460 /** |
| 1458 * Return the lexical identifiers associated with the given [identifiers]. | 1461 * Return the lexical identifiers associated with the given [identifiers]. |
| 1459 */ | 1462 */ |
| 1460 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { | 1463 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { |
| 1461 return identifiers.map((identifier) => identifier.name).toList(); | 1464 return identifiers.map((identifier) => identifier.name).toList(); |
| 1462 } | 1465 } |
| 1463 } | 1466 } |
| OLD | NEW |