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

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

Issue 780643002: More work on logging - new classes and timers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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.incremental_resolver; 5 library engine.incremental_resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' as math; 8 import 'dart:math' as math;
9 9
10 import 'ast.dart'; 10 import 'ast.dart';
11 import 'element.dart'; 11 import 'element.dart';
12 import 'engine.dart'; 12 import 'engine.dart';
13 import 'error.dart'; 13 import 'error.dart';
14 import 'error_verifier.dart'; 14 import 'error_verifier.dart';
15 import 'incremental_logger.dart' show logger; 15 import 'incremental_logger.dart' show logger, LoggerTimer;
16 import 'java_engine.dart'; 16 import 'java_engine.dart';
17 import 'parser.dart'; 17 import 'parser.dart';
18 import 'resolver.dart'; 18 import 'resolver.dart';
19 import 'scanner.dart'; 19 import 'scanner.dart';
20 import 'source.dart'; 20 import 'source.dart';
21 import 'utilities_dart.dart'; 21 import 'utilities_dart.dart';
22 22
23 23
24 /** 24 /**
25 * Instances of the class [DeclarationMatcher] determine whether the element 25 * Instances of the class [DeclarationMatcher] determine whether the element
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 /** 78 /**
79 * Return `true` if the declarations within the given AST structure define an element model 79 * Return `true` if the declarations within the given AST structure define an element model
80 * that is equivalent to the corresponding elements rooted at the given elemen t. 80 * that is equivalent to the corresponding elements rooted at the given elemen t.
81 * 81 *
82 * @param node the AST structure being compared to the element model 82 * @param node the AST structure being compared to the element model
83 * @param element the root of the element model being compared to the AST stru cture 83 * @param element the root of the element model being compared to the AST stru cture
84 * @return `true` if the AST structure defines the same elements as those in t he given 84 * @return `true` if the AST structure defines the same elements as those in t he given
85 * element model 85 * element model
86 */ 86 */
87 bool matches(AstNode node, Element element) { 87 bool matches(AstNode node, Element element) {
88 _captureEnclosingElements(element); 88 logger.enter('match $element @ ${element.nameOffset}');
89 _gatherElements(element);
90 try { 89 try {
90 _captureEnclosingElements(element);
91 _gatherElements(element);
91 node.accept(this); 92 node.accept(this);
92 } on _DeclarationMismatchException catch (exception) { 93 } on _DeclarationMismatchException catch (exception) {
93 return false; 94 return false;
95 } finally {
96 logger.exit();
94 } 97 }
95 return _unmatchedElements.isEmpty; 98 return _unmatchedElements.isEmpty;
96 } 99 }
97 100
98 @override 101 @override
99 visitBlockFunctionBody(BlockFunctionBody node) { 102 visitBlockFunctionBody(BlockFunctionBody node) {
100 // ignore bodies 103 // ignore bodies
101 } 104 }
102 105
103 @override 106 @override
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 _definingLibrary = _definingUnit.library; 666 _definingLibrary = _definingUnit.library;
664 _source = _definingUnit.source; 667 _source = _definingUnit.source;
665 } 668 }
666 669
667 /** 670 /**
668 * Resolve [node], reporting any errors or warnings to the given listener. 671 * Resolve [node], reporting any errors or warnings to the given listener.
669 * 672 *
670 * [node] - the root of the AST structure to be resolved. 673 * [node] - the root of the AST structure to be resolved.
671 */ 674 */
672 void resolve(AstNode node) { 675 void resolve(AstNode node) {
673 AstNode rootNode = _findResolutionRoot(node); 676 logger.enter('resolve: $_definingUnit');
674 // update elements 677 try {
675 _updateElementNameOffsets( 678 logger.log(() => 'node: $node');
676 _definingUnit, 679 AstNode rootNode = _findResolutionRoot(node);
677 _updateOffset, 680 logger.log(() => 'rootNode: $rootNode');
678 _updateNewLength - _updateOldLength); 681 // update elements
679 if (_elementModelChanged(rootNode)) { 682 _updateElementNameOffsets(
680 throw new AnalysisException("Cannot resolve node: element model changed"); 683 _definingUnit,
684 _updateOffset,
685 _updateNewLength - _updateOldLength);
686 if (_elementModelChanged(rootNode)) {
687 throw new AnalysisException(
688 "Cannot resolve node: element model changed");
689 }
690 _updateElements(rootNode);
691 // resolve
692 _resolveReferences(rootNode);
693 // verify
694 _verify(rootNode);
695 _generateHints(rootNode);
696 } finally {
697 logger.exit();
681 } 698 }
682 _updateElements(rootNode);
683 // resolve
684 _resolveReferences(rootNode);
685 // verify
686 _verify(rootNode);
687 _generateHints(rootNode);
688 } 699 }
689 700
690 /** 701 /**
691 * Return `true` if the given node can be resolved independently of any other 702 * Return `true` if the given node can be resolved independently of any other
692 * nodes. 703 * nodes.
693 * 704 *
694 * *Note*: This method needs to be kept in sync with 705 * *Note*: This method needs to be kept in sync with
695 * [ScopeBuilder.ContextBuilder]. 706 * [ScopeBuilder.ContextBuilder].
696 * 707 *
697 * [node] - the node being tested. 708 * [node] - the node being tested.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 while (node != null) { 755 while (node != null) {
745 if (_canBeResolved(node)) { 756 if (_canBeResolved(node)) {
746 return node; 757 return node;
747 } 758 }
748 node = node.parent; 759 node = node.parent;
749 } 760 }
750 throw new AnalysisException("Cannot resolve node: no resolvable node"); 761 throw new AnalysisException("Cannot resolve node: no resolvable node");
751 } 762 }
752 763
753 void _generateHints(AstNode node) { 764 void _generateHints(AstNode node) {
765 LoggerTimer timer = logger.startTimer();
Brian Wilkerson 2014/12/03 19:31:12 Should we use try/finally to ensure that the timin
scheglov 2014/12/03 19:46:35 Acknowledged.
754 RecordingErrorListener errorListener = new RecordingErrorListener(); 766 RecordingErrorListener errorListener = new RecordingErrorListener();
755 CompilationUnit unit = node.getAncestor((n) => n is CompilationUnit); 767 CompilationUnit unit = node.getAncestor((n) => n is CompilationUnit);
756 AnalysisContext analysisContext = _definingLibrary.context; 768 AnalysisContext analysisContext = _definingLibrary.context;
757 HintGenerator hintGenerator = 769 HintGenerator hintGenerator =
758 new HintGenerator(<CompilationUnit>[unit], analysisContext, errorListene r); 770 new HintGenerator(<CompilationUnit>[unit], analysisContext, errorListene r);
759 hintGenerator.generateForLibrary(); 771 hintGenerator.generateForLibrary();
760 _hints = errorListener.getErrorsForSource(_source); 772 _hints = errorListener.getErrorsForSource(_source);
773 timer.stop('generate hints');
761 } 774 }
762 775
763 /** 776 /**
764 * Return the element defined by [node], or `null` if the node does not 777 * Return the element defined by [node], or `null` if the node does not
765 * define an element. 778 * define an element.
766 */ 779 */
767 Element _getElement(AstNode node) { 780 Element _getElement(AstNode node) {
768 if (node is Declaration) { 781 if (node is Declaration) {
769 return node.element; 782 return node.element;
770 } else if (node is CompilationUnit) { 783 } else if (node is CompilationUnit) {
771 return node.element; 784 return node.element;
772 } 785 }
773 return null; 786 return null;
774 } 787 }
775 788
776 _resolveReferences(AstNode node) { 789 _resolveReferences(AstNode node) {
790 LoggerTimer timer = logger.startTimer();
777 RecordingErrorListener errorListener = new RecordingErrorListener(); 791 RecordingErrorListener errorListener = new RecordingErrorListener();
778 // prepare context 792 // prepare context
779 _resolutionContext = 793 _resolutionContext =
780 ResolutionContextBuilder.contextFor(node, errorListener); 794 ResolutionContextBuilder.contextFor(node, errorListener);
781 Scope scope = _resolutionContext.scope; 795 Scope scope = _resolutionContext.scope;
782 // resolve types 796 // resolve types
783 { 797 {
784 TypeResolverVisitor visitor = new TypeResolverVisitor.con3( 798 TypeResolverVisitor visitor = new TypeResolverVisitor.con3(
785 _definingLibrary, 799 _definingLibrary,
786 _source, 800 _source,
(...skipping 26 matching lines...) Expand all
813 } 827 }
814 if (node is Comment) { 828 if (node is Comment) {
815 visitor.resolveOnlyCommentInFunctionBody = true; 829 visitor.resolveOnlyCommentInFunctionBody = true;
816 node = node.parent; 830 node = node.parent;
817 } 831 }
818 visitor.initForIncrementalResolution(); 832 visitor.initForIncrementalResolution();
819 node.accept(visitor); 833 node.accept(visitor);
820 } 834 }
821 // remember errors 835 // remember errors
822 _resolveErrors = errorListener.getErrorsForSource(_source); 836 _resolveErrors = errorListener.getErrorsForSource(_source);
837 timer.stop('resolve references');
823 } 838 }
824 839
825 void _updateElements(AstNode node) { 840 void _updateElements(AstNode node) {
841 LoggerTimer timer = logger.startTimer();
826 // build elements in node 842 // build elements in node
827 ElementHolder holder; 843 ElementHolder holder;
828 _ElementsRestorer elementsRestorer = new _ElementsRestorer(node); 844 _ElementsRestorer elementsRestorer = new _ElementsRestorer(node);
829 try { 845 try {
830 holder = new ElementHolder(); 846 holder = new ElementHolder();
831 ElementBuilder builder = new ElementBuilder(holder); 847 ElementBuilder builder = new ElementBuilder(holder);
832 node.accept(builder); 848 node.accept(builder);
833 } finally { 849 } finally {
834 elementsRestorer.restore(); 850 elementsRestorer.restore();
835 } 851 }
(...skipping 27 matching lines...) Expand all
863 newElement = holderMethods[0]; 879 newElement = holderMethods[0];
864 } else if (holderAccessors.isNotEmpty) { 880 } else if (holderAccessors.isNotEmpty) {
865 newElement = holderAccessors[0]; 881 newElement = holderAccessors[0];
866 } 882 }
867 } 883 }
868 // update the old Element 884 // update the old Element
869 oldElement.functions = newElement.functions; 885 oldElement.functions = newElement.functions;
870 oldElement.labels = newElement.labels; 886 oldElement.labels = newElement.labels;
871 oldElement.localVariables = newElement.localVariables; 887 oldElement.localVariables = newElement.localVariables;
872 } 888 }
889 timer.stop('update elements');
873 } 890 }
874 891
875 void _verify(AstNode node) { 892 void _verify(AstNode node) {
893 LoggerTimer timer = logger.startTimer();
876 RecordingErrorListener errorListener = new RecordingErrorListener(); 894 RecordingErrorListener errorListener = new RecordingErrorListener();
877 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source); 895 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source);
878 ErrorVerifier errorVerifier = new ErrorVerifier( 896 ErrorVerifier errorVerifier = new ErrorVerifier(
879 errorReporter, 897 errorReporter,
880 _definingLibrary, 898 _definingLibrary,
881 _typeProvider, 899 _typeProvider,
882 new InheritanceManager(_definingLibrary)); 900 new InheritanceManager(_definingLibrary));
883 if (_resolutionContext.enclosingClassDeclaration != null) { 901 if (_resolutionContext.enclosingClassDeclaration != null) {
884 errorVerifier.visitClassDeclarationIncrementally( 902 errorVerifier.visitClassDeclarationIncrementally(
885 _resolutionContext.enclosingClassDeclaration); 903 _resolutionContext.enclosingClassDeclaration);
886 } 904 }
887 node.accept(errorVerifier); 905 node.accept(errorVerifier);
888 _verifyErrors = errorListener.getErrorsForSource(_source); 906 _verifyErrors = errorListener.getErrorsForSource(_source);
907 timer.stop('verify');
889 } 908 }
890 909
891 static void _updateElementNameOffsets(Element root, int offset, int delta) { 910 static void _updateElementNameOffsets(Element root, int offset, int delta) {
911 LoggerTimer timer = logger.startTimer();
892 root.accept(new _ElementNameOffsetUpdater(offset, delta)); 912 root.accept(new _ElementNameOffsetUpdater(offset, delta));
913 timer.stop('update element offsets');
893 } 914 }
894 } 915 }
895 916
896 917
897 class PoorMansIncrementalResolver { 918 class PoorMansIncrementalResolver {
898 final TypeProvider _typeProvider; 919 final TypeProvider _typeProvider;
899 final Source _unitSource; 920 final Source _unitSource;
900 final Source _librarySource; 921 final Source _librarySource;
901 final DartEntry _entry; 922 final DartEntry _entry;
902 923
(...skipping 10 matching lines...) Expand all
913 934
914 PoorMansIncrementalResolver(this._typeProvider, this._unitSource, 935 PoorMansIncrementalResolver(this._typeProvider, this._unitSource,
915 this._librarySource, this._entry); 936 this._librarySource, this._entry);
916 937
917 /** 938 /**
918 * Attempts to update [oldUnit] to the state corresponding to [newCode]. 939 * Attempts to update [oldUnit] to the state corresponding to [newCode].
919 * Returns `true` if success, or `false` otherwise. 940 * Returns `true` if success, or `false` otherwise.
920 * The [oldUnit] might be damaged. 941 * The [oldUnit] might be damaged.
921 */ 942 */
922 bool resolve(CompilationUnit oldUnit, String newCode) { 943 bool resolve(CompilationUnit oldUnit, String newCode) {
923 logger.enter('resolve $_unitSource'); 944 logger.enter('diff/resolve $_unitSource');
924 logger.log(oldUnit != null ? 'has oldUnit' : 'oldUnit is null'); 945 logger.log(oldUnit != null ? 'has oldUnit' : 'oldUnit is null');
925 try { 946 try {
926 CompilationUnit newUnit = _parseUnit(newCode); 947 CompilationUnit newUnit = _parseUnit(newCode);
927 _TokenPair firstPair = 948 _TokenPair firstPair =
928 _findFirstDifferentToken(oldUnit.beginToken, newUnit.beginToken); 949 _findFirstDifferentToken(oldUnit.beginToken, newUnit.beginToken);
929 _TokenPair lastPair = 950 _TokenPair lastPair =
930 _findLastDifferentToken(oldUnit.endToken, newUnit.endToken); 951 _findLastDifferentToken(oldUnit.endToken, newUnit.endToken);
931 if (firstPair != null && lastPair != null) { 952 if (firstPair != null && lastPair != null) {
932 int firstOffsetOld = firstPair.oldToken.offset; 953 int firstOffsetOld = firstPair.oldToken.offset;
933 int firstOffsetNew = firstPair.newToken.offset; 954 int firstOffsetNew = firstPair.newToken.offset;
(...skipping 22 matching lines...) Expand all
956 _updateEntry(); 977 _updateEntry();
957 } 978 }
958 logger.log('Success.'); 979 logger.log('Success.');
959 return true; 980 return true;
960 } 981 }
961 // Find nodes covering the "old" and "new" token ranges. 982 // Find nodes covering the "old" and "new" token ranges.
962 AstNode oldNode = 983 AstNode oldNode =
963 _findNodeCovering(oldUnit, beginOffsetOld, endOffsetOld); 984 _findNodeCovering(oldUnit, beginOffsetOld, endOffsetOld);
964 AstNode newNode = 985 AstNode newNode =
965 _findNodeCovering(newUnit, beginOffsetNew, endOffsetNew); 986 _findNodeCovering(newUnit, beginOffsetNew, endOffsetNew);
966 logger.log('oldNode: $oldNode'); 987 logger.log(() => 'oldNode: $oldNode');
967 logger.log('newNode: $newNode'); 988 logger.log(() => 'newNode: $newNode');
968 // Try to find the smallest common node, a FunctionBody currently. 989 // Try to find the smallest common node, a FunctionBody currently.
969 { 990 {
970 List<AstNode> oldParents = _getParents(oldNode); 991 List<AstNode> oldParents = _getParents(oldNode);
971 List<AstNode> newParents = _getParents(newNode); 992 List<AstNode> newParents = _getParents(newNode);
972 int length = math.min(oldParents.length, newParents.length); 993 int length = math.min(oldParents.length, newParents.length);
973 bool found = false; 994 bool found = false;
974 for (int i = 0; i < length; i++) { 995 for (int i = 0; i < length; i++) {
975 AstNode oldParent = oldParents[i]; 996 AstNode oldParent = oldParents[i];
976 AstNode newParent = newParents[i]; 997 AstNode newParent = newParents[i];
977 if (oldParent is FunctionDeclaration && 998 if (oldParent is FunctionDeclaration &&
978 newParent is FunctionDeclaration || 999 newParent is FunctionDeclaration ||
979 oldParent is MethodDeclaration && newParent is MethodDeclaration || 1000 oldParent is MethodDeclaration && newParent is MethodDeclaration ||
980 oldParent is ConstructorDeclaration && newParent is ConstructorD eclaration) { 1001 oldParent is ConstructorDeclaration && newParent is ConstructorD eclaration) {
981 oldNode = oldParent; 1002 oldNode = oldParent;
982 newNode = newParent; 1003 newNode = newParent;
983 found = true; 1004 found = true;
984 } 1005 }
985 if (oldParent is FunctionBody && newParent is FunctionBody) { 1006 if (oldParent is FunctionBody && newParent is FunctionBody) {
986 oldNode = oldParent; 1007 oldNode = oldParent;
987 newNode = newParent; 1008 newNode = newParent;
988 found = true; 1009 found = true;
989 break; 1010 break;
990 } 1011 }
991 } 1012 }
992 if (!found) { 1013 if (!found) {
993 logger.log('Failure: no enclosing function body or executable.'); 1014 logger.log('Failure: no enclosing function body or executable.');
994 return false; 1015 return false;
995 } 1016 }
996 } 1017 }
997 logger.log('oldNode: $oldNode'); 1018 logger.log(() => 'oldNode: $oldNode');
998 logger.log('newNode: $newNode'); 1019 logger.log(() => 'newNode: $newNode');
999 // prepare update range 1020 // prepare update range
1000 _updateOffset = oldNode.offset; 1021 _updateOffset = oldNode.offset;
1001 _updateEndOld = oldNode.end; 1022 _updateEndOld = oldNode.end;
1002 _updateEndNew = newNode.end; 1023 _updateEndNew = newNode.end;
1003 _updateDelta = _updateEndNew - _updateEndOld; 1024 _updateDelta = _updateEndNew - _updateEndOld;
1004 // replace node 1025 // replace node
1005 NodeReplacer.replace(oldNode, newNode); 1026 NodeReplacer.replace(oldNode, newNode);
1006 // update token references 1027 // update token references
1007 { 1028 {
1008 Token oldBeginToken = _getBeginTokenNotComment(oldNode); 1029 Token oldBeginToken = _getBeginTokenNotComment(oldNode);
(...skipping 26 matching lines...) Expand all
1035 logger.log(e); 1056 logger.log(e);
1036 logger.log(st); 1057 logger.log(st);
1037 logger.log('Failure: exception.'); 1058 logger.log('Failure: exception.');
1038 } finally { 1059 } finally {
1039 logger.exit(); 1060 logger.exit();
1040 } 1061 }
1041 return false; 1062 return false;
1042 } 1063 }
1043 1064
1044 CompilationUnit _parseUnit(String code) { 1065 CompilationUnit _parseUnit(String code) {
1045 Token token = _scan(code); 1066 LoggerTimer timer = logger.startTimer();
1046 RecordingErrorListener errorListener = new RecordingErrorListener(); 1067 try {
1047 Parser parser = new Parser(_unitSource, errorListener); 1068 Token token = _scan(code);
1048 CompilationUnit unit = parser.parseCompilationUnit(token); 1069 RecordingErrorListener errorListener = new RecordingErrorListener();
1049 _newParseErrors = errorListener.errors; 1070 Parser parser = new Parser(_unitSource, errorListener);
1050 return unit; 1071 CompilationUnit unit = parser.parseCompilationUnit(token);
1072 _newParseErrors = errorListener.errors;
1073 return unit;
1074 } finally {
1075 timer.stop('parse');
1076 }
1051 } 1077 }
1052 1078
1053 void _resolveComment(CompilationUnit oldUnit, CompilationUnit newUnit, 1079 void _resolveComment(CompilationUnit oldUnit, CompilationUnit newUnit,
1054 _TokenPair firstPair) { 1080 _TokenPair firstPair) {
1055 Token oldToken = firstPair.oldToken; 1081 Token oldToken = firstPair.oldToken;
1056 CommentToken precedingComments = oldToken.precedingComments; 1082 CommentToken precedingComments = oldToken.precedingComments;
1057 int offset = precedingComments.offset; 1083 int offset = precedingComments.offset;
1058 logger.log('offset: $offset'); 1084 logger.log('offset: $offset');
1059 Comment oldComment = _findNodeCovering(oldUnit, offset, offset); 1085 Comment oldComment = _findNodeCovering(oldUnit, offset, offset);
1060 Comment newComment = _findNodeCovering(newUnit, offset, offset); 1086 Comment newComment = _findNodeCovering(newUnit, offset, offset);
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 } 1584 }
1559 } 1585 }
1560 1586
1561 1587
1562 class _TokenPair { 1588 class _TokenPair {
1563 final Token oldToken; 1589 final Token oldToken;
1564 final Token newToken; 1590 final Token newToken;
1565 final bool atComment; 1591 final bool atComment;
1566 _TokenPair(this.oldToken, this.newToken, [this.atComment = false]); 1592 _TokenPair(this.oldToken, this.newToken, [this.atComment = false]);
1567 } 1593 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698