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

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

Issue 751343002: Fixes for identifying changed token ranges and updating them. (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
« 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 import 'dart:math' as math; 8 import 'dart:math' as math;
9 9
10 import 'package:analyzer/src/generated/error_verifier.dart'; 10 import 'package:analyzer/src/generated/error_verifier.dart';
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 * The [oldUnit] might be damaged. 892 * The [oldUnit] might be damaged.
893 */ 893 */
894 bool resolve(CompilationUnit oldUnit, String newCode) { 894 bool resolve(CompilationUnit oldUnit, String newCode) {
895 try { 895 try {
896 CompilationUnit newUnit = _parseUnit(newCode); 896 CompilationUnit newUnit = _parseUnit(newCode);
897 _TokenPair firstPair = 897 _TokenPair firstPair =
898 _findFirstDifferentToken(oldUnit.beginToken, newUnit.beginToken); 898 _findFirstDifferentToken(oldUnit.beginToken, newUnit.beginToken);
899 _TokenPair lastPair = 899 _TokenPair lastPair =
900 _findLastDifferentToken(oldUnit.endToken, newUnit.endToken); 900 _findLastDifferentToken(oldUnit.endToken, newUnit.endToken);
901 if (firstPair != null && lastPair != null) { 901 if (firstPair != null && lastPair != null) {
902 // Prepare the "old" token range. 902 int firstOffsetOld = firstPair.oldToken.offset;
903 Token oldBeginToken; 903 int firstOffsetNew = firstPair.newToken.offset;
904 Token oldEndToken; 904 int lastOffsetOld = lastPair.oldToken.end;
905 if (firstPair.oldToken.offset < lastPair.oldToken.offset) { 905 int lastOffsetNew = lastPair.newToken.end;
906 oldBeginToken = firstPair.oldToken; 906 int beginOffsetOld = math.min(firstOffsetOld, lastOffsetOld);
907 oldEndToken = lastPair.oldToken; 907 int endOffsetOld = math.max(firstOffsetOld, lastOffsetOld);
908 } else { 908 int beginOffsetNew = math.min(firstOffsetNew, lastOffsetNew);
909 oldBeginToken = lastPair.oldToken; 909 int endOffsetNew = math.max(firstOffsetNew, lastOffsetNew);
910 oldEndToken = firstPair.oldToken; 910 // print('beginOffsetOld: $beginOffsetOld endOffsetOld: $endOffsetOld');
911 } 911 // print('beginOffsetNew: $beginOffsetNew endOffsetNew: $endOffsetNew');
912 // Prepare the "old" token tange.
913 Token newBeginToken;
914 Token newEndToken;
915 if (firstPair.newToken.offset < lastPair.newToken.offset) {
916 newBeginToken = firstPair.newToken;
917 newEndToken = lastPair.newToken;
918 } else {
919 newBeginToken = lastPair.newToken;
920 newEndToken = firstPair.newToken;
921 }
922 // Find nodes covering the "old" and "new" token ranges. 912 // Find nodes covering the "old" and "new" token ranges.
923 AstNode oldNode = 913 AstNode oldNode =
924 _findNodeWithTokens(oldUnit, oldBeginToken, oldEndToken); 914 _findNodeCovering(oldUnit, beginOffsetOld, endOffsetOld);
925 AstNode newNode = 915 AstNode newNode =
926 _findNodeWithTokens(newUnit, newBeginToken, newEndToken); 916 _findNodeCovering(newUnit, beginOffsetNew, endOffsetNew);
917 // print('oldNode: $oldNode');
918 // print('newNode: $newNode');
927 // Try to find the smallest common node, a FunctionBody currently. 919 // Try to find the smallest common node, a FunctionBody currently.
928 { 920 {
929 List<AstNode> oldParents = _getParents(oldNode); 921 List<AstNode> oldParents = _getParents(oldNode);
930 List<AstNode> newParents = _getParents(newNode); 922 List<AstNode> newParents = _getParents(newNode);
931 int length = math.min(oldParents.length, newParents.length); 923 int length = math.min(oldParents.length, newParents.length);
932 bool found = false; 924 bool found = false;
933 for (int i = 0; i < length; i++) { 925 for (int i = 0; i < length; i++) {
934 AstNode oldParent = oldParents[i]; 926 AstNode oldParent = oldParents[i];
935 AstNode newParent = newParents[i]; 927 AstNode newParent = newParents[i];
936 if (oldParent is FunctionBody && newParent is FunctionBody) { 928 if (oldParent is FunctionBody && newParent is FunctionBody) {
937 oldNode = oldParent; 929 oldNode = oldParent;
938 newNode = newParent; 930 newNode = newParent;
939 found = true; 931 found = true;
940 break; 932 break;
941 } 933 }
942 } 934 }
943 if (!found) { 935 if (!found) {
944 return false; 936 return false;
945 } 937 }
946 } 938 }
939 // prepare update range
940 _updateOffset = oldNode.offset;
941 _updateEndOld = oldNode.end;
942 _updateEndNew = newNode.end;
943 _updateDelta = _updateEndNew - _updateEndOld;
944 // _updateDelta = lastPair.delta;
947 // replace node 945 // replace node
948 NodeReplacer.replace(oldNode, newNode); 946 NodeReplacer.replace(oldNode, newNode);
949 // update token references 947 // update token references
950 oldNode.beginToken.previous.setNext(newNode.beginToken); 948 oldNode.beginToken.previous.setNext(newNode.beginToken);
951 oldNode.endToken.setNext(oldNode.endToken.next); 949 newNode.endToken.setNext(oldNode.endToken.next);
952 // prepare update range 950 _shiftTokens(oldNode.endToken.next, _updateDelta);
953 _updateOffset = oldNode.offset;
954 _updateDelta = lastPair.delta;
955 _updateEndOld = oldNode.end;
956 _updateEndNew = newNode.end;
957 // perform incremental resolution 951 // perform incremental resolution
958 CompilationUnitElement oldUnitElement = oldUnit.element; 952 CompilationUnitElement oldUnitElement = oldUnit.element;
959 IncrementalResolver incrementalResolver = new IncrementalResolver( 953 IncrementalResolver incrementalResolver = new IncrementalResolver(
960 _typeProvider, 954 _typeProvider,
961 oldUnitElement.library, 955 oldUnitElement.library,
962 oldUnitElement, 956 oldUnitElement,
963 oldUnitElement.source, 957 oldUnitElement.source,
964 _updateOffset, 958 _updateOffset,
965 oldNode.length, 959 oldNode.length,
966 newNode.length + _updateDelta); 960 newNode.length);
967 incrementalResolver.resolve(newNode); 961 incrementalResolver.resolve(newNode);
968 _newResolveErrors = incrementalResolver._resolveErrors; 962 _newResolveErrors = incrementalResolver._resolveErrors;
969 _newVerifyErrors = incrementalResolver._verifyErrors; 963 _newVerifyErrors = incrementalResolver._verifyErrors;
970 _newHints = incrementalResolver._hints; 964 _newHints = incrementalResolver._hints;
971 _updateEntry(); 965 _updateEntry();
972 return true; 966 return true;
973 } 967 }
974 } catch (e, st) { 968 } catch (e, st) {
975 // TODO(scheglov) find a way to log these exceptions 969 // TODO(scheglov) find a way to log these exceptions
976 print(e); 970 print(e);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 if (oldToken.type != newToken.type) { 1048 if (oldToken.type != newToken.type) {
1055 return false; 1049 return false;
1056 } 1050 }
1057 if (newToken.offset - oldToken.offset != delta) { 1051 if (newToken.offset - oldToken.offset != delta) {
1058 return false; 1052 return false;
1059 } 1053 }
1060 return oldToken.lexeme == newToken.lexeme; 1054 return oldToken.lexeme == newToken.lexeme;
1061 } 1055 }
1062 1056
1063 static _TokenPair _findFirstDifferentToken(Token oldToken, Token newToken) { 1057 static _TokenPair _findFirstDifferentToken(Token oldToken, Token newToken) {
1064 // print('first ------------'); 1058 // print('first ------------');
1065 while (oldToken.type != TokenType.EOF && newToken.type != TokenType.EOF) { 1059 while (oldToken.type != TokenType.EOF && newToken.type != TokenType.EOF) {
1066 // print('old: $oldToken @ ${oldToken.offset}'); 1060 // print('old: $oldToken @ ${oldToken.offset}');
1067 // print('new: $newToken @ ${newToken.offset}'); 1061 // print('new: $newToken @ ${newToken.offset}');
1068 if (!_equalToken(oldToken, newToken, 0)) { 1062 if (!_equalToken(oldToken, newToken, 0)) {
1069 return new _TokenPair(oldToken, newToken, 0); 1063 return new _TokenPair(oldToken, newToken);
1070 } 1064 }
1071 oldToken = oldToken.next; 1065 oldToken = oldToken.next;
1072 newToken = newToken.next; 1066 newToken = newToken.next;
1073 } 1067 }
1074 return null; 1068 return null;
1075 } 1069 }
1076 1070
1077 static _TokenPair _findLastDifferentToken(Token oldToken, Token newToken) { 1071 static _TokenPair _findLastDifferentToken(Token oldToken, Token newToken) {
1078 // print('last ------------'); 1072 // print('last ------------');
1079 int delta = newToken.offset - oldToken.offset; 1073 int delta = newToken.offset - oldToken.offset;
1080 while (oldToken.previous != oldToken && newToken.previous != newToken) { 1074 while (oldToken.previous != oldToken && newToken.previous != newToken) {
1081 // print('old: $oldToken @ ${oldToken.offset}'); 1075 // print('old: $oldToken @ ${oldToken.offset}');
1082 // print('new: $newToken @ ${newToken.offset}'); 1076 // print('new: $newToken @ ${newToken.offset}');
1083 if (!_equalToken(oldToken, newToken, delta)) { 1077 if (!_equalToken(oldToken, newToken, delta)) {
1084 return new _TokenPair(oldToken.next, newToken.next, delta); 1078 return new _TokenPair(oldToken, newToken);
1085 } 1079 }
1086 oldToken.offset += delta;
1087 oldToken = oldToken.previous; 1080 oldToken = oldToken.previous;
1088 newToken = newToken.previous; 1081 newToken = newToken.previous;
1089 } 1082 }
1090 return null; 1083 return null;
1091 } 1084 }
1092 1085
1093 static AstNode _findNodeWithTokens(AstNode root, Token first, Token last) { 1086 static AstNode _findNodeCovering(AstNode root, int offset, int end) {
1094 int offset = first.offset;
1095 int end = last.end;
1096 NodeLocator nodeLocator = new NodeLocator.con2(offset, end); 1087 NodeLocator nodeLocator = new NodeLocator.con2(offset, end);
1097 return nodeLocator.searchWithin(root); 1088 return nodeLocator.searchWithin(root);
1098 } 1089 }
1099 1090
1100 static List<AstNode> _getParents(AstNode node) { 1091 static List<AstNode> _getParents(AstNode node) {
1101 List<AstNode> parents = <AstNode>[]; 1092 List<AstNode> parents = <AstNode>[];
1102 while (node != null) { 1093 while (node != null) {
1103 parents.insert(0, node); 1094 parents.insert(0, node);
1104 node = node.parent; 1095 node = node.parent;
1105 } 1096 }
1106 return parents; 1097 return parents;
1107 } 1098 }
1099
1100 static void _shiftTokens(Token token, int delta) {
1101 while (true) {
1102 token.offset += delta;
1103 if (token.type == TokenType.EOF) {
1104 break;
1105 }
1106 token = token.next;
1107 }
1108 }
1108 } 1109 }
1109 1110
1110 1111
1111 /** 1112 /**
1112 * The context to resolve an [AstNode] in. 1113 * The context to resolve an [AstNode] in.
1113 */ 1114 */
1114 class ResolutionContext { 1115 class ResolutionContext {
1115 ClassDeclaration enclosingClassDeclaration; 1116 ClassDeclaration enclosingClassDeclaration;
1116 ClassElement enclosingClass; 1117 ClassElement enclosingClass;
1117 Scope scope; 1118 Scope scope;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 @override 1395 @override
1395 visitSimpleIdentifier(SimpleIdentifier node) { 1396 visitSimpleIdentifier(SimpleIdentifier node) {
1396 _elements[node] = node.staticElement; 1397 _elements[node] = node.staticElement;
1397 } 1398 }
1398 } 1399 }
1399 1400
1400 1401
1401 class _TokenPair { 1402 class _TokenPair {
1402 final Token oldToken; 1403 final Token oldToken;
1403 final Token newToken; 1404 final Token newToken;
1404 final int delta; 1405 _TokenPair(this.oldToken, this.newToken);
1405 _TokenPair(this.oldToken, this.newToken, this.delta);
1406 } 1406 }
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