| 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.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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |