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

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

Issue 743543002: Extract incremental resolver classes into separate files. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
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 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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/incremental_resolver.dart ('k') | pkg/analyzer/test/generated/incremental_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698