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

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

Issue 746903002: Build elements for local variable and label in functions/methods. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge 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
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/incremental_resolver_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.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 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); 659 if (_elementModelChanged(rootNode)) {
660 if (_elementModelChanged(rootNode.parent)) {
661 throw new AnalysisException("Cannot resolve node: element model changed"); 660 throw new AnalysisException("Cannot resolve node: element model changed");
662 } 661 }
662 // update elements
663 _definingUnit.accept( 663 _definingUnit.accept(
664 new _ElementNameOffsetUpdater( 664 new _ElementNameOffsetUpdater(
665 _updateOffset, 665 _updateOffset,
666 _updateNewLength - _updateOldLength)); 666 _updateNewLength - _updateOldLength));
667 _resolveTypes(node, scope); 667 _updateElements(rootNode);
668 _resolveVariables(node, scope); 668 // resolve root in scope
669 _resolveReferences(node, scope); 669 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener);
670 _resolveTypes(rootNode, scope);
671 _resolveVariables(rootNode, scope);
672 _resolveReferences(rootNode, scope);
670 } 673 }
671 674
672 /** 675 /**
673 * Return `true` if the given node can be resolved independently of any other 676 * Return `true` if the given node can be resolved independently of any other
674 * nodes. 677 * nodes.
675 * 678 *
676 * *Note*: This method needs to be kept in sync with 679 * *Note*: This method needs to be kept in sync with
677 * [ScopeBuilder.scopeForAstNode]. 680 * [ScopeBuilder.scopeForAstNode].
678 * 681 *
679 * [node] - the node being tested. 682 * [node] - the node being tested.
(...skipping 28 matching lines...) Expand all
708 711
709 /** 712 /**
710 * Starting at [node], find the smallest AST node that can be resolved 713 * Starting at [node], find the smallest AST node that can be resolved
711 * independently of any other nodes. Return the node that was found. 714 * independently of any other nodes. Return the node that was found.
712 * 715 *
713 * [node] - the node at which the search is to begin 716 * [node] - the node at which the search is to begin
714 * 717 *
715 * Throws [AnalysisException] if there is no such node. 718 * Throws [AnalysisException] if there is no such node.
716 */ 719 */
717 AstNode _findResolutionRoot(AstNode node) { 720 AstNode _findResolutionRoot(AstNode node) {
718 AstNode result = node; 721 while (node != null) {
719 AstNode parent = result.parent; 722 if (_canBeResolved(node)) {
720 while (parent != null && !_canBeResolved(parent)) { 723 return node;
721 result = parent; 724 }
722 parent = result.parent; 725 node = node.parent;
723 } 726 }
724 if (parent == null) { 727 throw new AnalysisException("Cannot resolve node: no resolvable node");
725 throw new AnalysisException("Cannot resolve node: no resolvable node");
726 }
727 return result;
728 } 728 }
729 729
730 /** 730 /**
731 * Return the element defined by [node], or `null` if the node does not 731 * Return the element defined by [node], or `null` if the node does not
732 * define an element. 732 * define an element.
733 */ 733 */
734 Element _getElement(AstNode node) { 734 Element _getElement(AstNode node) {
735 if (node is Declaration) { 735 if (node is Declaration) {
736 return node.element; 736 return node.element;
737 } else if (node is CompilationUnit) { 737 } else if (node is CompilationUnit) {
(...skipping 24 matching lines...) Expand all
762 762
763 void _resolveVariables(AstNode node, Scope scope) { 763 void _resolveVariables(AstNode node, Scope scope) {
764 VariableResolverVisitor visitor = new VariableResolverVisitor.con2( 764 VariableResolverVisitor visitor = new VariableResolverVisitor.con2(
765 _definingLibrary, 765 _definingLibrary,
766 _source, 766 _source,
767 _typeProvider, 767 _typeProvider,
768 scope, 768 scope,
769 _errorListener); 769 _errorListener);
770 node.accept(visitor); 770 node.accept(visitor);
771 } 771 }
772
773 void _updateElements(AstNode node) {
774 // build elements in node
775 ElementHolder holder;
776 _ElementsRestorer elementsRestorer = new _ElementsRestorer(node);
777 try {
778 holder = new ElementHolder();
779 ElementBuilder builder = new ElementBuilder(holder);
780 node.accept(builder);
781 } finally {
782 elementsRestorer.restore();
783 }
784 // apply compatible changes to elements
785 if (node is FunctionDeclaration) {
786 FunctionElementImpl oldElement = node.element;
787 FunctionElementImpl newElement = holder.functions[0];
788 oldElement.labels = newElement.labels;
789 oldElement.localVariables = newElement.localVariables;
790 }
791 if (node is MethodDeclaration) {
792 MethodElementImpl oldElement = node.element;
793 MethodElementImpl newElement = holder.methods[0];
794 oldElement.labels = newElement.labels;
795 oldElement.localVariables = newElement.localVariables;
796 }
797 }
772 } 798 }
773 799
774 800
775 /** 801 /**
776 * Instances of the class [ScopeBuilder] build the scope for a given node in an 802 * Instances of the class [ScopeBuilder] build the scope for a given node in an
777 * AST structure. At the moment, this class only handles top-level and 803 * AST structure. At the moment, this class only handles top-level and
778 * class-level declarations. 804 * class-level declarations.
779 */ 805 */
780 class ScopeBuilder { 806 class ScopeBuilder {
781 /** 807 /**
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 // Don't visit children (such as property accessors). 992 // Don't visit children (such as property accessors).
967 } 993 }
968 994
969 void _addElement(Element element) { 995 void _addElement(Element element) {
970 if (element != null) { 996 if (element != null) {
971 matcher._allElements.add(element); 997 matcher._allElements.add(element);
972 matcher._unmatchedElements.add(element); 998 matcher._unmatchedElements.add(element);
973 } 999 }
974 } 1000 }
975 } 1001 }
1002
1003
1004 /**
1005 * [ElementBuilder] not just builds elements, it also applies them to nodes.
1006 * But we want to keep externally visible (and referenced) elements instances.
1007 * So, we need to remember them and restore.
1008 */
1009 class _ElementsRestorer extends RecursiveAstVisitor {
1010 final Map<AstNode, Element> _elements = <AstNode, Element>{};
1011
1012 _ElementsRestorer(AstNode root) {
1013 root.accept(this);
1014 }
1015
1016 void restore() {
1017 _elements.forEach((AstNode node, Element element) {
1018 if (node is ConstructorDeclaration) {
1019 node.element = element;
1020 } else if (node is FunctionExpression) {
1021 node.element = element;
1022 } else if (node is SimpleIdentifier) {
1023 node.staticElement = element;
1024 }
1025 });
1026 }
1027
1028 @override
1029 visitBlockFunctionBody(BlockFunctionBody node) {
1030 }
1031
1032 @override
1033 visitConstructorDeclaration(ConstructorDeclaration node) {
1034 _elements[node] = node.element;
1035 super.visitConstructorDeclaration(node);
1036 }
1037
1038 @override
1039 visitExpressionFunctionBody(ExpressionFunctionBody node) {
1040 }
1041
1042 @override
1043 visitFunctionExpression(FunctionExpression node) {
1044 _elements[node] = node.element;
1045 super.visitFunctionExpression(node);
1046 }
1047
1048 @override
1049 visitSimpleIdentifier(SimpleIdentifier node) {
1050 _elements[node] = node.staticElement;
1051 }
1052 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/incremental_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698