| 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_test; | 5 library engine.incremental_resolver_test; |
| 6 | 6 |
| 7 import 'package:analyzer/src/generated/ast.dart'; | 7 import 'package:analyzer/src/generated/ast.dart'; |
| 8 import 'package:analyzer/src/generated/element.dart'; | 8 import 'package:analyzer/src/generated/element.dart'; |
| 9 import 'package:analyzer/src/generated/engine.dart'; | 9 import 'package:analyzer/src/generated/engine.dart'; |
| 10 import 'package:analyzer/src/generated/error.dart'; | 10 import 'package:analyzer/src/generated/error.dart'; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 main() { | 27 main() { |
| 28 groupSep = ' | '; | 28 groupSep = ' | '; |
| 29 runReflectiveTests(DeclarationMatcherTest); | 29 runReflectiveTests(DeclarationMatcherTest); |
| 30 runReflectiveTests(IncrementalResolverTest); | 30 runReflectiveTests(IncrementalResolverTest); |
| 31 runReflectiveTests(ResolutionContextBuilderTest); | 31 runReflectiveTests(ResolutionContextBuilderTest); |
| 32 } | 32 } |
| 33 | 33 |
| 34 | 34 |
| 35 class DeclarationMatcherTest extends ResolverTestCase { | 35 class DeclarationMatcherTest extends ResolverTestCase { |
| 36 void fail_test_methodDeclarationMatches_false_localVariable() { | |
| 37 // TODO(scheglov) as I understand DeclarationMatcher, we care only | |
| 38 // about externally visible model changes. So, because we analyze (at least | |
| 39 // right now) incremental changes on method level, local variable can be | |
| 40 // ignored. | |
| 41 _assertMethodMatches(false, r''' | |
| 42 class C { | |
| 43 int m(int p) { | |
| 44 return p + p; | |
| 45 } | |
| 46 }''', r''' | |
| 47 class C { | |
| 48 int m(int p) { | |
| 49 int product = p * p; | |
| 50 return product + product; | |
| 51 } | |
| 52 }'''); | |
| 53 } | |
| 54 | |
| 55 void test_false_class_list_add() { | 36 void test_false_class_list_add() { |
| 56 _assertCompilationUnitMatches(false, r''' | 37 _assertCompilationUnitMatches(false, r''' |
| 57 class A {} | 38 class A {} |
| 58 class B {} | 39 class B {} |
| 59 ''', r''' | 40 ''', r''' |
| 60 class A {} | 41 class A {} |
| 61 class B {} | 42 class B {} |
| 62 class C {} | 43 class C {} |
| 63 '''); | 44 '''); |
| 64 } | 45 } |
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 } | 1064 } |
| 1084 } | 1065 } |
| 1085 | 1066 |
| 1086 | 1067 |
| 1087 class IncrementalResolverTest extends ResolverTestCase { | 1068 class IncrementalResolverTest extends ResolverTestCase { |
| 1088 Source source; | 1069 Source source; |
| 1089 String code; | 1070 String code; |
| 1090 LibraryElement library; | 1071 LibraryElement library; |
| 1091 CompilationUnit unit; | 1072 CompilationUnit unit; |
| 1092 | 1073 |
| 1093 void fail_test_constructor_fieldInitializer_add() { | |
| 1094 // TODO(scheglov) resolver uses "enclosingClass", which we don't set yet | |
| 1095 _resolveUnit(r''' | |
| 1096 class A { | |
| 1097 int f; | |
| 1098 A(int a, int b); | |
| 1099 }'''); | |
| 1100 _resolve(_editString(');', ') : f = a + b;'), _isClassMember); | |
| 1101 } | |
| 1102 | |
| 1103 void fail_test_topLevelFunction_parameter_rename() { | |
| 1104 // TODO(scheglov) Decide if incremental parser keeps the element | |
| 1105 // of the function. If so, we can resolve parameter renames. | |
| 1106 _resolveUnit(r''' | |
| 1107 int main(int a, int b) { | |
| 1108 return a + b; | |
| 1109 } | |
| 1110 '''); | |
| 1111 _resolve(_editString(r'''(int a, int b) { | |
| 1112 return a + b;''', r'''(int first, int b) { | |
| 1113 return first + b;'''), _isDeclaration); | |
| 1114 } | |
| 1115 | |
| 1116 void test_constructor_body() { | 1074 void test_constructor_body() { |
| 1117 _resolveUnit(r''' | 1075 _resolveUnit(r''' |
| 1118 class A { | 1076 class A { |
| 1119 int f; | 1077 int f; |
| 1120 A(int a, int b) { | 1078 A(int a, int b) { |
| 1121 f = a + b; | 1079 f = a + b; |
| 1122 } | 1080 } |
| 1123 }'''); | 1081 }'''); |
| 1124 _resolve(_editString('+', '*'), _isFunctionBody); | 1082 _resolve(_editString('+', '*'), _isFunctionBody); |
| 1125 } | 1083 } |
| 1126 | 1084 |
| 1085 void test_constructor_fieldInitializer_add() { |
| 1086 _resolveUnit(r''' |
| 1087 class A { |
| 1088 int f; |
| 1089 A(int a, int b); |
| 1090 }'''); |
| 1091 _resolve(_editString(');', ') : f = a + b;'), _isClassMember); |
| 1092 } |
| 1093 |
| 1127 void test_constructor_fieldInitializer_edit() { | 1094 void test_constructor_fieldInitializer_edit() { |
| 1128 _resolveUnit(r''' | 1095 _resolveUnit(r''' |
| 1129 class A { | 1096 class A { |
| 1130 int f; | 1097 int f; |
| 1131 A(int a, int b) : f = a + b { | 1098 A(int a, int b) : f = a + b { |
| 1132 int a = 42; | 1099 int a = 42; |
| 1133 } | 1100 } |
| 1134 }'''); | 1101 }'''); |
| 1135 _resolve(_editString('+', '*'), _isExpression); | 1102 _resolve(_editString('+', '*'), _isExpression); |
| 1136 } | 1103 } |
| 1137 | 1104 |
| 1138 void test_constructor_superConstructorInvocation() { | 1105 void test_constructor_superConstructorInvocation() { |
| 1139 _resolveUnit(r''' | 1106 _resolveUnit(r''' |
| 1140 class A { | 1107 class A { |
| 1141 A(int p); | 1108 A(int p); |
| 1142 } | 1109 } |
| 1143 class A { | 1110 class B extends A { |
| 1144 A(int a, int b) : super(a + b); | 1111 B(int a, int b) : super(a + b); |
| 1145 } | 1112 } |
| 1146 '''); | 1113 '''); |
| 1147 _resolve(_editString('+', '*'), _isExpression); | 1114 _resolve(_editString('+', '*'), _isExpression); |
| 1148 } | 1115 } |
| 1149 | 1116 |
| 1150 void test_functionBody_body() { | 1117 void test_functionBody_body() { |
| 1151 _resolveUnit(r''' | 1118 _resolveUnit(r''' |
| 1152 main(int a, int b) { | 1119 main(int a, int b) { |
| 1153 return a + b; | 1120 return a + b; |
| 1154 }'''); | 1121 }'''); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 return a + b; | 1165 return a + b; |
| 1199 } | 1166 } |
| 1200 } | 1167 } |
| 1201 '''); | 1168 '''); |
| 1202 _resolve(_editString(' return a + b;', r''' | 1169 _resolve(_editString(' return a + b;', r''' |
| 1203 int res = a + b; | 1170 int res = a + b; |
| 1204 return res; | 1171 return res; |
| 1205 '''), _isBlock); | 1172 '''), _isBlock); |
| 1206 } | 1173 } |
| 1207 | 1174 |
| 1175 void test_method_parameter_rename() { |
| 1176 _resolveUnit(r''' |
| 1177 class A { |
| 1178 int m(int a, int b, int c) { |
| 1179 return a + b + c; |
| 1180 } |
| 1181 } |
| 1182 '''); |
| 1183 _resolve(_editString(r'''(int a, int b, int c) { |
| 1184 return a + b + c;''', r'''(int a, int second, int c) { |
| 1185 return a + second + c;'''), _isDeclaration); |
| 1186 } |
| 1187 |
| 1208 void test_topLevelFunction_label_add() { | 1188 void test_topLevelFunction_label_add() { |
| 1209 _resolveUnit(r''' | 1189 _resolveUnit(r''' |
| 1210 int main(int a, int b) { | 1190 int main(int a, int b) { |
| 1211 return a + b; | 1191 return a + b; |
| 1212 } | 1192 } |
| 1213 '''); | 1193 '''); |
| 1214 _resolve(_editString(' return', 'label: return a + b;'), _isBlock); | 1194 _resolve(_editString(' return', 'label: return a + b;'), _isBlock); |
| 1215 } | 1195 } |
| 1216 | 1196 |
| 1217 void test_topLevelFunction_label_remove() { | 1197 void test_topLevelFunction_label_remove() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1238 void test_topLevelFunction_localVariable_remove() { | 1218 void test_topLevelFunction_localVariable_remove() { |
| 1239 _resolveUnit(r''' | 1219 _resolveUnit(r''' |
| 1240 int main(int a, int b) { | 1220 int main(int a, int b) { |
| 1241 int res = a * b; | 1221 int res = a * b; |
| 1242 return a + b; | 1222 return a + b; |
| 1243 } | 1223 } |
| 1244 '''); | 1224 '''); |
| 1245 _resolve(_editString('int res = a * b;', ''), _isBlock); | 1225 _resolve(_editString('int res = a * b;', ''), _isBlock); |
| 1246 } | 1226 } |
| 1247 | 1227 |
| 1228 void test_topLevelFunction_parameter_rename() { |
| 1229 _resolveUnit(r''' |
| 1230 int main(int a, int b) { |
| 1231 return a + b; |
| 1232 } |
| 1233 '''); |
| 1234 _resolve(_editString(r'''(int a, int b) { |
| 1235 return a + b;''', r'''(int first, int b) { |
| 1236 return first + b;'''), _isDeclaration); |
| 1237 } |
| 1238 |
| 1248 void test_topLevelVariable_initializer() { | 1239 void test_topLevelVariable_initializer() { |
| 1249 _resolveUnit(r''' | 1240 _resolveUnit(r''' |
| 1250 int C = 1 + 2; | 1241 int C = 1 + 2; |
| 1251 '''); | 1242 '''); |
| 1252 _resolve(_editString('+', '*'), _isExpression); | 1243 _resolve(_editString('+', '*'), _isExpression); |
| 1253 } | 1244 } |
| 1254 | 1245 |
| 1255 void test_updateElementOffset() { | 1246 void test_updateElementOffset() { |
| 1256 _resolveUnit(r''' | 1247 _resolveUnit(r''' |
| 1257 class A { | 1248 class A { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 * the incremental resolution and non-incremental resolutions are the same. | 1281 * the incremental resolution and non-incremental resolutions are the same. |
| 1291 */ | 1282 */ |
| 1292 void _resolve(_Edit edit, Predicate<AstNode> predicate) { | 1283 void _resolve(_Edit edit, Predicate<AstNode> predicate) { |
| 1293 int offset = edit.offset; | 1284 int offset = edit.offset; |
| 1294 // parse "newCode" | 1285 // parse "newCode" |
| 1295 String newCode = | 1286 String newCode = |
| 1296 code.substring(0, offset) + | 1287 code.substring(0, offset) + |
| 1297 edit.replacement + | 1288 edit.replacement + |
| 1298 code.substring(offset + edit.length); | 1289 code.substring(offset + edit.length); |
| 1299 CompilationUnit newUnit = _parseUnit(newCode); | 1290 CompilationUnit newUnit = _parseUnit(newCode); |
| 1291 // update tokens |
| 1292 { |
| 1293 int delta = edit.replacement.length - edit.length; |
| 1294 _shiftTokens(unit.beginToken, offset, delta); |
| 1295 } |
| 1300 // replace the node | 1296 // replace the node |
| 1301 AstNode oldNode = _findNodeAt(unit, offset, predicate); | 1297 AstNode oldNode = _findNodeAt(unit, offset, predicate); |
| 1302 AstNode newNode = _findNodeAt(newUnit, offset, predicate); | 1298 AstNode newNode = _findNodeAt(newUnit, offset, predicate); |
| 1303 bool success = NodeReplacer.replace(oldNode, newNode); | 1299 bool success = NodeReplacer.replace(oldNode, newNode); |
| 1304 expect(success, isTrue); | 1300 expect(success, isTrue); |
| 1305 // do incremental resolution | 1301 // do incremental resolution |
| 1306 GatheringErrorListener errorListener = new GatheringErrorListener(); | 1302 GatheringErrorListener errorListener = new GatheringErrorListener(); |
| 1307 IncrementalResolver resolver = new IncrementalResolver( | 1303 IncrementalResolver resolver = new IncrementalResolver( |
| 1308 errorListener, | 1304 errorListener, |
| 1309 typeProvider, | 1305 typeProvider, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1351 static bool _isStatement(AstNode node) => node is Statement; | 1347 static bool _isStatement(AstNode node) => node is Statement; |
| 1352 | 1348 |
| 1353 static CompilationUnit _parseUnit(String code) { | 1349 static CompilationUnit _parseUnit(String code) { |
| 1354 var errorListener = new BooleanErrorListener(); | 1350 var errorListener = new BooleanErrorListener(); |
| 1355 var reader = new CharSequenceReader(code); | 1351 var reader = new CharSequenceReader(code); |
| 1356 var scanner = new Scanner(null, reader, errorListener); | 1352 var scanner = new Scanner(null, reader, errorListener); |
| 1357 var token = scanner.tokenize(); | 1353 var token = scanner.tokenize(); |
| 1358 var parser = new Parser(null, errorListener); | 1354 var parser = new Parser(null, errorListener); |
| 1359 return parser.parseCompilationUnit(token); | 1355 return parser.parseCompilationUnit(token); |
| 1360 } | 1356 } |
| 1357 |
| 1358 static void _shiftTokens(Token token, int afterOffset, int delta) { |
| 1359 while (token.type != TokenType.EOF) { |
| 1360 if (token.offset >= afterOffset) { |
| 1361 token.applyDelta(delta); |
| 1362 } |
| 1363 token = token.next; |
| 1364 } |
| 1365 } |
| 1361 } | 1366 } |
| 1362 | 1367 |
| 1363 | 1368 |
| 1364 class ResolutionContextBuilderTest extends EngineTestCase { | 1369 class ResolutionContextBuilderTest extends EngineTestCase { |
| 1365 GatheringErrorListener listener = new GatheringErrorListener(); | 1370 GatheringErrorListener listener = new GatheringErrorListener(); |
| 1366 | 1371 |
| 1367 void test_scopeFor_ClassDeclaration() { | 1372 void test_scopeFor_ClassDeclaration() { |
| 1368 Scope scope = _scopeFor(_createResolvedClassDeclaration()); | 1373 Scope scope = _scopeFor(_createResolvedClassDeclaration()); |
| 1369 EngineTestCase.assertInstanceOf( | 1374 EngineTestCase.assertInstanceOf( |
| 1370 (obj) => obj is LibraryScope, | 1375 (obj) => obj is LibraryScope, |
| (...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2358 _visitNode(node.expression, other.expression); | 2363 _visitNode(node.expression, other.expression); |
| 2359 } | 2364 } |
| 2360 | 2365 |
| 2361 void _verifyElement(Element a, Element b) { | 2366 void _verifyElement(Element a, Element b) { |
| 2362 if (a != b) { | 2367 if (a != b) { |
| 2363 fail('Expected: $b\n Actual: $a'); | 2368 fail('Expected: $b\n Actual: $a'); |
| 2364 } | 2369 } |
| 2365 if (a == null && b == null) { | 2370 if (a == null && b == null) { |
| 2366 return; | 2371 return; |
| 2367 } | 2372 } |
| 2368 expect(a.nameOffset, b.nameOffset); | 2373 if (a.nameOffset != b.nameOffset) { |
| 2374 fail('Expected: ${b.nameOffset}\n Actual: ${a.nameOffset}'); |
| 2375 } |
| 2369 } | 2376 } |
| 2370 | 2377 |
| 2371 void _verifyType(DartType a, DartType b) { | 2378 void _verifyType(DartType a, DartType b) { |
| 2372 expect(a, equals(b)); | 2379 expect(a, equals(b)); |
| 2373 } | 2380 } |
| 2374 | 2381 |
| 2375 void _visitAnnotatedNode(AnnotatedNode node, AnnotatedNode other) { | 2382 void _visitAnnotatedNode(AnnotatedNode node, AnnotatedNode other) { |
| 2376 _visitNode(node.documentationComment, other.documentationComment); | 2383 _visitNode(node.documentationComment, other.documentationComment); |
| 2377 _visitList(node.metadata, other.metadata); | 2384 _visitList(node.metadata, other.metadata); |
| 2378 } | 2385 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2418 _visitList(node.metadata, other.metadata); | 2425 _visitList(node.metadata, other.metadata); |
| 2419 _visitNode(node.identifier, other.identifier); | 2426 _visitNode(node.identifier, other.identifier); |
| 2420 } | 2427 } |
| 2421 | 2428 |
| 2422 static void assertSameResolution(CompilationUnit actual, | 2429 static void assertSameResolution(CompilationUnit actual, |
| 2423 CompilationUnit expected) { | 2430 CompilationUnit expected) { |
| 2424 _SameResolutionValidator validator = new _SameResolutionValidator(expected); | 2431 _SameResolutionValidator validator = new _SameResolutionValidator(expected); |
| 2425 actual.accept(validator); | 2432 actual.accept(validator); |
| 2426 } | 2433 } |
| 2427 } | 2434 } |
| OLD | NEW |