Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 2406863003: Move class DeclarationResolver to its own file. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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';
11 import 'package:analyzer/dart/ast/visitor.dart'; 11 import 'package:analyzer/dart/ast/visitor.dart';
12 import 'package:analyzer/dart/element/element.dart'; 12 import 'package:analyzer/dart/element/element.dart';
13 import 'package:analyzer/dart/element/type.dart'; 13 import 'package:analyzer/dart/element/type.dart';
14 import 'package:analyzer/dart/element/visitor.dart'; 14 import 'package:analyzer/dart/element/visitor.dart';
15 import 'package:analyzer/error/error.dart'; 15 import 'package:analyzer/error/error.dart';
16 import 'package:analyzer/error/listener.dart'; 16 import 'package:analyzer/error/listener.dart';
17 import 'package:analyzer/exception/exception.dart'; 17 import 'package:analyzer/exception/exception.dart';
18 import 'package:analyzer/src/dart/ast/ast.dart'; 18 import 'package:analyzer/src/dart/ast/ast.dart';
19 import 'package:analyzer/src/dart/ast/utilities.dart'; 19 import 'package:analyzer/src/dart/ast/utilities.dart';
20 import 'package:analyzer/src/dart/element/element.dart'; 20 import 'package:analyzer/src/dart/element/element.dart';
21 import 'package:analyzer/src/dart/element/type.dart'; 21 import 'package:analyzer/src/dart/element/type.dart';
22 import 'package:analyzer/src/dart/element/utilities.dart';
23 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; 22 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
24 import 'package:analyzer/src/dart/resolver/scope.dart'; 23 import 'package:analyzer/src/dart/resolver/scope.dart';
25 import 'package:analyzer/src/error/codes.dart'; 24 import 'package:analyzer/src/error/codes.dart';
26 import 'package:analyzer/src/generated/constant.dart'; 25 import 'package:analyzer/src/generated/constant.dart';
27 import 'package:analyzer/src/generated/element_resolver.dart'; 26 import 'package:analyzer/src/generated/element_resolver.dart';
28 import 'package:analyzer/src/generated/engine.dart'; 27 import 'package:analyzer/src/generated/engine.dart';
29 import 'package:analyzer/src/generated/error_verifier.dart'; 28 import 'package:analyzer/src/generated/error_verifier.dart';
30 import 'package:analyzer/src/generated/source.dart'; 29 import 'package:analyzer/src/generated/source.dart';
31 import 'package:analyzer/src/generated/static_type_analyzer.dart'; 30 import 'package:analyzer/src/generated/static_type_analyzer.dart';
32 import 'package:analyzer/src/generated/type_system.dart'; 31 import 'package:analyzer/src/generated/type_system.dart';
(...skipping 2227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 } 2259 }
2261 if (element is PropertyAccessorElement) { 2260 if (element is PropertyAccessorElement) {
2262 PropertyInducingElement variable = element.variable; 2261 PropertyInducingElement variable = element.variable;
2263 return variable != null && variable.isConst; 2262 return variable != null && variable.isConst;
2264 } 2263 }
2265 return false; 2264 return false;
2266 } 2265 }
2267 } 2266 }
2268 2267
2269 /** 2268 /**
2270 * A visitor that resolves declarations in an AST structure to already built
2271 * elements.
2272 *
2273 * The resulting AST must have everything resolved that would have been resolved
2274 * by a [CompilationUnitBuilder] (that is, must be a valid [RESOLVED_UNIT1]).
2275 * This class must not assume that the [CompilationUnitElement] passed to it is
2276 * any more complete than a [COMPILATION_UNIT_ELEMENT].
2277 */
2278 class DeclarationResolver extends RecursiveAstVisitor<Object>
2279 with ExistingElementResolver {
2280 /**
2281 * The analysis context containing the sources to be analyzed.
2282 */
2283 AnalysisContext _context;
2284
2285 /**
2286 * The elements that are reachable from the compilation unit element. When a
2287 * compilation unit has been resolved, this set should be empty.
2288 */
2289 Set<Element> _expectedElements;
2290
2291 /**
2292 * The function type alias containing the AST nodes being visited, or `null`
2293 * if we are not in the scope of a function type alias.
2294 */
2295 FunctionTypeAliasElement _enclosingAlias;
2296
2297 /**
2298 * The class containing the AST nodes being visited, or `null` if we are not
2299 * in the scope of a class.
2300 */
2301 ClassElement _enclosingClass;
2302
2303 /**
2304 * The method or function containing the AST nodes being visited, or `null` if
2305 * we are not in the scope of a method or function.
2306 */
2307 ExecutableElement _enclosingExecutable;
2308
2309 /**
2310 * The parameter containing the AST nodes being visited, or `null` if we are
2311 * not in the scope of a parameter.
2312 */
2313 ParameterElement _enclosingParameter;
2314
2315 /**
2316 * Resolve the declarations within the given compilation [unit] to the
2317 * elements rooted at the given [element]. Throw an [ElementMismatchException]
2318 * if the element model and compilation unit do not match each other.
2319 */
2320 void resolve(CompilationUnit unit, CompilationUnitElement element) {
2321 _context = element.context;
2322 ElementGatherer gatherer = new ElementGatherer();
2323 element.accept(gatherer);
2324 _expectedElements = gatherer.elements;
2325 _enclosingUnit = element;
2326 _expectedElements.remove(element);
2327 unit.element = element;
2328 unit.accept(this);
2329 _validateResolution();
2330 }
2331
2332 @override
2333 Object visitCatchClause(CatchClause node) {
2334 SimpleIdentifier exceptionParameter = node.exceptionParameter;
2335 if (exceptionParameter != null) {
2336 List<LocalVariableElement> localVariables =
2337 _enclosingExecutable.localVariables;
2338 _findIdentifier(localVariables, exceptionParameter);
2339 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
2340 if (stackTraceParameter != null) {
2341 _findIdentifier(localVariables, stackTraceParameter);
2342 }
2343 }
2344 return super.visitCatchClause(node);
2345 }
2346
2347 @override
2348 Object visitClassDeclaration(ClassDeclaration node) {
2349 ClassElement outerClass = _enclosingClass;
2350 try {
2351 SimpleIdentifier className = node.name;
2352 _enclosingClass = _findIdentifier(_enclosingUnit.types, className);
2353 super.visitClassDeclaration(node);
2354 _resolveMetadata(node, node.metadata, _enclosingClass);
2355 return null;
2356 } finally {
2357 _enclosingClass = outerClass;
2358 }
2359 }
2360
2361 @override
2362 Object visitClassTypeAlias(ClassTypeAlias node) {
2363 ClassElement outerClass = _enclosingClass;
2364 try {
2365 SimpleIdentifier className = node.name;
2366 _enclosingClass = _findIdentifier(_enclosingUnit.types, className);
2367 super.visitClassTypeAlias(node);
2368 _resolveMetadata(node, node.metadata, _enclosingClass);
2369 return null;
2370 } finally {
2371 _enclosingClass = outerClass;
2372 }
2373 }
2374
2375 @override
2376 Object visitConstructorDeclaration(ConstructorDeclaration node) {
2377 ExecutableElement outerExecutable = _enclosingExecutable;
2378 try {
2379 SimpleIdentifier constructorName = node.name;
2380 if (constructorName == null) {
2381 _enclosingExecutable = _enclosingClass.unnamedConstructor;
2382 if (_enclosingExecutable == null) {
2383 _mismatch('Could not find default constructor', node);
2384 }
2385 } else {
2386 _enclosingExecutable =
2387 _enclosingClass.getNamedConstructor(constructorName.name);
2388 if (_enclosingExecutable == null) {
2389 _mismatch(
2390 'Could not find constructor element with name "${constructorName.n ame}',
2391 node);
2392 }
2393 constructorName.staticElement = _enclosingExecutable;
2394 }
2395 _expectedElements.remove(_enclosingExecutable);
2396 node.element = _enclosingExecutable as ConstructorElement;
2397 super.visitConstructorDeclaration(node);
2398 _resolveMetadata(node, node.metadata, _enclosingExecutable);
2399 return null;
2400 } finally {
2401 _enclosingExecutable = outerExecutable;
2402 }
2403 }
2404
2405 @override
2406 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
2407 SimpleIdentifier variableName = node.identifier;
2408 Element element =
2409 _findIdentifier(_enclosingExecutable.localVariables, variableName);
2410 super.visitDeclaredIdentifier(node);
2411 _resolveMetadata(node, node.metadata, element);
2412 return null;
2413 }
2414
2415 @override
2416 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
2417 SimpleIdentifier parameterName = node.parameter.identifier;
2418 ParameterElement element = _getElementForParameter(node, parameterName);
2419 Expression defaultValue = node.defaultValue;
2420 if (defaultValue != null) {
2421 ExecutableElement outerExecutable = _enclosingExecutable;
2422 try {
2423 _enclosingExecutable = element.initializer;
2424 defaultValue.accept(this);
2425 } finally {
2426 _enclosingExecutable = outerExecutable;
2427 }
2428 }
2429 ParameterElement outerParameter = _enclosingParameter;
2430 try {
2431 _enclosingParameter = element;
2432 super.visitDefaultFormalParameter(node);
2433 _resolveMetadata(node, node.metadata, element);
2434 return null;
2435 } finally {
2436 _enclosingParameter = outerParameter;
2437 }
2438 }
2439
2440 @override
2441 Object visitEnumDeclaration(EnumDeclaration node) {
2442 ClassElement enclosingEnum =
2443 _findIdentifier(_enclosingUnit.enums, node.name);
2444 List<FieldElement> constants = enclosingEnum.fields;
2445 for (EnumConstantDeclaration constant in node.constants) {
2446 _findIdentifier(constants, constant.name);
2447 }
2448 super.visitEnumDeclaration(node);
2449 _resolveMetadata(node, node.metadata, enclosingEnum);
2450 return null;
2451 }
2452
2453 @override
2454 Object visitExportDirective(ExportDirective node) {
2455 super.visitExportDirective(node);
2456 _resolveAnnotations(
2457 node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
2458 return null;
2459 }
2460
2461 @override
2462 Object visitFieldDeclaration(FieldDeclaration node) {
2463 super.visitFieldDeclaration(node);
2464 _resolveMetadata(node, node.metadata, node.fields.variables[0].element);
2465 return null;
2466 }
2467
2468 @override
2469 Object visitFieldFormalParameter(FieldFormalParameter node) {
2470 if (node.parent is! DefaultFormalParameter) {
2471 SimpleIdentifier parameterName = node.identifier;
2472 ParameterElement element = _getElementForParameter(node, parameterName);
2473 ParameterElement outerParameter = _enclosingParameter;
2474 try {
2475 _enclosingParameter = element;
2476 super.visitFieldFormalParameter(node);
2477 _resolveMetadata(node, node.metadata, element);
2478 return null;
2479 } finally {
2480 _enclosingParameter = outerParameter;
2481 }
2482 } else {
2483 return super.visitFieldFormalParameter(node);
2484 }
2485 }
2486
2487 @override
2488 Object visitFunctionDeclaration(FunctionDeclaration node) {
2489 ExecutableElement outerExecutable = _enclosingExecutable;
2490 try {
2491 SimpleIdentifier functionName = node.name;
2492 Token property = node.propertyKeyword;
2493 if (property == null) {
2494 if (_enclosingExecutable != null) {
2495 _enclosingExecutable =
2496 _findIdentifier(_enclosingExecutable.functions, functionName);
2497 } else {
2498 _enclosingExecutable =
2499 _findIdentifier(_enclosingUnit.functions, functionName);
2500 }
2501 } else {
2502 if (_enclosingExecutable != null) {
2503 _enclosingExecutable =
2504 _findIdentifier(_enclosingExecutable.functions, functionName);
2505 } else {
2506 List<PropertyAccessorElement> accessors;
2507 if (_enclosingClass != null) {
2508 accessors = _enclosingClass.accessors;
2509 } else {
2510 accessors = _enclosingUnit.accessors;
2511 }
2512 PropertyAccessorElement accessor;
2513 if (property.keyword == Keyword.GET) {
2514 accessor = _findIdentifier(accessors, functionName);
2515 } else if (property.keyword == Keyword.SET) {
2516 accessor = _findWithNameAndOffset(accessors, functionName,
2517 functionName.name + '=', functionName.offset);
2518 _expectedElements.remove(accessor);
2519 functionName.staticElement = accessor;
2520 }
2521 _enclosingExecutable = accessor;
2522 }
2523 }
2524 node.functionExpression.element = _enclosingExecutable;
2525 super.visitFunctionDeclaration(node);
2526 _resolveMetadata(node, node.metadata, _enclosingExecutable);
2527 return null;
2528 } finally {
2529 _enclosingExecutable = outerExecutable;
2530 }
2531 }
2532
2533 @override
2534 Object visitFunctionExpression(FunctionExpression node) {
2535 if (node.parent is! FunctionDeclaration) {
2536 FunctionElement element = _findAtOffset(
2537 _enclosingExecutable.functions, node, node.beginToken.offset);
2538 _expectedElements.remove(element);
2539 node.element = element;
2540 }
2541 ExecutableElement outerExecutable = _enclosingExecutable;
2542 try {
2543 _enclosingExecutable = node.element;
2544 return super.visitFunctionExpression(node);
2545 } finally {
2546 _enclosingExecutable = outerExecutable;
2547 }
2548 }
2549
2550 @override
2551 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
2552 FunctionTypeAliasElement outerAlias = _enclosingAlias;
2553 try {
2554 SimpleIdentifier aliasName = node.name;
2555 _enclosingAlias =
2556 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName);
2557 super.visitFunctionTypeAlias(node);
2558 _resolveMetadata(node, node.metadata, _enclosingAlias);
2559 return null;
2560 } finally {
2561 _enclosingAlias = outerAlias;
2562 }
2563 }
2564
2565 @override
2566 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
2567 if (node.parent is! DefaultFormalParameter) {
2568 SimpleIdentifier parameterName = node.identifier;
2569 ParameterElement element = _getElementForParameter(node, parameterName);
2570 ParameterElement outerParameter = _enclosingParameter;
2571 try {
2572 _enclosingParameter = element;
2573 super.visitFunctionTypedFormalParameter(node);
2574 _resolveMetadata(node, node.metadata, _enclosingParameter);
2575 return null;
2576 } finally {
2577 _enclosingParameter = outerParameter;
2578 }
2579 } else {
2580 return super.visitFunctionTypedFormalParameter(node);
2581 }
2582 }
2583
2584 @override
2585 Object visitImportDirective(ImportDirective node) {
2586 super.visitImportDirective(node);
2587 _resolveAnnotations(
2588 node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
2589 return null;
2590 }
2591
2592 @override
2593 Object visitLabeledStatement(LabeledStatement node) {
2594 for (Label label in node.labels) {
2595 SimpleIdentifier labelName = label.label;
2596 _findIdentifier(_enclosingExecutable.labels, labelName);
2597 }
2598 return super.visitLabeledStatement(node);
2599 }
2600
2601 @override
2602 Object visitLibraryDirective(LibraryDirective node) {
2603 super.visitLibraryDirective(node);
2604 _resolveAnnotations(
2605 node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
2606 return null;
2607 }
2608
2609 @override
2610 Object visitMethodDeclaration(MethodDeclaration node) {
2611 ExecutableElement outerExecutable = _enclosingExecutable;
2612 try {
2613 Token property = node.propertyKeyword;
2614 SimpleIdentifier methodName = node.name;
2615 String nameOfMethod = methodName.name;
2616 if (property == null) {
2617 String elementName = nameOfMethod == '-' &&
2618 node.parameters != null &&
2619 node.parameters.parameters.isEmpty
2620 ? 'unary-'
2621 : nameOfMethod;
2622 _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods,
2623 methodName, elementName, methodName.offset);
2624 _expectedElements.remove(_enclosingExecutable);
2625 methodName.staticElement = _enclosingExecutable;
2626 } else {
2627 PropertyAccessorElement accessor;
2628 if (property.keyword == Keyword.GET) {
2629 accessor = _findIdentifier(_enclosingClass.accessors, methodName);
2630 } else if (property.keyword == Keyword.SET) {
2631 accessor = _findWithNameAndOffset(_enclosingClass.accessors,
2632 methodName, nameOfMethod + '=', methodName.offset);
2633 _expectedElements.remove(accessor);
2634 methodName.staticElement = accessor;
2635 }
2636 _enclosingExecutable = accessor;
2637 }
2638 super.visitMethodDeclaration(node);
2639 _resolveMetadata(node, node.metadata, _enclosingExecutable);
2640 return null;
2641 } finally {
2642 _enclosingExecutable = outerExecutable;
2643 }
2644 }
2645
2646 @override
2647 Object visitPartDirective(PartDirective node) {
2648 super.visitPartDirective(node);
2649 _resolveAnnotations(
2650 node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
2651 return null;
2652 }
2653
2654 @override
2655 Object visitPartOfDirective(PartOfDirective node) {
2656 node.element = _enclosingUnit.library;
2657 return super.visitPartOfDirective(node);
2658 }
2659
2660 @override
2661 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
2662 if (node.parent is! DefaultFormalParameter) {
2663 SimpleIdentifier parameterName = node.identifier;
2664 ParameterElement element = _getElementForParameter(node, parameterName);
2665 ParameterElement outerParameter = _enclosingParameter;
2666 try {
2667 _enclosingParameter = element;
2668 super.visitSimpleFormalParameter(node);
2669 _resolveMetadata(node, node.metadata, element);
2670 return null;
2671 } finally {
2672 _enclosingParameter = outerParameter;
2673 }
2674 } else {}
2675 return super.visitSimpleFormalParameter(node);
2676 }
2677
2678 @override
2679 Object visitSwitchCase(SwitchCase node) {
2680 for (Label label in node.labels) {
2681 SimpleIdentifier labelName = label.label;
2682 _findIdentifier(_enclosingExecutable.labels, labelName);
2683 }
2684 return super.visitSwitchCase(node);
2685 }
2686
2687 @override
2688 Object visitSwitchDefault(SwitchDefault node) {
2689 for (Label label in node.labels) {
2690 SimpleIdentifier labelName = label.label;
2691 _findIdentifier(_enclosingExecutable.labels, labelName);
2692 }
2693 return super.visitSwitchDefault(node);
2694 }
2695
2696 @override
2697 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
2698 super.visitTopLevelVariableDeclaration(node);
2699 _resolveMetadata(node, node.metadata, node.variables.variables[0].element);
2700 return null;
2701 }
2702
2703 @override
2704 Object visitTypeParameter(TypeParameter node) {
2705 SimpleIdentifier parameterName = node.name;
2706 Element element = null;
2707 if (_enclosingExecutable != null) {
2708 element = _findIdentifier(
2709 _enclosingExecutable.typeParameters, parameterName,
2710 required: false);
2711 }
2712 if (element == null) {
2713 if (_enclosingClass != null) {
2714 element =
2715 _findIdentifier(_enclosingClass.typeParameters, parameterName);
2716 } else if (_enclosingAlias != null) {
2717 element =
2718 _findIdentifier(_enclosingAlias.typeParameters, parameterName);
2719 }
2720 }
2721 if (element == null) {
2722 String name = parameterName.name;
2723 int offset = parameterName.offset;
2724 _mismatch(
2725 'Could not find type parameter with name "$name" at $offset', node);
2726 }
2727 super.visitTypeParameter(node);
2728 _resolveMetadata(node, node.metadata, element);
2729 return null;
2730 }
2731
2732 @override
2733 Object visitVariableDeclaration(VariableDeclaration node) {
2734 VariableElement element = null;
2735 SimpleIdentifier variableName = node.name;
2736 if (_enclosingExecutable != null) {
2737 element = _findIdentifier(
2738 _enclosingExecutable.localVariables, variableName,
2739 required: false);
2740 }
2741 if (element == null && _enclosingClass != null) {
2742 element = _findIdentifier(_enclosingClass.fields, variableName,
2743 required: false);
2744 }
2745 if (element == null && _enclosingUnit != null) {
2746 element = _findIdentifier(_enclosingUnit.topLevelVariables, variableName);
2747 }
2748 Expression initializer = node.initializer;
2749 if (initializer != null) {
2750 ExecutableElement outerExecutable = _enclosingExecutable;
2751 try {
2752 _enclosingExecutable = element.initializer;
2753 return super.visitVariableDeclaration(node);
2754 } finally {
2755 _enclosingExecutable = outerExecutable;
2756 }
2757 }
2758 return super.visitVariableDeclaration(node);
2759 }
2760
2761 @override
2762 Object visitVariableDeclarationList(VariableDeclarationList node) {
2763 super.visitVariableDeclarationList(node);
2764 if (node.parent is! FieldDeclaration &&
2765 node.parent is! TopLevelVariableDeclaration) {
2766 _resolveMetadata(node, node.metadata, node.variables[0].element);
2767 }
2768 return null;
2769 }
2770
2771 /**
2772 * Return the element in the given list of [elements] that was created for the
2773 * declaration at the given [offset]. Throw an [ElementMismatchException] if
2774 * an element at that offset cannot be found.
2775 *
2776 * This method should only be used when there is no name associated with the
2777 * node.
2778 */
2779 Element _findAtOffset(List<Element> elements, AstNode node, int offset) =>
2780 _findWithNameAndOffset(elements, node, '', offset);
2781
2782 /**
2783 * Return the element in the given list of [elements] that was created for the
2784 * declaration with the given [identifier]. As a side-effect, associate the
2785 * returned element with the identifier. Throw an [ElementMismatchException]
2786 * if an element corresponding to the identifier cannot be found unless
2787 * [required] is `false`, in which case return `null`.
2788 */
2789 Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier,
2790 {bool required: true}) {
2791 Element element = _findWithNameAndOffset(
2792 elements, identifier, identifier.name, identifier.offset,
2793 required: required);
2794 _expectedElements.remove(element);
2795 identifier.staticElement = element;
2796 return element;
2797 }
2798
2799 /**
2800 * Return the element in the given list of [elements] that was created for the
2801 * declaration with the given [name] at the given [offset]. Throw an
2802 * [ElementMismatchException] if an element corresponding to the identifier
2803 * cannot be found unless [required] is `false`, in which case return `null`.
2804 */
2805 Element _findWithNameAndOffset(
2806 List<Element> elements, AstNode node, String name, int offset,
2807 {bool required: true}) {
2808 int length = elements.length;
2809 for (int i = 0; i < length; i++) {
2810 Element element = elements[i];
2811 if (element.nameOffset == offset && element.name == name) {
2812 return element;
2813 }
2814 }
2815 if (!required) {
2816 return null;
2817 }
2818 for (int i = 0; i < length; i++) {
2819 Element element = elements[i];
2820 if (element.name == name) {
2821 _mismatch(
2822 'Found element with name "$name" at ${element.nameOffset}, '
2823 'but expected offset of $offset',
2824 node);
2825 }
2826 if (element.nameOffset == offset) {
2827 _mismatch(
2828 'Found element with name "${element.name}" at $offset, '
2829 'but expected element with name "$name"',
2830 node);
2831 }
2832 }
2833 _mismatch('Could not find element with name "$name" at $offset', node);
2834 return null; // Never reached
2835 }
2836
2837 /**
2838 * Search the most closely enclosing list of parameter elements for a
2839 * parameter, defined by the given [node], with the given [parameterName].
2840 * Return the element that was found, or throw an [ElementMismatchException]
2841 * if an element corresponding to the identifier cannot be found.
2842 */
2843 ParameterElement _getElementForParameter(
2844 FormalParameter node, SimpleIdentifier parameterName) {
2845 List<ParameterElement> parameters = null;
2846 if (_enclosingParameter != null) {
2847 parameters = _enclosingParameter.parameters;
2848 }
2849 if (parameters == null && _enclosingExecutable != null) {
2850 parameters = _enclosingExecutable.parameters;
2851 }
2852 if (parameters == null && _enclosingAlias != null) {
2853 parameters = _enclosingAlias.parameters;
2854 }
2855 if (parameters == null) {
2856 StringBuffer buffer = new StringBuffer();
2857 buffer.writeln('Could not find parameter in enclosing scope');
2858 buffer.writeln(
2859 '(_enclosingParameter == null) == ${_enclosingParameter == null}');
2860 buffer.writeln(
2861 '(_enclosingExecutable == null) == ${_enclosingExecutable == null}');
2862 buffer.writeln('(_enclosingAlias == null) == ${_enclosingAlias == null}');
2863 _mismatch(buffer.toString(), parameterName);
2864 }
2865 return _findIdentifier(parameters, parameterName);
2866 }
2867
2868 /**
2869 * Associate each of the annotation [nodes] with the corresponding
2870 * [ElementAnnotation] in [annotations]. If there is a problem, report it
2871 * against the given [parent] node.
2872 */
2873 void _resolveAnnotations(AstNode parent, NodeList<Annotation> nodes,
2874 List<ElementAnnotation> annotations) {
2875 int nodeCount = nodes.length;
2876 if (nodeCount != annotations.length) {
2877 _mismatch(
2878 'Found $nodeCount annotation nodes and '
2879 '${annotations.length} element annotations',
2880 parent);
2881 }
2882 for (int i = 0; i < nodeCount; i++) {
2883 nodes[i].elementAnnotation = annotations[i];
2884 }
2885 }
2886
2887 /**
2888 * If [element] is not `null`, associate each of the annotation [nodes] with
2889 * the corresponding [ElementAnnotation] in [element.metadata]. If there is a
2890 * problem, report it against the given [parent] node.
2891 *
2892 * If [element] is `null`, do nothing--this allows us to be robust in the
2893 * case where we are operating on an element model that hasn't been fully
2894 * built.
2895 */
2896 void _resolveMetadata(
2897 AstNode parent, NodeList<Annotation> nodes, Element element) {
2898 if (element != null) {
2899 _resolveAnnotations(parent, nodes, element.metadata);
2900 }
2901 }
2902
2903 /**
2904 * Throw an exception if there are non-synthetic elements in the element model
2905 * that were not associated with an AST node.
2906 */
2907 void _validateResolution() {
2908 if (_expectedElements.isNotEmpty) {
2909 StringBuffer buffer = new StringBuffer();
2910 buffer.write(_expectedElements.length);
2911 buffer.writeln(' unmatched elements found:');
2912 for (Element element in _expectedElements) {
2913 buffer.write(' ');
2914 buffer.writeln(element);
2915 }
2916 throw new ElementMismatchException(buffer.toString());
2917 }
2918 }
2919 }
2920
2921 /**
2922 * A visitor that resolves directives in an AST structure to already built 2269 * A visitor that resolves directives in an AST structure to already built
2923 * elements. 2270 * elements.
2924 * 2271 *
2925 * The resulting AST must have everything resolved that would have been resolved 2272 * The resulting AST must have everything resolved that would have been resolved
2926 * by a [DirectiveElementBuilder]. 2273 * by a [DirectiveElementBuilder].
2927 */ 2274 */
2928 class DirectiveResolver extends SimpleAstVisitor { 2275 class DirectiveResolver extends SimpleAstVisitor {
2929 LibraryElement _enclosingLibrary; 2276 LibraryElement _enclosingLibrary;
2930 2277
2931 @override 2278 @override
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
3324 buffer.write(_typeParameters.length); 2671 buffer.write(_typeParameters.length);
3325 buffer.write(" type parameters"); 2672 buffer.write(" type parameters");
3326 } 2673 }
3327 if (buffer.length > 0) { 2674 if (buffer.length > 0) {
3328 AnalysisEngine.instance.logger 2675 AnalysisEngine.instance.logger
3329 .logError("Failed to capture elements: $buffer"); 2676 .logError("Failed to capture elements: $buffer");
3330 } 2677 }
3331 } 2678 }
3332 } 2679 }
3333 2680
3334 class ElementMismatchException extends AnalysisException {
3335 /**
3336 * Initialize a newly created exception to have the given [message] and
3337 * [cause].
3338 */
3339 ElementMismatchException(String message, [CaughtException cause = null])
3340 : super(message, cause);
3341 }
3342
3343 /** 2681 /**
3344 * Instances of the class `EnumMemberBuilder` build the members in enum declarat ions. 2682 * Instances of the class `EnumMemberBuilder` build the members in enum declarat ions.
3345 */ 2683 */
3346 class EnumMemberBuilder extends RecursiveAstVisitor<Object> { 2684 class EnumMemberBuilder extends RecursiveAstVisitor<Object> {
3347 /** 2685 /**
3348 * The type provider used to access the types needed to build an element model for enum 2686 * The type provider used to access the types needed to build an element model for enum
3349 * declarations. 2687 * declarations.
3350 */ 2688 */
3351 final TypeProvider _typeProvider; 2689 final TypeProvider _typeProvider;
3352 2690
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3424 2762
3425 /** 2763 /**
3426 * Create a getter that corresponds to the given [field]. 2764 * Create a getter that corresponds to the given [field].
3427 */ 2765 */
3428 PropertyAccessorElement _createGetter(FieldElementImpl field) { 2766 PropertyAccessorElement _createGetter(FieldElementImpl field) {
3429 return new PropertyAccessorElementImpl_ImplicitGetter(field); 2767 return new PropertyAccessorElementImpl_ImplicitGetter(field);
3430 } 2768 }
3431 } 2769 }
3432 2770
3433 /** 2771 /**
3434 * A mixin for classes that use an existing element model to resolve a portion
3435 * of an AST structure.
3436 */
3437 class ExistingElementResolver {
3438 /**
3439 * The compilation unit containing the AST nodes being visited.
3440 */
3441 CompilationUnitElementImpl _enclosingUnit;
3442
3443 /**
3444 * Throw an [ElementMismatchException] to report that the element model and th e
3445 * AST do not match. The [message] will have the path to the given [node]
3446 * appended to it.
3447 */
3448 void _mismatch(String message, AstNode node) {
3449 StringBuffer buffer = new StringBuffer();
3450 buffer.write('Mismatch in ');
3451 buffer.write(runtimeType);
3452 buffer.write(' while resolving ');
3453 buffer.writeln(_enclosingUnit?.source?.fullName);
3454 buffer.writeln(message);
3455 buffer.write('Path to root:');
3456 String separator = ' ';
3457 AstNode parent = node;
3458 while (parent != null) {
3459 buffer.write(separator);
3460 buffer.write(parent.runtimeType.toString());
3461 separator = ', ';
3462 parent = parent.parent;
3463 }
3464 throw new ElementMismatchException(buffer.toString());
3465 }
3466 }
3467
3468 /**
3469 * Instances of the class `ExitDetector` determine whether the visited AST node is guaranteed 2772 * Instances of the class `ExitDetector` determine whether the visited AST node is guaranteed
3470 * to terminate by executing a `return` statement, `throw` expression, `rethrow` 2773 * to terminate by executing a `return` statement, `throw` expression, `rethrow`
3471 * expression, or simple infinite loop such as `while(true)`. 2774 * expression, or simple infinite loop such as `while(true)`.
3472 */ 2775 */
3473 class ExitDetector extends GeneralizingAstVisitor<bool> { 2776 class ExitDetector extends GeneralizingAstVisitor<bool> {
3474 /** 2777 /**
3475 * Set to `true` when a `break` is encountered, and reset to `false` when a 2778 * Set to `true` when a `break` is encountered, and reset to `false` when a
3476 * `do`, `while`, `for` or `switch` block is entered. 2779 * `do`, `while`, `for` or `switch` block is entered.
3477 */ 2780 */
3478 bool _enclosingBlockContainsBreak = false; 2781 bool _enclosingBlockContainsBreak = false;
(...skipping 7794 matching lines...) Expand 10 before | Expand all | Expand 10 after
11273 return null; 10576 return null;
11274 } 10577 }
11275 if (identical(node.staticElement, variable)) { 10578 if (identical(node.staticElement, variable)) {
11276 if (node.inSetterContext()) { 10579 if (node.inSetterContext()) {
11277 result = true; 10580 result = true;
11278 } 10581 }
11279 } 10582 }
11280 return null; 10583 return null;
11281 } 10584 }
11282 } 10585 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/declaration_resolver.dart ('k') | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698