| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library engine.incremental_resolver; | 5 library engine.incremental_resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'ast.dart'; | 9 import 'ast.dart'; |
| 10 import 'element.dart'; | 10 import 'element.dart'; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 */ | 30 */ |
| 31 CompilationUnitElement _enclosingUnit; | 31 CompilationUnitElement _enclosingUnit; |
| 32 | 32 |
| 33 /** | 33 /** |
| 34 * The function type alias containing the AST nodes being visited, or `null` i
f we are not | 34 * The function type alias containing the AST nodes being visited, or `null` i
f we are not |
| 35 * in the scope of a function type alias. | 35 * in the scope of a function type alias. |
| 36 */ | 36 */ |
| 37 FunctionTypeAliasElement _enclosingAlias; | 37 FunctionTypeAliasElement _enclosingAlias; |
| 38 | 38 |
| 39 /** | 39 /** |
| 40 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of | 40 * The class containing the AST nodes being visited, or `null` if we are not |
| 41 * a class. | 41 * in the scope of a class. |
| 42 */ | 42 */ |
| 43 ClassElement _enclosingClass; | 43 ClassElement _enclosingClass; |
| 44 | 44 |
| 45 /** | 45 /** |
| 46 * The parameter containing the AST nodes being visited, or `null` if we are n
ot in the | 46 * The parameter containing the AST nodes being visited, or `null` if we are n
ot in the |
| 47 * scope of a parameter. | 47 * scope of a parameter. |
| 48 */ | 48 */ |
| 49 ParameterElement _enclosingParameter; | 49 ParameterElement _enclosingParameter; |
| 50 | 50 |
| 51 FieldDeclaration _enclosingFieldNode = null; | 51 FieldDeclaration _enclosingFieldNode = null; |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 this._definingLibrary, this._definingUnit, this._source, this._updateOffse
t, | 649 this._definingLibrary, this._definingUnit, this._source, this._updateOffse
t, |
| 650 this._updateOldLength, this._updateNewLength); | 650 this._updateOldLength, this._updateNewLength); |
| 651 | 651 |
| 652 /** | 652 /** |
| 653 * Resolve [node], reporting any errors or warnings to the given listener. | 653 * Resolve [node], reporting any errors or warnings to the given listener. |
| 654 * | 654 * |
| 655 * [node] - the root of the AST structure to be resolved. | 655 * [node] - the root of the AST structure to be resolved. |
| 656 */ | 656 */ |
| 657 void resolve(AstNode node) { | 657 void resolve(AstNode node) { |
| 658 AstNode rootNode = _findResolutionRoot(node); | 658 AstNode rootNode = _findResolutionRoot(node); |
| 659 if (_elementModelChanged(rootNode)) { | |
| 660 throw new AnalysisException("Cannot resolve node: element model changed"); | |
| 661 } | |
| 662 // update elements | 659 // update elements |
| 663 _definingUnit.accept( | 660 _definingUnit.accept( |
| 664 new _ElementNameOffsetUpdater( | 661 new _ElementNameOffsetUpdater( |
| 665 _updateOffset, | 662 _updateOffset, |
| 666 _updateNewLength - _updateOldLength)); | 663 _updateNewLength - _updateOldLength)); |
| 667 _updateElements(rootNode); | 664 _updateElements(rootNode); |
| 665 if (_elementModelChanged(rootNode)) { |
| 666 throw new AnalysisException("Cannot resolve node: element model changed"); |
| 667 } |
| 668 // resolve root in scope | 668 // resolve root in scope |
| 669 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); | 669 ResolutionContext context = |
| 670 ResolutionContextBuilder.contextFor(rootNode, _errorListener); |
| 671 Scope scope = context.scope; |
| 670 _resolveTypes(rootNode, scope); | 672 _resolveTypes(rootNode, scope); |
| 671 _resolveVariables(rootNode, scope); | 673 _resolveVariables(rootNode, scope); |
| 672 _resolveReferences(rootNode, scope); | 674 _resolveReferences(rootNode, context); |
| 673 } | 675 } |
| 674 | 676 |
| 675 /** | 677 /** |
| 676 * Return `true` if the given node can be resolved independently of any other | 678 * Return `true` if the given node can be resolved independently of any other |
| 677 * nodes. | 679 * nodes. |
| 678 * | 680 * |
| 679 * *Note*: This method needs to be kept in sync with | 681 * *Note*: This method needs to be kept in sync with |
| 680 * [ScopeBuilder.scopeForAstNode]. | 682 * [ScopeBuilder.ContextBuilder]. |
| 681 * | 683 * |
| 682 * [node] - the node being tested. | 684 * [node] - the node being tested. |
| 683 */ | 685 */ |
| 684 bool _canBeResolved(AstNode node) => | 686 bool _canBeResolved(AstNode node) => |
| 685 node is ClassDeclaration || | 687 node is ClassDeclaration || |
| 686 node is ClassTypeAlias || | 688 node is ClassTypeAlias || |
| 687 node is CompilationUnit || | 689 node is CompilationUnit || |
| 688 node is ConstructorDeclaration || | 690 node is ConstructorDeclaration || |
| 689 node is FunctionDeclaration || | 691 node is FunctionDeclaration || |
| 690 node is FunctionTypeAlias || | 692 node is FunctionTypeAlias || |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 */ | 735 */ |
| 734 Element _getElement(AstNode node) { | 736 Element _getElement(AstNode node) { |
| 735 if (node is Declaration) { | 737 if (node is Declaration) { |
| 736 return node.element; | 738 return node.element; |
| 737 } else if (node is CompilationUnit) { | 739 } else if (node is CompilationUnit) { |
| 738 return node.element; | 740 return node.element; |
| 739 } | 741 } |
| 740 return null; | 742 return null; |
| 741 } | 743 } |
| 742 | 744 |
| 743 void _resolveReferences(AstNode node, Scope scope) { | 745 void _resolveReferences(AstNode node, ResolutionContext context) { |
| 744 ResolverVisitor visitor = new ResolverVisitor.con3( | 746 ResolverVisitor visitor = new ResolverVisitor.con3( |
| 745 _definingLibrary, | 747 _definingLibrary, |
| 746 _source, | 748 _source, |
| 747 _typeProvider, | 749 _typeProvider, |
| 748 scope, | 750 context.scope, |
| 749 _errorListener); | 751 _errorListener); |
| 752 visitor.enclosingClass = context.enclosingClass; |
| 750 node.accept(visitor); | 753 node.accept(visitor); |
| 751 } | 754 } |
| 752 | 755 |
| 753 void _resolveTypes(AstNode node, Scope scope) { | 756 void _resolveTypes(AstNode node, Scope scope) { |
| 754 TypeResolverVisitor visitor = new TypeResolverVisitor.con3( | 757 TypeResolverVisitor visitor = new TypeResolverVisitor.con3( |
| 755 _definingLibrary, | 758 _definingLibrary, |
| 756 _source, | 759 _source, |
| 757 _typeProvider, | 760 _typeProvider, |
| 758 scope, | 761 scope, |
| 759 _errorListener); | 762 _errorListener); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 MethodElementImpl oldElement = node.element; | 795 MethodElementImpl oldElement = node.element; |
| 793 MethodElementImpl newElement = holder.methods[0]; | 796 MethodElementImpl newElement = holder.methods[0]; |
| 794 oldElement.labels = newElement.labels; | 797 oldElement.labels = newElement.labels; |
| 795 oldElement.localVariables = newElement.localVariables; | 798 oldElement.localVariables = newElement.localVariables; |
| 796 } | 799 } |
| 797 } | 800 } |
| 798 } | 801 } |
| 799 | 802 |
| 800 | 803 |
| 801 /** | 804 /** |
| 802 * Instances of the class [ScopeBuilder] build the scope for a given node in an | 805 * The context to resolve an [AstNode] in. |
| 803 * AST structure. At the moment, this class only handles top-level and | |
| 804 * class-level declarations. | |
| 805 */ | 806 */ |
| 806 class ScopeBuilder { | 807 class ResolutionContext { |
| 808 ClassElement enclosingClass; |
| 809 Scope scope; |
| 810 } |
| 811 |
| 812 |
| 813 /** |
| 814 * Instances of the class [ResolutionContextBuilder] build the context for a |
| 815 * given node in an AST structure. At the moment, this class only handles |
| 816 * top-level and class-level declarations. |
| 817 */ |
| 818 class ResolutionContextBuilder { |
| 807 /** | 819 /** |
| 808 * The listener to which analysis errors will be reported. | 820 * The listener to which analysis errors will be reported. |
| 809 */ | 821 */ |
| 810 final AnalysisErrorListener _errorListener; | 822 final AnalysisErrorListener _errorListener; |
| 811 | 823 |
| 812 /** | 824 /** |
| 813 * Initialize a newly created scope builder to generate a scope that will repo
rt errors to the | 825 * The class containing the AST nodes being visited, or `null` if we are not |
| 814 * given listener. | 826 * in the scope of a class. |
| 815 * | |
| 816 * @param errorListener the listener to which analysis errors will be reported | |
| 817 */ | 827 */ |
| 818 ScopeBuilder(this._errorListener); | 828 ClassElement _enclosingClass; |
| 829 |
| 830 /** |
| 831 * Initialize a newly created scope builder to generate a scope that will |
| 832 * report errors to the given listener. |
| 833 */ |
| 834 ResolutionContextBuilder(this._errorListener); |
| 835 |
| 836 Scope _scopeFor(AstNode node) { |
| 837 if (node is CompilationUnit) { |
| 838 return _scopeForAstNode(node); |
| 839 } |
| 840 AstNode parent = node.parent; |
| 841 if (parent == null) { |
| 842 throw new AnalysisException( |
| 843 "Cannot create scope: node is not part of a CompilationUnit"); |
| 844 } |
| 845 return _scopeForAstNode(parent); |
| 846 } |
| 819 | 847 |
| 820 /** | 848 /** |
| 821 * Return the scope in which the given AST structure should be resolved. | 849 * Return the scope in which the given AST structure should be resolved. |
| 822 * | 850 * |
| 823 * <b>Note:</b> This method needs to be kept in sync with | 851 * *Note:* This method needs to be kept in sync with |
| 824 * [IncrementalResolver.canBeResolved]. | 852 * [IncrementalResolver.canBeResolved]. |
| 825 * | 853 * |
| 826 * @param node the root of the AST structure to be resolved | 854 * [node] - the root of the AST structure to be resolved. |
| 827 * @return the scope in which the given AST structure should be resolved | 855 * |
| 828 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a | 856 * Throws [AnalysisException] if the AST structure has not been resolved or |
| 829 * [CompilationUnit] | 857 * is not part of a [CompilationUnit] |
| 830 */ | 858 */ |
| 831 Scope _scopeForAstNode(AstNode node) { | 859 Scope _scopeForAstNode(AstNode node) { |
| 832 if (node is CompilationUnit) { | 860 if (node is CompilationUnit) { |
| 833 return _scopeForCompilationUnit(node); | 861 return _scopeForCompilationUnit(node); |
| 834 } | 862 } |
| 835 AstNode parent = node.parent; | 863 AstNode parent = node.parent; |
| 836 if (parent == null) { | 864 if (parent == null) { |
| 837 throw new AnalysisException( | 865 throw new AnalysisException( |
| 838 "Cannot create scope: node is not part of a CompilationUnit"); | 866 "Cannot create scope: node is not part of a CompilationUnit"); |
| 839 } | 867 } |
| 840 Scope scope = _scopeForAstNode(parent); | 868 Scope scope = _scopeForAstNode(parent); |
| 841 if (node is ClassDeclaration) { | 869 if (node is ClassDeclaration) { |
| 842 ClassElement element = node.element; | 870 _enclosingClass = node.element; |
| 843 if (element == null) { | 871 if (_enclosingClass == null) { |
| 844 throw new AnalysisException( | 872 throw new AnalysisException( |
| 845 "Cannot build a scope for an unresolved class"); | 873 "Cannot build a scope for an unresolved class"); |
| 846 } | 874 } |
| 847 scope = new ClassScope(new TypeParameterScope(scope, element), element); | 875 scope = new ClassScope( |
| 876 new TypeParameterScope(scope, _enclosingClass), |
| 877 _enclosingClass); |
| 848 } else if (node is ClassTypeAlias) { | 878 } else if (node is ClassTypeAlias) { |
| 849 ClassElement element = node.element; | 879 ClassElement element = node.element; |
| 850 if (element == null) { | 880 if (element == null) { |
| 851 throw new AnalysisException( | 881 throw new AnalysisException( |
| 852 "Cannot build a scope for an unresolved class type alias"); | 882 "Cannot build a scope for an unresolved class type alias"); |
| 853 } | 883 } |
| 854 scope = new ClassScope(new TypeParameterScope(scope, element), element); | 884 scope = new ClassScope(new TypeParameterScope(scope, element), element); |
| 855 } else if (node is ConstructorDeclaration) { | 885 } else if (node is ConstructorDeclaration) { |
| 856 ConstructorElement element = node.element; | 886 ConstructorElement element = node.element; |
| 857 if (element == null) { | 887 if (element == null) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 } | 923 } |
| 894 LibraryElement libraryElement = unitElement.library; | 924 LibraryElement libraryElement = unitElement.library; |
| 895 if (libraryElement == null) { | 925 if (libraryElement == null) { |
| 896 throw new AnalysisException( | 926 throw new AnalysisException( |
| 897 "Cannot create scope: compilation unit is not part of a library"); | 927 "Cannot create scope: compilation unit is not part of a library"); |
| 898 } | 928 } |
| 899 return new LibraryScope(libraryElement, _errorListener); | 929 return new LibraryScope(libraryElement, _errorListener); |
| 900 } | 930 } |
| 901 | 931 |
| 902 /** | 932 /** |
| 903 * Return the scope in which the given AST structure should be resolved. | 933 * Return the context in which the given AST structure should be resolved. |
| 904 * | 934 * |
| 905 * @param node the root of the AST structure to be resolved | 935 * [node] - the root of the AST structure to be resolved. |
| 906 * @param errorListener the listener to which analysis errors will be reported | 936 * [errorListener] - the listener to which analysis errors will be reported. |
| 907 * @return the scope in which the given AST structure should be resolved | 937 * |
| 908 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a | 938 * Throws [AnalysisException] if the AST structure has not been resolved or |
| 909 * [CompilationUnit] | 939 * is not part of a [CompilationUnit] |
| 910 */ | 940 */ |
| 911 static Scope scopeFor(AstNode node, AnalysisErrorListener errorListener) { | 941 static ResolutionContext contextFor(AstNode node, |
| 942 AnalysisErrorListener errorListener) { |
| 912 if (node == null) { | 943 if (node == null) { |
| 913 throw new AnalysisException("Cannot create scope: node is null"); | 944 throw new AnalysisException("Cannot create context: node is null"); |
| 914 } else if (node is CompilationUnit) { | |
| 915 ScopeBuilder builder = new ScopeBuilder(errorListener); | |
| 916 return builder._scopeForAstNode(node); | |
| 917 } | 945 } |
| 918 AstNode parent = node.parent; | 946 // build scope |
| 919 if (parent == null) { | 947 ResolutionContextBuilder builder = |
| 920 throw new AnalysisException( | 948 new ResolutionContextBuilder(errorListener); |
| 921 "Cannot create scope: node is not part of a CompilationUnit"); | 949 Scope scope = builder._scopeFor(node); |
| 922 } | 950 // prepare context |
| 923 ScopeBuilder builder = new ScopeBuilder(errorListener); | 951 ResolutionContext context = new ResolutionContext(); |
| 924 return builder._scopeForAstNode(parent); | 952 context.scope = scope; |
| 953 context.enclosingClass = builder._enclosingClass; |
| 954 return context; |
| 925 } | 955 } |
| 926 } | 956 } |
| 927 | 957 |
| 928 | 958 |
| 929 /** | 959 /** |
| 930 * Instances of the class [_DeclarationMismatchException] represent an exception | 960 * Instances of the class [_DeclarationMismatchException] represent an exception |
| 931 * that is thrown when the element model defined by a given AST structure does | 961 * that is thrown when the element model defined by a given AST structure does |
| 932 * not match an existing element model. | 962 * not match an existing element model. |
| 933 */ | 963 */ |
| 934 class _DeclarationMismatchException { | 964 class _DeclarationMismatchException { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 visitFunctionExpression(FunctionExpression node) { | 1073 visitFunctionExpression(FunctionExpression node) { |
| 1044 _elements[node] = node.element; | 1074 _elements[node] = node.element; |
| 1045 super.visitFunctionExpression(node); | 1075 super.visitFunctionExpression(node); |
| 1046 } | 1076 } |
| 1047 | 1077 |
| 1048 @override | 1078 @override |
| 1049 visitSimpleIdentifier(SimpleIdentifier node) { | 1079 visitSimpleIdentifier(SimpleIdentifier node) { |
| 1050 _elements[node] = node.staticElement; | 1080 _elements[node] = node.staticElement; |
| 1051 } | 1081 } |
| 1052 } | 1082 } |
| OLD | NEW |