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

Side by Side Diff: pkg/analyzer/test/src/context/context_test.dart

Issue 2834773003: Remove the limited invalidation feature. (Closed)
Patch Set: Created 3 years, 8 months 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
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 analyzer.test.src.context.context_test; 5 library analyzer.test.src.context.context_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
11 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; 11 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
12 import 'package:analyzer/dart/element/element.dart'; 12 import 'package:analyzer/dart/element/element.dart';
13 import 'package:analyzer/dart/element/type.dart'; 13 import 'package:analyzer/dart/element/type.dart';
14 import 'package:analyzer/dart/element/visitor.dart'; 14 import 'package:analyzer/dart/element/visitor.dart';
15 import 'package:analyzer/error/error.dart'; 15 import 'package:analyzer/error/error.dart';
16 import 'package:analyzer/exception/exception.dart'; 16 import 'package:analyzer/exception/exception.dart';
17 import 'package:analyzer/file_system/file_system.dart'; 17 import 'package:analyzer/file_system/file_system.dart';
18 import 'package:analyzer/file_system/memory_file_system.dart'; 18 import 'package:analyzer/file_system/memory_file_system.dart';
19 import 'package:analyzer/source/package_map_resolver.dart'; 19 import 'package:analyzer/source/package_map_resolver.dart';
20 import 'package:analyzer/src/cancelable_future.dart'; 20 import 'package:analyzer/src/cancelable_future.dart';
21 import 'package:analyzer/src/context/cache.dart'; 21 import 'package:analyzer/src/context/cache.dart';
22 import 'package:analyzer/src/context/context.dart'; 22 import 'package:analyzer/src/context/context.dart';
23 import 'package:analyzer/src/dart/element/element.dart';
24 import 'package:analyzer/src/dart/scanner/scanner.dart'; 23 import 'package:analyzer/src/dart/scanner/scanner.dart';
25 import 'package:analyzer/src/generated/engine.dart'; 24 import 'package:analyzer/src/generated/engine.dart';
26 import 'package:analyzer/src/generated/resolver.dart'; 25 import 'package:analyzer/src/generated/resolver.dart';
27 import 'package:analyzer/src/generated/source.dart'; 26 import 'package:analyzer/src/generated/source.dart';
28 import 'package:analyzer/src/generated/utilities_collection.dart'; 27 import 'package:analyzer/src/generated/utilities_collection.dart';
29 import 'package:analyzer/src/task/dart.dart'; 28 import 'package:analyzer/src/task/dart.dart';
30 import 'package:analyzer/src/task/html.dart'; 29 import 'package:analyzer/src/task/html.dart';
31 import 'package:analyzer/task/dart.dart'; 30 import 'package:analyzer/task/dart.dart';
32 import 'package:analyzer/task/general.dart';
33 import 'package:analyzer/task/model.dart'; 31 import 'package:analyzer/task/model.dart';
34 import 'package:html/dom.dart' show Document; 32 import 'package:html/dom.dart' show Document;
35 import 'package:test/test.dart'; 33 import 'package:test/test.dart';
36 import 'package:test_reflective_loader/test_reflective_loader.dart'; 34 import 'package:test_reflective_loader/test_reflective_loader.dart';
37 import 'package:watcher/src/utils.dart'; 35 import 'package:watcher/src/utils.dart';
38 36
39 import '../../generated/engine_test.dart'; 37 import '../../generated/engine_test.dart';
40 import '../../generated/test_support.dart'; 38 import '../../generated/test_support.dart';
41 import '../../utils.dart';
42 import 'abstract_context.dart'; 39 import 'abstract_context.dart';
43 40
44 main() { 41 main() {
45 defineReflectiveSuite(() { 42 defineReflectiveSuite(() {
46 defineReflectiveTests(AnalysisContextImplTest); 43 defineReflectiveTests(AnalysisContextImplTest);
47 defineReflectiveTests(LimitedInvalidateTest);
48 }); 44 });
49 } 45 }
50 46
51 @reflectiveTest 47 @reflectiveTest
52 class AnalysisContextImplTest extends AbstractContextTest { 48 class AnalysisContextImplTest extends AbstractContextTest {
53 void fail_getErrors_html_some() { 49 void fail_getErrors_html_some() {
54 Source source = addSource( 50 Source source = addSource(
55 "/test.html", 51 "/test.html",
56 r''' 52 r'''
57 <html><head> 53 <html><head>
(...skipping 2172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2230 addSource("/test.dart", "library lib; part 'test-part.dart';"); 2226 addSource("/test.dart", "library lib; part 'test-part.dart';");
2231 Source partSource = addSource("/test-part.dart", "part of lib;"); 2227 Source partSource = addSource("/test-part.dart", "part of lib;");
2232 _analyzeAll_assertFinished(); 2228 _analyzeAll_assertFinished();
2233 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, 2229 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
2234 reason: "library resolved 1"); 2230 reason: "library resolved 1");
2235 expect( 2231 expect(
2236 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, 2232 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
2237 reason: "part resolved 1"); 2233 reason: "part resolved 1");
2238 // update and analyze #1 2234 // update and analyze #1
2239 context.setContents(partSource, "part of lib; // 1"); 2235 context.setContents(partSource, "part of lib; // 1");
2240 if (context.analysisOptions.finerGrainedInvalidation) { 2236 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
2241 expect( 2237 reason: "library changed 2");
2242 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, 2238 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
2243 reason: "library changed 2"); 2239 reason: "part changed 2");
2244 expect( 2240 _analyzeAll_assertFinished();
2245 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, 2241 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
2246 reason: "part changed 2"); 2242 reason: "library resolved 2");
2247 } else { 2243 expect(
2248 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, 2244 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
2249 reason: "library changed 2"); 2245 reason: "part resolved 2");
2250 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
2251 reason: "part changed 2");
2252 _analyzeAll_assertFinished();
2253 expect(
2254 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
2255 reason: "library resolved 2");
2256 expect(
2257 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
2258 reason: "part resolved 2");
2259 }
2260 // update and analyze #2 2246 // update and analyze #2
2261 context.setContents(partSource, "part of lib; // 12"); 2247 context.setContents(partSource, "part of lib; // 12");
2262 if (context.analysisOptions.finerGrainedInvalidation) { 2248 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
2263 expect( 2249 reason: "library changed 3");
2264 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, 2250 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
2265 reason: "library changed 3"); 2251 reason: "part changed 3");
2266 expect( 2252 _analyzeAll_assertFinished();
2267 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, 2253 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
2268 reason: "part changed 3"); 2254 reason: "library resolved 3");
2269 } else { 2255 expect(
2270 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, 2256 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
2271 reason: "library changed 3"); 2257 reason: "part resolved 3");
2272 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
2273 reason: "part changed 3");
2274 _analyzeAll_assertFinished();
2275 expect(
2276 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
2277 reason: "library resolved 3");
2278 expect(
2279 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
2280 reason: "part resolved 3");
2281 }
2282 } 2258 }
2283 2259
2284 void test_performAnalysisTask_getContentException_dart() { 2260 void test_performAnalysisTask_getContentException_dart() {
2285 Source source = _addSourceWithException('test.dart'); 2261 Source source = _addSourceWithException('test.dart');
2286 // prepare errors 2262 // prepare errors
2287 _analyzeAll_assertFinished(); 2263 _analyzeAll_assertFinished();
2288 List<AnalysisError> errors = context.getErrors(source).errors; 2264 List<AnalysisError> errors = context.getErrors(source).errors;
2289 // validate errors 2265 // validate errors
2290 expect(errors, hasLength(1)); 2266 expect(errors, hasLength(1));
2291 AnalysisError error = errors[0]; 2267 AnalysisError error = errors[0];
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 } 2384 }
2409 2385
2410 void test_performAnalysisTask_IOException() { 2386 void test_performAnalysisTask_IOException() {
2411 TestSource source = _addSourceWithException2("/test.dart", "library test;"); 2387 TestSource source = _addSourceWithException2("/test.dart", "library test;");
2412 source.generateExceptionOnRead = false; 2388 source.generateExceptionOnRead = false;
2413 _analyzeAll_assertFinished(); 2389 _analyzeAll_assertFinished();
2414 expect(source.readCount, 2); 2390 expect(source.readCount, 2);
2415 _changeSource(source, ""); 2391 _changeSource(source, "");
2416 source.generateExceptionOnRead = true; 2392 source.generateExceptionOnRead = true;
2417 _analyzeAll_assertFinished(); 2393 _analyzeAll_assertFinished();
2418 if (context.analysisOptions.finerGrainedInvalidation) { 2394 expect(source.readCount, 5);
2419 expect(source.readCount, 7);
2420 } else {
2421 expect(source.readCount, 5);
2422 }
2423 } 2395 }
2424 2396
2425 void test_performAnalysisTask_missingPart() { 2397 void test_performAnalysisTask_missingPart() {
2426 Source source = 2398 Source source =
2427 addSource("/test.dart", "library lib; part 'no-such-file.dart';"); 2399 addSource("/test.dart", "library lib; part 'no-such-file.dart';");
2428 _analyzeAll_assertFinished(); 2400 _analyzeAll_assertFinished();
2429 expect(context.getLibraryElement(source), isNotNull, 2401 expect(context.getLibraryElement(source), isNotNull,
2430 reason: "performAnalysisTask failed to compute an element model"); 2402 reason: "performAnalysisTask failed to compute an element model");
2431 } 2403 }
2432 2404
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
3015 List<AnalysisError> errors = errorInfo.errors; 2987 List<AnalysisError> errors = errorInfo.errors;
3016 for (AnalysisError analysisError in errors) { 2988 for (AnalysisError analysisError in errors) {
3017 if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) { 2989 if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) {
3018 return true; 2990 return true;
3019 } 2991 }
3020 } 2992 }
3021 return false; 2993 return false;
3022 } 2994 }
3023 } 2995 }
3024 2996
3025 @reflectiveTest
3026 class LimitedInvalidateTest extends AbstractContextTest {
3027 @override
3028 void setUp() {
3029 super.setUp();
3030 AnalysisOptionsImpl options =
3031 new AnalysisOptionsImpl.from(context.analysisOptions);
3032 options.incremental = true;
3033 options.finerGrainedInvalidation = true;
3034 context.analysisOptions = options;
3035 }
3036
3037 void test_applyChanges_changedSource_removeFile() {
3038 File file = resourceProvider.newFile('/test.dart', 'main() {}');
3039 Source source = file.createSource();
3040 context.applyChanges(new ChangeSet()..addedSource(source));
3041 // Analyze all.
3042 _performPendingAnalysisTasks();
3043 expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
3044 // Delete the file, but tell the context that it is changed.
3045 // This might happen as a race condition.
3046 // Or it might be a mishandling of file notification events.
3047 file.delete();
3048 context.applyChanges(new ChangeSet()..changedSource(source));
3049 // All the analysis results are gone.
3050 void noResolvedUnits() {
3051 LibrarySpecificUnit unit = new LibrarySpecificUnit(source, source);
3052 RESOLVED_UNIT_RESULTS.forEach((result) {
3053 expect(context.getResult(unit, result), isNull);
3054 });
3055 }
3056
3057 noResolvedUnits();
3058 // Analyze again.
3059 // The source does not exist, so still no resolution.
3060 _performPendingAnalysisTasks();
3061 noResolvedUnits();
3062 expect(context.getModificationStamp(source), -1);
3063 }
3064
3065 void test_class_addMethod_useAsHole_inTopLevelVariable() {
3066 Source a = addSource(
3067 '/a.dart',
3068 r'''
3069 class A {
3070 }
3071 ''');
3072 Source b = addSource(
3073 '/b.dart',
3074 r'''
3075 import 'a.dart';
3076 var B = A.foo;
3077 ''');
3078 Source c = addSource(
3079 '/c.dart',
3080 r'''
3081 import 'b.dart';
3082 var C = B;
3083 ''');
3084 _performPendingAnalysisTasks();
3085 expect(context.getErrors(b).errors, hasLength(1));
3086 // Update a.dart: add A.foo.
3087 // 'B' in b.dart is invalid, because 'B' references 'foo'
3088 // c.dart is invalid, because 'C' references 'B'
3089 context.setContents(
3090 a,
3091 r'''
3092 class A {
3093 static void foo(int p) {}
3094 }
3095 ''');
3096 _assertValidForChangedLibrary(a);
3097 _assertInvalid(a, LIBRARY_ERRORS_READY);
3098
3099 _assertValidForDependentLibrary(b);
3100 _assertInvalid(b, LIBRARY_ERRORS_READY);
3101 _assertInvalidUnits(b, RESOLVED_UNIT4);
3102
3103 _assertValidForDependentLibrary(c);
3104 _assertInvalid(c, LIBRARY_ERRORS_READY);
3105 _assertInvalidUnits(c, RESOLVED_UNIT4);
3106 }
3107
3108 void test_class_addMethod_useClass() {
3109 Source a = addSource(
3110 '/a.dart',
3111 r'''
3112 class A {}
3113 class B extends A {
3114 foo() {}
3115 }
3116 ''');
3117 Source b = addSource(
3118 '/b.dart',
3119 r'''
3120 import 'a.dart';
3121 B b = null;
3122 ''');
3123 _performPendingAnalysisTasks();
3124 // Update a.dart: remove add A.bar.
3125 // b.dart is valid, because though it uses A, it has the same element.
3126 context.setContents(
3127 a,
3128 r'''
3129 class A {}
3130 class B extends A {
3131 foo() {}
3132 bar() {}
3133 }
3134 ''');
3135 _assertValidForChangedLibrary(a);
3136 _assertInvalid(a, LIBRARY_ERRORS_READY);
3137 _assertValidForDependentLibrary(b);
3138 _assertValidAllLibraryUnitResults(b);
3139 _assertValid(b, LIBRARY_ERRORS_READY);
3140 }
3141
3142 void test_class_annotation_add_deprecated() {
3143 Source a = addSource(
3144 '/a.dart',
3145 r'''
3146 class A {}
3147 ''');
3148 Source b = addSource(
3149 '/b.dart',
3150 r'''
3151 import 'a.dart';
3152 List<A> foo() => [];
3153 ''');
3154 _performPendingAnalysisTasks();
3155 expect(context.getErrors(b).errors, hasLength(0));
3156 // Add @deprecated annotation.
3157 // b.dart has valid resolution, because A is still A, so only errors are
3158 // invalidated.
3159 context.setContents(
3160 a,
3161 r'''
3162 @deprecated
3163 class A {}
3164 ''');
3165 _assertValidForChangedLibrary(a);
3166 _assertInvalid(a, LIBRARY_ERRORS_READY);
3167 _assertValidForDependentLibrary(b);
3168 _assertInvalid(b, LIBRARY_ERRORS_READY);
3169 _assertValidAllResolution(b);
3170 // Analysis is done successfully.
3171 _performPendingAnalysisTasks();
3172 _assertValid(a, LIBRARY_ERRORS_READY);
3173 _assertValid(a, READY_RESOLVED_UNIT);
3174 _assertValid(b, LIBRARY_ERRORS_READY);
3175 _assertValid(b, READY_RESOLVED_UNIT);
3176 expect(context.getErrors(b).errors, hasLength(1));
3177 }
3178
3179 void test_class_annotation_remove_deprecated() {
3180 Source a = addSource(
3181 '/a.dart',
3182 r'''
3183 @deprecated
3184 class A {}
3185 ''');
3186 Source b = addSource(
3187 '/b.dart',
3188 r'''
3189 import 'a.dart';
3190 List<A> foo() => [];
3191 ''');
3192 _performPendingAnalysisTasks();
3193 expect(context.getErrors(b).errors, hasLength(1));
3194 // Add @deprecated annotation.
3195 // b.dart has valid resolution, because A is still A, so only errors are
3196 // invalidated.
3197 context.setContents(
3198 a,
3199 r'''
3200 class A {}
3201 ''');
3202 _assertValidForChangedLibrary(a);
3203 _assertInvalid(a, LIBRARY_ERRORS_READY);
3204 _assertValidForDependentLibrary(b);
3205 _assertInvalid(b, LIBRARY_ERRORS_READY);
3206 _assertValidAllResolution(b);
3207 // Analysis is done successfully.
3208 _performPendingAnalysisTasks();
3209 _assertValid(a, LIBRARY_ERRORS_READY);
3210 _assertValid(a, READY_RESOLVED_UNIT);
3211 _assertValid(b, LIBRARY_ERRORS_READY);
3212 _assertValid(b, READY_RESOLVED_UNIT);
3213 expect(context.getErrors(b).errors, hasLength(0));
3214 }
3215
3216 void test_class_constructor_named_changeName() {
3217 // Update a.dart: change A.named() to A.named2().
3218 // b.dart is invalid, because it references A.named().
3219 _verifyTwoLibrariesInvalidatesResolution(
3220 r'''
3221 class A {
3222 A.named();
3223 }
3224 ''',
3225 r'''
3226 class A {
3227 A.named2();
3228 }
3229 ''',
3230 r'''
3231 import 'a.dart';
3232 main() {
3233 new A.named();
3234 }
3235 ''');
3236 }
3237
3238 void test_class_constructor_named_parameters_add() {
3239 // Update a.dart: add a new parameter to A.named().
3240 // b.dart is invalid, because it references A.named().
3241 _verifyTwoLibrariesInvalidatesResolution(
3242 r'''
3243 class A {
3244 A.named();
3245 }
3246 ''',
3247 r'''
3248 class A {
3249 A.named(int p);
3250 }
3251 ''',
3252 r'''
3253 import 'a.dart';
3254 main() {
3255 new A.named();
3256 }
3257 ''');
3258 }
3259
3260 void test_class_constructor_named_parameters_change_usedSuper() {
3261 // Update a.dart: change A.named().
3262 // b.dart is invalid, because it references A.named().
3263 _verifyTwoLibrariesInvalidatesResolution(
3264 r'''
3265 class A {
3266 A.named(int a);
3267 }
3268 ''',
3269 r'''
3270 class A {
3271 A.named(String a);
3272 }
3273 ''',
3274 r'''
3275 import 'a.dart';
3276 class B extends A {
3277 B() : super.named(42);
3278 }
3279 ''');
3280 }
3281
3282 void test_class_constructor_named_parameters_remove() {
3283 // Update a.dart: remove a new parameter of A.named().
3284 // b.dart is invalid, because it references A.named().
3285 _verifyTwoLibrariesInvalidatesResolution(
3286 r'''
3287 class A {
3288 A.named(int p);
3289 }
3290 ''',
3291 r'''
3292 class A {
3293 A.named();
3294 }
3295 ''',
3296 r'''
3297 import 'a.dart';
3298 main() {
3299 new A.named();
3300 }
3301 ''');
3302 }
3303
3304 void test_class_constructor_named_remove_notUsed() {
3305 // Update a.dart: remove A.foo().
3306 // b.dart is valid, because it does not reference A.foo().
3307 _verifyTwoLibrariesAllValid(
3308 r'''
3309 class A {
3310 A.foo();
3311 A.bar();
3312 }
3313 ''',
3314 r'''
3315 class A {
3316 A.bar();
3317 }
3318 ''',
3319 r'''
3320 import 'a.dart';
3321 main() {
3322 new A.bar();
3323 }
3324 ''');
3325 }
3326
3327 void test_class_constructor_named_remove_used() {
3328 // Update a.dart: remove A.named().
3329 // b.dart is invalid, because it references A.named().
3330 _verifyTwoLibrariesInvalidatesResolution(
3331 r'''
3332 class A {
3333 A.named();
3334 }
3335 ''',
3336 r'''
3337 class A {
3338 }
3339 ''',
3340 r'''
3341 import 'a.dart';
3342 main() {
3343 new A.named();
3344 }
3345 ''');
3346 }
3347
3348 void test_class_constructor_unnamed_parameters_change_notUsedSuper() {
3349 // Update a.dart: change A().
3350 // Resolution of b.dart is valid, because it does not reference A().
3351 // Hints and verify errors are invalid, because it extends A.
3352 // TODO(scheglov) we could keep valid hints and verify errors,
3353 // because only constructor is changed - this cannot add/remove
3354 // inherited unimplemented members.
3355 _verifyTwoLibrariesInvalidHintsVerifyErrors(
3356 r'''
3357 class A {
3358 A(int a);
3359 A.named(int a);
3360 }
3361 ''',
3362 r'''
3363 class A {
3364 A(String a);
3365 A.named(int a);
3366 }
3367 ''',
3368 r'''
3369 import 'a.dart';
3370 class B extends A {
3371 B() : super.named(42);
3372 }
3373 ''');
3374 }
3375
3376 void test_class_constructor_unnamed_parameters_change_usedSuper() {
3377 // Update a.dart: change A().
3378 // b.dart is invalid, because it references A().
3379 _verifyTwoLibrariesInvalidatesResolution(
3380 r'''
3381 class A {
3382 A(int a);
3383 }
3384 ''',
3385 r'''
3386 class A {
3387 A(String a);
3388 }
3389 ''',
3390 r'''
3391 import 'a.dart';
3392 class B extends A {
3393 B() : super(42);
3394 }
3395 ''');
3396 }
3397
3398 void test_class_constructor_unnamed_parameters_remove() {
3399 // Update a.dart: change A().
3400 // b.dart is invalid, because it references A().
3401 _verifyTwoLibrariesInvalidatesResolution(
3402 r'''
3403 class A {
3404 A(int a, int b);
3405 }
3406 ''',
3407 r'''
3408 class A {
3409 A(int a);
3410 }
3411 ''',
3412 r'''
3413 import 'a.dart';
3414 main() {
3415 new A(1, 2);
3416 }
3417 ''');
3418 }
3419
3420 void test_class_constructor_unnamed_remove_notUsed() {
3421 // Update a.dart: remove A().
3422 // b.dart is invalid, because it instantiates A.
3423 _verifyTwoLibrariesInvalidatesResolution(
3424 r'''
3425 class A {
3426 A();
3427 A.named();
3428 }
3429 ''',
3430 r'''
3431 class A {
3432 A.named();
3433 }
3434 ''',
3435 r'''
3436 import 'a.dart';
3437 main() {
3438 new A.named();
3439 }
3440 ''');
3441 }
3442
3443 void test_class_constructor_unnamed_remove_used() {
3444 // Update a.dart: remove A().
3445 // b.dart is invalid, because it references A().
3446 _verifyTwoLibrariesInvalidatesResolution(
3447 r'''
3448 class A {
3449 A();
3450 }
3451 ''',
3452 r'''
3453 class A {
3454 }
3455 ''',
3456 r'''
3457 import 'a.dart';
3458 main() {
3459 new A();
3460 }
3461 ''');
3462 }
3463
3464 void test_class_method_change_notUsed() {
3465 Source a = addSource(
3466 '/a.dart',
3467 r'''
3468 class A {
3469 foo() {}
3470 bar() {}
3471 }
3472 ''');
3473 Source b = addSource(
3474 '/b.dart',
3475 r'''
3476 import 'a.dart';
3477 main(A a) {
3478 a.foo();
3479 }
3480 ''');
3481 _performPendingAnalysisTasks();
3482 // Update a.dart: remove A.bar, add A.bar2.
3483 // b.dart is valid, because it doesn't references 'bar' or 'bar2'.
3484 context.setContents(
3485 a,
3486 r'''
3487 class A {
3488 foo() {}
3489 bar2() {}
3490 }
3491 ''');
3492 _assertValidForChangedLibrary(a);
3493 _assertInvalid(a, LIBRARY_ERRORS_READY);
3494 _assertValidForDependentLibrary(b);
3495 _assertValidAllLibraryUnitResults(b);
3496 _assertValid(b, LIBRARY_ERRORS_READY);
3497 }
3498
3499 void test_class_method_change_notUsed_throughSubclass_extends() {
3500 Source a = addSource(
3501 '/a.dart',
3502 r'''
3503 class A {
3504 foo() {}
3505 bar() {}
3506 }
3507 class B extends A {}
3508 ''');
3509 Source b = addSource(
3510 '/b.dart',
3511 r'''
3512 import 'a.dart';
3513 main(B b) {
3514 a.foo();
3515 }
3516 ''');
3517 _performPendingAnalysisTasks();
3518 // Update a.dart: remove A.bar, add A.bar2.
3519 // b.dart is valid, because it doesn't references 'bar' or 'bar2'.
3520 context.setContents(
3521 a,
3522 r'''
3523 class A {
3524 foo() {}
3525 bar2() {}
3526 }
3527 class B extends A {}
3528 ''');
3529 _assertValidForChangedLibrary(a);
3530 _assertInvalid(a, LIBRARY_ERRORS_READY);
3531 _assertValidForDependentLibrary(b);
3532 _assertValidAllLibraryUnitResults(b);
3533 _assertValid(b, LIBRARY_ERRORS_READY);
3534 }
3535
3536 void test_class_method_definedInSuper_sameLibrary() {
3537 Source a = addSource(
3538 '/a.dart',
3539 r'''
3540 class A {
3541 m() {}
3542 }
3543 class B extends A {}
3544 ''');
3545 Source b = addSource(
3546 '/b.dart',
3547 r'''
3548 import 'a.dart';
3549 main(B b) {
3550 b.m();
3551 }
3552 ''');
3553 _performPendingAnalysisTasks();
3554 // Update a.dart: change A.m
3555 // This makes B changed.
3556 // b.dart is invalid, because it references B.
3557 context.setContents(
3558 a,
3559 r'''
3560 class A {
3561 m2() {}
3562 }
3563 class B extends A {}
3564 ''');
3565 _assertValidForChangedLibrary(a);
3566 _assertValidForDependentLibrary(b);
3567 _assertInvalid(a, LIBRARY_ERRORS_READY);
3568 _assertInvalid(b, LIBRARY_ERRORS_READY);
3569 }
3570
3571 void test_class_method_remove_notUsed_instantiated() {
3572 Source a = addSource(
3573 '/a.dart',
3574 r'''
3575 abstract class I {
3576 void foo();
3577 }
3578 class A implements I {
3579 void foo() {}
3580 }
3581 ''');
3582 Source b = addSource(
3583 '/b.dart',
3584 r'''
3585 import 'a.dart';
3586 main() {
3587 new A();
3588 }
3589 ''');
3590 _performPendingAnalysisTasks();
3591 // Update a.dart: remove 'A.foo'.
3592 // b.dart is valid because it does not reference 'foo'.
3593 // The class 'A' has a warning, but it is still not abstract.
3594 context.setContents(
3595 a,
3596 r'''
3597 abstract class I {
3598 void fo();
3599 }
3600 class A implements I {
3601 }
3602 ''');
3603 _assertValidForChangedLibrary(a);
3604 _assertInvalid(a, LIBRARY_ERRORS_READY);
3605
3606 _assertValidForDependentLibrary(b);
3607 _assertValidAllLibraryUnitResults(b);
3608 _assertValidAllResolution(b);
3609 _assertValidAllErrors(b);
3610 }
3611
3612 void test_class_method_remove_subclass() {
3613 Source a = addSource(
3614 '/a.dart',
3615 r'''
3616 abstract class I {
3617 void foo();
3618 }
3619 class A implements I {
3620 void foo() {}
3621 }
3622 ''');
3623 Source b = addSource(
3624 '/b.dart',
3625 r'''
3626 import 'a.dart';
3627 class B extends A {}
3628 ''');
3629 _performPendingAnalysisTasks();
3630 // Update a.dart: remove A.bar, add A.bar2.
3631 // b.dart
3632 // Resolution is valid because 'foo' is not referenced.
3633 // HINTS are invalid because 'B' might have invalid @override.
3634 // VERIFY_ERRORS are invalid because 'B' might not implement something.
3635 // Other errors are also invalid.
3636 context.setContents(
3637 a,
3638 r'''
3639 abstract class I {
3640 void foo();
3641 }
3642 class A implements I {
3643 }
3644 ''');
3645 _assertValidForChangedLibrary(a);
3646 _assertInvalid(a, LIBRARY_ERRORS_READY);
3647
3648 _assertValidForDependentLibrary(b);
3649 _assertValidAllResolution(b);
3650 _assertInvalidHintsVerifyErrors(b);
3651 }
3652
3653 void test_class_private_member() {
3654 Source a = addSource(
3655 '/a.dart',
3656 r'''
3657 class A {
3658 A();
3659 A._privateConstructor();
3660
3661 foo() {}
3662
3663 int _privateField;
3664 _privateMethod() {}
3665 int get _privateGetter => null;
3666 void set _privateSetter(_) {}
3667 }
3668 ''');
3669 Source b = addSource(
3670 '/b.dart',
3671 r'''
3672 import 'a.dart';
3673 main(A a) {
3674 a.foo();
3675 }
3676 ''');
3677 _performPendingAnalysisTasks();
3678 // Update a.dart: rename private members of A
3679 // b.dart is valid, it cannot see these private members.
3680 context.setContents(
3681 a,
3682 r'''
3683 class A {
3684 A();
3685 A._privateConstructor2();
3686
3687 foo() {}
3688
3689 int _privateField2;
3690 _privateMethod2() {}
3691 int get _privateGetter2 => null;
3692 void set _privateSetter2(_) {}
3693 }
3694 ''');
3695 _assertValidForChangedLibrary(a);
3696 _assertInvalid(a, LIBRARY_ERRORS_READY);
3697 _assertValidForDependentLibrary(b);
3698 _assertValidAllLibraryUnitResults(b);
3699 _assertValid(b, LIBRARY_ERRORS_READY);
3700 }
3701
3702 void test_enum_add() {
3703 Source a = addSource(
3704 '/a.dart',
3705 r'''
3706 main() {
3707 print(MyEnum.A);
3708 }
3709 ''');
3710 _performPendingAnalysisTasks();
3711 // Insert a new enum declaration.
3712 // No errors expected.
3713 context.setContents(
3714 a,
3715 r'''
3716 main() {
3717 print(MyEnum.A);
3718 }
3719 enum MyEnum { A, B, C }
3720 ''');
3721 _performPendingAnalysisTasks();
3722 expect(context.getErrors(a).errors, isEmpty);
3723 }
3724
3725 void test_private_class() {
3726 Source a = addSource(
3727 '/a.dart',
3728 r'''
3729 class _A {}
3730 class _B2 {}
3731 ''');
3732 Source b = addSource(
3733 '/b.dart',
3734 r'''
3735 import 'a.dart';
3736 main() {
3737 new _A();
3738 new _B();
3739 }
3740 ''');
3741 _performPendingAnalysisTasks();
3742 // Update a.dart: change _A and _B2
3743 // b.dart is valid, because _A, _B, _A2 and _B2 are all private,
3744 // so b.dart cannot see them.
3745 context.setContents(
3746 a,
3747 r'''
3748 class _A2 {}
3749 class _B {}
3750 ''');
3751 _assertValidForChangedLibrary(a);
3752 _assertInvalid(a, LIBRARY_ERRORS_READY);
3753 _assertValidForDependentLibrary(b);
3754 _assertValidAllLibraryUnitResults(b);
3755 _assertValid(b, LIBRARY_ERRORS_READY);
3756 }
3757
3758 void test_private_topLevelVariable() {
3759 Source a = addSource(
3760 '/a.dart',
3761 r'''
3762 int _V = 1;
3763 ''');
3764 Source b = addSource(
3765 '/b.dart',
3766 r'''
3767 import 'a.dart';
3768 main() {
3769 print(_A);
3770 }
3771 ''');
3772 _performPendingAnalysisTasks();
3773 // Update a.dart: change _V
3774 // b.dart is valid, because _V is private and b.dart cannot see it.
3775 context.setContents(
3776 a,
3777 r'''
3778 int _V = 2;
3779 ''');
3780 _assertValidForChangedLibrary(a);
3781 _assertInvalid(a, LIBRARY_ERRORS_READY);
3782 _assertValidForDependentLibrary(b);
3783 _assertValidAllLibraryUnitResults(b);
3784 _assertValid(b, LIBRARY_ERRORS_READY);
3785 }
3786
3787 void test_private_topLevelVariable_throughPublic() {
3788 Source a = addSource(
3789 '/a.dart',
3790 r'''
3791 int _A = 1;
3792 int B = _A + 1;
3793 ''');
3794 Source b = addSource(
3795 '/b.dart',
3796 r'''
3797 import 'a.dart';
3798 main() {
3799 print(B);
3800 }
3801 ''');
3802 _performPendingAnalysisTasks();
3803 // Update a.dart: change _A
3804 // b.dart is invalid, because it uses B, which uses _A.
3805 context.setContents(
3806 a,
3807 r'''
3808 int _A = 2;
3809 int B = _A + 1;
3810 ''');
3811 _assertValidForChangedLibrary(a);
3812 _assertInvalid(a, LIBRARY_ERRORS_READY);
3813 _assertValidForDependentLibrary(b);
3814 _assertInvalid(b, LIBRARY_ERRORS_READY);
3815 }
3816
3817 void test_sequence_applyChanges_changedSource() {
3818 Source a = addSource(
3819 '/a.dart',
3820 r'''
3821 class A {}
3822 class B {}
3823 ''');
3824 Source b = addSource(
3825 '/b.dart',
3826 r'''
3827 import 'a.dart';
3828 main() {
3829 new A();
3830 new B();
3831 }
3832 ''');
3833 _performPendingAnalysisTasks();
3834 resourceProvider.updateFile(
3835 resourceProvider.convertPath('/a.dart'),
3836 r'''
3837 class A2 {}
3838 class B {}
3839 ''');
3840 // Update a.dart: remove A, add A2.
3841 // b.dart is invalid, because it references A.
3842 var changeSet = new ChangeSet()..changedSource(a);
3843 context.applyChanges(changeSet);
3844 _assertValidForChangedLibrary(a);
3845 _assertInvalid(a, LIBRARY_ERRORS_READY);
3846 _assertValidForDependentLibrary(b);
3847 _assertInvalid(b, LIBRARY_ERRORS_READY);
3848 _assertInvalidUnits(b, RESOLVED_UNIT4);
3849 // Analyze.
3850 _performPendingAnalysisTasks();
3851 expect(context.getErrors(a).errors, hasLength(0));
3852 expect(context.getErrors(b).errors, hasLength(1));
3853 _assertValid(a, READY_RESOLVED_UNIT);
3854 _assertValid(b, READY_RESOLVED_UNIT);
3855 _assertValidAllLibraryUnitResults(a);
3856 _assertValidAllLibraryUnitResults(b);
3857 }
3858
3859 void test_sequence_class_give_take() {
3860 Source a = addSource(
3861 '/a.dart',
3862 r'''
3863 class A {}
3864 class B {}
3865 class C {}
3866 ''');
3867 Source b = addSource(
3868 '/b.dart',
3869 r'''
3870 import 'a.dart';
3871 main() {
3872 new A();
3873 new C2();
3874 }
3875 ''');
3876 _performPendingAnalysisTasks();
3877 expect(context.getErrors(b).errors, hasLength(1));
3878 // Update a.dart: remove C, add C2.
3879 // b.dart is invalid, because it references C2.
3880 context.setContents(
3881 a,
3882 r'''
3883 class A {}
3884 class B {}
3885 class C2 {}
3886 ''');
3887 _assertValidForChangedLibrary(a);
3888 _assertInvalid(a, LIBRARY_ERRORS_READY);
3889 _assertValidForDependentLibrary(b);
3890 _assertInvalid(b, LIBRARY_ERRORS_READY);
3891 _assertInvalidUnits(b, RESOLVED_UNIT4);
3892 // Now b.dart is analyzed and the error is fixed.
3893 _performPendingAnalysisTasks();
3894 expect(context.getErrors(b).errors, hasLength(0));
3895 // Update a.dart: remove C2, add C.
3896 // b.dart is invalid, because it references C2.
3897 context.setContents(
3898 a,
3899 r'''
3900 class A {}
3901 class B {}
3902 class C {}
3903 ''');
3904 _assertValidForChangedLibrary(a);
3905 _assertInvalid(a, LIBRARY_ERRORS_READY);
3906 _assertValidForDependentLibrary(b);
3907 _assertInvalid(b, LIBRARY_ERRORS_READY);
3908 _assertInvalidUnits(b, RESOLVED_UNIT4);
3909 // Now b.dart is analyzed and it again has the error.
3910 _performPendingAnalysisTasks();
3911 expect(context.getErrors(b).errors, hasLength(1));
3912 }
3913
3914 void test_sequence_class_removeMethod_overridden() {
3915 Source a = addSource(
3916 '/a.dart',
3917 r'''
3918 class A {
3919 void foo() {}
3920 }
3921 ''');
3922 Source b = addSource(
3923 '/b.dart',
3924 r'''
3925 import 'a.dart';
3926 class B extends A {
3927 @override
3928 void foo() {}
3929 }
3930 ''');
3931 _performPendingAnalysisTasks();
3932 expect(context.getErrors(b).errors, hasLength(0));
3933 // Update a.dart: remove add A.foo.
3934 // b.dart has a new hint, because B.foo does not override anything
3935 context.setContents(
3936 a,
3937 r'''
3938 class A {
3939 }
3940 ''');
3941 _assertValidForChangedLibrary(a);
3942 _assertInvalid(a, LIBRARY_ERRORS_READY);
3943 _assertValidForDependentLibrary(b);
3944 _assertValidAllResolution(b);
3945 _assertInvalidHintsVerifyErrors(b);
3946
3947 _performPendingAnalysisTasks();
3948 expect(context.getErrors(b).errors, hasLength(1));
3949 }
3950
3951 void test_sequence_clearParameterElements() {
3952 Source a = addSource(
3953 '/a.dart',
3954 r'''
3955 class A {
3956 foo(int p) {}
3957 }
3958 final a = new A();
3959 main() {
3960 a.foo(42);
3961 }
3962 ''');
3963 _performPendingAnalysisTasks();
3964 Expression find42() {
3965 CompilationUnit unit =
3966 context.getResult(new LibrarySpecificUnit(a, a), RESOLVED_UNIT);
3967 ExpressionStatement statement =
3968 AstFinder.getStatementsInTopLevelFunction(unit, 'main').single;
3969 MethodInvocation invocation = statement.expression;
3970 return invocation.argumentList.arguments[0];
3971 }
3972
3973 {
3974 Expression argument = find42();
3975 expect(argument.staticParameterElement, isNull);
3976 }
3977
3978 // Update a.dart: add type annotation for 'a'.
3979 // '42' has 'staticParameterElement'.
3980 context.setContents(
3981 a,
3982 r'''
3983 class A {
3984 foo(int p) {}
3985 }
3986 final A a = new A();
3987 main() {
3988 a.foo(42);
3989 }
3990 ''');
3991 _performPendingAnalysisTasks();
3992 {
3993 Expression argument = find42();
3994 expect(argument.staticParameterElement, isNotNull);
3995 }
3996
3997 // Update a.dart: remove type annotation for 'a'.
3998 // '42' doesn't have 'staticParameterElement'.
3999 context.setContents(
4000 a,
4001 r'''
4002 class A {
4003 foo(int p) {}
4004 }
4005 final a = new A();
4006 main() {
4007 a.foo(42);
4008 }
4009 ''');
4010 _performPendingAnalysisTasks();
4011 {
4012 Expression argument = find42();
4013 expect(argument.staticParameterElement, isNull);
4014 }
4015 }
4016
4017 void test_sequence_closureParameterTypesPropagation() {
4018 Source a = addSource(
4019 '/a.dart',
4020 r'''
4021 main() {
4022 f((p) => 4.2);
4023 }
4024 f(c(int p)) {}
4025 ''');
4026 _performPendingAnalysisTasks();
4027 LibrarySpecificUnit targetA = new LibrarySpecificUnit(a, a);
4028 // Update and analyze.
4029 String newCode = r'''
4030 newFunction() {}
4031 main() {
4032 f((p) => 4.2);
4033 }
4034 f(c(int p)) {}
4035 ''';
4036 context.setContents(a, newCode);
4037 _performPendingAnalysisTasks();
4038 // Validate "(p) => 4.2" types.
4039 CompilationUnit unit = context.getResult(targetA, RESOLVED_UNIT2);
4040 SimpleIdentifier parameterName =
4041 EngineTestCase.findSimpleIdentifier(unit, newCode, 'p) => 4.2);');
4042 expect(parameterName.staticType, context.typeProvider.dynamicType);
4043 expect(parameterName.propagatedType, context.typeProvider.intType);
4044 }
4045
4046 void test_sequence_closureParameterTypesPropagation2() {
4047 var code = r'''
4048 import 'b.dart';
4049 main(x) {
4050 x.toMap();
4051 f((p) => 'z');
4052 }
4053 f(double c(int p)) {}
4054 ''';
4055 Source a = addSource('/a.dart', code);
4056 Source b = addSource(
4057 '/b.dart',
4058 r'''
4059 import 'c.dart';
4060 ''');
4061 addSource(
4062 '/c.dart',
4063 r'''
4064 import 'd.dart';
4065 ''');
4066 Source d = addSource(
4067 '/d.dart',
4068 r'''
4069 class D {}
4070 ''');
4071 _performPendingAnalysisTasks();
4072 LibrarySpecificUnit targetA = new LibrarySpecificUnit(a, a);
4073 // Update b.dart, resolution in a.dart is not affected.
4074 context.setContents(
4075 b,
4076 r'''
4077 import 'c.dart';
4078 class B {}
4079 ''');
4080 _assertValidAllResolution(a);
4081 _performPendingAnalysisTasks();
4082 // Update d.dart, this should invalidate a.dart and type propagation
4083 // performed for the closure parameter.
4084 context.setContents(
4085 d,
4086 r'''
4087 class D {
4088 toMap() {}
4089 }
4090 ''');
4091 _assertValidUnits(a, RESOLVED_UNIT6);
4092 _assertInvalidUnits(a, RESOLVED_UNIT7);
4093 _performPendingAnalysisTasks();
4094 // Validate "(p) =>" types.
4095 {
4096 CompilationUnit unit = context.getResult(targetA, RESOLVED_UNIT2);
4097 SimpleIdentifier parameterName =
4098 EngineTestCase.findSimpleIdentifier(unit, code, 'p) =>');
4099 expect(parameterName.staticType, context.typeProvider.dynamicType);
4100 expect(parameterName.propagatedType, context.typeProvider.intType);
4101 }
4102 }
4103
4104 void test_sequence_compoundingResults_exportNamespace() {
4105 Source a = addSource(
4106 '/a.dart',
4107 r'''
4108 class A<T> {}
4109 ''');
4110 Source b = addSource(
4111 '/b.dart',
4112 r'''
4113 export 'a.dart';
4114 ''');
4115 Source c = addSource(
4116 '/c.dart',
4117 r'''
4118 import 'b.dart';
4119 main() {
4120 new A<int>();
4121 }
4122 ''');
4123 _performPendingAnalysisTasks();
4124 expect(context.getErrors(c).errors, isEmpty);
4125 // Update a.dart, so that `A<T>` has a type bound.
4126 // This should invalidate export namespace for b.dart.
4127 // Currently we invalidate the whole LIBRARY_ELEMENT4.
4128 // So, c.dart will see the new `A<T extends B>` and report an error.
4129 context.setContents(
4130 a,
4131 r'''
4132 class A<T extends B> {}
4133 class B {}
4134 ''');
4135 _assertInvalid(b, LIBRARY_ELEMENT4);
4136 // Analyze and validate that a new error is reported.
4137 _performPendingAnalysisTasks();
4138 expect(context.getErrors(c).errors, hasLength(1));
4139 _assertValid(a, LIBRARY_ERRORS_READY);
4140 _assertValid(b, LIBRARY_ERRORS_READY);
4141 _assertValid(c, LIBRARY_ERRORS_READY);
4142 }
4143
4144 void test_sequence_compoundingResults_invalidateButKeepDependency() {
4145 Source a = addSource(
4146 '/a.dart',
4147 r'''
4148 import 'b.dart';
4149 class A {}
4150 ''');
4151 Source b = addSource(
4152 '/b.dart',
4153 r'''
4154 import 'a.dart';
4155 import 'c.dart';
4156 class B {}
4157 ''');
4158 Source c = addSource(
4159 '/c.dart',
4160 r'''
4161 class C {}
4162 ''');
4163 Source d = addSource(
4164 '/d.dart',
4165 r'''
4166 export 'b.dart';
4167 ''');
4168 _performPendingAnalysisTasks();
4169 expect(context.getErrors(c).errors, isEmpty);
4170 // Update: a.dart (limited) and b.dart (limited).
4171 // This should invalidate LIBRARY_ELEMENT4 in d.dart, but it should be
4172 // done in a way that keep dependency of other results od d.dart on
4173 // LIBRARY_ELEMENT4 of d.dart, so that when we perform unlimited
4174 // invalidation of c.dart, this makes d.dart invalid.
4175 context.setContents(
4176 a,
4177 r'''
4178 import 'b.dart';
4179 class A2 {}
4180 ''');
4181 context.setContents(
4182 b,
4183 r'''
4184 import 'a.dart';
4185 import 'c.dart';
4186 class B2 {}
4187 ''');
4188 context.setContents(
4189 c,
4190 r'''
4191 import 'dart:async';
4192 class C {}
4193 ''');
4194 _assertInvalid(d, LIBRARY_ELEMENT4);
4195 _assertInvalid(d, LIBRARY_ERRORS_READY);
4196 // Analyze and validate that a new error is reported.
4197 _performPendingAnalysisTasks();
4198 _assertValid(a, EXPORT_SOURCE_CLOSURE);
4199 _assertValid(b, EXPORT_SOURCE_CLOSURE);
4200 _assertValid(c, EXPORT_SOURCE_CLOSURE);
4201 _assertValid(d, EXPORT_SOURCE_CLOSURE);
4202 _assertValid(a, LIBRARY_ERRORS_READY);
4203 _assertValid(b, LIBRARY_ERRORS_READY);
4204 _assertValid(c, LIBRARY_ERRORS_READY);
4205 _assertValid(d, LIBRARY_ERRORS_READY);
4206 }
4207
4208 void test_sequence_compoundingResults_resolvedTypeNames() {
4209 Source a = addSource(
4210 '/a.dart',
4211 r'''
4212 class A {}
4213 ''');
4214 Source b = addSource(
4215 '/b.dart',
4216 r'''
4217 class B<T> {
4218 B(p);
4219 }
4220 ''');
4221 Source c = addSource(
4222 '/c.dart',
4223 r'''
4224 export 'a.dart';
4225 export 'b.dart';
4226 ''');
4227 Source d = addSource(
4228 '/d.dart',
4229 r'''
4230 import 'c.dart';
4231 main() {
4232 new B<int>(null);
4233 }
4234 ''');
4235 _performPendingAnalysisTasks();
4236 // Update a.dart and b.dart
4237 // This should invalidate most results in a.dart and b.dart
4238 //
4239 // This should also invalidate "compounding" results in c.dart, such as
4240 // READY_LIBRARY_ELEMENT6, which represent a state of the whole source
4241 // closure, not a result of this single unit or a library.
4242 //
4243 // The reason is that although type names (RESOLVED_UNIT5) b.dart will be
4244 // eventually resolved and set into b.dart elements, it may happen
4245 // after we attempted to re-resolve c.dart, which created Member(s), and
4246 // attempts to use elements without types set.
4247 context.setContents(
4248 a,
4249 r'''
4250 class A2 {}
4251 ''');
4252 context.setContents(
4253 b,
4254 r'''
4255 class B<T> {
4256 B(T p);
4257 }
4258 ''');
4259 _assertValidForChangedLibrary(a);
4260 _assertInvalid(a, LIBRARY_ERRORS_READY);
4261 _assertValidForChangedLibrary(b);
4262 _assertInvalid(b, LIBRARY_ERRORS_READY);
4263 _assertInvalid(c, READY_LIBRARY_ELEMENT6);
4264 _assertInvalid(c, READY_LIBRARY_ELEMENT7);
4265 // Analyze and validate that all results are valid.
4266 _performPendingAnalysisTasks();
4267 _assertValid(a, LIBRARY_ERRORS_READY);
4268 _assertValid(b, LIBRARY_ERRORS_READY);
4269 _assertValid(c, LIBRARY_ERRORS_READY);
4270 _assertValid(d, LIBRARY_ERRORS_READY);
4271 }
4272
4273 void test_sequence_dependenciesWithCycles() {
4274 Source a = addSource(
4275 '/a.dart',
4276 r'''
4277 const A = 1;
4278 ''');
4279 Source b = addSource(
4280 '/b.dart',
4281 r'''
4282 import 'c.dart';
4283 const B = C1 + 1;
4284 ''');
4285 Source c = addSource(
4286 '/c.dart',
4287 r'''
4288 import 'a.dart';
4289 import 'b.dart';
4290 const C1 = A + 1;
4291 const C2 = B + 2;
4292 ''');
4293 Source d = addSource(
4294 '/d.dart',
4295 r'''
4296 import 'c.dart';
4297 const D = C2 + 1;
4298 ''');
4299 _performPendingAnalysisTasks();
4300 // Update "A" constant.
4301 // This should invalidate results in all sources.
4302 context.setContents(
4303 a,
4304 r'''
4305 const A = 2;
4306 ''');
4307 _assertInvalid(a, LIBRARY_ERRORS_READY);
4308 _assertInvalid(b, LIBRARY_ERRORS_READY);
4309 _assertInvalid(c, LIBRARY_ERRORS_READY);
4310 _assertInvalid(d, LIBRARY_ERRORS_READY);
4311 }
4312
4313 void test_sequence_duplicateField_syntheticAndNot_renameNotSynthetic() {
4314 context.analysisOptions =
4315 new AnalysisOptionsImpl.from(context.analysisOptions)
4316 ..strongMode = true;
4317 Source a = addSource(
4318 '/a.dart',
4319 r'''
4320 class A {
4321 int foo;
4322 int get foo => 1;
4323 }
4324 class B extends A {
4325 int get foo => 2;
4326 }
4327 ''');
4328 _performPendingAnalysisTasks();
4329 expect(context.getErrors(a).errors, hasLength(1));
4330 // Update a.dart: rename "int foo" to "int bar".
4331 context.setContents(
4332 a,
4333 r'''
4334 class A {
4335 int bar;
4336 int get foo => 1;
4337 }
4338 class B extends A {
4339 int get foo => 2;
4340 }
4341 ''');
4342 _performPendingAnalysisTasks();
4343 expect(context.getErrors(a).errors, isEmpty);
4344 }
4345
4346 void test_sequence_inBodyChange_addRef_deltaChange() {
4347 Source a = addSource(
4348 '/a.dart',
4349 r'''
4350 class A {
4351 }
4352 ''');
4353 Source b = addSource(
4354 '/b.dart',
4355 r'''
4356 import 'a.dart';
4357 main(A a) {
4358 }
4359 ''');
4360 _performPendingAnalysisTasks();
4361 expect(context.getErrors(b).errors, hasLength(0));
4362 // Update b.dart: in-body incremental change - start referencing 'foo'.
4363 // Should update referenced names.
4364 context.setContents(
4365 b,
4366 r'''
4367 import 'a.dart';
4368 main(A a) {
4369 a.foo;
4370 }
4371 ''');
4372 _performPendingAnalysisTasks();
4373 expect(context.getErrors(b).errors, hasLength(1));
4374 // Update a.dart: add A.foo
4375 // b.dart is invalid, because it references 'foo'.
4376 context.setContents(
4377 a,
4378 r'''
4379 class A {
4380 int foo;
4381 }
4382 ''');
4383 _assertValidForChangedLibrary(a);
4384 _assertInvalid(a, LIBRARY_ERRORS_READY);
4385 _assertValidForDependentLibrary(b);
4386 _assertInvalid(b, LIBRARY_ERRORS_READY);
4387 _assertInvalidUnits(b, RESOLVED_UNIT4);
4388 // No errors after analysis.
4389 _performPendingAnalysisTasks();
4390 expect(context.getErrors(b).errors, hasLength(0));
4391 }
4392
4393 void test_sequence_inBodyChange_removeRef_deltaChange() {
4394 Source a = addSource(
4395 '/a.dart',
4396 r'''
4397 class A {
4398 }
4399 ''');
4400 Source b = addSource(
4401 '/b.dart',
4402 r'''
4403 import 'a.dart';
4404 main(A a) {
4405 a.foo;
4406 }
4407 ''');
4408 _performPendingAnalysisTasks();
4409 expect(context.getErrors(b).errors, hasLength(1));
4410 // Update b.dart: in-body incremental change - stop referencing 'foo'.
4411 // Should update referenced names.
4412 context.setContents(
4413 b,
4414 r'''
4415 import 'a.dart';
4416 main(A a) {
4417 }
4418 ''');
4419 _performPendingAnalysisTasks();
4420 expect(context.getErrors(b).errors, hasLength(0));
4421 // Update a.dart: add A.foo
4422 // b.dart is still valid, because it does references 'foo' anymore.
4423 context.setContents(
4424 a,
4425 r'''
4426 class A {
4427 int foo;
4428 }
4429 ''');
4430 _assertValidForChangedLibrary(a);
4431 _assertInvalid(a, LIBRARY_ERRORS_READY);
4432 _assertValidForDependentLibrary(b);
4433 _assertValidAllLibraryUnitResults(b);
4434 _assertValid(b, LIBRARY_ERRORS_READY);
4435 }
4436
4437 void test_sequence_middleLimited_thenFirstFull() {
4438 Source a = addSource(
4439 '/a.dart',
4440 r'''
4441 class A {}
4442 ''');
4443 Source b = addSource(
4444 '/b.dart',
4445 r'''
4446 export 'a.dart';
4447 ''');
4448 Source c = addSource(
4449 '/c.dart',
4450 r'''
4451 import 'b.dart';
4452 A a;
4453 ''');
4454 _performPendingAnalysisTasks();
4455 // Update b.dart: limited invalidation.
4456 // Results in c.dart are valid, because the change in b.dart does not
4457 // affect anything in c.dart.
4458 context.setContents(
4459 b,
4460 r'''
4461 export 'a.dart';
4462 class B {}
4463 ''');
4464 _assertValid(a, LIBRARY_ERRORS_READY);
4465 _assertInvalid(b, LIBRARY_ERRORS_READY);
4466 _assertValid(c, LIBRARY_ERRORS_READY);
4467 _assertUnitValid(c, RESOLVED_UNIT4);
4468 _assertUnitValid(c, RESOLVED_UNIT5);
4469 // Update a.dart: unlimited invalidation.
4470 // Results RESOLVED_UNIT4, RESOLVED_UNIT5, and RESOLVED_UNIT6 in c.dart
4471 // are invalid, because after unlimited change to a.dart everything
4472 // should be invalidated.
4473 // This fixes the problem that c.dart was not re-resolving type names.
4474 context.setContents(
4475 a,
4476 r'''
4477 import 'dart:async';
4478 class A {}
4479 ''');
4480 _assertInvalid(a, LIBRARY_ERRORS_READY);
4481 _assertInvalid(b, LIBRARY_ERRORS_READY);
4482 _assertInvalid(c, LIBRARY_ERRORS_READY);
4483 _assertInvalidUnits(c, RESOLVED_UNIT4);
4484 }
4485
4486 void test_sequence_noChange_thenChange() {
4487 Source a = addSource(
4488 '/a.dart',
4489 r'''
4490 class A {
4491 A();
4492 }
4493
4494 class B {
4495 B();
4496 }
4497 ''');
4498 Source b = addSource(
4499 '/b.dart',
4500 r'''
4501 import 'a.dart';
4502 main() {
4503 new A();
4504 }
4505 ''');
4506 _performPendingAnalysisTasks();
4507 expect(context.getErrors(a).errors, hasLength(0));
4508 expect(context.getErrors(b).errors, hasLength(0));
4509 var unitA = context.getResolvedCompilationUnit2(a, a);
4510 var unitElementA = resolutionMap.elementDeclaredByCompilationUnit(unitA);
4511 var libraryElementA = unitElementA.library;
4512 // Update a.dart, no declaration changes.
4513 context.setContents(
4514 a,
4515 r'''
4516 class A {
4517 A();
4518 }
4519 class B {
4520 B();
4521 }
4522 ''');
4523 _assertValidForChangedLibrary(a);
4524 _assertInvalid(a, LIBRARY_ERRORS_READY);
4525 _assertValidForDependentLibrary(b);
4526 _assertValidAllLibraryUnitResults(b);
4527 _assertValid(b, LIBRARY_ERRORS_READY);
4528 // The a.dart's unit and element are updated incrementally.
4529 // They are the same instances as initially.
4530 // So, all the references from other units are still valid.
4531 {
4532 LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
4533 expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
4534 expect(unitA.element, same(unitElementA));
4535 expect(unitElementA.library, same(libraryElementA));
4536 }
4537 // Analyze.
4538 _performPendingAnalysisTasks();
4539 expect(context.getErrors(a).errors, hasLength(0));
4540 expect(context.getErrors(b).errors, hasLength(0));
4541 // The a.dart's unit and element are the same.
4542 {
4543 LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
4544 expect(analysisCache.getValue(target, RESOLVED_UNIT), same(unitA));
4545 expect(unitA.element, same(unitElementA));
4546 expect(unitElementA.library, same(libraryElementA));
4547 }
4548 // Add a new method to a.dart. This invalidates b.dart, so
4549 // we know that the previous update did not damage dependencies.
4550 context.setContents(
4551 a,
4552 r'''
4553 class A {
4554 A();
4555 m() {}
4556 }
4557 class B {
4558 B();
4559 }
4560 ''');
4561 _assertValidForChangedLibrary(a);
4562 _assertInvalid(a, LIBRARY_ERRORS_READY);
4563 _assertValidForDependentLibrary(b);
4564 _assertValidAllResolution(b);
4565 _assertValidAllErrors(b);
4566 // The a.dart's unit and element are the same.
4567 {
4568 LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
4569 expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
4570 expect(unitA.element, same(unitElementA));
4571 expect(unitElementA.library, same(libraryElementA));
4572 }
4573 // Analyze.
4574 _performPendingAnalysisTasks();
4575 expect(context.getErrors(a).errors, hasLength(0));
4576 expect(context.getErrors(b).errors, hasLength(0));
4577 }
4578
4579 void test_sequence_parts_disableForPart() {
4580 Source a = addSource(
4581 '/a.dart',
4582 r'''
4583 library my_lib;
4584 part 'b.dart';
4585 ''');
4586 Source b = addSource(
4587 '/b.dart',
4588 r'''
4589 part of my_lib;
4590 class A {}
4591 ''');
4592 _performPendingAnalysisTasks();
4593 // Update b.dart - it is a part, which we don't support.
4594 // So, invalidate everything.
4595 context.setContents(
4596 b,
4597 r'''
4598 part of my_lib;
4599 class A {}
4600 class B {}
4601 ''');
4602 _assertInvalid(a, LIBRARY_ERRORS_READY);
4603 _assertInvalid(b, LIBRARY_ERRORS_READY);
4604 _assertInvalidUnits(a, RESOLVED_UNIT2);
4605 _assertInvalidUnits(b, RESOLVED_UNIT1);
4606 }
4607
4608 void test_sequence_parts_disableWithPart() {
4609 Source a = addSource(
4610 '/a.dart',
4611 r'''
4612 library my_lib;
4613 part 'b.dart';
4614 ''');
4615 Source b = addSource(
4616 '/b.dart',
4617 r'''
4618 part of my_lib;
4619 class B {}
4620 ''');
4621 _performPendingAnalysisTasks();
4622 // Update a.dart - it is a library with a part, which we don't support.
4623 // So, invalidate everything.
4624 context.setContents(
4625 a,
4626 r'''
4627 library my_lib;
4628 part 'b.dart';
4629 class A {}
4630 ''');
4631 _assertInvalid(a, LIBRARY_ERRORS_READY);
4632 _assertInvalid(b, LIBRARY_ERRORS_READY);
4633 _assertInvalidUnits(a, RESOLVED_UNIT1);
4634 _assertInvalidUnits(b, RESOLVED_UNIT1);
4635 }
4636
4637 void test_sequence_reorder_localFunctions() {
4638 Source a = addSource(
4639 '/a.dart',
4640 r'''
4641 f1() {
4642 localFunction() {
4643 const C = 1;
4644 }
4645 }
4646 f2() {}
4647 ''');
4648 _performPendingAnalysisTasks();
4649 // Update a.dart: reorder functions.
4650 // This should not fail with FrozenHashCodeException, because identifiers
4651 // of local elements should be relative to the enclosing top-level elements.
4652 context.setContents(
4653 a,
4654 r'''
4655 f2() {}
4656 f1() {
4657 localFunction() {
4658 const C = 1;
4659 }
4660 }
4661 ''');
4662 _assertValidForChangedLibrary(a);
4663 _assertInvalid(a, LIBRARY_ERRORS_READY);
4664 }
4665
4666 void test_sequence_unitConstants_addRemove() {
4667 Source a = addSource(
4668 '/a.dart',
4669 r'''
4670 const A = 1;
4671 const B = 2;
4672 const C = 3;
4673 foo() {
4674 const V1 = 10;
4675 }
4676 bar() {
4677 const V2 = 20;
4678 }
4679 ''');
4680 _performPendingAnalysisTasks();
4681 LibrarySpecificUnit unitA = new LibrarySpecificUnit(a, a);
4682 List<ConstantEvaluationTarget> oldConstants =
4683 context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
4684 expect(oldConstants, hasLength(5));
4685 ConstVariableElement oldA = _findConstVariable(oldConstants, 'A');
4686 ConstVariableElement oldB = _findConstVariable(oldConstants, 'B');
4687 ConstVariableElement oldC = _findConstVariable(oldConstants, 'C');
4688 ConstVariableElement oldV1 = _findConstVariable(oldConstants, 'V1');
4689 ConstVariableElement oldV2 = _findConstVariable(oldConstants, 'V2');
4690 expect(context.analysisCache.get(oldA), isNotNull);
4691 expect(context.analysisCache.get(oldB), isNotNull);
4692 expect(context.analysisCache.get(oldC), isNotNull);
4693 expect(context.analysisCache.get(oldV1), isNotNull);
4694 // Update and validate new constants.
4695 context.setContents(
4696 a,
4697 r'''
4698 const A = 1;
4699 const B = 2;
4700 const D = 4;
4701 foo() {
4702 const V1 = 10;
4703 }
4704 baz() {
4705 const V3 = 30;
4706 }
4707 ''');
4708 List<ConstantEvaluationTarget> newConstants =
4709 context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
4710 expect(newConstants, hasLength(5));
4711 expect(newConstants, contains(same(oldA)));
4712 expect(newConstants, contains(same(oldB)));
4713 expect(newConstants, contains(same(oldV1)));
4714 ConstVariableElement newD = _findConstVariable(newConstants, 'D');
4715 ConstVariableElement newV3 = _findConstVariable(newConstants, 'V3');
4716 // Perform analysis, compute constant values.
4717 _performPendingAnalysisTasks();
4718 // Validate const variable values.
4719 expect(context.analysisCache.get(oldA), isNotNull);
4720 expect(context.analysisCache.get(oldB), isNotNull);
4721 expect(context.analysisCache.get(oldV1), isNotNull);
4722 expect(context.analysisCache.get(oldC), isNull);
4723 expect(context.analysisCache.get(oldV2), isNull);
4724 expect(context.analysisCache.get(newD), isNotNull);
4725 expect(context.analysisCache.get(newV3), isNotNull);
4726 expect(oldA.evaluationResult.value.toIntValue(), 1);
4727 expect(oldB.evaluationResult.value.toIntValue(), 2);
4728 expect(newD.evaluationResult.value.toIntValue(), 4);
4729 expect(oldV1.evaluationResult.value.toIntValue(), 10);
4730 expect(newV3.evaluationResult.value.toIntValue(), 30);
4731 }
4732
4733 void test_sequence_unitConstants_local_insertSpace() {
4734 Source a = addSource(
4735 '/a.dart',
4736 r'''
4737 main() {
4738 const C = 1;
4739 }
4740 ''');
4741 _performPendingAnalysisTasks();
4742 LibrarySpecificUnit unitA = new LibrarySpecificUnit(a, a);
4743 List<ConstantEvaluationTarget> oldConstants =
4744 context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
4745 expect(oldConstants, hasLength(1));
4746 ConstVariableElement C = _findConstVariable(oldConstants, 'C');
4747 expect(context.analysisCache.get(C), isNotNull);
4748 // Insert a space before the name.
4749 context.setContents(
4750 a,
4751 r'''
4752 main() {
4753 const C = 1;
4754 }
4755 ''');
4756 List<ConstantEvaluationTarget> newConstants =
4757 context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
4758 expect(newConstants, hasLength(1));
4759 expect(newConstants, contains(same(C)));
4760 // Perform analysis, compute constant values.
4761 _performPendingAnalysisTasks();
4762 // Validate const variable values.
4763 expect(context.analysisCache.get(C), isNotNull);
4764 expect(C.evaluationResult.value.toIntValue(), 1);
4765 }
4766
4767 void test_sequence_useAnyResolvedUnit() {
4768 Source a = addSource(
4769 '/a.dart',
4770 r'''
4771 class A {}
4772 class B {}
4773 ''');
4774 Source b = addSource(
4775 '/b.dart',
4776 r'''
4777 import 'a.dart';
4778 main() {
4779 new A();
4780 }
4781 ''');
4782 _performPendingAnalysisTasks();
4783 _assertValid(a, LIBRARY_ERRORS_READY);
4784 _assertValid(b, LIBRARY_ERRORS_READY);
4785 // Invalidate RESOLVED_UNIT
4786 CacheEntry entryA = context.getCacheEntry(new LibrarySpecificUnit(a, a));
4787 entryA.setState(RESOLVED_UNIT, CacheState.FLUSHED);
4788 entryA.setState(RESOLVED_UNIT1, CacheState.FLUSHED);
4789 entryA.setState(RESOLVED_UNIT2, CacheState.FLUSHED);
4790 entryA.setState(RESOLVED_UNIT3, CacheState.FLUSHED);
4791 context.setContents(
4792 a,
4793 r'''
4794 class A {}
4795 class B2 {}
4796 ''');
4797 _assertValidAllLibraryUnitResults(b);
4798 _assertValid(b, LIBRARY_ERRORS_READY);
4799 }
4800
4801 void test_sequence_useAnyResolvedUnit_needsLibraryElement() {
4802 Source a = addSource(
4803 '/a.dart',
4804 r'''
4805 class A {}
4806 class B {}
4807 ''');
4808 // Perform analysis until we get RESOLVED_UNIT1.
4809 // But it does not have 'library' set, so `unitElement.context` is `null`.
4810 LibrarySpecificUnit aUnitTarget = new LibrarySpecificUnit(a, a);
4811 while (context.getResult(aUnitTarget, RESOLVED_UNIT1) == null) {
4812 context.performAnalysisTask();
4813 }
4814 // There was a bug with exception in incremental element builder.
4815 // We should not attempt to use `unitElement.context`.
4816 // It calls `unitElement.library`, which might be not set yet.
4817 context.setContents(
4818 a,
4819 r'''
4820 class A {}
4821 class B2 {}
4822 ''');
4823 // OK, no exceptions.
4824 }
4825
4826 void test_unusedName_class_add() {
4827 Source a = addSource(
4828 '/a.dart',
4829 r'''
4830 class A {}
4831 class B {}
4832 class C {}
4833 ''');
4834 Source b = addSource(
4835 '/b.dart',
4836 r'''
4837 import 'a.dart';
4838 main() {
4839 new A();
4840 new C();
4841 }
4842 ''');
4843 _performPendingAnalysisTasks();
4844 _assertValid(a, LINE_INFO);
4845 // The class B is not referenced.
4846 // a.dart is invalid.
4847 // b.dart is valid.
4848 context.setContents(
4849 a,
4850 r'''
4851 class A {}
4852 class B2 {}
4853 class C {}
4854 ''');
4855 _assertValidForChangedLibrary(a);
4856 _assertInvalid(a, LIBRARY_ERRORS_READY);
4857 _assertUnitInvalid(a, RESOLVED_UNIT);
4858 _assertValidForDependentLibrary(b);
4859 _assertValidAllLibraryUnitResults(b);
4860 _assertValid(b, LIBRARY_ERRORS_READY);
4861 }
4862
4863 void test_usedName_class_name_asHole_inBody() {
4864 Source a = addSource(
4865 '/a.dart',
4866 r'''
4867 class A {}
4868 class B {}
4869 class C {}
4870 ''');
4871 Source b = addSource(
4872 '/b.dart',
4873 r'''
4874 import 'a.dart';
4875 main() {
4876 new A();
4877 new C2();
4878 }
4879 ''');
4880 _performPendingAnalysisTasks();
4881 // Update a.dart: remove C, add C2.
4882 // b.dart is invalid, because it references C2.
4883 context.setContents(
4884 a,
4885 r'''
4886 class A {}
4887 class B {}
4888 class C2 {}
4889 ''');
4890 _assertValidForChangedLibrary(a);
4891 _assertInvalid(a, LIBRARY_ERRORS_READY);
4892 _assertValidForDependentLibrary(b);
4893 _assertInvalid(b, LIBRARY_ERRORS_READY);
4894 _assertInvalidUnits(b, RESOLVED_UNIT4);
4895 }
4896
4897 void test_usedName_class_name_asSuper() {
4898 Source a = addSource(
4899 '/a.dart',
4900 r'''
4901 class A {}
4902 ''');
4903 Source b = addSource(
4904 '/b.dart',
4905 r'''
4906 import 'a.dart';
4907 class B extends A {}
4908 ''');
4909 _performPendingAnalysisTasks();
4910 // Update a.dart: remove A, add A2.
4911 // b.dart is invalid, because it references A.
4912 context.setContents(
4913 a,
4914 r'''
4915 class A2 {}
4916 ''');
4917 _assertValidForChangedLibrary(a);
4918 _assertInvalid(a, LIBRARY_ERRORS_READY);
4919 _assertValidForDependentLibrary(b);
4920 _assertInvalid(b, LIBRARY_ERRORS_READY);
4921 _assertInvalidUnits(b, RESOLVED_UNIT4);
4922 }
4923
4924 void test_usedName_class_name_asTypeBound() {
4925 Source a = addSource(
4926 '/a.dart',
4927 r'''
4928 class A {}
4929 ''');
4930 Source b = addSource(
4931 '/b.dart',
4932 r'''
4933 import 'a.dart';
4934 class B<T extends A> {
4935 T f;
4936 }
4937 ''');
4938 _performPendingAnalysisTasks();
4939 // Update a.dart: remove A, add A2.
4940 // b.dart is invalid, because it references A.
4941 context.setContents(
4942 a,
4943 r'''
4944 class A2 {}
4945 ''');
4946 _assertValidForChangedLibrary(a);
4947 _assertInvalid(a, LIBRARY_ERRORS_READY);
4948 _assertValidForDependentLibrary(b);
4949 _assertInvalid(b, LIBRARY_ERRORS_READY);
4950 _assertInvalidUnits(b, RESOLVED_UNIT4);
4951 }
4952
4953 void test_usedName_class_name_inBody() {
4954 Source a = addSource(
4955 '/a.dart',
4956 r'''
4957 class A {}
4958 class B {}
4959 class C {}
4960 ''');
4961 Source b = addSource(
4962 '/b.dart',
4963 r'''
4964 import 'a.dart';
4965 main() {
4966 new A();
4967 new C();
4968 }
4969 ''');
4970 _performPendingAnalysisTasks();
4971 // Update a.dart: remove C, add C2.
4972 // b.dart is invalid, because it references C.
4973 context.setContents(
4974 a,
4975 r'''
4976 class A {}
4977 class B {}
4978 class C2 {}
4979 ''');
4980 _assertValidForChangedLibrary(a);
4981 _assertValidForDependentLibrary(b);
4982 _assertInvalid(a, LIBRARY_ERRORS_READY);
4983 _assertInvalid(b, LIBRARY_ERRORS_READY);
4984 _assertInvalidUnits(b, RESOLVED_UNIT4);
4985 }
4986
4987 void test_usedName_classMethod_name_inBody() {
4988 Source a = addSource(
4989 '/a.dart',
4990 r'''
4991 class A {
4992 m() {}
4993 }
4994 ''');
4995 Source b = addSource(
4996 '/b.dart',
4997 r'''
4998 import 'a.dart';
4999 main() {
5000 A a = new A();
5001 a.m();
5002 }
5003 ''');
5004 _performPendingAnalysisTasks();
5005 // Update a.dart: remove A.m, add A.m2.
5006 // b.dart is invalid, because it references 'm'.
5007 context.setContents(
5008 a,
5009 r'''
5010 class A {
5011 m2() {}
5012 }
5013 ''');
5014 _assertValidForChangedLibrary(a);
5015 _assertInvalid(a, LIBRARY_ERRORS_READY);
5016 _assertValidForDependentLibrary(b);
5017 _assertInvalidLibraryElements(b, LIBRARY_ELEMENT4);
5018 _assertInvalidUnits(b, RESOLVED_UNIT4);
5019 _assertInvalid(b, LIBRARY_ERRORS_READY);
5020 }
5021
5022 void test_usedName_indirect_classMethod_name_inBody() {
5023 Source a = addSource(
5024 '/a.dart',
5025 r'''
5026 class A {
5027 m() {}
5028 }
5029 ''');
5030 Source b = addSource(
5031 '/b.dart',
5032 r'''
5033 import 'a.dart';
5034 class B extends A {}
5035 ''');
5036 Source c = addSource(
5037 '/c.dart',
5038 r'''
5039 import 'b.dart';
5040 main() {
5041 B b = new B();
5042 b.m();
5043 }
5044 ''');
5045 _performPendingAnalysisTasks();
5046 // Update a.dart: remove A.m, add A.m2.
5047 // b.dart has valid resolution, and invalid errors.
5048 // c.dart is invalid, because 'main' references 'm'.
5049 context.setContents(
5050 a,
5051 r'''
5052 class A {
5053 m2() {}
5054 }
5055 ''');
5056 _assertValidForChangedLibrary(a);
5057 _assertInvalid(a, LIBRARY_ERRORS_READY);
5058
5059 _assertValidForDependentLibrary(b);
5060 _assertValidAllResolution(b);
5061 _assertInvalidHintsVerifyErrors(b);
5062
5063 _assertValidForDependentLibrary(c);
5064 _assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
5065 _assertInvalidUnits(c, RESOLVED_UNIT4);
5066 _assertInvalid(c, LIBRARY_ERRORS_READY);
5067 }
5068
5069 void test_usedName_indirect_classMethod_returnType_inBody() {
5070 Source a = addSource(
5071 '/a.dart',
5072 r'''
5073 class A {
5074 int m() {
5075 return 1;
5076 }
5077 }
5078 ''');
5079 Source b = addSource(
5080 '/b.dart',
5081 r'''
5082 import 'a.dart';
5083 class B extends A {}
5084 ''');
5085 Source c = addSource(
5086 '/c.dart',
5087 r'''
5088 import 'b.dart';
5089 main() {
5090 B b = new B();
5091 b.m();
5092 }
5093 ''');
5094 _performPendingAnalysisTasks();
5095 // Update a.dart: remove A.m, add A.m2.
5096 // b.dart is invalid, because B extends A.
5097 // c.dart is invalid, because 'main' references 'm'.
5098 context.setContents(
5099 a,
5100 r'''
5101 class A {
5102 double m() {
5103 return 1.2;
5104 }
5105 }
5106 ''');
5107 _assertInvalid(a, LIBRARY_ERRORS_READY);
5108
5109 _assertValidForDependentLibrary(b);
5110 _assertValidAllResolution(b);
5111 _assertInvalidHintsVerifyErrors(b);
5112
5113 _assertValidForDependentLibrary(c);
5114 _assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
5115 _assertInvalidUnits(c, RESOLVED_UNIT4);
5116 _assertInvalid(c, LIBRARY_ERRORS_READY);
5117 }
5118
5119 void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
5120 CacheState actual = analysisCache.getState(target, descriptor);
5121 if (actual != CacheState.INVALID) {
5122 fail("cache state of $target $descriptor: wanted INVALID, got: $actual");
5123 }
5124 }
5125
5126 /**
5127 * Assert that [VERIFY_ERRORS] and other error results that include it,
5128 * are invalid.
5129 */
5130 void _assertInvalidHintsVerifyErrors(Source unit) {
5131 _assertUnitInvalid(unit, HINTS);
5132 _assertUnitInvalid(unit, VERIFY_ERRORS);
5133 _assertUnitInvalid(unit, LIBRARY_UNIT_ERRORS);
5134 _assertInvalid(unit, DART_ERRORS);
5135 _assertInvalid(unit, LIBRARY_ERRORS_READY);
5136 }
5137
5138 /**
5139 * Assert that [LIBRARY_ELEMENT_RESULTS] for [first] and after it are invalid.
5140 */
5141 void _assertInvalidLibraryElements(
5142 Source source, ResultDescriptor<LibraryElement> first) {
5143 bool foundFirst = false;
5144 for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
5145 foundFirst = foundFirst || result == first;
5146 if (foundFirst) {
5147 _assertInvalid(source, result);
5148 }
5149 }
5150 }
5151
5152 void _assertInvalidUnits(Source unit, ResultDescriptor<CompilationUnit> first,
5153 {Source library}) {
5154 var target = new LibrarySpecificUnit(library ?? unit, unit);
5155 bool foundFirst = false;
5156 for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
5157 foundFirst = foundFirst || result == first;
5158 if (foundFirst) {
5159 _assertInvalid(target, result);
5160 }
5161 }
5162 }
5163
5164 void _assertUnitInvalid(Source unitSource, ResultDescriptor descriptor,
5165 {Source librarySource}) {
5166 librarySource ??= unitSource;
5167 _assertInvalid(
5168 new LibrarySpecificUnit(librarySource, unitSource), descriptor);
5169 }
5170
5171 void _assertUnitValid(Source unitSource, ResultDescriptor descriptor,
5172 {Source librarySource}) {
5173 librarySource ??= unitSource;
5174 _assertValid(
5175 new LibrarySpecificUnit(librarySource, unitSource), descriptor);
5176 }
5177
5178 void _assertUnitValidTaskResults(Source unitSource, TaskDescriptor descriptor,
5179 {Source librarySource}) {
5180 librarySource ??= unitSource;
5181 for (ResultDescriptor result in descriptor.results) {
5182 _assertUnitValid(unitSource, result, librarySource: librarySource);
5183 }
5184 }
5185
5186 void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) {
5187 CacheState state = analysisCache.getState(target, descriptor);
5188 expect(state, isIn([CacheState.VALID, CacheState.FLUSHED]),
5189 reason: '$descriptor in $target');
5190 }
5191
5192 /**
5193 * Assert that all error results for the given [unit] are valid.
5194 */
5195 void _assertValidAllErrors(Source unit) {
5196 for (ListResultDescriptor<AnalysisError> result in ERROR_SOURCE_RESULTS) {
5197 _assertValid(unit, result);
5198 }
5199 for (ListResultDescriptor<AnalysisError> result in ERROR_UNIT_RESULTS) {
5200 _assertUnitValid(unit, result);
5201 }
5202 }
5203
5204 void _assertValidAllLibraryUnitResults(Source source, {Source library}) {
5205 library ??= source;
5206 for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
5207 if (result == LIBRARY_ELEMENT4) {
5208 continue;
5209 }
5210 _assertValid(library, result);
5211 }
5212 LibrarySpecificUnit target = new LibrarySpecificUnit(library, source);
5213 for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
5214 _assertValid(target, result);
5215 }
5216 }
5217
5218 void _assertValidAllResolution(Source unit) {
5219 _assertValidUnits(unit, null);
5220 _assertUnitValidTaskResults(unit, ResolveUnitTypeNamesTask.DESCRIPTOR);
5221 _assertUnitValidTaskResults(unit, ResolveUnitTask.DESCRIPTOR);
5222 _assertValidTaskResults(unit, ResolveLibraryReferencesTask.DESCRIPTOR);
5223 _assertValidTaskResults(unit, ResolveLibraryTask.DESCRIPTOR);
5224 }
5225
5226 void _assertValidForAnyLibrary(Source source) {
5227 // Source results.
5228 _assertValidTaskResults(source, ScanDartTask.DESCRIPTOR);
5229 // Library results.
5230 _assertValidTaskResults(source, BuildLibraryElementTask.DESCRIPTOR);
5231 _assertValidTaskResults(source, BuildDirectiveElementsTask.DESCRIPTOR);
5232 _assertValidTaskResults(source, BuildSourceExportClosureTask.DESCRIPTOR);
5233 _assertValidTaskResults(source, ReadyLibraryElement2Task.DESCRIPTOR);
5234 _assertValidTaskResults(source, ComputeLibraryCycleTask.DESCRIPTOR);
5235 // Unit results.
5236 _assertUnitValidTaskResults(
5237 source, BuildCompilationUnitElementTask.DESCRIPTOR);
5238 _assertUnitValidTaskResults(
5239 source, ResolveDirectiveElementsTask.DESCRIPTOR);
5240 _assertUnitValidTaskResults(source, BuildEnumMemberElementsTask.DESCRIPTOR);
5241 }
5242
5243 void _assertValidForChangedLibrary(Source source) {
5244 _assertValidForAnyLibrary(source);
5245 }
5246
5247 void _assertValidForDependentLibrary(Source source) {
5248 _assertValidForAnyLibrary(source);
5249 // Library results.
5250 _assertValidTaskResults(source, BuildPublicNamespaceTask.DESCRIPTOR);
5251 }
5252
5253 void _assertValidTaskResults(AnalysisTarget target, TaskDescriptor task) {
5254 for (ResultDescriptor result in task.results) {
5255 _assertValid(target, result);
5256 }
5257 }
5258
5259 void _assertValidUnits(Source unit, ResultDescriptor<CompilationUnit> last,
5260 {Source library}) {
5261 var target = new LibrarySpecificUnit(library ?? unit, unit);
5262 bool foundLast = false;
5263 for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
5264 if (!foundLast) {
5265 _assertValid(target, result);
5266 }
5267 foundLast = foundLast || result == last;
5268 }
5269 }
5270
5271 ConstVariableElement _findConstVariable(
5272 List<ConstantEvaluationTarget> constants, String name) {
5273 return constants.singleWhere((c) {
5274 return c is ConstVariableElement && c.name == name;
5275 });
5276 }
5277
5278 void _performPendingAnalysisTasks([int maxTasks = 512]) {
5279 for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) {
5280 if (i > maxTasks) {
5281 fail('Analysis did not terminate.');
5282 }
5283 }
5284 }
5285
5286 void _verifyTwoLibrariesAllValid(
5287 String firstCodeA, String secondCodeA, String codeB) {
5288 Source a = addSource('/a.dart', firstCodeA);
5289 Source b = addSource('/b.dart', codeB);
5290 _performPendingAnalysisTasks();
5291 context.setContents(a, secondCodeA);
5292 _assertValidForChangedLibrary(a);
5293 _assertInvalid(a, LIBRARY_ERRORS_READY);
5294 _assertValidForDependentLibrary(b);
5295 _assertValidAllResolution(b);
5296 _assertValidAllErrors(b);
5297 }
5298
5299 void _verifyTwoLibrariesInvalidatesResolution(
5300 String firstCodeA, String secondCodeA, String codeB) {
5301 Source a = addSource('/a.dart', firstCodeA);
5302 Source b = addSource('/b.dart', codeB);
5303 _performPendingAnalysisTasks();
5304 context.setContents(a, secondCodeA);
5305 _assertValidForChangedLibrary(a);
5306 _assertInvalid(a, LIBRARY_ERRORS_READY);
5307 _assertValidForDependentLibrary(b);
5308 _assertInvalid(b, LIBRARY_ERRORS_READY);
5309 _assertInvalidUnits(b, RESOLVED_UNIT4);
5310 }
5311
5312 void _verifyTwoLibrariesInvalidHintsVerifyErrors(
5313 String firstCodeA, String secondCodeA, String codeB) {
5314 Source a = addSource('/a.dart', firstCodeA);
5315 Source b = addSource('/b.dart', codeB);
5316 _performPendingAnalysisTasks();
5317 context.setContents(a, secondCodeA);
5318 _assertValidForChangedLibrary(a);
5319 _assertInvalid(a, LIBRARY_ERRORS_READY);
5320 _assertValidForDependentLibrary(b);
5321 _assertValidAllResolution(b);
5322 _assertUnitValid(b, RESOLVE_UNIT_ERRORS);
5323 _assertInvalidHintsVerifyErrors(b);
5324 }
5325 }
5326
5327 class _AnalysisContextImplTest_Source_exists_true extends TestSource { 2997 class _AnalysisContextImplTest_Source_exists_true extends TestSource {
5328 @override 2998 @override
5329 bool exists() => true; 2999 bool exists() => true;
5330 } 3000 }
5331 3001
5332 class _AnalysisContextImplTest_Source_getModificationStamp_fromSource 3002 class _AnalysisContextImplTest_Source_getModificationStamp_fromSource
5333 extends TestSource { 3003 extends TestSource {
5334 int stamp; 3004 int stamp;
5335 _AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp); 3005 _AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
5336 @override 3006 @override
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
5444 * Initialize the visitor. 3114 * Initialize the visitor.
5445 */ 3115 */
5446 _ElementGatherer(); 3116 _ElementGatherer();
5447 3117
5448 @override 3118 @override
5449 void visitElement(Element element) { 3119 void visitElement(Element element) {
5450 elements[element] = element; 3120 elements[element] = element;
5451 super.visitElement(element); 3121 super.visitElement(element);
5452 } 3122 }
5453 } 3123 }
OLDNEW
« no previous file with comments | « pkg/analyzer/test/src/context/builder_test.dart ('k') | pkg/analyzer/test/src/task/incremental_element_builder_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698