| 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.incremental_resolver; | 5 library engine.incremental_resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'ast.dart'; | 9 import 'ast.dart'; |
| 10 import 'element.dart'; | 10 import 'element.dart'; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 * the scope of a method or function. | 42 * the scope of a method or function. |
| 43 */ | 43 */ |
| 44 ExecutableElement _enclosingExecutable; | 44 ExecutableElement _enclosingExecutable; |
| 45 | 45 |
| 46 /** | 46 /** |
| 47 * The parameter containing the AST nodes being visited, or `null` if we are n
ot in the | 47 * The parameter containing the AST nodes being visited, or `null` if we are n
ot in the |
| 48 * scope of a parameter. | 48 * scope of a parameter. |
| 49 */ | 49 */ |
| 50 ParameterElement _enclosingParameter; | 50 ParameterElement _enclosingParameter; |
| 51 | 51 |
| 52 bool _inTopLevelVariableDeclaration = false; |
| 53 |
| 52 /** | 54 /** |
| 53 * A set containing all of the elements in the element model that were defined
by the old AST node | 55 * A set containing all of the elements in the element model that were defined
by the old AST node |
| 54 * corresponding to the AST node being visited. | 56 * corresponding to the AST node being visited. |
| 55 */ | 57 */ |
| 56 HashSet<Element> _allElements = new HashSet<Element>(); | 58 HashSet<Element> _allElements = new HashSet<Element>(); |
| 57 | 59 |
| 58 /** | 60 /** |
| 59 * A set containing all of the elements in the element model that were defined
by the old AST node | 61 * A set containing all of the elements in the element model that were defined
by the old AST node |
| 60 * corresponding to the AST node being visited that have not already been matc
hed to nodes in the | 62 * corresponding to the AST node being visited that have not already been matc
hed to nodes in the |
| 61 * AST structure being visited. | 63 * AST structure being visited. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 72 * element model | 74 * element model |
| 73 */ | 75 */ |
| 74 bool matches(AstNode node, Element element) { | 76 bool matches(AstNode node, Element element) { |
| 75 _captureEnclosingElements(element); | 77 _captureEnclosingElements(element); |
| 76 _gatherElements(element); | 78 _gatherElements(element); |
| 77 try { | 79 try { |
| 78 node.accept(this); | 80 node.accept(this); |
| 79 } on _DeclarationMismatchException catch (exception) { | 81 } on _DeclarationMismatchException catch (exception) { |
| 80 return false; | 82 return false; |
| 81 } | 83 } |
| 84 print(_unmatchedElements.join('\n')); |
| 82 return _unmatchedElements.isEmpty; | 85 return _unmatchedElements.isEmpty; |
| 83 } | 86 } |
| 84 | 87 |
| 85 void processElement(Element element) { | |
| 86 if (element == null) { | |
| 87 throw new _DeclarationMismatchException(); | |
| 88 } | |
| 89 if (!_allElements.contains(element)) { | |
| 90 throw new _DeclarationMismatchException(); | |
| 91 } | |
| 92 _unmatchedElements.remove(element); | |
| 93 } | |
| 94 | |
| 95 @override | 88 @override |
| 96 Object visitCatchClause(CatchClause node) { | 89 Object visitCatchClause(CatchClause node) { |
| 97 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 90 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
| 98 if (exceptionParameter != null) { | 91 if (exceptionParameter != null) { |
| 99 List<LocalVariableElement> localVariables = | 92 List<LocalVariableElement> localVariables = |
| 100 _enclosingExecutable.localVariables; | 93 _enclosingExecutable.localVariables; |
| 101 LocalVariableElement exceptionElement = | 94 LocalVariableElement exceptionElement = |
| 102 _findIdentifier(localVariables, exceptionParameter); | 95 _findIdentifier(localVariables, exceptionParameter); |
| 103 processElement(exceptionElement); | 96 _processElement(exceptionElement); |
| 104 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | 97 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; |
| 105 if (stackTraceParameter != null) { | 98 if (stackTraceParameter != null) { |
| 106 LocalVariableElement stackTraceElement = | 99 LocalVariableElement stackTraceElement = |
| 107 _findIdentifier(localVariables, stackTraceParameter); | 100 _findIdentifier(localVariables, stackTraceParameter); |
| 108 processElement(stackTraceElement); | 101 _processElement(stackTraceElement); |
| 109 } | 102 } |
| 110 } | 103 } |
| 111 return super.visitCatchClause(node); | 104 return super.visitCatchClause(node); |
| 112 } | 105 } |
| 113 | 106 |
| 114 @override | 107 @override |
| 115 Object visitClassDeclaration(ClassDeclaration node) { | 108 Object visitClassDeclaration(ClassDeclaration node) { |
| 116 ClassElement outerClass = _enclosingClass; | 109 ClassElement outerClass = _enclosingClass; |
| 117 try { | 110 try { |
| 118 SimpleIdentifier className = node.name; | 111 SimpleIdentifier className = node.name; |
| 119 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); | 112 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 120 processElement(_enclosingClass); | 113 _processElement(_enclosingClass); |
| 121 if (!_hasConstructor(node)) { | 114 if (!_hasConstructor(node)) { |
| 122 ConstructorElement constructor = _enclosingClass.unnamedConstructor; | 115 ConstructorElement constructor = _enclosingClass.unnamedConstructor; |
| 123 if (constructor.isSynthetic) { | 116 if (constructor.isSynthetic) { |
| 124 processElement(constructor); | 117 _processElement(constructor); |
| 125 } | 118 } |
| 126 } | 119 } |
| 127 return super.visitClassDeclaration(node); | 120 return super.visitClassDeclaration(node); |
| 128 } finally { | 121 } finally { |
| 129 _enclosingClass = outerClass; | 122 _enclosingClass = outerClass; |
| 130 } | 123 } |
| 131 } | 124 } |
| 132 | 125 |
| 133 @override | 126 @override |
| 134 Object visitClassTypeAlias(ClassTypeAlias node) { | 127 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 135 ClassElement outerClass = _enclosingClass; | 128 ClassElement outerClass = _enclosingClass; |
| 136 try { | 129 try { |
| 137 SimpleIdentifier className = node.name; | 130 SimpleIdentifier className = node.name; |
| 138 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); | 131 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 139 processElement(_enclosingClass); | 132 _processElement(_enclosingClass); |
| 140 return super.visitClassTypeAlias(node); | 133 return super.visitClassTypeAlias(node); |
| 141 } finally { | 134 } finally { |
| 142 _enclosingClass = outerClass; | 135 _enclosingClass = outerClass; |
| 143 } | 136 } |
| 144 } | 137 } |
| 145 | 138 |
| 146 @override | 139 @override |
| 147 Object visitCompilationUnit(CompilationUnit node) { | 140 Object visitCompilationUnit(CompilationUnit node) { |
| 148 processElement(_enclosingUnit); | 141 _processElement(_enclosingUnit); |
| 149 return super.visitCompilationUnit(node); | 142 return super.visitCompilationUnit(node); |
| 150 } | 143 } |
| 151 | 144 |
| 152 @override | 145 @override |
| 153 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 146 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 154 ExecutableElement outerExecutable = _enclosingExecutable; | 147 ExecutableElement outerExecutable = _enclosingExecutable; |
| 155 try { | 148 try { |
| 156 SimpleIdentifier constructorName = node.name; | 149 SimpleIdentifier constructorName = node.name; |
| 157 if (constructorName == null) { | 150 if (constructorName == null) { |
| 158 _enclosingExecutable = _enclosingClass.unnamedConstructor; | 151 _enclosingExecutable = _enclosingClass.unnamedConstructor; |
| 159 } else { | 152 } else { |
| 160 _enclosingExecutable = | 153 _enclosingExecutable = |
| 161 _enclosingClass.getNamedConstructor(constructorName.name); | 154 _enclosingClass.getNamedConstructor(constructorName.name); |
| 162 } | 155 } |
| 163 processElement(_enclosingExecutable); | 156 _processElement(_enclosingExecutable); |
| 164 return super.visitConstructorDeclaration(node); | 157 return super.visitConstructorDeclaration(node); |
| 165 } finally { | 158 } finally { |
| 166 _enclosingExecutable = outerExecutable; | 159 _enclosingExecutable = outerExecutable; |
| 167 } | 160 } |
| 168 } | 161 } |
| 169 | 162 |
| 170 @override | 163 @override |
| 171 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 164 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 172 SimpleIdentifier variableName = node.identifier; | 165 SimpleIdentifier variableName = node.identifier; |
| 173 LocalVariableElement element = | 166 LocalVariableElement element = |
| 174 _findIdentifier(_enclosingExecutable.localVariables, variableName); | 167 _findIdentifier(_enclosingExecutable.localVariables, variableName); |
| 175 processElement(element); | 168 _processElement(element); |
| 176 return super.visitDeclaredIdentifier(node); | 169 return super.visitDeclaredIdentifier(node); |
| 177 } | 170 } |
| 178 | 171 |
| 179 @override | 172 @override |
| 180 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 173 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 181 SimpleIdentifier parameterName = node.parameter.identifier; | 174 SimpleIdentifier parameterName = node.parameter.identifier; |
| 182 ParameterElement element = _getElementForParameter(node, parameterName); | 175 ParameterElement element = _getElementForParameter(node, parameterName); |
| 183 Expression defaultValue = node.defaultValue; | 176 Expression defaultValue = node.defaultValue; |
| 184 if (defaultValue != null) { | 177 if (defaultValue != null) { |
| 185 ExecutableElement outerExecutable = _enclosingExecutable; | 178 ExecutableElement outerExecutable = _enclosingExecutable; |
| 186 try { | 179 try { |
| 187 if (element == null) { | 180 if (element == null) { |
| 188 // TODO(brianwilkerson) Report this internal error. | 181 // TODO(brianwilkerson) Report this internal error. |
| 189 } else { | 182 } else { |
| 190 _enclosingExecutable = element.initializer; | 183 _enclosingExecutable = element.initializer; |
| 191 } | 184 } |
| 192 defaultValue.accept(this); | 185 defaultValue.accept(this); |
| 193 } finally { | 186 } finally { |
| 194 _enclosingExecutable = outerExecutable; | 187 _enclosingExecutable = outerExecutable; |
| 195 } | 188 } |
| 196 processElement(_enclosingExecutable); | 189 _processElement(_enclosingExecutable); |
| 197 } | 190 } |
| 198 ParameterElement outerParameter = _enclosingParameter; | 191 ParameterElement outerParameter = _enclosingParameter; |
| 199 try { | 192 try { |
| 200 _enclosingParameter = element; | 193 _enclosingParameter = element; |
| 201 processElement(_enclosingParameter); | 194 _processElement(_enclosingParameter); |
| 202 return super.visitDefaultFormalParameter(node); | 195 return super.visitDefaultFormalParameter(node); |
| 203 } finally { | 196 } finally { |
| 204 _enclosingParameter = outerParameter; | 197 _enclosingParameter = outerParameter; |
| 205 } | 198 } |
| 206 } | 199 } |
| 207 | 200 |
| 208 @override | 201 @override |
| 209 Object visitEnumDeclaration(EnumDeclaration node) { | 202 Object visitEnumDeclaration(EnumDeclaration node) { |
| 210 ClassElement enclosingEnum = | 203 ClassElement enclosingEnum = |
| 211 _findIdentifier(_enclosingUnit.enums, node.name); | 204 _findIdentifier(_enclosingUnit.enums, node.name); |
| 212 processElement(enclosingEnum); | 205 _processElement(enclosingEnum); |
| 213 List<FieldElement> constants = enclosingEnum.fields; | 206 List<FieldElement> constants = enclosingEnum.fields; |
| 214 for (EnumConstantDeclaration constant in node.constants) { | 207 for (EnumConstantDeclaration constant in node.constants) { |
| 215 FieldElement constantElement = _findIdentifier(constants, constant.name); | 208 FieldElement constantElement = _findIdentifier(constants, constant.name); |
| 216 processElement(constantElement); | 209 _processElement(constantElement); |
| 217 } | 210 } |
| 218 return super.visitEnumDeclaration(node); | 211 return super.visitEnumDeclaration(node); |
| 219 } | 212 } |
| 220 | 213 |
| 221 @override | 214 @override |
| 222 Object visitExportDirective(ExportDirective node) { | 215 Object visitExportDirective(ExportDirective node) { |
| 223 String uri = _getStringValue(node.uri); | 216 String uri = _getStringValue(node.uri); |
| 224 if (uri != null) { | 217 if (uri != null) { |
| 225 LibraryElement library = _enclosingUnit.library; | 218 LibraryElement library = _enclosingUnit.library; |
| 226 ExportElement exportElement = _findExport( | 219 ExportElement exportElement = _findExport( |
| 227 library.exports, | 220 library.exports, |
| 228 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri)); | 221 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri)); |
| 229 processElement(exportElement); | 222 _processElement(exportElement); |
| 230 } | 223 } |
| 231 return super.visitExportDirective(node); | 224 return super.visitExportDirective(node); |
| 232 } | 225 } |
| 233 | 226 |
| 234 @override | 227 @override |
| 235 Object visitFieldFormalParameter(FieldFormalParameter node) { | 228 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 236 if (node.parent is! DefaultFormalParameter) { | 229 if (node.parent is! DefaultFormalParameter) { |
| 237 SimpleIdentifier parameterName = node.identifier; | 230 SimpleIdentifier parameterName = node.identifier; |
| 238 ParameterElement element = _getElementForParameter(node, parameterName); | 231 ParameterElement element = _getElementForParameter(node, parameterName); |
| 239 ParameterElement outerParameter = _enclosingParameter; | 232 ParameterElement outerParameter = _enclosingParameter; |
| 240 try { | 233 try { |
| 241 _enclosingParameter = element; | 234 _enclosingParameter = element; |
| 242 processElement(_enclosingParameter); | 235 _processElement(_enclosingParameter); |
| 243 return super.visitFieldFormalParameter(node); | 236 return super.visitFieldFormalParameter(node); |
| 244 } finally { | 237 } finally { |
| 245 _enclosingParameter = outerParameter; | 238 _enclosingParameter = outerParameter; |
| 246 } | 239 } |
| 247 } else { | 240 } else { |
| 248 return super.visitFieldFormalParameter(node); | 241 return super.visitFieldFormalParameter(node); |
| 249 } | 242 } |
| 250 } | 243 } |
| 251 | 244 |
| 252 @override | 245 @override |
| (...skipping 11 matching lines...) Expand all Loading... |
| 264 _findIdentifier(_enclosingUnit.functions, functionName); | 257 _findIdentifier(_enclosingUnit.functions, functionName); |
| 265 } | 258 } |
| 266 } else { | 259 } else { |
| 267 PropertyAccessorElement accessor = | 260 PropertyAccessorElement accessor = |
| 268 _findIdentifier(_enclosingUnit.accessors, functionName); | 261 _findIdentifier(_enclosingUnit.accessors, functionName); |
| 269 if ((property as KeywordToken).keyword == Keyword.SET) { | 262 if ((property as KeywordToken).keyword == Keyword.SET) { |
| 270 accessor = accessor.variable.setter; | 263 accessor = accessor.variable.setter; |
| 271 } | 264 } |
| 272 _enclosingExecutable = accessor; | 265 _enclosingExecutable = accessor; |
| 273 } | 266 } |
| 274 processElement(_enclosingExecutable); | 267 _processElement(_enclosingExecutable); |
| 275 return super.visitFunctionDeclaration(node); | 268 return super.visitFunctionDeclaration(node); |
| 276 } finally { | 269 } finally { |
| 277 _enclosingExecutable = outerExecutable; | 270 _enclosingExecutable = outerExecutable; |
| 278 } | 271 } |
| 279 } | 272 } |
| 280 | 273 |
| 281 @override | 274 @override |
| 282 Object visitFunctionExpression(FunctionExpression node) { | 275 Object visitFunctionExpression(FunctionExpression node) { |
| 283 if (node.parent is! FunctionDeclaration) { | 276 if (node.parent is! FunctionDeclaration) { |
| 284 FunctionElement element = | 277 FunctionElement element = |
| 285 _findAtOffset(_enclosingExecutable.functions, node.beginToken.offset); | 278 _findAtOffset(_enclosingExecutable.functions, node.beginToken.offset); |
| 286 processElement(element); | 279 _processElement(element); |
| 287 } | 280 } |
| 288 ExecutableElement outerExecutable = _enclosingExecutable; | 281 ExecutableElement outerExecutable = _enclosingExecutable; |
| 289 try { | 282 try { |
| 290 _enclosingExecutable = node.element; | 283 _enclosingExecutable = node.element; |
| 291 processElement(_enclosingExecutable); | 284 _processElement(_enclosingExecutable); |
| 292 return super.visitFunctionExpression(node); | 285 return super.visitFunctionExpression(node); |
| 293 } finally { | 286 } finally { |
| 294 _enclosingExecutable = outerExecutable; | 287 _enclosingExecutable = outerExecutable; |
| 295 } | 288 } |
| 296 } | 289 } |
| 297 | 290 |
| 298 @override | 291 @override |
| 299 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 292 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 300 FunctionTypeAliasElement outerAlias = _enclosingAlias; | 293 FunctionTypeAliasElement outerAlias = _enclosingAlias; |
| 301 try { | 294 try { |
| 302 SimpleIdentifier aliasName = node.name; | 295 SimpleIdentifier aliasName = node.name; |
| 303 _enclosingAlias = | 296 _enclosingAlias = |
| 304 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); | 297 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); |
| 305 processElement(_enclosingAlias); | 298 _processElement(_enclosingAlias); |
| 306 return super.visitFunctionTypeAlias(node); | 299 return super.visitFunctionTypeAlias(node); |
| 307 } finally { | 300 } finally { |
| 308 _enclosingAlias = outerAlias; | 301 _enclosingAlias = outerAlias; |
| 309 } | 302 } |
| 310 } | 303 } |
| 311 | 304 |
| 312 @override | 305 @override |
| 313 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 306 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 314 if (node.parent is! DefaultFormalParameter) { | 307 if (node.parent is! DefaultFormalParameter) { |
| 315 SimpleIdentifier parameterName = node.identifier; | 308 SimpleIdentifier parameterName = node.identifier; |
| 316 ParameterElement element = _getElementForParameter(node, parameterName); | 309 ParameterElement element = _getElementForParameter(node, parameterName); |
| 317 ParameterElement outerParameter = _enclosingParameter; | 310 ParameterElement outerParameter = _enclosingParameter; |
| 318 try { | 311 try { |
| 319 _enclosingParameter = element; | 312 _enclosingParameter = element; |
| 320 processElement(_enclosingParameter); | 313 _processElement(_enclosingParameter); |
| 321 return super.visitFunctionTypedFormalParameter(node); | 314 return super.visitFunctionTypedFormalParameter(node); |
| 322 } finally { | 315 } finally { |
| 323 _enclosingParameter = outerParameter; | 316 _enclosingParameter = outerParameter; |
| 324 } | 317 } |
| 325 } else { | 318 } else { |
| 326 return super.visitFunctionTypedFormalParameter(node); | 319 return super.visitFunctionTypedFormalParameter(node); |
| 327 } | 320 } |
| 328 } | 321 } |
| 329 | 322 |
| 330 @override | 323 @override |
| 331 Object visitImportDirective(ImportDirective node) { | 324 Object visitImportDirective(ImportDirective node) { |
| 332 String uri = _getStringValue(node.uri); | 325 String uri = _getStringValue(node.uri); |
| 333 if (uri != null) { | 326 if (uri != null) { |
| 334 LibraryElement library = _enclosingUnit.library; | 327 LibraryElement library = _enclosingUnit.library; |
| 335 ImportElement importElement = _findImport( | 328 ImportElement importElement = _findImport( |
| 336 library.imports, | 329 library.imports, |
| 337 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri), | 330 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri), |
| 338 node.prefix); | 331 node.prefix); |
| 339 processElement(importElement); | 332 _processElement(importElement); |
| 340 } | 333 } |
| 341 return super.visitImportDirective(node); | 334 return super.visitImportDirective(node); |
| 342 } | 335 } |
| 343 | 336 |
| 344 @override | 337 @override |
| 345 Object visitLabeledStatement(LabeledStatement node) { | 338 Object visitLabeledStatement(LabeledStatement node) { |
| 346 for (Label label in node.labels) { | 339 for (Label label in node.labels) { |
| 347 SimpleIdentifier labelName = label.label; | 340 SimpleIdentifier labelName = label.label; |
| 348 LabelElement element = | 341 LabelElement element = |
| 349 _findIdentifier(_enclosingExecutable.labels, labelName); | 342 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 350 processElement(element); | 343 _processElement(element); |
| 351 } | 344 } |
| 352 return super.visitLabeledStatement(node); | 345 return super.visitLabeledStatement(node); |
| 353 } | 346 } |
| 354 | 347 |
| 355 @override | 348 @override |
| 356 Object visitMethodDeclaration(MethodDeclaration node) { | 349 Object visitMethodDeclaration(MethodDeclaration node) { |
| 357 ExecutableElement outerExecutable = _enclosingExecutable; | 350 ExecutableElement outerExecutable = _enclosingExecutable; |
| 358 try { | 351 try { |
| 359 Token property = node.propertyKeyword; | 352 Token property = node.propertyKeyword; |
| 360 SimpleIdentifier methodName = node.name; | 353 SimpleIdentifier methodName = node.name; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 371 methodName.staticElement = _enclosingExecutable; | 364 methodName.staticElement = _enclosingExecutable; |
| 372 } else { | 365 } else { |
| 373 PropertyAccessorElement accessor = | 366 PropertyAccessorElement accessor = |
| 374 _findIdentifier(_enclosingClass.accessors, methodName); | 367 _findIdentifier(_enclosingClass.accessors, methodName); |
| 375 if ((property as KeywordToken).keyword == Keyword.SET) { | 368 if ((property as KeywordToken).keyword == Keyword.SET) { |
| 376 accessor = accessor.variable.setter; | 369 accessor = accessor.variable.setter; |
| 377 methodName.staticElement = accessor; | 370 methodName.staticElement = accessor; |
| 378 } | 371 } |
| 379 _enclosingExecutable = accessor; | 372 _enclosingExecutable = accessor; |
| 380 } | 373 } |
| 381 processElement(_enclosingExecutable); | 374 _processElement(_enclosingExecutable); |
| 382 return super.visitMethodDeclaration(node); | 375 return super.visitMethodDeclaration(node); |
| 383 } finally { | 376 } finally { |
| 384 _enclosingExecutable = outerExecutable; | 377 _enclosingExecutable = outerExecutable; |
| 385 } | 378 } |
| 386 } | 379 } |
| 387 | 380 |
| 388 @override | 381 @override |
| 389 Object visitPartDirective(PartDirective node) { | 382 Object visitPartDirective(PartDirective node) { |
| 390 String uri = _getStringValue(node.uri); | 383 String uri = _getStringValue(node.uri); |
| 391 if (uri != null) { | 384 if (uri != null) { |
| 392 Source partSource = | 385 Source partSource = |
| 393 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri); | 386 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri); |
| 394 CompilationUnitElement element = | 387 CompilationUnitElement element = |
| 395 _findPart(_enclosingUnit.library.parts, partSource); | 388 _findPart(_enclosingUnit.library.parts, partSource); |
| 396 processElement(element); | 389 _processElement(element); |
| 397 } | 390 } |
| 398 return super.visitPartDirective(node); | 391 return super.visitPartDirective(node); |
| 399 } | 392 } |
| 400 | 393 |
| 401 @override | 394 @override |
| 402 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 395 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 403 if (node.parent is! DefaultFormalParameter) { | 396 if (node.parent is! DefaultFormalParameter) { |
| 404 SimpleIdentifier parameterName = node.identifier; | 397 SimpleIdentifier parameterName = node.identifier; |
| 405 ParameterElement element = _getElementForParameter(node, parameterName); | 398 ParameterElement element = _getElementForParameter(node, parameterName); |
| 406 ParameterElement outerParameter = _enclosingParameter; | 399 ParameterElement outerParameter = _enclosingParameter; |
| 407 try { | 400 try { |
| 408 _enclosingParameter = element; | 401 _enclosingParameter = element; |
| 409 processElement(_enclosingParameter); | 402 _processElement(_enclosingParameter); |
| 410 return super.visitSimpleFormalParameter(node); | 403 return super.visitSimpleFormalParameter(node); |
| 411 } finally { | 404 } finally { |
| 412 _enclosingParameter = outerParameter; | 405 _enclosingParameter = outerParameter; |
| 413 } | 406 } |
| 414 } else { | 407 } else { |
| 415 } | 408 } |
| 416 return super.visitSimpleFormalParameter(node); | 409 return super.visitSimpleFormalParameter(node); |
| 417 } | 410 } |
| 418 | 411 |
| 419 @override | 412 @override |
| 420 Object visitSwitchCase(SwitchCase node) { | 413 Object visitSwitchCase(SwitchCase node) { |
| 421 for (Label label in node.labels) { | 414 for (Label label in node.labels) { |
| 422 SimpleIdentifier labelName = label.label; | 415 SimpleIdentifier labelName = label.label; |
| 423 LabelElement element = | 416 LabelElement element = |
| 424 _findIdentifier(_enclosingExecutable.labels, labelName); | 417 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 425 processElement(element); | 418 _processElement(element); |
| 426 } | 419 } |
| 427 return super.visitSwitchCase(node); | 420 return super.visitSwitchCase(node); |
| 428 } | 421 } |
| 429 | 422 |
| 430 @override | 423 @override |
| 431 Object visitSwitchDefault(SwitchDefault node) { | 424 Object visitSwitchDefault(SwitchDefault node) { |
| 432 for (Label label in node.labels) { | 425 for (Label label in node.labels) { |
| 433 SimpleIdentifier labelName = label.label; | 426 SimpleIdentifier labelName = label.label; |
| 434 LabelElement element = | 427 LabelElement element = |
| 435 _findIdentifier(_enclosingExecutable.labels, labelName); | 428 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 436 processElement(element); | 429 _processElement(element); |
| 437 } | 430 } |
| 438 return super.visitSwitchDefault(node); | 431 return super.visitSwitchDefault(node); |
| 439 } | 432 } |
| 440 | 433 |
| 441 @override | 434 @override |
| 435 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 436 _inTopLevelVariableDeclaration = true; |
| 437 try { |
| 438 return super.visitTopLevelVariableDeclaration(node); |
| 439 } finally { |
| 440 _inTopLevelVariableDeclaration = false; |
| 441 } |
| 442 } |
| 443 |
| 444 @override |
| 442 Object visitTypeParameter(TypeParameter node) { | 445 Object visitTypeParameter(TypeParameter node) { |
| 443 SimpleIdentifier parameterName = node.name; | 446 SimpleIdentifier parameterName = node.name; |
| 444 TypeParameterElement element = null; | 447 TypeParameterElement element = null; |
| 445 if (_enclosingClass != null) { | 448 if (_enclosingClass != null) { |
| 446 element = _findIdentifier(_enclosingClass.typeParameters, parameterName); | 449 element = _findIdentifier(_enclosingClass.typeParameters, parameterName); |
| 447 } else if (_enclosingAlias != null) { | 450 } else if (_enclosingAlias != null) { |
| 448 element = _findIdentifier(_enclosingAlias.typeParameters, parameterName); | 451 element = _findIdentifier(_enclosingAlias.typeParameters, parameterName); |
| 449 } | 452 } |
| 450 processElement(element); | 453 _processElement(element); |
| 451 return super.visitTypeParameter(node); | 454 return super.visitTypeParameter(node); |
| 452 } | 455 } |
| 453 | 456 |
| 454 @override | 457 @override |
| 455 Object visitVariableDeclaration(VariableDeclaration node) { | 458 Object visitVariableDeclaration(VariableDeclaration node) { |
| 456 VariableElement element = null; | 459 String name = node.name.name; |
| 457 SimpleIdentifier variableName = node.name; | 460 if (_inTopLevelVariableDeclaration) { |
| 461 TopLevelVariableElement variable = |
| 462 _findElement(_enclosingUnit.topLevelVariables, name); |
| 463 _assertNotNull(variable); |
| 464 _assertFalse(variable.isSynthetic); |
| 465 _assertEquals(node.isConst, variable.isConst); |
| 466 _assertEquals(node.isFinal, variable.isFinal); |
| 467 _assertSameType( |
| 468 (node.parent as VariableDeclarationList).type, |
| 469 variable.type); |
| 470 _processElement(variable); |
| 471 return null; |
| 472 } |
| 473 VariableElement element; |
| 458 if (_enclosingExecutable != null) { | 474 if (_enclosingExecutable != null) { |
| 459 element = | 475 element = _findElement(_enclosingExecutable.localVariables, name); |
| 460 _findIdentifier(_enclosingExecutable.localVariables, variableName); | |
| 461 } | 476 } |
| 462 if (element == null && _enclosingClass != null) { | 477 if (element == null && _enclosingClass != null) { |
| 463 element = _findIdentifier(_enclosingClass.fields, variableName); | 478 element = _findElement(_enclosingClass.fields, name); |
| 464 } | |
| 465 if (element == null && _enclosingUnit != null) { | |
| 466 element = _findIdentifier(_enclosingUnit.topLevelVariables, variableName); | |
| 467 } | |
| 468 Expression initializer = node.initializer; | |
| 469 if (initializer != null) { | |
| 470 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 471 try { | |
| 472 if (element == null) { | |
| 473 // TODO(brianwilkerson) Report this internal error. | |
| 474 } else { | |
| 475 _enclosingExecutable = element.initializer; | |
| 476 } | |
| 477 processElement(element); | |
| 478 processElement(_enclosingExecutable); | |
| 479 return super.visitVariableDeclaration(node); | |
| 480 } finally { | |
| 481 _enclosingExecutable = outerExecutable; | |
| 482 } | |
| 483 } | 479 } |
| 484 return super.visitVariableDeclaration(node); | 480 return super.visitVariableDeclaration(node); |
| 485 } | 481 } |
| 486 | 482 |
| 483 void _assertSameType(TypeName node, DartType type) { |
| 484 String nodeName = node.name.name; |
| 485 if (type is InterfaceType) { |
| 486 _assertEquals(nodeName, type.name); |
| 487 TypeArgumentList nodeArgumentList = node.typeArguments; |
| 488 List<DartType> typeArguments = type.typeArguments; |
| 489 if (nodeArgumentList == null) { |
| 490 _assertTrue(typeArguments.isEmpty); |
| 491 } else { |
| 492 List<TypeName> nodeArguments = nodeArgumentList.arguments; |
| 493 int numArguments = nodeArguments.length; |
| 494 _assertEquals(numArguments, typeArguments.length); |
| 495 for (int i = 0; i < numArguments; i++) { |
| 496 _assertSameType(nodeArguments[i], typeArguments[i]); |
| 497 } |
| 498 } |
| 499 } else { |
| 500 // TODO(scheglov) support other types |
| 501 _assertTrue(false); |
| 502 } |
| 503 } |
| 504 |
| 505 void _assertFalse(bool condition) { |
| 506 if (condition) { |
| 507 throw new _DeclarationMismatchException(); |
| 508 } |
| 509 } |
| 510 |
| 511 void _assertNotNull(Element element) { |
| 512 if (element == null) { |
| 513 throw new _DeclarationMismatchException(); |
| 514 } |
| 515 } |
| 516 |
| 517 void _assertEquals(Object a, Object b) { |
| 518 if (a != b) { |
| 519 throw new _DeclarationMismatchException(); |
| 520 } |
| 521 } |
| 522 |
| 523 void _assertTrue(bool condition) { |
| 524 if (!condition) { |
| 525 throw new _DeclarationMismatchException(); |
| 526 } |
| 527 } |
| 528 |
| 487 /** | 529 /** |
| 488 * Given that the comparison is to begin with the given element, capture the e
nclosing elements | 530 * Given that the comparison is to begin with the given element, capture the e
nclosing elements |
| 489 * that might be used while performing the comparison. | 531 * that might be used while performing the comparison. |
| 490 * | 532 * |
| 491 * @param element the element corresponding to the AST structure to be compare
d | 533 * @param element the element corresponding to the AST structure to be compare
d |
| 492 */ | 534 */ |
| 493 void _captureEnclosingElements(Element element) { | 535 void _captureEnclosingElements(Element element) { |
| 494 Element parent = | 536 Element parent = |
| 495 element is CompilationUnitElement ? element : element.enclosingElement; | 537 element is CompilationUnitElement ? element : element.enclosingElement; |
| 496 while (parent != null) { | 538 while (parent != null) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 522 * given offset. This method should only be used when there is no name | 564 * given offset. This method should only be used when there is no name |
| 523 * | 565 * |
| 524 * @param elements the elements of the appropriate kind that exist in the curr
ent context | 566 * @param elements the elements of the appropriate kind that exist in the curr
ent context |
| 525 * @param offset the offset of the name of the element to be returned | 567 * @param offset the offset of the name of the element to be returned |
| 526 * @return the element at the given offset | 568 * @return the element at the given offset |
| 527 */ | 569 */ |
| 528 Element _findAtOffset(List<Element> elements, int offset) => | 570 Element _findAtOffset(List<Element> elements, int offset) => |
| 529 _findWithNameAndOffset(elements, "", offset); | 571 _findWithNameAndOffset(elements, "", offset); |
| 530 | 572 |
| 531 /** | 573 /** |
| 574 * Return the [Element] in [elements] with the given [name]. |
| 575 */ |
| 576 Element _findElement(List<Element> elements, String name) { |
| 577 for (Element element in elements) { |
| 578 if (element.displayName == name) { |
| 579 return element; |
| 580 } |
| 581 } |
| 582 return null; |
| 583 } |
| 584 |
| 585 /** |
| 532 * Return the export element from the given array whose library has the given
source, or | 586 * Return the export element from the given array whose library has the given
source, or |
| 533 * `null` if there is no such export. | 587 * `null` if there is no such export. |
| 534 * | 588 * |
| 535 * @param exports the export elements being searched | 589 * @param exports the export elements being searched |
| 536 * @param source the source of the library associated with the export element
to being searched | 590 * @param source the source of the library associated with the export element
to being searched |
| 537 * for | 591 * for |
| 538 * @return the export element whose library has the given source | 592 * @return the export element whose library has the given source |
| 539 */ | 593 */ |
| 540 ExportElement _findExport(List<ExportElement> exports, Source source) { | 594 ExportElement _findExport(List<ExportElement> exports, Source source) { |
| 541 for (ExportElement export in exports) { | 595 for (ExportElement export in exports) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 * @return `true` if the class defines at least one constructor | 728 * @return `true` if the class defines at least one constructor |
| 675 */ | 729 */ |
| 676 bool _hasConstructor(ClassDeclaration node) { | 730 bool _hasConstructor(ClassDeclaration node) { |
| 677 for (ClassMember member in node.members) { | 731 for (ClassMember member in node.members) { |
| 678 if (member is ConstructorDeclaration) { | 732 if (member is ConstructorDeclaration) { |
| 679 return true; | 733 return true; |
| 680 } | 734 } |
| 681 } | 735 } |
| 682 return false; | 736 return false; |
| 683 } | 737 } |
| 738 |
| 739 void _processElement(Element element) { |
| 740 _assertNotNull(element); |
| 741 if (!_allElements.contains(element)) { |
| 742 throw new _DeclarationMismatchException(); |
| 743 } |
| 744 bool did = _unmatchedElements.remove(element); |
| 745 print('remove: $element | $did'); |
| 746 } |
| 684 } | 747 } |
| 685 | 748 |
| 686 | 749 |
| 687 /** | 750 /** |
| 688 * Instances of the class [IncrementalResolver] resolve the smallest portion of | 751 * Instances of the class [IncrementalResolver] resolve the smallest portion of |
| 689 * an AST structure that we currently know how to resolve. | 752 * an AST structure that we currently know how to resolve. |
| 690 */ | 753 */ |
| 691 class IncrementalResolver { | 754 class IncrementalResolver { |
| 692 /** | 755 /** |
| 693 * The element for the library containing the compilation unit being visited. | 756 * The element for the library containing the compilation unit being visited. |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 } | 1043 } |
| 981 | 1044 |
| 982 | 1045 |
| 983 class _ElementsGatherer extends GeneralizingElementVisitor { | 1046 class _ElementsGatherer extends GeneralizingElementVisitor { |
| 984 final DeclarationMatcher matcher; | 1047 final DeclarationMatcher matcher; |
| 985 | 1048 |
| 986 _ElementsGatherer(this.matcher); | 1049 _ElementsGatherer(this.matcher); |
| 987 | 1050 |
| 988 @override | 1051 @override |
| 989 visitElement(Element element) { | 1052 visitElement(Element element) { |
| 990 matcher._allElements.add(element); | 1053 _addElement(element); |
| 991 matcher._unmatchedElements.add(element); | |
| 992 super.visitElement(element); | 1054 super.visitElement(element); |
| 993 } | 1055 } |
| 1056 |
| 1057 @override |
| 1058 visitPropertyAccessorElement(PropertyAccessorElement element) { |
| 1059 if (!element.isSynthetic) { |
| 1060 _addElement(element); |
| 1061 } |
| 1062 // Don't visit children (such as a synthetic setter parameter). |
| 1063 } |
| 1064 |
| 1065 @override |
| 1066 visitPropertyInducingElement(PropertyInducingElement element) { |
| 1067 // TODO(scheglov) should we remove synthetic variable initializer? |
| 1068 // _addElement(element); |
| 1069 // element.getter.accept(this); |
| 1070 // element.setter.accept(this); |
| 1071 // _addElement(element.getter); |
| 1072 // _addElement(element.setter); |
| 1073 } |
| 1074 |
| 1075 @override |
| 1076 visitTopLevelVariableElement(TopLevelVariableElement element) { |
| 1077 if (!element.isSynthetic) { |
| 1078 _addElement(element); |
| 1079 } |
| 1080 } |
| 1081 |
| 1082 void _addElement(Element element) { |
| 1083 if (element != null) { |
| 1084 matcher._allElements.add(element); |
| 1085 matcher._unmatchedElements.add(element); |
| 1086 } |
| 1087 } |
| 994 } | 1088 } |
| OLD | NEW |