| 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.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 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 18 matching lines...) Expand all Loading... |
| 29 import 'package:analyzer/src/generated/source.dart'; | 29 import 'package:analyzer/src/generated/source.dart'; |
| 30 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | 30 import 'package:analyzer/src/generated/static_type_analyzer.dart'; |
| 31 import 'package:analyzer/src/generated/type_system.dart'; | 31 import 'package:analyzer/src/generated/type_system.dart'; |
| 32 import 'package:analyzer/src/generated/utilities_dart.dart'; | 32 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 33 import 'package:analyzer/src/task/strong/info.dart' | 33 import 'package:analyzer/src/task/strong/info.dart' |
| 34 show InferredType, StaticInfo; | 34 show InferredType, StaticInfo; |
| 35 | 35 |
| 36 export 'package:analyzer/src/generated/type_system.dart'; | 36 export 'package:analyzer/src/generated/type_system.dart'; |
| 37 | 37 |
| 38 /** | 38 /** |
| 39 * Throw an [ElementMismatchException] to report that the element model and the |
| 40 * AST do not match. The [message] will have the path to the given [node] |
| 41 * appended to it. |
| 42 */ |
| 43 void _mismatch(String message, AstNode node) { |
| 44 StringBuffer buffer = new StringBuffer(); |
| 45 buffer.writeln(message); |
| 46 buffer.write('Path to root:'); |
| 47 String separator = ' '; |
| 48 AstNode parent = node; |
| 49 while (parent != null) { |
| 50 buffer.write(separator); |
| 51 buffer.write(parent.runtimeType.toString()); |
| 52 separator = ', '; |
| 53 parent = parent.parent; |
| 54 } |
| 55 throw new ElementMismatchException(buffer.toString()); |
| 56 } |
| 57 |
| 58 /** |
| 39 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for | 59 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for |
| 40 * violations of Dart best practices. | 60 * violations of Dart best practices. |
| 41 */ | 61 */ |
| 42 class BestPracticesVerifier extends RecursiveAstVisitor<Object> { | 62 class BestPracticesVerifier extends RecursiveAstVisitor<Object> { |
| 43 // static String _HASHCODE_GETTER_NAME = "hashCode"; | 63 // static String _HASHCODE_GETTER_NAME = "hashCode"; |
| 44 | 64 |
| 45 static String _NULL_TYPE_NAME = "Null"; | 65 static String _NULL_TYPE_NAME = "Null"; |
| 46 | 66 |
| 47 static String _TO_INT_METHOD_NAME = "toInt"; | 67 static String _TO_INT_METHOD_NAME = "toInt"; |
| 48 | 68 |
| (...skipping 2063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2112 void _safelyVisit(AstNode node) { | 2132 void _safelyVisit(AstNode node) { |
| 2113 if (node != null) { | 2133 if (node != null) { |
| 2114 node.accept(this); | 2134 node.accept(this); |
| 2115 } | 2135 } |
| 2116 } | 2136 } |
| 2117 } | 2137 } |
| 2118 | 2138 |
| 2119 /** | 2139 /** |
| 2120 * A visitor that resolves declarations in an AST structure to already built | 2140 * A visitor that resolves declarations in an AST structure to already built |
| 2121 * elements. | 2141 * elements. |
| 2142 * |
| 2143 * The resulting AST must have everything resolved that would have been resolved |
| 2144 * by a [CompilationUnitBuilder] (that is, must be a valid [RESOLVED_UNIT1]). |
| 2145 * This class must not assume that the [CompilationUnitElement] passed to it is |
| 2146 * any more complete than a [COMPILATION_UNIT_ELEMENT]. |
| 2122 */ | 2147 */ |
| 2123 class DeclarationResolver extends RecursiveAstVisitor<Object> { | 2148 class DeclarationResolver extends RecursiveAstVisitor<Object> { |
| 2124 /** | 2149 /** |
| 2125 * The analysis context containing the sources to be analyzed. | 2150 * The analysis context containing the sources to be analyzed. |
| 2126 */ | 2151 */ |
| 2127 AnalysisContext _context; | 2152 AnalysisContext _context; |
| 2128 | 2153 |
| 2129 /** | 2154 /** |
| 2130 * The elements that are reachable from the compilation unit element. When a | 2155 * The elements that are reachable from the compilation unit element. When a |
| 2131 * compilation unit has been resolved, this set should be empty. | 2156 * compilation unit has been resolved, this set should be empty. |
| 2132 */ | 2157 */ |
| 2133 Set<Element> _expectedElements; | 2158 Set<Element> _expectedElements; |
| 2134 | 2159 |
| 2135 /** | 2160 /** |
| 2136 * The compilation unit containing the AST nodes being visited. | 2161 * The compilation unit containing the AST nodes being visited. |
| 2137 */ | 2162 */ |
| 2138 CompilationUnitElement _enclosingUnit; | 2163 CompilationUnitElementImpl _enclosingUnit; |
| 2139 | 2164 |
| 2140 /** | 2165 /** |
| 2141 * The function type alias containing the AST nodes being visited, or `null` | 2166 * The function type alias containing the AST nodes being visited, or `null` |
| 2142 * if we are not in the scope of a function type alias. | 2167 * if we are not in the scope of a function type alias. |
| 2143 */ | 2168 */ |
| 2144 FunctionTypeAliasElement _enclosingAlias; | 2169 FunctionTypeAliasElement _enclosingAlias; |
| 2145 | 2170 |
| 2146 /** | 2171 /** |
| 2147 * The class containing the AST nodes being visited, or `null` if we are not | 2172 * The class containing the AST nodes being visited, or `null` if we are not |
| 2148 * in the scope of a class. | 2173 * in the scope of a class. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2193 return super.visitCatchClause(node); | 2218 return super.visitCatchClause(node); |
| 2194 } | 2219 } |
| 2195 | 2220 |
| 2196 @override | 2221 @override |
| 2197 Object visitClassDeclaration(ClassDeclaration node) { | 2222 Object visitClassDeclaration(ClassDeclaration node) { |
| 2198 ClassElement outerClass = _enclosingClass; | 2223 ClassElement outerClass = _enclosingClass; |
| 2199 try { | 2224 try { |
| 2200 SimpleIdentifier className = node.name; | 2225 SimpleIdentifier className = node.name; |
| 2201 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); | 2226 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 2202 super.visitClassDeclaration(node); | 2227 super.visitClassDeclaration(node); |
| 2203 _resolveMetadata(node.metadata, _enclosingClass); | 2228 _resolveMetadata(node, node.metadata, _enclosingClass); |
| 2204 return null; | 2229 return null; |
| 2205 } finally { | 2230 } finally { |
| 2206 _enclosingClass = outerClass; | 2231 _enclosingClass = outerClass; |
| 2207 } | 2232 } |
| 2208 } | 2233 } |
| 2209 | 2234 |
| 2210 @override | 2235 @override |
| 2211 Object visitClassTypeAlias(ClassTypeAlias node) { | 2236 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 2212 ClassElement outerClass = _enclosingClass; | 2237 ClassElement outerClass = _enclosingClass; |
| 2213 try { | 2238 try { |
| 2214 SimpleIdentifier className = node.name; | 2239 SimpleIdentifier className = node.name; |
| 2215 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); | 2240 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 2216 super.visitClassTypeAlias(node); | 2241 super.visitClassTypeAlias(node); |
| 2217 _resolveMetadata(node.metadata, _enclosingClass); | 2242 _resolveMetadata(node, node.metadata, _enclosingClass); |
| 2218 return null; | 2243 return null; |
| 2219 } finally { | 2244 } finally { |
| 2220 _enclosingClass = outerClass; | 2245 _enclosingClass = outerClass; |
| 2221 } | 2246 } |
| 2222 } | 2247 } |
| 2223 | 2248 |
| 2224 @override | 2249 @override |
| 2225 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 2250 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 2226 ExecutableElement outerExecutable = _enclosingExecutable; | 2251 ExecutableElement outerExecutable = _enclosingExecutable; |
| 2227 try { | 2252 try { |
| 2228 SimpleIdentifier constructorName = node.name; | 2253 SimpleIdentifier constructorName = node.name; |
| 2229 if (constructorName == null) { | 2254 if (constructorName == null) { |
| 2230 _enclosingExecutable = _enclosingClass.unnamedConstructor; | 2255 _enclosingExecutable = _enclosingClass.unnamedConstructor; |
| 2231 if (_enclosingExecutable == null) { | 2256 if (_enclosingExecutable == null) { |
| 2232 _mismatch('Could not find default constructor', node); | 2257 _mismatch('Could not find default constructor', node); |
| 2233 } | 2258 } |
| 2234 } else { | 2259 } else { |
| 2235 _enclosingExecutable = | 2260 _enclosingExecutable = |
| 2236 _enclosingClass.getNamedConstructor(constructorName.name); | 2261 _enclosingClass.getNamedConstructor(constructorName.name); |
| 2237 if (_enclosingExecutable == null) { | 2262 if (_enclosingExecutable == null) { |
| 2238 _mismatch( | 2263 _mismatch( |
| 2239 'Could not find constructor element with name "${constructorName.n
ame}', | 2264 'Could not find constructor element with name "${constructorName.n
ame}', |
| 2240 node); | 2265 node); |
| 2241 } | 2266 } |
| 2242 constructorName.staticElement = _enclosingExecutable; | 2267 constructorName.staticElement = _enclosingExecutable; |
| 2243 } | 2268 } |
| 2244 _expectedElements.remove(_enclosingExecutable); | 2269 _expectedElements.remove(_enclosingExecutable); |
| 2245 node.element = _enclosingExecutable as ConstructorElement; | 2270 node.element = _enclosingExecutable as ConstructorElement; |
| 2246 super.visitConstructorDeclaration(node); | 2271 super.visitConstructorDeclaration(node); |
| 2247 _resolveMetadata(node.metadata, _enclosingExecutable); | 2272 _resolveMetadata(node, node.metadata, _enclosingExecutable); |
| 2248 return null; | 2273 return null; |
| 2249 } finally { | 2274 } finally { |
| 2250 _enclosingExecutable = outerExecutable; | 2275 _enclosingExecutable = outerExecutable; |
| 2251 } | 2276 } |
| 2252 } | 2277 } |
| 2253 | 2278 |
| 2254 @override | 2279 @override |
| 2255 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 2280 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 2256 SimpleIdentifier variableName = node.identifier; | 2281 SimpleIdentifier variableName = node.identifier; |
| 2257 Element element = | 2282 Element element = |
| 2258 _findIdentifier(_enclosingExecutable.localVariables, variableName); | 2283 _findIdentifier(_enclosingExecutable.localVariables, variableName); |
| 2259 super.visitDeclaredIdentifier(node); | 2284 super.visitDeclaredIdentifier(node); |
| 2260 _resolveMetadata(node.metadata, element); | 2285 _resolveMetadata(node, node.metadata, element); |
| 2261 return null; | 2286 return null; |
| 2262 } | 2287 } |
| 2263 | 2288 |
| 2264 @override | 2289 @override |
| 2265 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 2290 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 2266 SimpleIdentifier parameterName = node.parameter.identifier; | 2291 SimpleIdentifier parameterName = node.parameter.identifier; |
| 2267 ParameterElement element = _getElementForParameter(node, parameterName); | 2292 ParameterElement element = _getElementForParameter(node, parameterName); |
| 2268 Expression defaultValue = node.defaultValue; | 2293 Expression defaultValue = node.defaultValue; |
| 2269 if (defaultValue != null) { | 2294 if (defaultValue != null) { |
| 2270 ExecutableElement outerExecutable = _enclosingExecutable; | 2295 ExecutableElement outerExecutable = _enclosingExecutable; |
| 2271 try { | 2296 try { |
| 2272 _enclosingExecutable = element.initializer; | 2297 _enclosingExecutable = element.initializer; |
| 2273 defaultValue.accept(this); | 2298 defaultValue.accept(this); |
| 2274 } finally { | 2299 } finally { |
| 2275 _enclosingExecutable = outerExecutable; | 2300 _enclosingExecutable = outerExecutable; |
| 2276 } | 2301 } |
| 2277 } | 2302 } |
| 2278 ParameterElement outerParameter = _enclosingParameter; | 2303 ParameterElement outerParameter = _enclosingParameter; |
| 2279 try { | 2304 try { |
| 2280 _enclosingParameter = element; | 2305 _enclosingParameter = element; |
| 2281 super.visitDefaultFormalParameter(node); | 2306 super.visitDefaultFormalParameter(node); |
| 2282 _resolveMetadata(node.metadata, element); | 2307 _resolveMetadata(node, node.metadata, element); |
| 2283 return null; | 2308 return null; |
| 2284 } finally { | 2309 } finally { |
| 2285 _enclosingParameter = outerParameter; | 2310 _enclosingParameter = outerParameter; |
| 2286 } | 2311 } |
| 2287 } | 2312 } |
| 2288 | 2313 |
| 2289 @override | 2314 @override |
| 2290 Object visitEnumDeclaration(EnumDeclaration node) { | 2315 Object visitEnumDeclaration(EnumDeclaration node) { |
| 2291 ClassElement enclosingEnum = | 2316 ClassElement enclosingEnum = |
| 2292 _findIdentifier(_enclosingUnit.enums, node.name); | 2317 _findIdentifier(_enclosingUnit.enums, node.name); |
| 2293 List<FieldElement> constants = enclosingEnum.fields; | 2318 List<FieldElement> constants = enclosingEnum.fields; |
| 2294 for (EnumConstantDeclaration constant in node.constants) { | 2319 for (EnumConstantDeclaration constant in node.constants) { |
| 2295 _findIdentifier(constants, constant.name); | 2320 _findIdentifier(constants, constant.name); |
| 2296 } | 2321 } |
| 2297 super.visitEnumDeclaration(node); | 2322 super.visitEnumDeclaration(node); |
| 2298 _resolveMetadata(node.metadata, enclosingEnum); | 2323 _resolveMetadata(node, node.metadata, enclosingEnum); |
| 2299 return null; | 2324 return null; |
| 2300 } | 2325 } |
| 2301 | 2326 |
| 2302 @override | 2327 @override |
| 2303 Object visitExportDirective(ExportDirective node) { | 2328 Object visitExportDirective(ExportDirective node) { |
| 2304 String uri = _getStringValue(node.uri); | |
| 2305 ExportElement exportElement; | |
| 2306 if (uri != null) { | |
| 2307 LibraryElement library = _enclosingUnit.library; | |
| 2308 Source source = _enclosingUnit.context.sourceFactory | |
| 2309 .resolveUri(_enclosingUnit.source, uri); | |
| 2310 exportElement = _findExport(node, library.exports, source); | |
| 2311 node.element = exportElement; | |
| 2312 } | |
| 2313 super.visitExportDirective(node); | 2329 super.visitExportDirective(node); |
| 2314 _resolveMetadata(node.metadata, exportElement); | 2330 _resolveAnnotations( |
| 2331 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); |
| 2315 return null; | 2332 return null; |
| 2316 } | 2333 } |
| 2317 | 2334 |
| 2318 @override | 2335 @override |
| 2319 Object visitFieldDeclaration(FieldDeclaration node) { | 2336 Object visitFieldDeclaration(FieldDeclaration node) { |
| 2320 super.visitFieldDeclaration(node); | 2337 super.visitFieldDeclaration(node); |
| 2321 _resolveMetadata(node.metadata, node.fields.variables[0].element); | 2338 _resolveMetadata(node, node.metadata, node.fields.variables[0].element); |
| 2322 return null; | 2339 return null; |
| 2323 } | 2340 } |
| 2324 | 2341 |
| 2325 @override | 2342 @override |
| 2326 Object visitFieldFormalParameter(FieldFormalParameter node) { | 2343 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 2327 if (node.parent is! DefaultFormalParameter) { | 2344 if (node.parent is! DefaultFormalParameter) { |
| 2328 SimpleIdentifier parameterName = node.identifier; | 2345 SimpleIdentifier parameterName = node.identifier; |
| 2329 ParameterElement element = _getElementForParameter(node, parameterName); | 2346 ParameterElement element = _getElementForParameter(node, parameterName); |
| 2330 ParameterElement outerParameter = _enclosingParameter; | 2347 ParameterElement outerParameter = _enclosingParameter; |
| 2331 try { | 2348 try { |
| 2332 _enclosingParameter = element; | 2349 _enclosingParameter = element; |
| 2333 super.visitFieldFormalParameter(node); | 2350 super.visitFieldFormalParameter(node); |
| 2334 _resolveMetadata(node.metadata, element); | 2351 _resolveMetadata(node, node.metadata, element); |
| 2335 return null; | 2352 return null; |
| 2336 } finally { | 2353 } finally { |
| 2337 _enclosingParameter = outerParameter; | 2354 _enclosingParameter = outerParameter; |
| 2338 } | 2355 } |
| 2339 } else { | 2356 } else { |
| 2340 return super.visitFieldFormalParameter(node); | 2357 return super.visitFieldFormalParameter(node); |
| 2341 } | 2358 } |
| 2342 } | 2359 } |
| 2343 | 2360 |
| 2344 @override | 2361 @override |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2373 accessor = _findWithNameAndOffset(accessors, functionName, | 2390 accessor = _findWithNameAndOffset(accessors, functionName, |
| 2374 functionName.name + '=', functionName.offset); | 2391 functionName.name + '=', functionName.offset); |
| 2375 _expectedElements.remove(accessor); | 2392 _expectedElements.remove(accessor); |
| 2376 functionName.staticElement = accessor; | 2393 functionName.staticElement = accessor; |
| 2377 } | 2394 } |
| 2378 _enclosingExecutable = accessor; | 2395 _enclosingExecutable = accessor; |
| 2379 } | 2396 } |
| 2380 } | 2397 } |
| 2381 node.functionExpression.element = _enclosingExecutable; | 2398 node.functionExpression.element = _enclosingExecutable; |
| 2382 super.visitFunctionDeclaration(node); | 2399 super.visitFunctionDeclaration(node); |
| 2383 _resolveMetadata(node.metadata, _enclosingExecutable); | 2400 _resolveMetadata(node, node.metadata, _enclosingExecutable); |
| 2384 return null; | 2401 return null; |
| 2385 } finally { | 2402 } finally { |
| 2386 _enclosingExecutable = outerExecutable; | 2403 _enclosingExecutable = outerExecutable; |
| 2387 } | 2404 } |
| 2388 } | 2405 } |
| 2389 | 2406 |
| 2390 @override | 2407 @override |
| 2391 Object visitFunctionExpression(FunctionExpression node) { | 2408 Object visitFunctionExpression(FunctionExpression node) { |
| 2392 if (node.parent is! FunctionDeclaration) { | 2409 if (node.parent is! FunctionDeclaration) { |
| 2393 FunctionElement element = _findAtOffset( | 2410 FunctionElement element = _findAtOffset( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2405 } | 2422 } |
| 2406 | 2423 |
| 2407 @override | 2424 @override |
| 2408 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 2425 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 2409 FunctionTypeAliasElement outerAlias = _enclosingAlias; | 2426 FunctionTypeAliasElement outerAlias = _enclosingAlias; |
| 2410 try { | 2427 try { |
| 2411 SimpleIdentifier aliasName = node.name; | 2428 SimpleIdentifier aliasName = node.name; |
| 2412 _enclosingAlias = | 2429 _enclosingAlias = |
| 2413 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); | 2430 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); |
| 2414 super.visitFunctionTypeAlias(node); | 2431 super.visitFunctionTypeAlias(node); |
| 2415 _resolveMetadata(node.metadata, _enclosingAlias); | 2432 _resolveMetadata(node, node.metadata, _enclosingAlias); |
| 2416 return null; | 2433 return null; |
| 2417 } finally { | 2434 } finally { |
| 2418 _enclosingAlias = outerAlias; | 2435 _enclosingAlias = outerAlias; |
| 2419 } | 2436 } |
| 2420 } | 2437 } |
| 2421 | 2438 |
| 2422 @override | 2439 @override |
| 2423 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 2440 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 2424 if (node.parent is! DefaultFormalParameter) { | 2441 if (node.parent is! DefaultFormalParameter) { |
| 2425 SimpleIdentifier parameterName = node.identifier; | 2442 SimpleIdentifier parameterName = node.identifier; |
| 2426 ParameterElement element = _getElementForParameter(node, parameterName); | 2443 ParameterElement element = _getElementForParameter(node, parameterName); |
| 2427 ParameterElement outerParameter = _enclosingParameter; | 2444 ParameterElement outerParameter = _enclosingParameter; |
| 2428 try { | 2445 try { |
| 2429 _enclosingParameter = element; | 2446 _enclosingParameter = element; |
| 2430 super.visitFunctionTypedFormalParameter(node); | 2447 super.visitFunctionTypedFormalParameter(node); |
| 2431 _resolveMetadata(node.metadata, _enclosingParameter); | 2448 _resolveMetadata(node, node.metadata, _enclosingParameter); |
| 2432 return null; | 2449 return null; |
| 2433 } finally { | 2450 } finally { |
| 2434 _enclosingParameter = outerParameter; | 2451 _enclosingParameter = outerParameter; |
| 2435 } | 2452 } |
| 2436 } else { | 2453 } else { |
| 2437 return super.visitFunctionTypedFormalParameter(node); | 2454 return super.visitFunctionTypedFormalParameter(node); |
| 2438 } | 2455 } |
| 2439 } | 2456 } |
| 2440 | 2457 |
| 2441 @override | 2458 @override |
| 2442 Object visitImportDirective(ImportDirective node) { | 2459 Object visitImportDirective(ImportDirective node) { |
| 2443 String uri = _getStringValue(node.uri); | |
| 2444 ImportElement importElement; | |
| 2445 if (uri != null) { | |
| 2446 LibraryElement library = _enclosingUnit.library; | |
| 2447 Source source = _enclosingUnit.context.sourceFactory | |
| 2448 .resolveUri(_enclosingUnit.source, uri); | |
| 2449 importElement = _findImport(node, library.imports, source); | |
| 2450 node.element = importElement; | |
| 2451 } | |
| 2452 super.visitImportDirective(node); | 2460 super.visitImportDirective(node); |
| 2453 _resolveMetadata(node.metadata, importElement); | 2461 _resolveAnnotations( |
| 2462 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); |
| 2454 return null; | 2463 return null; |
| 2455 } | 2464 } |
| 2456 | 2465 |
| 2457 @override | 2466 @override |
| 2458 Object visitLabeledStatement(LabeledStatement node) { | 2467 Object visitLabeledStatement(LabeledStatement node) { |
| 2459 for (Label label in node.labels) { | 2468 for (Label label in node.labels) { |
| 2460 SimpleIdentifier labelName = label.label; | 2469 SimpleIdentifier labelName = label.label; |
| 2461 _findIdentifier(_enclosingExecutable.labels, labelName); | 2470 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 2462 } | 2471 } |
| 2463 return super.visitLabeledStatement(node); | 2472 return super.visitLabeledStatement(node); |
| 2464 } | 2473 } |
| 2465 | 2474 |
| 2466 @override | 2475 @override |
| 2467 Object visitLibraryDirective(LibraryDirective node) { | 2476 Object visitLibraryDirective(LibraryDirective node) { |
| 2468 LibraryElement libraryElement = _enclosingUnit.library; | |
| 2469 node.element = libraryElement; | |
| 2470 super.visitLibraryDirective(node); | 2477 super.visitLibraryDirective(node); |
| 2471 _resolveMetadata(node.metadata, libraryElement); | 2478 _resolveAnnotations( |
| 2479 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); |
| 2472 return null; | 2480 return null; |
| 2473 } | 2481 } |
| 2474 | 2482 |
| 2475 @override | 2483 @override |
| 2476 Object visitMethodDeclaration(MethodDeclaration node) { | 2484 Object visitMethodDeclaration(MethodDeclaration node) { |
| 2477 ExecutableElement outerExecutable = _enclosingExecutable; | 2485 ExecutableElement outerExecutable = _enclosingExecutable; |
| 2478 try { | 2486 try { |
| 2479 Token property = node.propertyKeyword; | 2487 Token property = node.propertyKeyword; |
| 2480 SimpleIdentifier methodName = node.name; | 2488 SimpleIdentifier methodName = node.name; |
| 2481 String nameOfMethod = methodName.name; | 2489 String nameOfMethod = methodName.name; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2493 accessor = _findIdentifier(_enclosingClass.accessors, methodName); | 2501 accessor = _findIdentifier(_enclosingClass.accessors, methodName); |
| 2494 } else if ((property as KeywordToken).keyword == Keyword.SET) { | 2502 } else if ((property as KeywordToken).keyword == Keyword.SET) { |
| 2495 accessor = _findWithNameAndOffset(_enclosingClass.accessors, | 2503 accessor = _findWithNameAndOffset(_enclosingClass.accessors, |
| 2496 methodName, nameOfMethod + '=', methodName.offset); | 2504 methodName, nameOfMethod + '=', methodName.offset); |
| 2497 _expectedElements.remove(accessor); | 2505 _expectedElements.remove(accessor); |
| 2498 methodName.staticElement = accessor; | 2506 methodName.staticElement = accessor; |
| 2499 } | 2507 } |
| 2500 _enclosingExecutable = accessor; | 2508 _enclosingExecutable = accessor; |
| 2501 } | 2509 } |
| 2502 super.visitMethodDeclaration(node); | 2510 super.visitMethodDeclaration(node); |
| 2503 _resolveMetadata(node.metadata, _enclosingExecutable); | 2511 _resolveMetadata(node, node.metadata, _enclosingExecutable); |
| 2504 return null; | 2512 return null; |
| 2505 } finally { | 2513 } finally { |
| 2506 _enclosingExecutable = outerExecutable; | 2514 _enclosingExecutable = outerExecutable; |
| 2507 } | 2515 } |
| 2508 } | 2516 } |
| 2509 | 2517 |
| 2510 @override | 2518 @override |
| 2511 Object visitPartDirective(PartDirective node) { | 2519 Object visitPartDirective(PartDirective node) { |
| 2512 String uri = _getStringValue(node.uri); | |
| 2513 CompilationUnitElement compilationUnitElement; | |
| 2514 if (uri != null) { | |
| 2515 Source partSource = _enclosingUnit.context.sourceFactory | |
| 2516 .resolveUri(_enclosingUnit.source, uri); | |
| 2517 compilationUnitElement = | |
| 2518 _findPart(_enclosingUnit.library.parts, node, partSource); | |
| 2519 } | |
| 2520 super.visitPartDirective(node); | 2520 super.visitPartDirective(node); |
| 2521 _resolveMetadata(node.metadata, compilationUnitElement); | 2521 _resolveAnnotations( |
| 2522 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); |
| 2522 return null; | 2523 return null; |
| 2523 } | 2524 } |
| 2524 | 2525 |
| 2525 @override | 2526 @override |
| 2526 Object visitPartOfDirective(PartOfDirective node) { | 2527 Object visitPartOfDirective(PartOfDirective node) { |
| 2527 node.element = _enclosingUnit.library; | 2528 node.element = _enclosingUnit.library; |
| 2528 return super.visitPartOfDirective(node); | 2529 return super.visitPartOfDirective(node); |
| 2529 } | 2530 } |
| 2530 | 2531 |
| 2531 @override | 2532 @override |
| 2532 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 2533 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 2533 if (node.parent is! DefaultFormalParameter) { | 2534 if (node.parent is! DefaultFormalParameter) { |
| 2534 SimpleIdentifier parameterName = node.identifier; | 2535 SimpleIdentifier parameterName = node.identifier; |
| 2535 ParameterElement element = _getElementForParameter(node, parameterName); | 2536 ParameterElement element = _getElementForParameter(node, parameterName); |
| 2536 ParameterElement outerParameter = _enclosingParameter; | 2537 ParameterElement outerParameter = _enclosingParameter; |
| 2537 try { | 2538 try { |
| 2538 _enclosingParameter = element; | 2539 _enclosingParameter = element; |
| 2539 super.visitSimpleFormalParameter(node); | 2540 super.visitSimpleFormalParameter(node); |
| 2540 _resolveMetadata(node.metadata, element); | 2541 _resolveMetadata(node, node.metadata, element); |
| 2541 return null; | 2542 return null; |
| 2542 } finally { | 2543 } finally { |
| 2543 _enclosingParameter = outerParameter; | 2544 _enclosingParameter = outerParameter; |
| 2544 } | 2545 } |
| 2545 } else {} | 2546 } else {} |
| 2546 return super.visitSimpleFormalParameter(node); | 2547 return super.visitSimpleFormalParameter(node); |
| 2547 } | 2548 } |
| 2548 | 2549 |
| 2549 @override | 2550 @override |
| 2550 Object visitSwitchCase(SwitchCase node) { | 2551 Object visitSwitchCase(SwitchCase node) { |
| 2551 for (Label label in node.labels) { | 2552 for (Label label in node.labels) { |
| 2552 SimpleIdentifier labelName = label.label; | 2553 SimpleIdentifier labelName = label.label; |
| 2553 _findIdentifier(_enclosingExecutable.labels, labelName); | 2554 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 2554 } | 2555 } |
| 2555 return super.visitSwitchCase(node); | 2556 return super.visitSwitchCase(node); |
| 2556 } | 2557 } |
| 2557 | 2558 |
| 2558 @override | 2559 @override |
| 2559 Object visitSwitchDefault(SwitchDefault node) { | 2560 Object visitSwitchDefault(SwitchDefault node) { |
| 2560 for (Label label in node.labels) { | 2561 for (Label label in node.labels) { |
| 2561 SimpleIdentifier labelName = label.label; | 2562 SimpleIdentifier labelName = label.label; |
| 2562 _findIdentifier(_enclosingExecutable.labels, labelName); | 2563 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 2563 } | 2564 } |
| 2564 return super.visitSwitchDefault(node); | 2565 return super.visitSwitchDefault(node); |
| 2565 } | 2566 } |
| 2566 | 2567 |
| 2567 @override | 2568 @override |
| 2568 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 2569 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 2569 super.visitTopLevelVariableDeclaration(node); | 2570 super.visitTopLevelVariableDeclaration(node); |
| 2570 _resolveMetadata(node.metadata, node.variables.variables[0].element); | 2571 _resolveMetadata(node, node.metadata, node.variables.variables[0].element); |
| 2571 return null; | 2572 return null; |
| 2572 } | 2573 } |
| 2573 | 2574 |
| 2574 @override | 2575 @override |
| 2575 Object visitTypeParameter(TypeParameter node) { | 2576 Object visitTypeParameter(TypeParameter node) { |
| 2576 SimpleIdentifier parameterName = node.name; | 2577 SimpleIdentifier parameterName = node.name; |
| 2577 Element element = null; | 2578 Element element = null; |
| 2578 if (_enclosingExecutable != null) { | 2579 if (_enclosingExecutable != null) { |
| 2579 element = _findIdentifier( | 2580 element = _findIdentifier( |
| 2580 _enclosingExecutable.typeParameters, parameterName, | 2581 _enclosingExecutable.typeParameters, parameterName, |
| 2581 required: false); | 2582 required: false); |
| 2582 } | 2583 } |
| 2583 if (element == null) { | 2584 if (element == null) { |
| 2584 if (_enclosingClass != null) { | 2585 if (_enclosingClass != null) { |
| 2585 element = | 2586 element = |
| 2586 _findIdentifier(_enclosingClass.typeParameters, parameterName); | 2587 _findIdentifier(_enclosingClass.typeParameters, parameterName); |
| 2587 } else if (_enclosingAlias != null) { | 2588 } else if (_enclosingAlias != null) { |
| 2588 element = | 2589 element = |
| 2589 _findIdentifier(_enclosingAlias.typeParameters, parameterName); | 2590 _findIdentifier(_enclosingAlias.typeParameters, parameterName); |
| 2590 } | 2591 } |
| 2591 } | 2592 } |
| 2592 if (element == null) { | 2593 if (element == null) { |
| 2593 String name = parameterName.name; | 2594 String name = parameterName.name; |
| 2594 int offset = parameterName.offset; | 2595 int offset = parameterName.offset; |
| 2595 _mismatch( | 2596 _mismatch( |
| 2596 'Could not find type parameter with name "$name" at $offset', node); | 2597 'Could not find type parameter with name "$name" at $offset', node); |
| 2597 } | 2598 } |
| 2598 super.visitTypeParameter(node); | 2599 super.visitTypeParameter(node); |
| 2599 _resolveMetadata(node.metadata, element); | 2600 _resolveMetadata(node, node.metadata, element); |
| 2600 return null; | 2601 return null; |
| 2601 } | 2602 } |
| 2602 | 2603 |
| 2603 @override | 2604 @override |
| 2604 Object visitVariableDeclaration(VariableDeclaration node) { | 2605 Object visitVariableDeclaration(VariableDeclaration node) { |
| 2605 VariableElement element = null; | 2606 VariableElement element = null; |
| 2606 SimpleIdentifier variableName = node.name; | 2607 SimpleIdentifier variableName = node.name; |
| 2607 if (_enclosingExecutable != null) { | 2608 if (_enclosingExecutable != null) { |
| 2608 element = _findIdentifier( | 2609 element = _findIdentifier( |
| 2609 _enclosingExecutable.localVariables, variableName, | 2610 _enclosingExecutable.localVariables, variableName, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2627 } | 2628 } |
| 2628 } | 2629 } |
| 2629 return super.visitVariableDeclaration(node); | 2630 return super.visitVariableDeclaration(node); |
| 2630 } | 2631 } |
| 2631 | 2632 |
| 2632 @override | 2633 @override |
| 2633 Object visitVariableDeclarationList(VariableDeclarationList node) { | 2634 Object visitVariableDeclarationList(VariableDeclarationList node) { |
| 2634 super.visitVariableDeclarationList(node); | 2635 super.visitVariableDeclarationList(node); |
| 2635 if (node.parent is! FieldDeclaration && | 2636 if (node.parent is! FieldDeclaration && |
| 2636 node.parent is! TopLevelVariableDeclaration) { | 2637 node.parent is! TopLevelVariableDeclaration) { |
| 2637 _resolveMetadata(node.metadata, node.variables[0].element); | 2638 _resolveMetadata(node, node.metadata, node.variables[0].element); |
| 2638 } | 2639 } |
| 2639 return null; | 2640 return null; |
| 2640 } | 2641 } |
| 2641 | 2642 |
| 2642 /** | 2643 /** |
| 2643 * Return the element in the given list of [elements] that was created for the | 2644 * Return the element in the given list of [elements] that was created for the |
| 2644 * declaration at the given [offset]. Throw an [ElementMismatchException] if | 2645 * declaration at the given [offset]. Throw an [ElementMismatchException] if |
| 2645 * an element at that offset cannot be found. | 2646 * an element at that offset cannot be found. |
| 2646 * | 2647 * |
| 2647 * This method should only be used when there is no name associated with the | 2648 * This method should only be used when there is no name associated with the |
| 2648 * node. | 2649 * node. |
| 2649 */ | 2650 */ |
| 2650 Element _findAtOffset(List<Element> elements, AstNode node, int offset) => | 2651 Element _findAtOffset(List<Element> elements, AstNode node, int offset) => |
| 2651 _findWithNameAndOffset(elements, node, '', offset); | 2652 _findWithNameAndOffset(elements, node, '', offset); |
| 2652 | 2653 |
| 2653 /** | 2654 /** |
| 2654 * Return the export element from the given list of [exports] whose library | |
| 2655 * has the given [source]. Throw an [ElementMismatchException] if an element | |
| 2656 * corresponding to the identifier cannot be found. | |
| 2657 */ | |
| 2658 ExportElement _findExport( | |
| 2659 ExportDirective node, List<ExportElement> exports, Source source) { | |
| 2660 if (source == null || !_context.exists(source)) { | |
| 2661 return null; | |
| 2662 } | |
| 2663 for (ExportElement export in exports) { | |
| 2664 if (export.exportedLibrary.source == source) { | |
| 2665 return export; | |
| 2666 } | |
| 2667 } | |
| 2668 _mismatch("Could not find export element for '$source'", node); | |
| 2669 return null; // Never reached | |
| 2670 } | |
| 2671 | |
| 2672 /** | |
| 2673 * Return the element in the given list of [elements] that was created for the | 2655 * Return the element in the given list of [elements] that was created for the |
| 2674 * declaration with the given [identifier]. As a side-effect, associate the | 2656 * declaration with the given [identifier]. As a side-effect, associate the |
| 2675 * returned element with the identifier. Throw an [ElementMismatchException] | 2657 * returned element with the identifier. Throw an [ElementMismatchException] |
| 2676 * if an element corresponding to the identifier cannot be found unless | 2658 * if an element corresponding to the identifier cannot be found unless |
| 2677 * [required] is `false`, in which case return `null`. | 2659 * [required] is `false`, in which case return `null`. |
| 2678 */ | 2660 */ |
| 2679 Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier, | 2661 Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier, |
| 2680 {bool required: true}) { | 2662 {bool required: true}) { |
| 2681 Element element = _findWithNameAndOffset( | 2663 Element element = _findWithNameAndOffset( |
| 2682 elements, identifier, identifier.name, identifier.offset, | 2664 elements, identifier, identifier.name, identifier.offset, |
| 2683 required: required); | 2665 required: required); |
| 2684 _expectedElements.remove(element); | 2666 _expectedElements.remove(element); |
| 2685 identifier.staticElement = element; | 2667 identifier.staticElement = element; |
| 2686 return element; | 2668 return element; |
| 2687 } | 2669 } |
| 2688 | 2670 |
| 2689 /** | 2671 /** |
| 2690 * Return the import element from the given list of [imports] whose library | |
| 2691 * has the given [source]. Throw an [ElementMismatchException] if an element | |
| 2692 * corresponding to the [source] cannot be found. | |
| 2693 */ | |
| 2694 ImportElement _findImport( | |
| 2695 ImportDirective node, List<ImportElement> imports, Source source) { | |
| 2696 if (source == null || !_context.exists(source)) { | |
| 2697 return null; | |
| 2698 } | |
| 2699 SimpleIdentifier prefix = node.prefix; | |
| 2700 bool foundSource = false; | |
| 2701 for (ImportElement element in imports) { | |
| 2702 if (element.importedLibrary.source == source) { | |
| 2703 foundSource = true; | |
| 2704 PrefixElement prefixElement = element.prefix; | |
| 2705 if (prefix == null) { | |
| 2706 if (prefixElement == null) { | |
| 2707 return element; | |
| 2708 } | |
| 2709 } else { | |
| 2710 if (prefixElement != null && | |
| 2711 prefix.name == prefixElement.displayName) { | |
| 2712 return element; | |
| 2713 } | |
| 2714 } | |
| 2715 } | |
| 2716 } | |
| 2717 if (foundSource) { | |
| 2718 if (prefix == null) { | |
| 2719 _mismatch( | |
| 2720 "Could not find import element for '$source' with no prefix", node); | |
| 2721 } | |
| 2722 _mismatch( | |
| 2723 "Could not find import element for '$source' with prefix ${prefix.name
}", | |
| 2724 node); | |
| 2725 } | |
| 2726 _mismatch("Could not find import element for '$source'", node); | |
| 2727 return null; // Never reached | |
| 2728 } | |
| 2729 | |
| 2730 /** | |
| 2731 * Return the element in the given list of [parts] that was created for the | |
| 2732 * part with the given [source]. Throw an [ElementMismatchException] if an | |
| 2733 * element corresponding to the source cannot be found. | |
| 2734 */ | |
| 2735 CompilationUnitElement _findPart(List<CompilationUnitElement> parts, | |
| 2736 PartDirective directive, Source source) { | |
| 2737 for (CompilationUnitElement part in parts) { | |
| 2738 if (part.source == source) { | |
| 2739 return part; | |
| 2740 } | |
| 2741 } | |
| 2742 _mismatch( | |
| 2743 'Could not find compilation unit element for "$source"', directive); | |
| 2744 return null; // Never reached | |
| 2745 } | |
| 2746 | |
| 2747 /** | |
| 2748 * Return the element in the given list of [elements] that was created for the | 2672 * Return the element in the given list of [elements] that was created for the |
| 2749 * declaration with the given [name] at the given [offset]. Throw an | 2673 * declaration with the given [name] at the given [offset]. Throw an |
| 2750 * [ElementMismatchException] if an element corresponding to the identifier | 2674 * [ElementMismatchException] if an element corresponding to the identifier |
| 2751 * cannot be found unless [required] is `false`, in which case return `null`. | 2675 * cannot be found unless [required] is `false`, in which case return `null`. |
| 2752 */ | 2676 */ |
| 2753 Element _findWithNameAndOffset( | 2677 Element _findWithNameAndOffset( |
| 2754 List<Element> elements, AstNode node, String name, int offset, | 2678 List<Element> elements, AstNode node, String name, int offset, |
| 2755 {bool required: true}) { | 2679 {bool required: true}) { |
| 2756 for (Element element in elements) { | 2680 for (Element element in elements) { |
| 2757 if (element.nameOffset == offset && element.name == name) { | 2681 if (element.nameOffset == offset && element.name == name) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2804 '(_enclosingParameter == null) == ${_enclosingParameter == null}'); | 2728 '(_enclosingParameter == null) == ${_enclosingParameter == null}'); |
| 2805 buffer.writeln( | 2729 buffer.writeln( |
| 2806 '(_enclosingExecutable == null) == ${_enclosingExecutable == null}'); | 2730 '(_enclosingExecutable == null) == ${_enclosingExecutable == null}'); |
| 2807 buffer.writeln('(_enclosingAlias == null) == ${_enclosingAlias == null}'); | 2731 buffer.writeln('(_enclosingAlias == null) == ${_enclosingAlias == null}'); |
| 2808 _mismatch(buffer.toString(), parameterName); | 2732 _mismatch(buffer.toString(), parameterName); |
| 2809 } | 2733 } |
| 2810 return _findIdentifier(parameters, parameterName); | 2734 return _findIdentifier(parameters, parameterName); |
| 2811 } | 2735 } |
| 2812 | 2736 |
| 2813 /** | 2737 /** |
| 2814 * Return the value of the given string [literal], or `null` if the string is | 2738 * Associate each of the annotation [nodes] with the corresponding |
| 2815 * not a constant string without any string interpolation. | 2739 * [ElementAnnotation] in [annotations]. If there is a problem, report it |
| 2740 * against the given [parent] node. |
| 2816 */ | 2741 */ |
| 2817 String _getStringValue(StringLiteral literal) { | 2742 void _resolveAnnotations(AstNode parent, NodeList<Annotation> nodes, |
| 2818 if (literal is StringInterpolation) { | 2743 List<ElementAnnotation> annotations) { |
| 2819 return null; | 2744 int nodeCount = nodes.length; |
| 2745 if (nodeCount != annotations.length) { |
| 2746 _mismatch( |
| 2747 'Found $nodeCount annotation nodes and ' |
| 2748 '${annotations.length} element annotations', |
| 2749 parent); |
| 2820 } | 2750 } |
| 2821 return literal.stringValue; | 2751 for (int i = 0; i < nodeCount; i++) { |
| 2752 nodes[i].elementAnnotation = annotations[i]; |
| 2753 } |
| 2822 } | 2754 } |
| 2823 | 2755 |
| 2824 /** | 2756 /** |
| 2825 * Throw an [ElementMismatchException] to report that the element model and | 2757 * If [element] is not `null`, associate each of the annotation [nodes] with |
| 2826 * the AST do not match. The [message] will have the path to the given [node] | 2758 * the corresponding [ElementAnnotation] in [element.metadata]. If there is a |
| 2827 * appended to it. | 2759 * problem, report it against the given [parent] node. |
| 2828 */ | |
| 2829 void _mismatch(String message, AstNode node) { | |
| 2830 StringBuffer buffer = new StringBuffer(); | |
| 2831 buffer.writeln(message); | |
| 2832 buffer.write('Path to root:'); | |
| 2833 String separator = ' '; | |
| 2834 AstNode parent = node; | |
| 2835 while (parent != null) { | |
| 2836 buffer.write(separator); | |
| 2837 buffer.write(parent.runtimeType.toString()); | |
| 2838 separator = ', '; | |
| 2839 parent = parent.parent; | |
| 2840 } | |
| 2841 throw new ElementMismatchException(buffer.toString()); | |
| 2842 } | |
| 2843 | |
| 2844 /** | |
| 2845 * If [element] is not `null`, associate each [Annotation] in [astMetadata] | |
| 2846 * with the corresponding [ElementAnnotation] in [element.metadata]. | |
| 2847 * | 2760 * |
| 2848 * If [element] is `null`, do nothing--this allows us to be robust in the | 2761 * If [element] is `null`, do nothing--this allows us to be robust in the |
| 2849 * case where we are operating on an element model that hasn't been fully | 2762 * case where we are operating on an element model that hasn't been fully |
| 2850 * built. | 2763 * built. |
| 2851 */ | 2764 */ |
| 2852 void _resolveMetadata(NodeList<Annotation> astMetadata, Element element) { | 2765 void _resolveMetadata( |
| 2766 AstNode parent, NodeList<Annotation> nodes, Element element) { |
| 2853 if (element != null) { | 2767 if (element != null) { |
| 2854 List<ElementAnnotation> elementMetadata = element.metadata; | 2768 _resolveAnnotations(parent, nodes, element.metadata); |
| 2855 assert(astMetadata.length == elementMetadata.length); | |
| 2856 for (int i = 0; i < astMetadata.length; i++) { | |
| 2857 astMetadata[i].elementAnnotation = elementMetadata[i]; | |
| 2858 } | |
| 2859 } | 2769 } |
| 2860 } | 2770 } |
| 2861 | 2771 |
| 2862 /** | 2772 /** |
| 2863 * Throw an exception if there are non-synthetic elements in the element model | 2773 * Throw an exception if there are non-synthetic elements in the element model |
| 2864 * that were not associated with an AST node. | 2774 * that were not associated with an AST node. |
| 2865 */ | 2775 */ |
| 2866 void _validateResolution() { | 2776 void _validateResolution() { |
| 2867 if (_expectedElements.isNotEmpty) { | 2777 if (_expectedElements.isNotEmpty) { |
| 2868 StringBuffer buffer = new StringBuffer(); | 2778 StringBuffer buffer = new StringBuffer(); |
| 2869 buffer.write(_expectedElements.length); | 2779 buffer.write(_expectedElements.length); |
| 2870 buffer.writeln(' unmatched elements found:'); | 2780 buffer.writeln(' unmatched elements found:'); |
| 2871 for (Element element in _expectedElements) { | 2781 for (Element element in _expectedElements) { |
| 2872 buffer.write(' '); | 2782 buffer.write(' '); |
| 2873 buffer.writeln(element); | 2783 buffer.writeln(element); |
| 2874 } | 2784 } |
| 2875 throw new ElementMismatchException(buffer.toString()); | 2785 throw new ElementMismatchException(buffer.toString()); |
| 2876 } | 2786 } |
| 2877 } | 2787 } |
| 2878 } | 2788 } |
| 2879 | 2789 |
| 2880 /** | 2790 /** |
| 2791 * A visitor that resolves directives in an AST structure to already built |
| 2792 * elements. |
| 2793 * |
| 2794 * The resulting AST must have everything resolved that would have been resolved |
| 2795 * by a [DirectiveElementBuilder]. |
| 2796 */ |
| 2797 class DirectiveResolver extends SimpleAstVisitor { |
| 2798 CompilationUnitElementImpl _enclosingUnit; |
| 2799 |
| 2800 @override |
| 2801 void visitCompilationUnit(CompilationUnit node) { |
| 2802 _enclosingUnit = node.element; |
| 2803 for (Directive directive in node.directives) { |
| 2804 directive.accept(this); |
| 2805 } |
| 2806 } |
| 2807 |
| 2808 @override |
| 2809 void visitExportDirective(ExportDirective node) { |
| 2810 String uri = _getStringValue(node.uri); |
| 2811 if (uri != null) { |
| 2812 LibraryElement library = _enclosingUnit.library; |
| 2813 Source source = _enclosingUnit.context.sourceFactory |
| 2814 .resolveUri(_enclosingUnit.source, uri); |
| 2815 ExportElement exportElement = _findExport(node, library.exports, source); |
| 2816 node.element = exportElement; |
| 2817 } else { |
| 2818 node.element = null; |
| 2819 } |
| 2820 } |
| 2821 |
| 2822 @override |
| 2823 void visitImportDirective(ImportDirective node) { |
| 2824 String uri = _getStringValue(node.uri); |
| 2825 if (uri != null) { |
| 2826 LibraryElement library = _enclosingUnit.library; |
| 2827 Source source = _enclosingUnit.context.sourceFactory |
| 2828 .resolveUri(_enclosingUnit.source, uri); |
| 2829 ImportElement importElement = _findImport(node, library.imports, source); |
| 2830 node.element = importElement; |
| 2831 } else { |
| 2832 node.element = null; |
| 2833 } |
| 2834 } |
| 2835 |
| 2836 @override |
| 2837 void visitLibraryDirective(LibraryDirective node) { |
| 2838 node.element = _enclosingUnit.library; |
| 2839 } |
| 2840 |
| 2841 /** |
| 2842 * Return the export element from the given list of [exports] whose library |
| 2843 * has the given [source]. Throw an [ElementMismatchException] if an element |
| 2844 * corresponding to the identifier cannot be found. |
| 2845 */ |
| 2846 ExportElement _findExport( |
| 2847 ExportDirective node, List<ExportElement> exports, Source source) { |
| 2848 if (source == null || !_enclosingUnit.context.exists(source)) { |
| 2849 return null; |
| 2850 } |
| 2851 for (ExportElement export in exports) { |
| 2852 if (export.exportedLibrary.source == source) { |
| 2853 return export; |
| 2854 } |
| 2855 } |
| 2856 _mismatch("Could not find export element for '$source'", node); |
| 2857 return null; // Never reached |
| 2858 } |
| 2859 |
| 2860 /** |
| 2861 * Return the import element from the given list of [imports] whose library |
| 2862 * has the given [source]. Throw an [ElementMismatchException] if an element |
| 2863 * corresponding to the [source] cannot be found. |
| 2864 */ |
| 2865 ImportElement _findImport( |
| 2866 ImportDirective node, List<ImportElement> imports, Source source) { |
| 2867 if (source == null || !_enclosingUnit.context.exists(source)) { |
| 2868 return null; |
| 2869 } |
| 2870 SimpleIdentifier prefix = node.prefix; |
| 2871 bool foundSource = false; |
| 2872 for (ImportElement element in imports) { |
| 2873 if (element.importedLibrary.source == source) { |
| 2874 foundSource = true; |
| 2875 PrefixElement prefixElement = element.prefix; |
| 2876 if (prefix == null) { |
| 2877 if (prefixElement == null) { |
| 2878 return element; |
| 2879 } |
| 2880 } else { |
| 2881 if (prefixElement != null && |
| 2882 prefix.name == prefixElement.displayName) { |
| 2883 return element; |
| 2884 } |
| 2885 } |
| 2886 } |
| 2887 } |
| 2888 if (foundSource) { |
| 2889 if (prefix == null) { |
| 2890 _mismatch( |
| 2891 "Could not find import element for '$source' with no prefix", node); |
| 2892 } |
| 2893 _mismatch( |
| 2894 "Could not find import element for '$source' with prefix ${prefix.name
}", |
| 2895 node); |
| 2896 } |
| 2897 _mismatch("Could not find any import element for '$source'", node); |
| 2898 return null; // Never reached |
| 2899 } |
| 2900 |
| 2901 /** |
| 2902 * Return the value of the given string [literal], or `null` if the string is |
| 2903 * not a constant string without any string interpolation. |
| 2904 */ |
| 2905 String _getStringValue(StringLiteral literal) { |
| 2906 if (literal is StringInterpolation) { |
| 2907 return null; |
| 2908 } |
| 2909 return literal.stringValue; |
| 2910 } |
| 2911 } |
| 2912 |
| 2913 /** |
| 2881 * Instances of the class `ElementHolder` hold on to elements created while trav
ersing an AST | 2914 * Instances of the class `ElementHolder` hold on to elements created while trav
ersing an AST |
| 2882 * structure so that they can be accessed when creating their enclosing element. | 2915 * structure so that they can be accessed when creating their enclosing element. |
| 2883 */ | 2916 */ |
| 2884 class ElementHolder { | 2917 class ElementHolder { |
| 2885 List<PropertyAccessorElement> _accessors; | 2918 List<PropertyAccessorElement> _accessors; |
| 2886 | 2919 |
| 2887 List<ConstructorElement> _constructors; | 2920 List<ConstructorElement> _constructors; |
| 2888 | 2921 |
| 2889 List<ClassElement> _enums; | 2922 List<ClassElement> _enums; |
| 2890 | 2923 |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3248 } | 3281 } |
| 3249 | 3282 |
| 3250 /** | 3283 /** |
| 3251 * Instances of the class `EnclosedScope` implement a scope that is lexically en
closed in | 3284 * Instances of the class `EnclosedScope` implement a scope that is lexically en
closed in |
| 3252 * another scope. | 3285 * another scope. |
| 3253 */ | 3286 */ |
| 3254 class EnclosedScope extends Scope { | 3287 class EnclosedScope extends Scope { |
| 3255 /** | 3288 /** |
| 3256 * The scope in which this scope is lexically enclosed. | 3289 * The scope in which this scope is lexically enclosed. |
| 3257 */ | 3290 */ |
| 3291 @override |
| 3258 final Scope enclosingScope; | 3292 final Scope enclosingScope; |
| 3259 | 3293 |
| 3260 /** | 3294 /** |
| 3261 * A table mapping names that will be defined in this scope, but right now are
not initialized. | 3295 * A table mapping names that will be defined in this scope, but right now are
not initialized. |
| 3262 * According to the scoping rules these names are hidden, even if they were de
fined in an outer | 3296 * According to the scoping rules these names are hidden, even if they were de
fined in an outer |
| 3263 * scope. | 3297 * scope. |
| 3264 */ | 3298 */ |
| 3265 HashMap<String, Element> _hiddenElements = new HashMap<String, Element>(); | 3299 HashMap<String, Element> _hiddenElements = new HashMap<String, Element>(); |
| 3266 | 3300 |
| 3267 /** | 3301 /** |
| (...skipping 2771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6039 */ | 6073 */ |
| 6040 class LibraryImportScope extends Scope { | 6074 class LibraryImportScope extends Scope { |
| 6041 /** | 6075 /** |
| 6042 * The element representing the library in which this scope is enclosed. | 6076 * The element representing the library in which this scope is enclosed. |
| 6043 */ | 6077 */ |
| 6044 final LibraryElement _definingLibrary; | 6078 final LibraryElement _definingLibrary; |
| 6045 | 6079 |
| 6046 /** | 6080 /** |
| 6047 * The listener that is to be informed when an error is encountered. | 6081 * The listener that is to be informed when an error is encountered. |
| 6048 */ | 6082 */ |
| 6083 @override |
| 6049 final AnalysisErrorListener errorListener; | 6084 final AnalysisErrorListener errorListener; |
| 6050 | 6085 |
| 6051 /** | 6086 /** |
| 6052 * A list of the namespaces representing the names that are available in this
scope from imported | 6087 * A list of the namespaces representing the names that are available in this
scope from imported |
| 6053 * libraries. | 6088 * libraries. |
| 6054 */ | 6089 */ |
| 6055 List<Namespace> _importedNamespaces; | 6090 List<Namespace> _importedNamespaces; |
| 6056 | 6091 |
| 6057 /** | 6092 /** |
| 6058 * Initialize a newly created scope representing the names imported into the g
iven library. | 6093 * Initialize a newly created scope representing the names imported into the g
iven library. |
| (...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7236 | 7271 |
| 7237 /** | 7272 /** |
| 7238 * The type system in use during resolution. | 7273 * The type system in use during resolution. |
| 7239 */ | 7274 */ |
| 7240 TypeSystem typeSystem; | 7275 TypeSystem typeSystem; |
| 7241 | 7276 |
| 7242 /** | 7277 /** |
| 7243 * The class element representing the class containing the current node, | 7278 * The class element representing the class containing the current node, |
| 7244 * or `null` if the current node is not contained in a class. | 7279 * or `null` if the current node is not contained in a class. |
| 7245 */ | 7280 */ |
| 7281 @override |
| 7246 ClassElement enclosingClass = null; | 7282 ClassElement enclosingClass = null; |
| 7247 | 7283 |
| 7248 /** | 7284 /** |
| 7249 * The class declaration representing the class containing the current node, o
r `null` if | 7285 * The class declaration representing the class containing the current node, o
r `null` if |
| 7250 * the current node is not contained in a class. | 7286 * the current node is not contained in a class. |
| 7251 */ | 7287 */ |
| 7252 ClassDeclaration _enclosingClassDeclaration = null; | 7288 ClassDeclaration _enclosingClassDeclaration = null; |
| 7253 | 7289 |
| 7254 /** | 7290 /** |
| 7255 * The function type alias representing the function type containing the curre
nt node, or | 7291 * The function type alias representing the function type containing the curre
nt node, or |
| (...skipping 5684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12940 nonFields.add(node); | 12976 nonFields.add(node); |
| 12941 return null; | 12977 return null; |
| 12942 } | 12978 } |
| 12943 | 12979 |
| 12944 @override | 12980 @override |
| 12945 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 12981 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 12946 | 12982 |
| 12947 @override | 12983 @override |
| 12948 Object visitWithClause(WithClause node) => null; | 12984 Object visitWithClause(WithClause node) => null; |
| 12949 } | 12985 } |
| OLD | NEW |