| 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 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 } | 768 } |
| 769 } | 769 } |
| 770 | 770 |
| 771 | 771 |
| 772 /** | 772 /** |
| 773 * Instances of the class [IncrementalResolver] resolve the smallest portion of | 773 * Instances of the class [IncrementalResolver] resolve the smallest portion of |
| 774 * an AST structure that we currently know how to resolve. | 774 * an AST structure that we currently know how to resolve. |
| 775 */ | 775 */ |
| 776 class IncrementalResolver { | 776 class IncrementalResolver { |
| 777 /** | 777 /** |
| 778 * The element for the library containing the compilation unit being visited. | 778 * The error listener that will be informed of any errors that are found |
| 779 * during resolution. |
| 780 */ |
| 781 final AnalysisErrorListener _errorListener; |
| 782 |
| 783 /** |
| 784 * The object used to access the types from the core library. |
| 785 */ |
| 786 final TypeProvider _typeProvider; |
| 787 |
| 788 /** |
| 789 * The element for the library containing the compilation unit being resolved. |
| 779 */ | 790 */ |
| 780 final LibraryElement _definingLibrary; | 791 final LibraryElement _definingLibrary; |
| 781 | 792 |
| 782 /** | 793 /** |
| 794 * The element of the compilation unit being resolved. |
| 795 */ |
| 796 final CompilationUnitElement _definingUnit; |
| 797 |
| 798 /** |
| 783 * The source representing the compilation unit being visited. | 799 * The source representing the compilation unit being visited. |
| 784 */ | 800 */ |
| 785 final Source _source; | 801 final Source _source; |
| 786 | 802 |
| 787 /** | 803 /** |
| 788 * The object used to access the types from the core library. | 804 * The offset of the changed contents. |
| 789 */ | 805 */ |
| 790 final TypeProvider _typeProvider; | 806 final int _updateOffset; |
| 791 | 807 |
| 792 /** | 808 /** |
| 793 * The error listener that will be informed of any errors that are found durin
g resolution. | 809 * The number of characters in the original contents that were replaced. |
| 794 */ | 810 */ |
| 795 final AnalysisErrorListener _errorListener; | 811 final int _updateOldLength; |
| 796 | 812 |
| 797 /** | 813 /** |
| 798 * Initialize a newly created incremental resolver to resolve a node in the gi
ven source in the | 814 * The number of characters in the replacement text. |
| 799 * given library, reporting errors to the given error listener. | |
| 800 * | |
| 801 * @param definingLibrary the element for the library containing the compilati
on unit being | |
| 802 * visited | |
| 803 * @param source the source representing the compilation unit being visited | |
| 804 * @param typeProvider the object used to access the types from the core libra
ry | |
| 805 * @param errorListener the error listener that will be informed of any errors
that are found | |
| 806 * during resolution | |
| 807 */ | 815 */ |
| 808 IncrementalResolver(this._definingLibrary, this._source, this._typeProvider, | 816 final int _updateNewLength; |
| 809 this._errorListener); | |
| 810 | 817 |
| 811 /** | 818 /** |
| 812 * Resolve the given node, reporting any errors or warnings to the given liste
ner. | 819 * Initialize a newly created incremental resolver to resolve a node in the |
| 820 * given source in the given library, reporting errors to the given error |
| 821 * listener. |
| 822 */ |
| 823 IncrementalResolver(this._errorListener, this._typeProvider, |
| 824 this._definingLibrary, this._definingUnit, this._source, this._updateOffse
t, |
| 825 this._updateOldLength, this._updateNewLength); |
| 826 |
| 827 /** |
| 828 * Resolve [node], reporting any errors or warnings to the given listener. |
| 813 * | 829 * |
| 814 * @param node the root of the AST structure to be resolved | 830 * [node] - the root of the AST structure to be resolved. |
| 815 * @throws AnalysisException if the node could not be resolved | |
| 816 */ | 831 */ |
| 817 void resolve(AstNode node) { | 832 void resolve(AstNode node) { |
| 818 AstNode rootNode = _findResolutionRoot(node); | 833 AstNode rootNode = _findResolutionRoot(node); |
| 819 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); | 834 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); |
| 820 if (_elementModelChanged(rootNode.parent)) { | 835 if (_elementModelChanged(rootNode.parent)) { |
| 821 throw new AnalysisException("Cannot resolve node: element model changed"); | 836 throw new AnalysisException("Cannot resolve node: element model changed"); |
| 822 } | 837 } |
| 838 _definingUnit.accept( |
| 839 new _ElementNameOffsetUpdater(_updateOffset, _updateNewLength - _updateO
ldLength)); |
| 823 _resolveTypes(node, scope); | 840 _resolveTypes(node, scope); |
| 824 _resolveVariables(node, scope); | 841 _resolveVariables(node, scope); |
| 825 _resolveReferences(node, scope); | 842 _resolveReferences(node, scope); |
| 826 } | 843 } |
| 827 | 844 |
| 828 /** | 845 /** |
| 829 * Return `true` if the given node can be resolved independently of any other
nodes. | 846 * Return `true` if the given node can be resolved independently of any other |
| 847 * nodes. |
| 830 * | 848 * |
| 831 * <b>Note:</b> This method needs to be kept in sync with [ScopeBuilder.scopeF
orAstNode]. | 849 * *Note*: This method needs to be kept in sync with |
| 850 * [ScopeBuilder.scopeForAstNode]. |
| 832 * | 851 * |
| 833 * @param node the node being tested | 852 * [node] - the node being tested. |
| 834 * @return `true` if the given node can be resolved independently of any other
nodes | |
| 835 */ | 853 */ |
| 836 bool _canBeResolved(AstNode node) => | 854 bool _canBeResolved(AstNode node) => |
| 837 node is ClassDeclaration || | 855 node is ClassDeclaration || |
| 838 node is ClassTypeAlias || | 856 node is ClassTypeAlias || |
| 839 node is CompilationUnit || | 857 node is CompilationUnit || |
| 840 node is ConstructorDeclaration || | 858 node is ConstructorDeclaration || |
| 841 node is FunctionDeclaration || | 859 node is FunctionDeclaration || |
| 842 node is FunctionTypeAlias || | 860 node is FunctionTypeAlias || |
| 843 node is MethodDeclaration; | 861 node is MethodDeclaration; |
| 844 | 862 |
| 845 /** | 863 /** |
| 846 * Return `true` if the portion of the element model defined by the given node
has changed. | 864 * Return `true` if the portion of the element model defined by the given node |
| 865 * has changed. |
| 847 * | 866 * |
| 848 * @param node the node defining the portion of the element model being tested | 867 * [node] - the node defining the portion of the element model being tested. |
| 849 * @return `true` if the element model defined by the given node has changed | 868 * |
| 850 * @throws AnalysisException if the correctness of the element model cannot be
determined | 869 * Throws [AnalysisException] if the correctness of the element model cannot |
| 870 * be determined. |
| 851 */ | 871 */ |
| 852 bool _elementModelChanged(AstNode node) { | 872 bool _elementModelChanged(AstNode node) { |
| 853 Element element = _getElement(node); | 873 Element element = _getElement(node); |
| 854 if (element == null) { | 874 if (element == null) { |
| 855 throw new AnalysisException( | 875 throw new AnalysisException( |
| 856 "Cannot resolve node: a ${node.runtimeType} does not define an element
"); | 876 "Cannot resolve node: a ${node.runtimeType} does not define an element
"); |
| 857 } | 877 } |
| 858 DeclarationMatcher matcher = new DeclarationMatcher(); | 878 DeclarationMatcher matcher = new DeclarationMatcher(); |
| 859 return !matcher.matches(node, element); | 879 return !matcher.matches(node, element); |
| 860 } | 880 } |
| 861 | 881 |
| 862 /** | 882 /** |
| 863 * Starting at the given node, find the smallest AST node that can be resolved
independently of | 883 * Starting at [node], find the smallest AST node that can be resolved |
| 864 * any other nodes. Return the node that was found. | 884 * independently of any other nodes. Return the node that was found. |
| 865 * | 885 * |
| 866 * @param node the node at which the search is to begin | 886 * [node] - the node at which the search is to begin |
| 867 * @return the smallest AST node that can be resolved independently of any oth
er nodes | 887 * |
| 868 * @throws AnalysisException if there is no such node | 888 * Throws [AnalysisException] if there is no such node. |
| 869 */ | 889 */ |
| 870 AstNode _findResolutionRoot(AstNode node) { | 890 AstNode _findResolutionRoot(AstNode node) { |
| 871 AstNode result = node; | 891 AstNode result = node; |
| 872 AstNode parent = result.parent; | 892 AstNode parent = result.parent; |
| 873 while (parent != null && !_canBeResolved(parent)) { | 893 while (parent != null && !_canBeResolved(parent)) { |
| 874 result = parent; | 894 result = parent; |
| 875 parent = result.parent; | 895 parent = result.parent; |
| 876 } | 896 } |
| 877 if (parent == null) { | 897 if (parent == null) { |
| 878 throw new AnalysisException("Cannot resolve node: no resolvable node"); | 898 throw new AnalysisException("Cannot resolve node: no resolvable node"); |
| 879 } | 899 } |
| 880 return result; | 900 return result; |
| 881 } | 901 } |
| 882 | 902 |
| 883 /** | 903 /** |
| 884 * Return the element defined by the given node, or `null` if the node does no
t define an | 904 * Return the element defined by [node], or `null` if the node does not |
| 885 * element. | 905 * define an element. |
| 886 * | |
| 887 * @param node the node defining the element to be returned | |
| 888 * @return the element defined by the given node | |
| 889 */ | 906 */ |
| 890 Element _getElement(AstNode node) { | 907 Element _getElement(AstNode node) { |
| 891 if (node is Declaration) { | 908 if (node is Declaration) { |
| 892 return node.element; | 909 return node.element; |
| 893 } else if (node is CompilationUnit) { | 910 } else if (node is CompilationUnit) { |
| 894 return node.element; | 911 return node.element; |
| 895 } | 912 } |
| 896 return null; | 913 return null; |
| 897 } | 914 } |
| 898 | 915 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 } | 1118 } |
| 1102 } | 1119 } |
| 1103 | 1120 |
| 1104 void _addElement(Element element) { | 1121 void _addElement(Element element) { |
| 1105 if (element != null) { | 1122 if (element != null) { |
| 1106 matcher._allElements.add(element); | 1123 matcher._allElements.add(element); |
| 1107 matcher._unmatchedElements.add(element); | 1124 matcher._unmatchedElements.add(element); |
| 1108 } | 1125 } |
| 1109 } | 1126 } |
| 1110 } | 1127 } |
| 1128 |
| 1129 |
| 1130 class _ElementNameOffsetUpdater extends GeneralizingElementVisitor { |
| 1131 final int updateOffset; |
| 1132 final int updateDelta; |
| 1133 |
| 1134 _ElementNameOffsetUpdater(this.updateOffset, this.updateDelta); |
| 1135 |
| 1136 @override |
| 1137 visitElement(Element element) { |
| 1138 int nameOffset = element.nameOffset; |
| 1139 if (nameOffset >= updateOffset) { |
| 1140 (element as ElementImpl).nameOffset = nameOffset + updateDelta; |
| 1141 } |
| 1142 super.visitElement(element); |
| 1143 } |
| 1144 } |
| OLD | NEW |