| 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 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 import 'ast.dart'; | 10 import 'ast.dart'; |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 int beginOffsetOld = math.min(firstOffsetOld, lastOffsetOld); | 972 int beginOffsetOld = math.min(firstOffsetOld, lastOffsetOld); |
| 973 int endOffsetOld = math.max(firstOffsetOld, lastOffsetOld); | 973 int endOffsetOld = math.max(firstOffsetOld, lastOffsetOld); |
| 974 int beginOffsetNew = math.min(firstOffsetNew, lastOffsetNew); | 974 int beginOffsetNew = math.min(firstOffsetNew, lastOffsetNew); |
| 975 int endOffsetNew = math.max(firstOffsetNew, lastOffsetNew); | 975 int endOffsetNew = math.max(firstOffsetNew, lastOffsetNew); |
| 976 // check for a whitespace only change | 976 // check for a whitespace only change |
| 977 if (identical(lastPair.oldToken, firstPair.oldToken) && | 977 if (identical(lastPair.oldToken, firstPair.oldToken) && |
| 978 identical(lastPair.newToken, firstPair.newToken)) { | 978 identical(lastPair.newToken, firstPair.newToken)) { |
| 979 _updateOffset = beginOffsetOld - 1; | 979 _updateOffset = beginOffsetOld - 1; |
| 980 _updateEndOld = endOffsetOld; | 980 _updateEndOld = endOffsetOld; |
| 981 _updateDelta = newUnit.length - oldUnit.length; | 981 _updateDelta = newUnit.length - oldUnit.length; |
| 982 if (firstPair.atComment && lastPair.atComment) { | 982 // A Dart documentation comment change. |
| 983 logger.log('Comment change.'); | 983 if (firstPair.kind == _TokenDifferenceKind.COMMENT_DOC) { |
| 984 _resolveComment(oldUnit, newUnit, firstPair); | 984 _resolveComment(oldUnit, newUnit, firstPair); |
| 985 } else { | 985 logger.log('Success.'); |
| 986 return true; |
| 987 } |
| 988 // A pure whitespace change. |
| 989 if (firstPair.kind == _TokenDifferenceKind.OFFSET) { |
| 986 logger.log('Whitespace change.'); | 990 logger.log('Whitespace change.'); |
| 987 _shiftTokens(firstPair.oldToken); | 991 _shiftTokens(firstPair.oldToken); |
| 988 IncrementalResolver._updateElementNameOffsets( | 992 IncrementalResolver._updateElementNameOffsets( |
| 989 oldUnit.element, | 993 oldUnit.element, |
| 990 _updateOffset, | 994 _updateOffset, |
| 991 _updateDelta); | 995 _updateDelta); |
| 992 _updateEntry(); | 996 _updateEntry(); |
| 997 logger.log('Success.'); |
| 998 return true; |
| 993 } | 999 } |
| 994 logger.log('Success.'); | 1000 // fall-through, end-of-line comment |
| 995 return true; | |
| 996 } | 1001 } |
| 997 // Find nodes covering the "old" and "new" token ranges. | 1002 // Find nodes covering the "old" and "new" token ranges. |
| 998 AstNode oldNode = | 1003 AstNode oldNode = |
| 999 _findNodeCovering(oldUnit, beginOffsetOld, endOffsetOld); | 1004 _findNodeCovering(oldUnit, beginOffsetOld, endOffsetOld); |
| 1000 AstNode newNode = | 1005 AstNode newNode = |
| 1001 _findNodeCovering(newUnit, beginOffsetNew, endOffsetNew); | 1006 _findNodeCovering(newUnit, beginOffsetNew, endOffsetNew); |
| 1002 logger.log(() => 'oldNode: $oldNode'); | 1007 logger.log(() => 'oldNode: $oldNode'); |
| 1003 logger.log(() => 'newNode: $newNode'); | 1008 logger.log(() => 'newNode: $newNode'); |
| 1004 // Try to find the smallest common node, a FunctionBody currently. | 1009 // Try to find the smallest common node, a FunctionBody currently. |
| 1005 { | 1010 { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1195 for (AnalysisError error in newErrors) { | 1200 for (AnalysisError error in newErrors) { |
| 1196 int errorOffset = error.offset; | 1201 int errorOffset = error.offset; |
| 1197 if (errorOffset > _updateOffset && errorOffset < _updateEndNew) { | 1202 if (errorOffset > _updateOffset && errorOffset < _updateEndNew) { |
| 1198 errors.add(error); | 1203 errors.add(error); |
| 1199 } | 1204 } |
| 1200 } | 1205 } |
| 1201 // done | 1206 // done |
| 1202 return errors; | 1207 return errors; |
| 1203 } | 1208 } |
| 1204 | 1209 |
| 1205 static bool _equalToken(Token oldToken, Token newToken, int delta) { | 1210 static _TokenDifferenceKind _compareToken(Token oldToken, Token newToken, |
| 1211 int delta) { |
| 1212 if (oldToken == null && newToken == null) { |
| 1213 return null; |
| 1214 } |
| 1215 if (oldToken == null || newToken == null) { |
| 1216 return _TokenDifferenceKind.CONTENT; |
| 1217 } |
| 1206 if (oldToken.type != newToken.type) { | 1218 if (oldToken.type != newToken.type) { |
| 1207 return false; | 1219 return _TokenDifferenceKind.CONTENT; |
| 1220 } |
| 1221 if (oldToken.lexeme != newToken.lexeme) { |
| 1222 return _TokenDifferenceKind.CONTENT; |
| 1208 } | 1223 } |
| 1209 if (newToken.offset - oldToken.offset != delta) { | 1224 if (newToken.offset - oldToken.offset != delta) { |
| 1210 return false; | 1225 return _TokenDifferenceKind.OFFSET; |
| 1211 } | |
| 1212 return oldToken.lexeme == newToken.lexeme; | |
| 1213 } | |
| 1214 | |
| 1215 static _TokenPair _findFirstDifferentToken(Token oldToken, Token newToken) { | |
| 1216 // print('first ------------'); | |
| 1217 while (oldToken.type != TokenType.EOF && newToken.type != TokenType.EOF) { | |
| 1218 // print('old: $oldToken @ ${oldToken.offset}'); | |
| 1219 // print('new: $newToken @ ${newToken.offset}'); | |
| 1220 { | |
| 1221 Token oldComment = oldToken.precedingComments; | |
| 1222 Token newComment = newToken.precedingComments; | |
| 1223 if (oldComment != null && newComment != null) { | |
| 1224 if (!_equalToken(oldComment, newComment, 0)) { | |
| 1225 return new _TokenPair(oldToken, newToken, true); | |
| 1226 } | |
| 1227 } | |
| 1228 } | |
| 1229 if (!_equalToken(oldToken, newToken, 0)) { | |
| 1230 return new _TokenPair(oldToken, newToken); | |
| 1231 } | |
| 1232 oldToken = oldToken.next; | |
| 1233 newToken = newToken.next; | |
| 1234 } | 1226 } |
| 1235 return null; | 1227 return null; |
| 1236 } | 1228 } |
| 1237 | 1229 |
| 1238 static _TokenPair _findLastDifferentToken(Token oldToken, Token newToken) { | 1230 static _TokenPair _findFirstDifferentToken(Token oldToken, Token newToken) { |
| 1239 // print('last ------------'); | 1231 while (true) { |
| 1240 int delta = newToken.offset - oldToken.offset; | 1232 if (oldToken.type == TokenType.EOF && newToken.type == TokenType.EOF) { |
| 1241 while (oldToken.previous != oldToken && newToken.previous != newToken) { | 1233 return null; |
| 1242 // print('old: $oldToken @ ${oldToken.offset}'); | |
| 1243 // print('new: $newToken @ ${newToken.offset}'); | |
| 1244 if (!_equalToken(oldToken, newToken, delta)) { | |
| 1245 return new _TokenPair(oldToken.next, newToken.next); | |
| 1246 } | 1234 } |
| 1235 if (oldToken.type == TokenType.EOF || newToken.type == TokenType.EOF) { |
| 1236 return new _TokenPair(_TokenDifferenceKind.CONTENT, oldToken, newToken); |
| 1237 } |
| 1238 // compare comments |
| 1247 { | 1239 { |
| 1248 Token oldComment = oldToken.precedingComments; | 1240 Token oldComment = oldToken.precedingComments; |
| 1249 Token newComment = newToken.precedingComments; | 1241 Token newComment = newToken.precedingComments; |
| 1250 if (oldComment != null && newComment != null) { | 1242 if (_compareToken(oldComment, newComment, 0) != null) { |
| 1251 if (!_equalToken(oldComment, newComment, delta)) { | 1243 _TokenDifferenceKind diffKind = _TokenDifferenceKind.COMMENT; |
| 1252 return new _TokenPair(oldToken, newToken, true); | 1244 if (oldComment is DocumentationCommentToken || |
| 1245 newComment is DocumentationCommentToken) { |
| 1246 diffKind = _TokenDifferenceKind.COMMENT_DOC; |
| 1253 } | 1247 } |
| 1248 return new _TokenPair(diffKind, oldToken, newToken); |
| 1254 } | 1249 } |
| 1255 } | 1250 } |
| 1251 // compare tokens |
| 1252 _TokenDifferenceKind diffKind = _compareToken(oldToken, newToken, 0); |
| 1253 if (diffKind != null) { |
| 1254 return new _TokenPair(diffKind, oldToken, newToken); |
| 1255 } |
| 1256 // next tokens |
| 1257 oldToken = oldToken.next; |
| 1258 newToken = newToken.next; |
| 1259 } |
| 1260 // no difference |
| 1261 return null; |
| 1262 } |
| 1263 |
| 1264 static _TokenPair _findLastDifferentToken(Token oldToken, Token newToken) { |
| 1265 int delta = newToken.offset - oldToken.offset; |
| 1266 while (oldToken.previous != oldToken && newToken.previous != newToken) { |
| 1267 // compare tokens |
| 1268 _TokenDifferenceKind diffKind = _compareToken(oldToken, newToken, delta); |
| 1269 if (diffKind != null) { |
| 1270 return new _TokenPair(diffKind, oldToken.next, newToken.next); |
| 1271 } |
| 1272 // compare comments |
| 1273 { |
| 1274 Token oldComment = oldToken.precedingComments; |
| 1275 Token newComment = newToken.precedingComments; |
| 1276 if (_compareToken(oldComment, newComment, delta) != null) { |
| 1277 _TokenDifferenceKind diffKind = _TokenDifferenceKind.COMMENT; |
| 1278 if (oldComment is DocumentationCommentToken || |
| 1279 newComment is DocumentationCommentToken) { |
| 1280 diffKind = _TokenDifferenceKind.COMMENT_DOC; |
| 1281 } |
| 1282 return new _TokenPair(diffKind, oldToken, newToken); |
| 1283 } |
| 1284 } |
| 1285 // next tokens |
| 1256 oldToken = oldToken.previous; | 1286 oldToken = oldToken.previous; |
| 1257 newToken = newToken.previous; | 1287 newToken = newToken.previous; |
| 1258 } | 1288 } |
| 1259 return null; | 1289 return null; |
| 1260 } | 1290 } |
| 1261 | 1291 |
| 1262 static AstNode _findNodeCovering(AstNode root, int offset, int end) { | 1292 static AstNode _findNodeCovering(AstNode root, int offset, int end) { |
| 1263 NodeLocator nodeLocator = new NodeLocator.con2(offset, end); | 1293 NodeLocator nodeLocator = new NodeLocator.con2(offset, end); |
| 1264 return nodeLocator.searchWithin(root); | 1294 return nodeLocator.searchWithin(root); |
| 1265 } | 1295 } |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 super.visitFunctionExpression(node); | 1623 super.visitFunctionExpression(node); |
| 1594 } | 1624 } |
| 1595 | 1625 |
| 1596 @override | 1626 @override |
| 1597 visitSimpleIdentifier(SimpleIdentifier node) { | 1627 visitSimpleIdentifier(SimpleIdentifier node) { |
| 1598 _elements[node] = node.staticElement; | 1628 _elements[node] = node.staticElement; |
| 1599 } | 1629 } |
| 1600 } | 1630 } |
| 1601 | 1631 |
| 1602 | 1632 |
| 1633 /** |
| 1634 * Describes how two [Token]s are different. |
| 1635 */ |
| 1636 class _TokenDifferenceKind { |
| 1637 static const COMMENT = const _TokenDifferenceKind('COMMENT'); |
| 1638 static const COMMENT_DOC = const _TokenDifferenceKind('COMMENT_DOC'); |
| 1639 static const CONTENT = const _TokenDifferenceKind('CONTENT'); |
| 1640 static const OFFSET = const _TokenDifferenceKind('OFFSET'); |
| 1641 |
| 1642 final String name; |
| 1643 |
| 1644 const _TokenDifferenceKind(this.name); |
| 1645 |
| 1646 @override |
| 1647 String toString() => name; |
| 1648 } |
| 1649 |
| 1650 |
| 1603 class _TokenPair { | 1651 class _TokenPair { |
| 1652 final _TokenDifferenceKind kind; |
| 1604 final Token oldToken; | 1653 final Token oldToken; |
| 1605 final Token newToken; | 1654 final Token newToken; |
| 1606 final bool atComment; | 1655 _TokenPair(this.kind, this.oldToken, this.newToken); |
| 1607 _TokenPair(this.oldToken, this.newToken, [this.atComment = false]); | |
| 1608 } | 1656 } |
| OLD | NEW |