| 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.resolver; | 5 library engine.resolver; |
| 6 | 6 |
| 7 import "dart:math" as math; | 7 import "dart:math" as math; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'ast.dart'; | 10 import 'ast.dart'; |
| (...skipping 2418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2429 * @param node the node to be visited | 2429 * @param node the node to be visited |
| 2430 */ | 2430 */ |
| 2431 void _safelyVisit(AstNode node) { | 2431 void _safelyVisit(AstNode node) { |
| 2432 if (node != null) { | 2432 if (node != null) { |
| 2433 node.accept(this); | 2433 node.accept(this); |
| 2434 } | 2434 } |
| 2435 } | 2435 } |
| 2436 } | 2436 } |
| 2437 | 2437 |
| 2438 /** | 2438 /** |
| 2439 * Instances of the class `DeclarationMatcher` determine whether the element mod
el defined by | |
| 2440 * a given AST structure matches an existing element model. | |
| 2441 */ | |
| 2442 class DeclarationMatcher extends RecursiveAstVisitor<Object> { | |
| 2443 /** | |
| 2444 * The compilation unit containing the AST nodes being visited. | |
| 2445 */ | |
| 2446 CompilationUnitElement _enclosingUnit; | |
| 2447 | |
| 2448 /** | |
| 2449 * The function type alias containing the AST nodes being visited, or `null` i
f we are not | |
| 2450 * in the scope of a function type alias. | |
| 2451 */ | |
| 2452 FunctionTypeAliasElement _enclosingAlias; | |
| 2453 | |
| 2454 /** | |
| 2455 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of | |
| 2456 * a class. | |
| 2457 */ | |
| 2458 ClassElement _enclosingClass; | |
| 2459 | |
| 2460 /** | |
| 2461 * The method or function containing the AST nodes being visited, or `null` if
we are not in | |
| 2462 * the scope of a method or function. | |
| 2463 */ | |
| 2464 ExecutableElement _enclosingExecutable; | |
| 2465 | |
| 2466 /** | |
| 2467 * The parameter containing the AST nodes being visited, or `null` if we are n
ot in the | |
| 2468 * scope of a parameter. | |
| 2469 */ | |
| 2470 ParameterElement _enclosingParameter; | |
| 2471 | |
| 2472 /** | |
| 2473 * A set containing all of the elements in the element model that were defined
by the old AST node | |
| 2474 * corresponding to the AST node being visited. | |
| 2475 */ | |
| 2476 HashSet<Element> _allElements = new HashSet<Element>(); | |
| 2477 | |
| 2478 /** | |
| 2479 * A set containing all of the elements in the element model that were defined
by the old AST node | |
| 2480 * corresponding to the AST node being visited that have not already been matc
hed to nodes in the | |
| 2481 * AST structure being visited. | |
| 2482 */ | |
| 2483 HashSet<Element> _unmatchedElements = new HashSet<Element>(); | |
| 2484 | |
| 2485 /** | |
| 2486 * Return `true` if the declarations within the given AST structure define an
element model | |
| 2487 * that is equivalent to the corresponding elements rooted at the given elemen
t. | |
| 2488 * | |
| 2489 * @param node the AST structure being compared to the element model | |
| 2490 * @param element the root of the element model being compared to the AST stru
cture | |
| 2491 * @return `true` if the AST structure defines the same elements as those in t
he given | |
| 2492 * element model | |
| 2493 */ | |
| 2494 bool matches(AstNode node, Element element) { | |
| 2495 _captureEnclosingElements(element); | |
| 2496 _gatherElements(element); | |
| 2497 try { | |
| 2498 node.accept(this); | |
| 2499 } on DeclarationMatcher_DeclarationMismatchException catch (exception) { | |
| 2500 return false; | |
| 2501 } | |
| 2502 return _unmatchedElements.isEmpty; | |
| 2503 } | |
| 2504 | |
| 2505 void processElement(Element element) { | |
| 2506 if (element == null) { | |
| 2507 throw new DeclarationMatcher_DeclarationMismatchException(); | |
| 2508 } | |
| 2509 if (!_allElements.contains(element)) { | |
| 2510 throw new DeclarationMatcher_DeclarationMismatchException(); | |
| 2511 } | |
| 2512 _unmatchedElements.remove(element); | |
| 2513 } | |
| 2514 | |
| 2515 @override | |
| 2516 Object visitCatchClause(CatchClause node) { | |
| 2517 SimpleIdentifier exceptionParameter = node.exceptionParameter; | |
| 2518 if (exceptionParameter != null) { | |
| 2519 List<LocalVariableElement> localVariables = | |
| 2520 _enclosingExecutable.localVariables; | |
| 2521 LocalVariableElement exceptionElement = | |
| 2522 _findIdentifier(localVariables, exceptionParameter); | |
| 2523 processElement(exceptionElement); | |
| 2524 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | |
| 2525 if (stackTraceParameter != null) { | |
| 2526 LocalVariableElement stackTraceElement = | |
| 2527 _findIdentifier(localVariables, stackTraceParameter); | |
| 2528 processElement(stackTraceElement); | |
| 2529 } | |
| 2530 } | |
| 2531 return super.visitCatchClause(node); | |
| 2532 } | |
| 2533 | |
| 2534 @override | |
| 2535 Object visitClassDeclaration(ClassDeclaration node) { | |
| 2536 ClassElement outerClass = _enclosingClass; | |
| 2537 try { | |
| 2538 SimpleIdentifier className = node.name; | |
| 2539 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); | |
| 2540 processElement(_enclosingClass); | |
| 2541 if (!_hasConstructor(node)) { | |
| 2542 ConstructorElement constructor = _enclosingClass.unnamedConstructor; | |
| 2543 if (constructor.isSynthetic) { | |
| 2544 processElement(constructor); | |
| 2545 } | |
| 2546 } | |
| 2547 return super.visitClassDeclaration(node); | |
| 2548 } finally { | |
| 2549 _enclosingClass = outerClass; | |
| 2550 } | |
| 2551 } | |
| 2552 | |
| 2553 @override | |
| 2554 Object visitClassTypeAlias(ClassTypeAlias node) { | |
| 2555 ClassElement outerClass = _enclosingClass; | |
| 2556 try { | |
| 2557 SimpleIdentifier className = node.name; | |
| 2558 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); | |
| 2559 processElement(_enclosingClass); | |
| 2560 return super.visitClassTypeAlias(node); | |
| 2561 } finally { | |
| 2562 _enclosingClass = outerClass; | |
| 2563 } | |
| 2564 } | |
| 2565 | |
| 2566 @override | |
| 2567 Object visitCompilationUnit(CompilationUnit node) { | |
| 2568 processElement(_enclosingUnit); | |
| 2569 return super.visitCompilationUnit(node); | |
| 2570 } | |
| 2571 | |
| 2572 @override | |
| 2573 Object visitConstructorDeclaration(ConstructorDeclaration node) { | |
| 2574 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 2575 try { | |
| 2576 SimpleIdentifier constructorName = node.name; | |
| 2577 if (constructorName == null) { | |
| 2578 _enclosingExecutable = _enclosingClass.unnamedConstructor; | |
| 2579 } else { | |
| 2580 _enclosingExecutable = | |
| 2581 _enclosingClass.getNamedConstructor(constructorName.name); | |
| 2582 } | |
| 2583 processElement(_enclosingExecutable); | |
| 2584 return super.visitConstructorDeclaration(node); | |
| 2585 } finally { | |
| 2586 _enclosingExecutable = outerExecutable; | |
| 2587 } | |
| 2588 } | |
| 2589 | |
| 2590 @override | |
| 2591 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | |
| 2592 SimpleIdentifier variableName = node.identifier; | |
| 2593 LocalVariableElement element = | |
| 2594 _findIdentifier(_enclosingExecutable.localVariables, variableName); | |
| 2595 processElement(element); | |
| 2596 return super.visitDeclaredIdentifier(node); | |
| 2597 } | |
| 2598 | |
| 2599 @override | |
| 2600 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | |
| 2601 SimpleIdentifier parameterName = node.parameter.identifier; | |
| 2602 ParameterElement element = _getElementForParameter(node, parameterName); | |
| 2603 Expression defaultValue = node.defaultValue; | |
| 2604 if (defaultValue != null) { | |
| 2605 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 2606 try { | |
| 2607 if (element == null) { | |
| 2608 // TODO(brianwilkerson) Report this internal error. | |
| 2609 } else { | |
| 2610 _enclosingExecutable = element.initializer; | |
| 2611 } | |
| 2612 defaultValue.accept(this); | |
| 2613 } finally { | |
| 2614 _enclosingExecutable = outerExecutable; | |
| 2615 } | |
| 2616 processElement(_enclosingExecutable); | |
| 2617 } | |
| 2618 ParameterElement outerParameter = _enclosingParameter; | |
| 2619 try { | |
| 2620 _enclosingParameter = element; | |
| 2621 processElement(_enclosingParameter); | |
| 2622 return super.visitDefaultFormalParameter(node); | |
| 2623 } finally { | |
| 2624 _enclosingParameter = outerParameter; | |
| 2625 } | |
| 2626 } | |
| 2627 | |
| 2628 @override | |
| 2629 Object visitEnumDeclaration(EnumDeclaration node) { | |
| 2630 ClassElement enclosingEnum = | |
| 2631 _findIdentifier(_enclosingUnit.enums, node.name); | |
| 2632 processElement(enclosingEnum); | |
| 2633 List<FieldElement> constants = enclosingEnum.fields; | |
| 2634 for (EnumConstantDeclaration constant in node.constants) { | |
| 2635 FieldElement constantElement = _findIdentifier(constants, constant.name); | |
| 2636 processElement(constantElement); | |
| 2637 } | |
| 2638 return super.visitEnumDeclaration(node); | |
| 2639 } | |
| 2640 | |
| 2641 @override | |
| 2642 Object visitExportDirective(ExportDirective node) { | |
| 2643 String uri = _getStringValue(node.uri); | |
| 2644 if (uri != null) { | |
| 2645 LibraryElement library = _enclosingUnit.library; | |
| 2646 ExportElement exportElement = _findExport( | |
| 2647 library.exports, | |
| 2648 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri)); | |
| 2649 processElement(exportElement); | |
| 2650 } | |
| 2651 return super.visitExportDirective(node); | |
| 2652 } | |
| 2653 | |
| 2654 @override | |
| 2655 Object visitFieldFormalParameter(FieldFormalParameter node) { | |
| 2656 if (node.parent is! DefaultFormalParameter) { | |
| 2657 SimpleIdentifier parameterName = node.identifier; | |
| 2658 ParameterElement element = _getElementForParameter(node, parameterName); | |
| 2659 ParameterElement outerParameter = _enclosingParameter; | |
| 2660 try { | |
| 2661 _enclosingParameter = element; | |
| 2662 processElement(_enclosingParameter); | |
| 2663 return super.visitFieldFormalParameter(node); | |
| 2664 } finally { | |
| 2665 _enclosingParameter = outerParameter; | |
| 2666 } | |
| 2667 } else { | |
| 2668 return super.visitFieldFormalParameter(node); | |
| 2669 } | |
| 2670 } | |
| 2671 | |
| 2672 @override | |
| 2673 Object visitFunctionDeclaration(FunctionDeclaration node) { | |
| 2674 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 2675 try { | |
| 2676 SimpleIdentifier functionName = node.name; | |
| 2677 sc.Token property = node.propertyKeyword; | |
| 2678 if (property == null) { | |
| 2679 if (_enclosingExecutable != null) { | |
| 2680 _enclosingExecutable = | |
| 2681 _findIdentifier(_enclosingExecutable.functions, functionName); | |
| 2682 } else { | |
| 2683 _enclosingExecutable = | |
| 2684 _findIdentifier(_enclosingUnit.functions, functionName); | |
| 2685 } | |
| 2686 } else { | |
| 2687 PropertyAccessorElement accessor = | |
| 2688 _findIdentifier(_enclosingUnit.accessors, functionName); | |
| 2689 if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) { | |
| 2690 accessor = accessor.variable.setter; | |
| 2691 } | |
| 2692 _enclosingExecutable = accessor; | |
| 2693 } | |
| 2694 processElement(_enclosingExecutable); | |
| 2695 return super.visitFunctionDeclaration(node); | |
| 2696 } finally { | |
| 2697 _enclosingExecutable = outerExecutable; | |
| 2698 } | |
| 2699 } | |
| 2700 | |
| 2701 @override | |
| 2702 Object visitFunctionExpression(FunctionExpression node) { | |
| 2703 if (node.parent is! FunctionDeclaration) { | |
| 2704 FunctionElement element = | |
| 2705 _findAtOffset(_enclosingExecutable.functions, node.beginToken.offset); | |
| 2706 processElement(element); | |
| 2707 } | |
| 2708 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 2709 try { | |
| 2710 _enclosingExecutable = node.element; | |
| 2711 processElement(_enclosingExecutable); | |
| 2712 return super.visitFunctionExpression(node); | |
| 2713 } finally { | |
| 2714 _enclosingExecutable = outerExecutable; | |
| 2715 } | |
| 2716 } | |
| 2717 | |
| 2718 @override | |
| 2719 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | |
| 2720 FunctionTypeAliasElement outerAlias = _enclosingAlias; | |
| 2721 try { | |
| 2722 SimpleIdentifier aliasName = node.name; | |
| 2723 _enclosingAlias = | |
| 2724 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); | |
| 2725 processElement(_enclosingAlias); | |
| 2726 return super.visitFunctionTypeAlias(node); | |
| 2727 } finally { | |
| 2728 _enclosingAlias = outerAlias; | |
| 2729 } | |
| 2730 } | |
| 2731 | |
| 2732 @override | |
| 2733 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | |
| 2734 if (node.parent is! DefaultFormalParameter) { | |
| 2735 SimpleIdentifier parameterName = node.identifier; | |
| 2736 ParameterElement element = _getElementForParameter(node, parameterName); | |
| 2737 ParameterElement outerParameter = _enclosingParameter; | |
| 2738 try { | |
| 2739 _enclosingParameter = element; | |
| 2740 processElement(_enclosingParameter); | |
| 2741 return super.visitFunctionTypedFormalParameter(node); | |
| 2742 } finally { | |
| 2743 _enclosingParameter = outerParameter; | |
| 2744 } | |
| 2745 } else { | |
| 2746 return super.visitFunctionTypedFormalParameter(node); | |
| 2747 } | |
| 2748 } | |
| 2749 | |
| 2750 @override | |
| 2751 Object visitImportDirective(ImportDirective node) { | |
| 2752 String uri = _getStringValue(node.uri); | |
| 2753 if (uri != null) { | |
| 2754 LibraryElement library = _enclosingUnit.library; | |
| 2755 ImportElement importElement = _findImport( | |
| 2756 library.imports, | |
| 2757 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri), | |
| 2758 node.prefix); | |
| 2759 processElement(importElement); | |
| 2760 } | |
| 2761 return super.visitImportDirective(node); | |
| 2762 } | |
| 2763 | |
| 2764 @override | |
| 2765 Object visitLabeledStatement(LabeledStatement node) { | |
| 2766 for (Label label in node.labels) { | |
| 2767 SimpleIdentifier labelName = label.label; | |
| 2768 LabelElement element = | |
| 2769 _findIdentifier(_enclosingExecutable.labels, labelName); | |
| 2770 processElement(element); | |
| 2771 } | |
| 2772 return super.visitLabeledStatement(node); | |
| 2773 } | |
| 2774 | |
| 2775 @override | |
| 2776 Object visitMethodDeclaration(MethodDeclaration node) { | |
| 2777 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 2778 try { | |
| 2779 sc.Token property = node.propertyKeyword; | |
| 2780 SimpleIdentifier methodName = node.name; | |
| 2781 String nameOfMethod = methodName.name; | |
| 2782 if (nameOfMethod == sc.TokenType.MINUS.lexeme && | |
| 2783 node.parameters.parameters.length == 0) { | |
| 2784 nameOfMethod = "unary-"; | |
| 2785 } | |
| 2786 if (property == null) { | |
| 2787 _enclosingExecutable = _findWithNameAndOffset( | |
| 2788 _enclosingClass.methods, | |
| 2789 nameOfMethod, | |
| 2790 methodName.offset); | |
| 2791 methodName.staticElement = _enclosingExecutable; | |
| 2792 } else { | |
| 2793 PropertyAccessorElement accessor = | |
| 2794 _findIdentifier(_enclosingClass.accessors, methodName); | |
| 2795 if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) { | |
| 2796 accessor = accessor.variable.setter; | |
| 2797 methodName.staticElement = accessor; | |
| 2798 } | |
| 2799 _enclosingExecutable = accessor; | |
| 2800 } | |
| 2801 processElement(_enclosingExecutable); | |
| 2802 return super.visitMethodDeclaration(node); | |
| 2803 } finally { | |
| 2804 _enclosingExecutable = outerExecutable; | |
| 2805 } | |
| 2806 } | |
| 2807 | |
| 2808 @override | |
| 2809 Object visitPartDirective(PartDirective node) { | |
| 2810 String uri = _getStringValue(node.uri); | |
| 2811 if (uri != null) { | |
| 2812 Source partSource = | |
| 2813 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri); | |
| 2814 CompilationUnitElement element = | |
| 2815 _findPart(_enclosingUnit.library.parts, partSource); | |
| 2816 processElement(element); | |
| 2817 } | |
| 2818 return super.visitPartDirective(node); | |
| 2819 } | |
| 2820 | |
| 2821 @override | |
| 2822 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | |
| 2823 if (node.parent is! DefaultFormalParameter) { | |
| 2824 SimpleIdentifier parameterName = node.identifier; | |
| 2825 ParameterElement element = _getElementForParameter(node, parameterName); | |
| 2826 ParameterElement outerParameter = _enclosingParameter; | |
| 2827 try { | |
| 2828 _enclosingParameter = element; | |
| 2829 processElement(_enclosingParameter); | |
| 2830 return super.visitSimpleFormalParameter(node); | |
| 2831 } finally { | |
| 2832 _enclosingParameter = outerParameter; | |
| 2833 } | |
| 2834 } else { | |
| 2835 } | |
| 2836 return super.visitSimpleFormalParameter(node); | |
| 2837 } | |
| 2838 | |
| 2839 @override | |
| 2840 Object visitSwitchCase(SwitchCase node) { | |
| 2841 for (Label label in node.labels) { | |
| 2842 SimpleIdentifier labelName = label.label; | |
| 2843 LabelElement element = | |
| 2844 _findIdentifier(_enclosingExecutable.labels, labelName); | |
| 2845 processElement(element); | |
| 2846 } | |
| 2847 return super.visitSwitchCase(node); | |
| 2848 } | |
| 2849 | |
| 2850 @override | |
| 2851 Object visitSwitchDefault(SwitchDefault node) { | |
| 2852 for (Label label in node.labels) { | |
| 2853 SimpleIdentifier labelName = label.label; | |
| 2854 LabelElement element = | |
| 2855 _findIdentifier(_enclosingExecutable.labels, labelName); | |
| 2856 processElement(element); | |
| 2857 } | |
| 2858 return super.visitSwitchDefault(node); | |
| 2859 } | |
| 2860 | |
| 2861 @override | |
| 2862 Object visitTypeParameter(TypeParameter node) { | |
| 2863 SimpleIdentifier parameterName = node.name; | |
| 2864 TypeParameterElement element = null; | |
| 2865 if (_enclosingClass != null) { | |
| 2866 element = _findIdentifier(_enclosingClass.typeParameters, parameterName); | |
| 2867 } else if (_enclosingAlias != null) { | |
| 2868 element = _findIdentifier(_enclosingAlias.typeParameters, parameterName); | |
| 2869 } | |
| 2870 processElement(element); | |
| 2871 return super.visitTypeParameter(node); | |
| 2872 } | |
| 2873 | |
| 2874 @override | |
| 2875 Object visitVariableDeclaration(VariableDeclaration node) { | |
| 2876 VariableElement element = null; | |
| 2877 SimpleIdentifier variableName = node.name; | |
| 2878 if (_enclosingExecutable != null) { | |
| 2879 element = | |
| 2880 _findIdentifier(_enclosingExecutable.localVariables, variableName); | |
| 2881 } | |
| 2882 if (element == null && _enclosingClass != null) { | |
| 2883 element = _findIdentifier(_enclosingClass.fields, variableName); | |
| 2884 } | |
| 2885 if (element == null && _enclosingUnit != null) { | |
| 2886 element = _findIdentifier(_enclosingUnit.topLevelVariables, variableName); | |
| 2887 } | |
| 2888 Expression initializer = node.initializer; | |
| 2889 if (initializer != null) { | |
| 2890 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 2891 try { | |
| 2892 if (element == null) { | |
| 2893 // TODO(brianwilkerson) Report this internal error. | |
| 2894 } else { | |
| 2895 _enclosingExecutable = element.initializer; | |
| 2896 } | |
| 2897 processElement(element); | |
| 2898 processElement(_enclosingExecutable); | |
| 2899 return super.visitVariableDeclaration(node); | |
| 2900 } finally { | |
| 2901 _enclosingExecutable = outerExecutable; | |
| 2902 } | |
| 2903 } | |
| 2904 return super.visitVariableDeclaration(node); | |
| 2905 } | |
| 2906 | |
| 2907 /** | |
| 2908 * Given that the comparison is to begin with the given element, capture the e
nclosing elements | |
| 2909 * that might be used while performing the comparison. | |
| 2910 * | |
| 2911 * @param element the element corresponding to the AST structure to be compare
d | |
| 2912 */ | |
| 2913 void _captureEnclosingElements(Element element) { | |
| 2914 Element parent = | |
| 2915 element is CompilationUnitElement ? element : element.enclosingElement; | |
| 2916 while (parent != null) { | |
| 2917 if (parent is CompilationUnitElement) { | |
| 2918 _enclosingUnit = parent as CompilationUnitElement; | |
| 2919 } else if (parent is ClassElement) { | |
| 2920 if (_enclosingClass == null) { | |
| 2921 _enclosingClass = parent as ClassElement; | |
| 2922 } | |
| 2923 } else if (parent is FunctionTypeAliasElement) { | |
| 2924 if (_enclosingAlias == null) { | |
| 2925 _enclosingAlias = parent as FunctionTypeAliasElement; | |
| 2926 } | |
| 2927 } else if (parent is ExecutableElement) { | |
| 2928 if (_enclosingExecutable == null) { | |
| 2929 _enclosingExecutable = parent as ExecutableElement; | |
| 2930 } | |
| 2931 } else if (parent is ParameterElement) { | |
| 2932 if (_enclosingParameter == null) { | |
| 2933 _enclosingParameter = parent as ParameterElement; | |
| 2934 } | |
| 2935 } | |
| 2936 parent = parent.enclosingElement; | |
| 2937 } | |
| 2938 } | |
| 2939 | |
| 2940 /** | |
| 2941 * Return the element in the given array of elements that was created for the
declaration at the | |
| 2942 * given offset. This method should only be used when there is no name | |
| 2943 * | |
| 2944 * @param elements the elements of the appropriate kind that exist in the curr
ent context | |
| 2945 * @param offset the offset of the name of the element to be returned | |
| 2946 * @return the element at the given offset | |
| 2947 */ | |
| 2948 Element _findAtOffset(List<Element> elements, int offset) => | |
| 2949 _findWithNameAndOffset(elements, "", offset); | |
| 2950 | |
| 2951 /** | |
| 2952 * Return the export element from the given array whose library has the given
source, or | |
| 2953 * `null` if there is no such export. | |
| 2954 * | |
| 2955 * @param exports the export elements being searched | |
| 2956 * @param source the source of the library associated with the export element
to being searched | |
| 2957 * for | |
| 2958 * @return the export element whose library has the given source | |
| 2959 */ | |
| 2960 ExportElement _findExport(List<ExportElement> exports, Source source) { | |
| 2961 for (ExportElement export in exports) { | |
| 2962 if (export.exportedLibrary.source == source) { | |
| 2963 return export; | |
| 2964 } | |
| 2965 } | |
| 2966 return null; | |
| 2967 } | |
| 2968 | |
| 2969 /** | |
| 2970 * Return the element in the given array of elements that was created for the
declaration with the | |
| 2971 * given name. | |
| 2972 * | |
| 2973 * @param elements the elements of the appropriate kind that exist in the curr
ent context | |
| 2974 * @param identifier the name node in the declaration of the element to be ret
urned | |
| 2975 * @return the element created for the declaration with the given name | |
| 2976 */ | |
| 2977 Element _findIdentifier(List<Element> elements, | |
| 2978 SimpleIdentifier identifier) => | |
| 2979 _findWithNameAndOffset(elements, identifier.name, identifier.offset); | |
| 2980 | |
| 2981 /** | |
| 2982 * Return the import element from the given array whose library has the given
source and that has | |
| 2983 * the given prefix, or `null` if there is no such import. | |
| 2984 * | |
| 2985 * @param imports the import elements being searched | |
| 2986 * @param source the source of the library associated with the import element
to being searched | |
| 2987 * for | |
| 2988 * @param prefix the prefix with which the library was imported | |
| 2989 * @return the import element whose library has the given source and prefix | |
| 2990 */ | |
| 2991 ImportElement _findImport(List<ImportElement> imports, Source source, | |
| 2992 SimpleIdentifier prefix) { | |
| 2993 for (ImportElement element in imports) { | |
| 2994 if (element.importedLibrary.source == source) { | |
| 2995 PrefixElement prefixElement = element.prefix; | |
| 2996 if (prefix == null) { | |
| 2997 if (prefixElement == null) { | |
| 2998 return element; | |
| 2999 } | |
| 3000 } else { | |
| 3001 if (prefixElement != null && | |
| 3002 prefix.name == prefixElement.displayName) { | |
| 3003 return element; | |
| 3004 } | |
| 3005 } | |
| 3006 } | |
| 3007 } | |
| 3008 return null; | |
| 3009 } | |
| 3010 | |
| 3011 /** | |
| 3012 * Return the element for the part with the given source, or `null` if there i
s no element | |
| 3013 * for the given source. | |
| 3014 * | |
| 3015 * @param parts the elements for the parts | |
| 3016 * @param partSource the source for the part whose element is to be returned | |
| 3017 * @return the element for the part with the given source | |
| 3018 */ | |
| 3019 CompilationUnitElement _findPart(List<CompilationUnitElement> parts, | |
| 3020 Source partSource) { | |
| 3021 for (CompilationUnitElement part in parts) { | |
| 3022 if (part.source == partSource) { | |
| 3023 return part; | |
| 3024 } | |
| 3025 } | |
| 3026 return null; | |
| 3027 } | |
| 3028 | |
| 3029 /** | |
| 3030 * Return the element in the given array of elements that was created for the
declaration with the | |
| 3031 * given name at the given offset. | |
| 3032 * | |
| 3033 * @param elements the elements of the appropriate kind that exist in the curr
ent context | |
| 3034 * @param name the name of the element to be returned | |
| 3035 * @param offset the offset of the name of the element to be returned | |
| 3036 * @return the element with the given name and offset | |
| 3037 */ | |
| 3038 Element _findWithNameAndOffset(List<Element> elements, String name, | |
| 3039 int offset) { | |
| 3040 for (Element element in elements) { | |
| 3041 if (element.displayName == name && element.nameOffset == offset) { | |
| 3042 return element; | |
| 3043 } | |
| 3044 } | |
| 3045 return null; | |
| 3046 } | |
| 3047 | |
| 3048 void _gatherElements(Element element) { | |
| 3049 element.accept(new _DeclarationMatcher_gatherElements(this)); | |
| 3050 } | |
| 3051 | |
| 3052 /** | |
| 3053 * Search the most closely enclosing list of parameters for a parameter with t
he given name. | |
| 3054 * | |
| 3055 * @param node the node defining the parameter with the given name | |
| 3056 * @param parameterName the name of the parameter being searched for | |
| 3057 * @return the element representing the parameter with that name | |
| 3058 */ | |
| 3059 ParameterElement _getElementForParameter(FormalParameter node, | |
| 3060 SimpleIdentifier parameterName) { | |
| 3061 List<ParameterElement> parameters = null; | |
| 3062 if (_enclosingParameter != null) { | |
| 3063 parameters = _enclosingParameter.parameters; | |
| 3064 } | |
| 3065 if (parameters == null && _enclosingExecutable != null) { | |
| 3066 parameters = _enclosingExecutable.parameters; | |
| 3067 } | |
| 3068 if (parameters == null && _enclosingAlias != null) { | |
| 3069 parameters = _enclosingAlias.parameters; | |
| 3070 } | |
| 3071 return parameters == null ? | |
| 3072 null : | |
| 3073 _findIdentifier(parameters, parameterName); | |
| 3074 } | |
| 3075 | |
| 3076 /** | |
| 3077 * Return the value of the given string literal, or `null` if the string is no
t a constant | |
| 3078 * string without any string interpolation. | |
| 3079 * | |
| 3080 * @param literal the string literal whose value is to be returned | |
| 3081 * @return the value of the given string literal | |
| 3082 */ | |
| 3083 String _getStringValue(StringLiteral literal) { | |
| 3084 if (literal is StringInterpolation) { | |
| 3085 return null; | |
| 3086 } | |
| 3087 return literal.stringValue; | |
| 3088 } | |
| 3089 | |
| 3090 /** | |
| 3091 * Return `true` if the given class defines at least one constructor. | |
| 3092 * | |
| 3093 * @param node the class being tested | |
| 3094 * @return `true` if the class defines at least one constructor | |
| 3095 */ | |
| 3096 bool _hasConstructor(ClassDeclaration node) { | |
| 3097 for (ClassMember member in node.members) { | |
| 3098 if (member is ConstructorDeclaration) { | |
| 3099 return true; | |
| 3100 } | |
| 3101 } | |
| 3102 return false; | |
| 3103 } | |
| 3104 } | |
| 3105 | |
| 3106 /** | |
| 3107 * Instances of the class `DeclarationMismatchException` represent an exception
that is | |
| 3108 * thrown when the element model defined by a given AST structure does not match
an existing | |
| 3109 * element model. | |
| 3110 */ | |
| 3111 class DeclarationMatcher_DeclarationMismatchException extends RuntimeException { | |
| 3112 } | |
| 3113 | |
| 3114 /** | |
| 3115 * Instances of the class `DeclarationResolver` are used to resolve declarations
in an AST | 2439 * Instances of the class `DeclarationResolver` are used to resolve declarations
in an AST |
| 3116 * structure to already built elements. | 2440 * structure to already built elements. |
| 3117 */ | 2441 */ |
| 3118 class DeclarationResolver extends RecursiveAstVisitor<Object> { | 2442 class DeclarationResolver extends RecursiveAstVisitor<Object> { |
| 3119 /** | 2443 /** |
| 3120 * The compilation unit containing the AST nodes being visited. | 2444 * The compilation unit containing the AST nodes being visited. |
| 3121 */ | 2445 */ |
| 3122 CompilationUnitElement _enclosingUnit; | 2446 CompilationUnitElement _enclosingUnit; |
| 3123 | 2447 |
| 3124 /** | 2448 /** |
| (...skipping 3704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6829 */ | 6153 */ |
| 6830 void _visitMetadata(NodeList<Annotation> annotations) { | 6154 void _visitMetadata(NodeList<Annotation> annotations) { |
| 6831 int count = annotations.length; | 6155 int count = annotations.length; |
| 6832 for (int i = 0; i < count; i++) { | 6156 for (int i = 0; i < count; i++) { |
| 6833 annotations[i].accept(this); | 6157 annotations[i].accept(this); |
| 6834 } | 6158 } |
| 6835 } | 6159 } |
| 6836 } | 6160 } |
| 6837 | 6161 |
| 6838 /** | 6162 /** |
| 6839 * Instances of the class `IncrementalResolver` resolve the smallest portion of
an AST | |
| 6840 * structure that we currently know how to resolve. | |
| 6841 */ | |
| 6842 class IncrementalResolver { | |
| 6843 /** | |
| 6844 * The element for the library containing the compilation unit being visited. | |
| 6845 */ | |
| 6846 final LibraryElement _definingLibrary; | |
| 6847 | |
| 6848 /** | |
| 6849 * The source representing the compilation unit being visited. | |
| 6850 */ | |
| 6851 final Source _source; | |
| 6852 | |
| 6853 /** | |
| 6854 * The object used to access the types from the core library. | |
| 6855 */ | |
| 6856 final TypeProvider _typeProvider; | |
| 6857 | |
| 6858 /** | |
| 6859 * The error listener that will be informed of any errors that are found durin
g resolution. | |
| 6860 */ | |
| 6861 final AnalysisErrorListener _errorListener; | |
| 6862 | |
| 6863 /** | |
| 6864 * Initialize a newly created incremental resolver to resolve a node in the gi
ven source in the | |
| 6865 * given library, reporting errors to the given error listener. | |
| 6866 * | |
| 6867 * @param definingLibrary the element for the library containing the compilati
on unit being | |
| 6868 * visited | |
| 6869 * @param source the source representing the compilation unit being visited | |
| 6870 * @param typeProvider the object used to access the types from the core libra
ry | |
| 6871 * @param errorListener the error listener that will be informed of any errors
that are found | |
| 6872 * during resolution | |
| 6873 */ | |
| 6874 IncrementalResolver(this._definingLibrary, this._source, this._typeProvider, | |
| 6875 this._errorListener); | |
| 6876 | |
| 6877 /** | |
| 6878 * Resolve the given node, reporting any errors or warnings to the given liste
ner. | |
| 6879 * | |
| 6880 * @param node the root of the AST structure to be resolved | |
| 6881 * @throws AnalysisException if the node could not be resolved | |
| 6882 */ | |
| 6883 void resolve(AstNode node) { | |
| 6884 AstNode rootNode = _findResolutionRoot(node); | |
| 6885 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); | |
| 6886 if (_elementModelChanged(rootNode.parent)) { | |
| 6887 throw new AnalysisException("Cannot resolve node: element model changed"); | |
| 6888 } | |
| 6889 _resolveTypes(node, scope); | |
| 6890 _resolveVariables(node, scope); | |
| 6891 _resolveReferences(node, scope); | |
| 6892 } | |
| 6893 | |
| 6894 /** | |
| 6895 * Return `true` if the given node can be resolved independently of any other
nodes. | |
| 6896 * | |
| 6897 * <b>Note:</b> This method needs to be kept in sync with [ScopeBuilder.scopeF
orAstNode]. | |
| 6898 * | |
| 6899 * @param node the node being tested | |
| 6900 * @return `true` if the given node can be resolved independently of any other
nodes | |
| 6901 */ | |
| 6902 bool _canBeResolved(AstNode node) => | |
| 6903 node is ClassDeclaration || | |
| 6904 node is ClassTypeAlias || | |
| 6905 node is CompilationUnit || | |
| 6906 node is ConstructorDeclaration || | |
| 6907 node is FunctionDeclaration || | |
| 6908 node is FunctionTypeAlias || | |
| 6909 node is MethodDeclaration; | |
| 6910 | |
| 6911 /** | |
| 6912 * Return `true` if the portion of the element model defined by the given node
has changed. | |
| 6913 * | |
| 6914 * @param node the node defining the portion of the element model being tested | |
| 6915 * @return `true` if the element model defined by the given node has changed | |
| 6916 * @throws AnalysisException if the correctness of the element model cannot be
determined | |
| 6917 */ | |
| 6918 bool _elementModelChanged(AstNode node) { | |
| 6919 Element element = _getElement(node); | |
| 6920 if (element == null) { | |
| 6921 throw new AnalysisException( | |
| 6922 "Cannot resolve node: a ${node.runtimeType} does not define an element
"); | |
| 6923 } | |
| 6924 DeclarationMatcher matcher = new DeclarationMatcher(); | |
| 6925 return !matcher.matches(node, element); | |
| 6926 } | |
| 6927 | |
| 6928 /** | |
| 6929 * Starting at the given node, find the smallest AST node that can be resolved
independently of | |
| 6930 * any other nodes. Return the node that was found. | |
| 6931 * | |
| 6932 * @param node the node at which the search is to begin | |
| 6933 * @return the smallest AST node that can be resolved independently of any oth
er nodes | |
| 6934 * @throws AnalysisException if there is no such node | |
| 6935 */ | |
| 6936 AstNode _findResolutionRoot(AstNode node) { | |
| 6937 AstNode result = node; | |
| 6938 AstNode parent = result.parent; | |
| 6939 while (parent != null && !_canBeResolved(parent)) { | |
| 6940 result = parent; | |
| 6941 parent = result.parent; | |
| 6942 } | |
| 6943 if (parent == null) { | |
| 6944 throw new AnalysisException("Cannot resolve node: no resolvable node"); | |
| 6945 } | |
| 6946 return result; | |
| 6947 } | |
| 6948 | |
| 6949 /** | |
| 6950 * Return the element defined by the given node, or `null` if the node does no
t define an | |
| 6951 * element. | |
| 6952 * | |
| 6953 * @param node the node defining the element to be returned | |
| 6954 * @return the element defined by the given node | |
| 6955 */ | |
| 6956 Element _getElement(AstNode node) { | |
| 6957 if (node is Declaration) { | |
| 6958 return node.element; | |
| 6959 } else if (node is CompilationUnit) { | |
| 6960 return node.element; | |
| 6961 } | |
| 6962 return null; | |
| 6963 } | |
| 6964 | |
| 6965 void _resolveReferences(AstNode node, Scope scope) { | |
| 6966 ResolverVisitor visitor = new ResolverVisitor.con3( | |
| 6967 _definingLibrary, | |
| 6968 _source, | |
| 6969 _typeProvider, | |
| 6970 scope, | |
| 6971 _errorListener); | |
| 6972 node.accept(visitor); | |
| 6973 } | |
| 6974 | |
| 6975 void _resolveTypes(AstNode node, Scope scope) { | |
| 6976 TypeResolverVisitor visitor = new TypeResolverVisitor.con3( | |
| 6977 _definingLibrary, | |
| 6978 _source, | |
| 6979 _typeProvider, | |
| 6980 scope, | |
| 6981 _errorListener); | |
| 6982 node.accept(visitor); | |
| 6983 } | |
| 6984 | |
| 6985 void _resolveVariables(AstNode node, Scope scope) { | |
| 6986 VariableResolverVisitor visitor = new VariableResolverVisitor.con2( | |
| 6987 _definingLibrary, | |
| 6988 _source, | |
| 6989 _typeProvider, | |
| 6990 scope, | |
| 6991 _errorListener); | |
| 6992 node.accept(visitor); | |
| 6993 } | |
| 6994 } | |
| 6995 | |
| 6996 /** | |
| 6997 * Instances of the class `InheritanceManager` manage the knowledge of where cla
ss members | 6163 * Instances of the class `InheritanceManager` manage the knowledge of where cla
ss members |
| 6998 * (methods, getters & setters) are inherited from. | 6164 * (methods, getters & setters) are inherited from. |
| 6999 */ | 6165 */ |
| 7000 class InheritanceManager { | 6166 class InheritanceManager { |
| 7001 /** | 6167 /** |
| 7002 * The [LibraryElement] that is managed by this manager. | 6168 * The [LibraryElement] that is managed by this manager. |
| 7003 */ | 6169 */ |
| 7004 LibraryElement _library; | 6170 LibraryElement _library; |
| 7005 | 6171 |
| 7006 /** | 6172 /** |
| (...skipping 6418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13425 * Return `true` if the given name is a library-private name. | 12591 * Return `true` if the given name is a library-private name. |
| 13426 * | 12592 * |
| 13427 * @param name the name being tested | 12593 * @param name the name being tested |
| 13428 * @return `true` if the given name is a library-private name | 12594 * @return `true` if the given name is a library-private name |
| 13429 */ | 12595 */ |
| 13430 static bool isPrivateName(String name) => | 12596 static bool isPrivateName(String name) => |
| 13431 name != null && StringUtilities.startsWithChar(name, PRIVATE_NAME_PREFIX); | 12597 name != null && StringUtilities.startsWithChar(name, PRIVATE_NAME_PREFIX); |
| 13432 } | 12598 } |
| 13433 | 12599 |
| 13434 /** | 12600 /** |
| 13435 * Instances of the class `ScopeBuilder` build the scope for a given node in an
AST structure. | |
| 13436 * At the moment, this class only handles top-level and class-level declarations
. | |
| 13437 */ | |
| 13438 class ScopeBuilder { | |
| 13439 /** | |
| 13440 * The listener to which analysis errors will be reported. | |
| 13441 */ | |
| 13442 final AnalysisErrorListener _errorListener; | |
| 13443 | |
| 13444 /** | |
| 13445 * Initialize a newly created scope builder to generate a scope that will repo
rt errors to the | |
| 13446 * given listener. | |
| 13447 * | |
| 13448 * @param errorListener the listener to which analysis errors will be reported | |
| 13449 */ | |
| 13450 ScopeBuilder(this._errorListener); | |
| 13451 | |
| 13452 /** | |
| 13453 * Return the scope in which the given AST structure should be resolved. | |
| 13454 * | |
| 13455 * <b>Note:</b> This method needs to be kept in sync with | |
| 13456 * [IncrementalResolver.canBeResolved]. | |
| 13457 * | |
| 13458 * @param node the root of the AST structure to be resolved | |
| 13459 * @return the scope in which the given AST structure should be resolved | |
| 13460 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a | |
| 13461 * [CompilationUnit] | |
| 13462 */ | |
| 13463 Scope _scopeForAstNode(AstNode node) { | |
| 13464 if (node is CompilationUnit) { | |
| 13465 return _scopeForCompilationUnit(node); | |
| 13466 } | |
| 13467 AstNode parent = node.parent; | |
| 13468 if (parent == null) { | |
| 13469 throw new AnalysisException( | |
| 13470 "Cannot create scope: node is not part of a CompilationUnit"); | |
| 13471 } | |
| 13472 Scope scope = _scopeForAstNode(parent); | |
| 13473 if (node is ClassDeclaration) { | |
| 13474 ClassElement element = node.element; | |
| 13475 if (element == null) { | |
| 13476 throw new AnalysisException( | |
| 13477 "Cannot build a scope for an unresolved class"); | |
| 13478 } | |
| 13479 scope = new ClassScope(new TypeParameterScope(scope, element), element); | |
| 13480 } else if (node is ClassTypeAlias) { | |
| 13481 ClassElement element = node.element; | |
| 13482 if (element == null) { | |
| 13483 throw new AnalysisException( | |
| 13484 "Cannot build a scope for an unresolved class type alias"); | |
| 13485 } | |
| 13486 scope = new ClassScope(new TypeParameterScope(scope, element), element); | |
| 13487 } else if (node is ConstructorDeclaration) { | |
| 13488 ConstructorElement element = node.element; | |
| 13489 if (element == null) { | |
| 13490 throw new AnalysisException( | |
| 13491 "Cannot build a scope for an unresolved constructor"); | |
| 13492 } | |
| 13493 FunctionScope functionScope = new FunctionScope(scope, element); | |
| 13494 functionScope.defineParameters(); | |
| 13495 scope = functionScope; | |
| 13496 } else if (node is FunctionDeclaration) { | |
| 13497 ExecutableElement element = node.element; | |
| 13498 if (element == null) { | |
| 13499 throw new AnalysisException( | |
| 13500 "Cannot build a scope for an unresolved function"); | |
| 13501 } | |
| 13502 FunctionScope functionScope = new FunctionScope(scope, element); | |
| 13503 functionScope.defineParameters(); | |
| 13504 scope = functionScope; | |
| 13505 } else if (node is FunctionTypeAlias) { | |
| 13506 scope = new FunctionTypeScope(scope, node.element); | |
| 13507 } else if (node is MethodDeclaration) { | |
| 13508 ExecutableElement element = node.element; | |
| 13509 if (element == null) { | |
| 13510 throw new AnalysisException( | |
| 13511 "Cannot build a scope for an unresolved method"); | |
| 13512 } | |
| 13513 FunctionScope functionScope = new FunctionScope(scope, element); | |
| 13514 functionScope.defineParameters(); | |
| 13515 scope = functionScope; | |
| 13516 } | |
| 13517 return scope; | |
| 13518 } | |
| 13519 | |
| 13520 Scope _scopeForCompilationUnit(CompilationUnit node) { | |
| 13521 CompilationUnitElement unitElement = node.element; | |
| 13522 if (unitElement == null) { | |
| 13523 throw new AnalysisException( | |
| 13524 "Cannot create scope: compilation unit is not resolved"); | |
| 13525 } | |
| 13526 LibraryElement libraryElement = unitElement.library; | |
| 13527 if (libraryElement == null) { | |
| 13528 throw new AnalysisException( | |
| 13529 "Cannot create scope: compilation unit is not part of a library"); | |
| 13530 } | |
| 13531 return new LibraryScope(libraryElement, _errorListener); | |
| 13532 } | |
| 13533 | |
| 13534 /** | |
| 13535 * Return the scope in which the given AST structure should be resolved. | |
| 13536 * | |
| 13537 * @param node the root of the AST structure to be resolved | |
| 13538 * @param errorListener the listener to which analysis errors will be reported | |
| 13539 * @return the scope in which the given AST structure should be resolved | |
| 13540 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a | |
| 13541 * [CompilationUnit] | |
| 13542 */ | |
| 13543 static Scope scopeFor(AstNode node, AnalysisErrorListener errorListener) { | |
| 13544 if (node == null) { | |
| 13545 throw new AnalysisException("Cannot create scope: node is null"); | |
| 13546 } else if (node is CompilationUnit) { | |
| 13547 ScopeBuilder builder = new ScopeBuilder(errorListener); | |
| 13548 return builder._scopeForAstNode(node); | |
| 13549 } | |
| 13550 AstNode parent = node.parent; | |
| 13551 if (parent == null) { | |
| 13552 throw new AnalysisException( | |
| 13553 "Cannot create scope: node is not part of a CompilationUnit"); | |
| 13554 } | |
| 13555 ScopeBuilder builder = new ScopeBuilder(errorListener); | |
| 13556 return builder._scopeForAstNode(parent); | |
| 13557 } | |
| 13558 } | |
| 13559 | |
| 13560 /** | |
| 13561 * The abstract class `ScopedVisitor` maintains name and label scopes as an AST
structure is | 12601 * The abstract class `ScopedVisitor` maintains name and label scopes as an AST
structure is |
| 13562 * being visited. | 12602 * being visited. |
| 13563 */ | 12603 */ |
| 13564 abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { | 12604 abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
| 13565 /** | 12605 /** |
| 13566 * The element for the library containing the compilation unit being visited. | 12606 * The element for the library containing the compilation unit being visited. |
| 13567 */ | 12607 */ |
| 13568 LibraryElement _definingLibrary; | 12608 LibraryElement _definingLibrary; |
| 13569 | 12609 |
| 13570 /** | 12610 /** |
| (...skipping 3168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16739 } | 15779 } |
| 16740 return new DartObjectImpl( | 15780 return new DartObjectImpl( |
| 16741 type is InterfaceType ? type : verifier._typeProvider.objectType, | 15781 type is InterfaceType ? type : verifier._typeProvider.objectType, |
| 16742 GenericState.UNKNOWN_VALUE); | 15782 GenericState.UNKNOWN_VALUE); |
| 16743 } | 15783 } |
| 16744 } | 15784 } |
| 16745 return super.visitSimpleIdentifier(node); | 15785 return super.visitSimpleIdentifier(node); |
| 16746 } | 15786 } |
| 16747 } | 15787 } |
| 16748 | 15788 |
| 16749 class _DeclarationMatcher_gatherElements extends | |
| 16750 GeneralizingElementVisitor<Object> { | |
| 16751 final DeclarationMatcher matcher; | |
| 16752 | |
| 16753 _DeclarationMatcher_gatherElements(this.matcher) | |
| 16754 : super(); | |
| 16755 | |
| 16756 @override | |
| 16757 Object visitElement(Element element) { | |
| 16758 matcher._allElements.add(element); | |
| 16759 matcher._unmatchedElements.add(element); | |
| 16760 return super.visitElement(element); | |
| 16761 } | |
| 16762 } | |
| 16763 | |
| 16764 class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> { | 15789 class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> { |
| 16765 final ElementBuilder builder; | 15790 final ElementBuilder builder; |
| 16766 | 15791 |
| 16767 List<ClassMember> nonFields; | 15792 List<ClassMember> nonFields; |
| 16768 | 15793 |
| 16769 _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) | 15794 _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) |
| 16770 : super(); | 15795 : super(); |
| 16771 | 15796 |
| 16772 @override | 15797 @override |
| 16773 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 15798 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17197 * library. | 16222 * library. |
| 17198 */ | 16223 */ |
| 17199 final HashSet<String> members = new HashSet<String>(); | 16224 final HashSet<String> members = new HashSet<String>(); |
| 17200 | 16225 |
| 17201 /** | 16226 /** |
| 17202 * Names of resolved or unresolved class members that are read in the | 16227 * Names of resolved or unresolved class members that are read in the |
| 17203 * library. | 16228 * library. |
| 17204 */ | 16229 */ |
| 17205 final HashSet<String> readMembers = new HashSet<String>(); | 16230 final HashSet<String> readMembers = new HashSet<String>(); |
| 17206 } | 16231 } |
| OLD | NEW |