Chromium Code Reviews| 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 analyzer.test.generated.incremental_resolver_test; | 5 library analyzer.test.generated.incremental_resolver_test; |
| 6 | 6 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/element/element.dart'; | 8 import 'package:analyzer/dart/element/element.dart'; |
| 9 import 'package:analyzer/src/context/cache.dart'; | 9 import 'package:analyzer/src/context/cache.dart'; |
| 10 import 'package:analyzer/src/dart/ast/utilities.dart'; | 10 import 'package:analyzer/src/dart/ast/utilities.dart'; |
| 11 import 'package:analyzer/src/dart/element/builder.dart'; | 11 import 'package:analyzer/src/dart/element/builder.dart'; |
| 12 import 'package:analyzer/src/dart/element/element.dart'; | 12 import 'package:analyzer/src/dart/element/element.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 13 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/error.dart'; | 14 import 'package:analyzer/src/generated/error.dart'; |
| 15 import 'package:analyzer/src/generated/incremental_logger.dart' as logging; | 15 import 'package:analyzer/src/generated/incremental_logger.dart' as logging; |
| 16 import 'package:analyzer/src/generated/incremental_resolution_validator.dart'; | 16 import 'package:analyzer/src/generated/incremental_resolution_validator.dart'; |
| 17 import 'package:analyzer/src/generated/incremental_resolver.dart'; | 17 import 'package:analyzer/src/generated/incremental_resolver.dart'; |
| 18 import 'package:analyzer/src/generated/java_engine.dart'; | 18 import 'package:analyzer/src/generated/java_engine.dart'; |
| 19 import 'package:analyzer/src/generated/parser.dart'; | 19 import 'package:analyzer/src/generated/parser.dart'; |
| 20 import 'package:analyzer/src/generated/resolver.dart'; | 20 import 'package:analyzer/src/generated/resolver.dart'; |
| 21 import 'package:analyzer/src/generated/scanner.dart'; | 21 import 'package:analyzer/src/generated/scanner.dart'; |
| 22 import 'package:analyzer/src/generated/source_io.dart'; | 22 import 'package:analyzer/src/generated/source_io.dart'; |
| 23 import 'package:analyzer/src/generated/testing/ast_factory.dart'; | 23 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
| 24 import 'package:analyzer/src/generated/testing/element_factory.dart'; | 24 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
| 25 import 'package:analyzer/src/generated/utilities_collection.dart'; | |
| 25 import 'package:analyzer/src/task/dart.dart'; | 26 import 'package:analyzer/src/task/dart.dart'; |
| 26 import 'package:analyzer/task/dart.dart'; | 27 import 'package:analyzer/task/dart.dart'; |
| 28 import 'package:analyzer/task/model.dart'; | |
| 27 import 'package:unittest/unittest.dart'; | 29 import 'package:unittest/unittest.dart'; |
| 28 | 30 |
| 29 import '../reflective_tests.dart'; | 31 import '../reflective_tests.dart'; |
| 30 import 'resolver_test.dart'; | 32 import 'resolver_test.dart'; |
| 31 import 'test_support.dart'; | 33 import 'test_support.dart'; |
| 32 | 34 |
| 33 main() { | 35 main() { |
| 34 initializeTestEnvironment(); | 36 initializeTestEnvironment(); |
| 35 runReflectiveTests(DeclarationMatcherTest); | 37 runReflectiveTests(DeclarationMatcherTest); |
| 36 runReflectiveTests(IncrementalResolverTest); | 38 runReflectiveTests(IncrementalResolverTest); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 fullErrors.sort((a, b) => a.offset - b.offset); | 113 fullErrors.sort((a, b) => a.offset - b.offset); |
| 112 } | 114 } |
| 113 int length = incrErrors.length; | 115 int length = incrErrors.length; |
| 114 for (int i = 0; i < length; i++) { | 116 for (int i = 0; i < length; i++) { |
| 115 AnalysisError incrError = incrErrors[i]; | 117 AnalysisError incrError = incrErrors[i]; |
| 116 AnalysisError fullError = fullErrors[i]; | 118 AnalysisError fullError = fullErrors[i]; |
| 117 _assertEqualError(incrError, fullError); | 119 _assertEqualError(incrError, fullError); |
| 118 } | 120 } |
| 119 } | 121 } |
| 120 | 122 |
| 123 void _checkCacheEntries(AnalysisCache cache) { | |
| 124 Set seen = new Set(); | |
| 125 MapIterator<AnalysisTarget, CacheEntry> it = cache.iterator(); | |
| 126 while (it.moveNext()) { | |
| 127 AnalysisTarget key = it.key; | |
| 128 if (cache.get(key) == null) { | |
|
Brian Wilkerson
2016/02/02 22:51:14
Would the test
cache.get(key) != it.value
be b
scheglov
2016/02/02 23:04:25
`it.value` works mostly as `cache.get(key)`.
So, i
skybrian
2016/02/02 23:27:02
Yes, the old value is (usually) no longer accessib
| |
| 129 fail("cache corrupted: value of $key changed to null"); | |
| 130 } | |
| 131 if (seen.contains(key)) { | |
|
Brian Wilkerson
2016/02/02 22:51:14
nit: just use "!seen.add(key)" here and remove lin
skybrian
2016/02/02 23:27:02
Done.
| |
| 132 fail("cache corrupted: $key appears more than once"); | |
| 133 } | |
| 134 seen.add(key); | |
| 135 } | |
| 136 } | |
| 137 | |
| 121 @reflectiveTest | 138 @reflectiveTest |
| 122 class DeclarationMatcherTest extends ResolverTestCase { | 139 class DeclarationMatcherTest extends ResolverTestCase { |
| 123 void setUp() { | 140 void setUp() { |
| 124 super.setUp(); | 141 super.setUp(); |
| 125 test_resolveApiChanges = true; | 142 test_resolveApiChanges = true; |
| 126 } | 143 } |
| 127 | 144 |
| 128 void test_false_class_annotation_accessor_edit() { | 145 void test_false_class_annotation_accessor_edit() { |
| 129 _assertDoesNotMatch( | 146 _assertDoesNotMatch( |
| 130 r''' | 147 r''' |
| (...skipping 2983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3114 void test_classMemberAccessor_body() { | 3131 void test_classMemberAccessor_body() { |
| 3115 _resolveUnit(r''' | 3132 _resolveUnit(r''' |
| 3116 class A { | 3133 class A { |
| 3117 int get test { | 3134 int get test { |
| 3118 return 1 + 2; | 3135 return 1 + 2; |
| 3119 } | 3136 } |
| 3120 }'''); | 3137 }'''); |
| 3121 _resolve(_editString('+', '*'), _isFunctionBody); | 3138 _resolve(_editString('+', '*'), _isFunctionBody); |
| 3122 } | 3139 } |
| 3123 | 3140 |
| 3141 void test_computeConstants_offsetChanged() { | |
| 3142 _resolveUnit(r''' | |
| 3143 int f() => 0; | |
| 3144 main() { | |
| 3145 const x1 = f(); | |
| 3146 const x2 = f(); | |
| 3147 const x3 = f(); | |
| 3148 const x4 = f(); | |
| 3149 const x5 = f(); | |
| 3150 print(x1 + x2 + x3 + x4 + x5 + 1); | |
| 3151 } | |
| 3152 '''); | |
| 3153 _resolve(_editString('x1', ' x1'), _isFunctionBody); | |
| 3154 } | |
| 3155 | |
| 3124 void test_constructor_body() { | 3156 void test_constructor_body() { |
| 3125 _resolveUnit(r''' | 3157 _resolveUnit(r''' |
| 3126 class A { | 3158 class A { |
| 3127 int f; | 3159 int f; |
| 3128 A(int a, int b) { | 3160 A(int a, int b) { |
| 3129 f = a + b; | 3161 f = a + b; |
| 3130 } | 3162 } |
| 3131 }'''); | 3163 }'''); |
| 3132 _resolve(_editString('+', '*'), _isFunctionBody); | 3164 _resolve(_editString('+', '*'), _isFunctionBody); |
| 3133 } | 3165 } |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3419 * Then resolves the new code from scratch and validates that results of | 3451 * Then resolves the new code from scratch and validates that results of |
| 3420 * the incremental resolution and non-incremental resolutions are the same. | 3452 * the incremental resolution and non-incremental resolutions are the same. |
| 3421 */ | 3453 */ |
| 3422 void _resolve(_Edit edit, Predicate<AstNode> predicate) { | 3454 void _resolve(_Edit edit, Predicate<AstNode> predicate) { |
| 3423 int offset = edit.offset; | 3455 int offset = edit.offset; |
| 3424 // parse "newCode" | 3456 // parse "newCode" |
| 3425 String newCode = code.substring(0, offset) + | 3457 String newCode = code.substring(0, offset) + |
| 3426 edit.replacement + | 3458 edit.replacement + |
| 3427 code.substring(offset + edit.length); | 3459 code.substring(offset + edit.length); |
| 3428 CompilationUnit newUnit = _parseUnit(newCode); | 3460 CompilationUnit newUnit = _parseUnit(newCode); |
| 3461 AnalysisCache cache = analysisContext2.analysisCache; | |
| 3462 _checkCacheEntries(cache); | |
| 3463 | |
| 3429 // replace the node | 3464 // replace the node |
| 3430 AstNode oldNode = _findNodeAt(unit, offset, predicate); | 3465 AstNode oldNode = _findNodeAt(unit, offset, predicate); |
| 3431 AstNode newNode = _findNodeAt(newUnit, offset, predicate); | 3466 AstNode newNode = _findNodeAt(newUnit, offset, predicate); |
| 3432 { | 3467 { |
| 3433 bool success = NodeReplacer.replace(oldNode, newNode); | 3468 bool success = NodeReplacer.replace(oldNode, newNode); |
| 3434 expect(success, isTrue); | 3469 expect(success, isTrue); |
| 3435 } | 3470 } |
| 3436 // update tokens | 3471 // update tokens |
| 3437 { | 3472 { |
| 3438 int delta = edit.replacement.length - edit.length; | 3473 int delta = edit.replacement.length - edit.length; |
| 3439 _shiftTokens(unit.beginToken, offset, delta); | 3474 _shiftTokens(unit.beginToken, offset, delta); |
| 3440 } | 3475 } |
| 3441 // do incremental resolution | 3476 // do incremental resolution |
| 3442 int updateOffset = edit.offset; | 3477 int updateOffset = edit.offset; |
| 3443 int updateEndOld = updateOffset + edit.length; | 3478 int updateEndOld = updateOffset + edit.length; |
| 3444 int updateOldNew = updateOffset + edit.replacement.length; | 3479 int updateOldNew = updateOffset + edit.replacement.length; |
| 3445 IncrementalResolver resolver; | 3480 IncrementalResolver resolver; |
| 3446 LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source); | 3481 LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source); |
| 3447 AnalysisCache cache = analysisContext2.analysisCache; | 3482 resolver = new IncrementalResolver(cache, cache.get(source), cache.get(lsu), |
| 3448 resolver = new IncrementalResolver(cache.get(source), cache.get(lsu), | |
| 3449 unit.element, updateOffset, updateEndOld, updateOldNew); | 3483 unit.element, updateOffset, updateEndOld, updateOldNew); |
| 3450 bool success = resolver.resolve(newNode); | 3484 bool success = resolver.resolve(newNode); |
| 3451 expect(success, isTrue); | 3485 expect(success, isTrue); |
| 3486 _checkCacheEntries(cache); | |
| 3487 | |
| 3452 List<AnalysisError> newErrors = analysisContext.computeErrors(source); | 3488 List<AnalysisError> newErrors = analysisContext.computeErrors(source); |
| 3453 // resolve "newCode" from scratch | 3489 // resolve "newCode" from scratch |
| 3454 CompilationUnit fullNewUnit; | 3490 CompilationUnit fullNewUnit; |
| 3455 { | 3491 { |
| 3456 source = addSource(newCode); | 3492 source = addSource(newCode); |
| 3457 _runTasks(); | 3493 _runTasks(); |
| 3458 LibraryElement library = resolve2(source); | 3494 LibraryElement library = resolve2(source); |
| 3459 fullNewUnit = resolveCompilationUnit(source, library); | 3495 fullNewUnit = resolveCompilationUnit(source, library); |
| 3460 } | 3496 } |
| 3497 _checkCacheEntries(cache); | |
| 3498 | |
| 3461 try { | 3499 try { |
| 3462 assertSameResolution(unit, fullNewUnit); | 3500 assertSameResolution(unit, fullNewUnit); |
| 3463 } on IncrementalResolutionMismatch catch (mismatch) { | 3501 } on IncrementalResolutionMismatch catch (mismatch) { |
| 3464 fail(mismatch.message); | 3502 fail(mismatch.message); |
| 3465 } | 3503 } |
| 3466 // errors | 3504 // errors |
| 3467 List<AnalysisError> newFullErrors = | 3505 List<AnalysisError> newFullErrors = |
| 3468 analysisContext.getErrors(source).errors; | 3506 analysisContext.getErrors(source).errors; |
| 3469 _assertEqualErrors(newErrors, newFullErrors); | 3507 _assertEqualErrors(newErrors, newFullErrors); |
| 3470 // prepare for the next cycle | 3508 // prepare for the next cycle |
| 3471 code = newCode; | 3509 code = newCode; |
| 3472 } | 3510 } |
| 3473 | 3511 |
| 3474 void _resolveUnit(String code) { | 3512 void _resolveUnit(String code) { |
| 3475 this.code = code; | 3513 this.code = code; |
| 3476 source = addSource(code); | 3514 source = addSource(code); |
| 3477 library = resolve2(source); | 3515 library = resolve2(source); |
| 3478 unit = resolveCompilationUnit(source, library); | 3516 unit = resolveCompilationUnit(source, library); |
| 3479 _runTasks(); | 3517 _runTasks(); |
| 3518 _checkCacheEntries(analysisContext2.analysisCache); | |
| 3480 } | 3519 } |
| 3481 | 3520 |
| 3482 void _runTasks() { | 3521 void _runTasks() { |
| 3483 AnalysisResult result = analysisContext.performAnalysisTask(); | 3522 AnalysisResult result = analysisContext.performAnalysisTask(); |
| 3484 while (result.changeNotices != null) { | 3523 while (result.changeNotices != null) { |
| 3485 result = analysisContext.performAnalysisTask(); | 3524 result = analysisContext.performAnalysisTask(); |
| 3486 } | 3525 } |
| 3487 } | 3526 } |
| 3488 | 3527 |
| 3489 static AstNode _findNodeAt( | 3528 static AstNode _findNodeAt( |
| (...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4860 // Validate that "incremental" and "full" units have the same resolution. | 4899 // Validate that "incremental" and "full" units have the same resolution. |
| 4861 try { | 4900 try { |
| 4862 assertSameResolution(newUnit, fullNewUnit, validateTypes: true); | 4901 assertSameResolution(newUnit, fullNewUnit, validateTypes: true); |
| 4863 } on IncrementalResolutionMismatch catch (mismatch) { | 4902 } on IncrementalResolutionMismatch catch (mismatch) { |
| 4864 fail(mismatch.message); | 4903 fail(mismatch.message); |
| 4865 } | 4904 } |
| 4866 List<AnalysisError> newFullErrors = | 4905 List<AnalysisError> newFullErrors = |
| 4867 analysisContext.getErrors(source).errors; | 4906 analysisContext.getErrors(source).errors; |
| 4868 _assertEqualErrors(newErrors, newFullErrors); | 4907 _assertEqualErrors(newErrors, newFullErrors); |
| 4869 } | 4908 } |
| 4909 _checkCacheEntries(analysisContext2.analysisCache); | |
| 4870 } | 4910 } |
| 4871 | 4911 |
| 4872 static void _assertEqualToken(Token incrToken, Token fullToken) { | 4912 static void _assertEqualToken(Token incrToken, Token fullToken) { |
| 4873 // print('[${incrToken.offset}] |$incrToken| vs. [${fullToken.offset}] |$full Token|'); | 4913 // print('[${incrToken.offset}] |$incrToken| vs. [${fullToken.offset}] |$full Token|'); |
| 4874 expect(incrToken.type, fullToken.type); | 4914 expect(incrToken.type, fullToken.type); |
| 4875 expect(incrToken.offset, fullToken.offset); | 4915 expect(incrToken.offset, fullToken.offset); |
| 4876 expect(incrToken.length, fullToken.length); | 4916 expect(incrToken.length, fullToken.length); |
| 4877 expect(incrToken.lexeme, fullToken.lexeme); | 4917 expect(incrToken.lexeme, fullToken.lexeme); |
| 4878 } | 4918 } |
| 4879 | 4919 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5136 @override | 5176 @override |
| 5137 void logException(Object exception, [Object stackTrace]) { | 5177 void logException(Object exception, [Object stackTrace]) { |
| 5138 hasError = true; | 5178 hasError = true; |
| 5139 } | 5179 } |
| 5140 | 5180 |
| 5141 @override | 5181 @override |
| 5142 logging.LoggingTimer startTimer() { | 5182 logging.LoggingTimer startTimer() { |
| 5143 return new logging.LoggingTimer(this); | 5183 return new logging.LoggingTimer(this); |
| 5144 } | 5184 } |
| 5145 } | 5185 } |
| OLD | NEW |