OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library test.src.context.context_test; |
| 6 |
| 7 import 'dart:async'; |
| 8 |
| 9 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 10 import 'package:analyzer/src/cancelable_future.dart'; |
| 11 import 'package:analyzer/src/context/cache.dart'; |
| 12 import 'package:analyzer/src/context/context.dart'; |
| 13 import 'package:analyzer/src/generated/ast.dart'; |
| 14 import 'package:analyzer/src/generated/element.dart'; |
| 15 import 'package:analyzer/src/generated/engine.dart' |
| 16 show |
| 17 AnalysisContext, |
| 18 AnalysisContextStatistics, |
| 19 AnalysisDelta, |
| 20 AnalysisEngine, |
| 21 AnalysisErrorInfo, |
| 22 AnalysisLevel, |
| 23 AnalysisNotScheduledError, |
| 24 AnalysisOptions, |
| 25 AnalysisOptionsImpl, |
| 26 AnalysisResult, |
| 27 CacheState, |
| 28 ChangeNotice, |
| 29 ChangeSet, |
| 30 IncrementalAnalysisCache, |
| 31 TimestampedData; |
| 32 import 'package:analyzer/src/generated/error.dart'; |
| 33 import 'package:analyzer/src/generated/java_engine.dart'; |
| 34 import 'package:analyzer/src/generated/resolver.dart'; |
| 35 import 'package:analyzer/src/generated/scanner.dart'; |
| 36 import 'package:analyzer/src/generated/source.dart'; |
| 37 import 'package:analyzer/src/task/dart.dart'; |
| 38 import 'package:analyzer/src/task/html.dart'; |
| 39 import 'package:analyzer/task/dart.dart'; |
| 40 import 'package:analyzer/task/model.dart'; |
| 41 import 'package:html/dom.dart' show Document; |
| 42 import 'package:unittest/unittest.dart'; |
| 43 import 'package:watcher/src/utils.dart'; |
| 44 |
| 45 import '../../generated/engine_test.dart'; |
| 46 import '../../generated/test_support.dart'; |
| 47 import '../../reflective_tests.dart'; |
| 48 import '../../utils.dart'; |
| 49 import 'abstract_context.dart'; |
| 50 |
| 51 main() { |
| 52 initializeTestEnvironment(); |
| 53 runReflectiveTests(AnalysisContextImplTest); |
| 54 runReflectiveTests(LimitedInvalidateTest); |
| 55 } |
| 56 |
| 57 @reflectiveTest |
| 58 class AnalysisContextImplTest extends AbstractContextTest { |
| 59 Future fail_implicitAnalysisEvents_removed() async { |
| 60 AnalyzedSourcesListener listener = new AnalyzedSourcesListener(); |
| 61 context.implicitAnalysisEvents.listen(listener.onData); |
| 62 // |
| 63 // Create a file that references an file that is not explicitly being |
| 64 // analyzed and fully analyze it. Ensure that the listener is told about |
| 65 // the implicitly analyzed file. |
| 66 // |
| 67 Source sourceA = newSource('/a.dart', "library a; import 'b.dart';"); |
| 68 Source sourceB = newSource('/b.dart', "library b;"); |
| 69 ChangeSet changeSet = new ChangeSet(); |
| 70 changeSet.addedSource(sourceA); |
| 71 context.applyChanges(changeSet); |
| 72 context.computeErrors(sourceA); |
| 73 await pumpEventQueue(); |
| 74 listener.expectAnalyzed(sourceB); |
| 75 // |
| 76 // Remove the reference and ensure that the listener is told that we're no |
| 77 // longer implicitly analyzing the file. |
| 78 // |
| 79 context.setContents(sourceA, "library a;"); |
| 80 context.computeErrors(sourceA); |
| 81 await pumpEventQueue(); |
| 82 listener.expectNotAnalyzed(sourceB); |
| 83 } |
| 84 |
| 85 void fail_performAnalysisTask_importedLibraryDelete_html() { |
| 86 // NOTE: This was failing before converting to the new task model. |
| 87 Source htmlSource = addSource( |
| 88 "/page.html", |
| 89 r''' |
| 90 <html><body><script type="application/dart"> |
| 91 import 'libB.dart'; |
| 92 main() {print('hello dart');} |
| 93 </script></body></html>'''); |
| 94 Source libBSource = addSource("/libB.dart", "library libB;"); |
| 95 _analyzeAll_assertFinished(); |
| 96 context.computeErrors(htmlSource); |
| 97 expect( |
| 98 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, |
| 99 reason: "libB resolved 1"); |
| 100 expect(!_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)), |
| 101 isTrue, |
| 102 reason: "htmlSource doesn't have errors"); |
| 103 // remove libB.dart content and analyze |
| 104 context.setContents(libBSource, null); |
| 105 _analyzeAll_assertFinished(); |
| 106 context.computeErrors(htmlSource); |
| 107 AnalysisErrorInfo errors = context.getErrors(htmlSource); |
| 108 expect(_hasAnalysisErrorWithErrorSeverity(errors), isTrue, |
| 109 reason: "htmlSource has an error"); |
| 110 } |
| 111 |
| 112 void fail_recordLibraryElements() { |
| 113 fail("Implement this"); |
| 114 } |
| 115 |
| 116 @override |
| 117 void tearDown() { |
| 118 context = null; |
| 119 sourceFactory = null; |
| 120 super.tearDown(); |
| 121 } |
| 122 |
| 123 Future test_applyChanges_add() { |
| 124 SourcesChangedListener listener = new SourcesChangedListener(); |
| 125 context.onSourcesChanged.listen(listener.onData); |
| 126 expect(context.sourcesNeedingProcessing, isEmpty); |
| 127 Source source = newSource('/test.dart'); |
| 128 ChangeSet changeSet = new ChangeSet(); |
| 129 changeSet.addedSource(source); |
| 130 context.applyChanges(changeSet); |
| 131 expect(context.sourcesNeedingProcessing, contains(source)); |
| 132 return pumpEventQueue().then((_) { |
| 133 listener.assertEvent(wereSourcesAdded: true); |
| 134 listener.assertNoMoreEvents(); |
| 135 }); |
| 136 } |
| 137 |
| 138 Future test_applyChanges_change() { |
| 139 SourcesChangedListener listener = new SourcesChangedListener(); |
| 140 context.onSourcesChanged.listen(listener.onData); |
| 141 expect(context.sourcesNeedingProcessing, isEmpty); |
| 142 Source source = newSource('/test.dart'); |
| 143 ChangeSet changeSet1 = new ChangeSet(); |
| 144 changeSet1.addedSource(source); |
| 145 context.applyChanges(changeSet1); |
| 146 expect(context.sourcesNeedingProcessing, contains(source)); |
| 147 Source source2 = newSource('/test2.dart'); |
| 148 ChangeSet changeSet2 = new ChangeSet(); |
| 149 changeSet2.addedSource(source2); |
| 150 changeSet2.changedSource(source); |
| 151 context.applyChanges(changeSet2); |
| 152 return pumpEventQueue().then((_) { |
| 153 listener.assertEvent(wereSourcesAdded: true); |
| 154 listener.assertEvent(wereSourcesAdded: true, changedSources: [source]); |
| 155 listener.assertNoMoreEvents(); |
| 156 }); |
| 157 } |
| 158 |
| 159 Future test_applyChanges_change_content() { |
| 160 SourcesChangedListener listener = new SourcesChangedListener(); |
| 161 context.onSourcesChanged.listen(listener.onData); |
| 162 expect(context.sourcesNeedingProcessing, isEmpty); |
| 163 Source source = newSource('/test.dart'); |
| 164 ChangeSet changeSet1 = new ChangeSet(); |
| 165 changeSet1.addedSource(source); |
| 166 context.applyChanges(changeSet1); |
| 167 expect(context.sourcesNeedingProcessing, contains(source)); |
| 168 Source source2 = newSource('/test2.dart'); |
| 169 ChangeSet changeSet2 = new ChangeSet(); |
| 170 changeSet2.addedSource(source2); |
| 171 changeSet2.changedContent(source, 'library test;'); |
| 172 context.applyChanges(changeSet2); |
| 173 return pumpEventQueue().then((_) { |
| 174 listener.assertEvent(wereSourcesAdded: true); |
| 175 listener.assertEvent(wereSourcesAdded: true, changedSources: [source]); |
| 176 listener.assertNoMoreEvents(); |
| 177 }); |
| 178 } |
| 179 |
| 180 void test_applyChanges_change_flush_element() { |
| 181 Source librarySource = addSource( |
| 182 "/lib.dart", |
| 183 r''' |
| 184 library lib; |
| 185 int a = 0;'''); |
| 186 expect(context.computeLibraryElement(librarySource), isNotNull); |
| 187 context.setContents( |
| 188 librarySource, |
| 189 r''' |
| 190 library lib; |
| 191 int aa = 0;'''); |
| 192 expect(context.getLibraryElement(librarySource), isNull); |
| 193 } |
| 194 |
| 195 Future test_applyChanges_change_multiple() { |
| 196 SourcesChangedListener listener = new SourcesChangedListener(); |
| 197 context.onSourcesChanged.listen(listener.onData); |
| 198 String libraryContents1 = r''' |
| 199 library lib; |
| 200 part 'part.dart'; |
| 201 int a = 0;'''; |
| 202 Source librarySource = addSource("/lib.dart", libraryContents1); |
| 203 String partContents1 = r''' |
| 204 part of lib; |
| 205 int b = a;'''; |
| 206 Source partSource = addSource("/part.dart", partContents1); |
| 207 context.computeLibraryElement(librarySource); |
| 208 String libraryContents2 = r''' |
| 209 library lib; |
| 210 part 'part.dart'; |
| 211 int aa = 0;'''; |
| 212 context.setContents(librarySource, libraryContents2); |
| 213 String partContents2 = r''' |
| 214 part of lib; |
| 215 int b = aa;'''; |
| 216 context.setContents(partSource, partContents2); |
| 217 context.computeLibraryElement(librarySource); |
| 218 CompilationUnit libraryUnit = |
| 219 context.resolveCompilationUnit2(librarySource, librarySource); |
| 220 expect(libraryUnit, isNotNull); |
| 221 CompilationUnit partUnit = |
| 222 context.resolveCompilationUnit2(partSource, librarySource); |
| 223 expect(partUnit, isNotNull); |
| 224 TopLevelVariableDeclaration declaration = |
| 225 libraryUnit.declarations[0] as TopLevelVariableDeclaration; |
| 226 Element declarationElement = declaration.variables.variables[0].element; |
| 227 TopLevelVariableDeclaration use = |
| 228 partUnit.declarations[0] as TopLevelVariableDeclaration; |
| 229 Element useElement = (use.variables.variables[0].initializer |
| 230 as SimpleIdentifier).staticElement; |
| 231 expect((useElement as PropertyAccessorElement).variable, |
| 232 same(declarationElement)); |
| 233 return pumpEventQueue().then((_) { |
| 234 listener.assertEvent(wereSourcesAdded: true); |
| 235 listener.assertEvent(wereSourcesAdded: true); |
| 236 listener.assertEvent(changedSources: [librarySource]); |
| 237 listener.assertEvent(changedSources: [partSource]); |
| 238 listener.assertNoMoreEvents(); |
| 239 }); |
| 240 } |
| 241 |
| 242 Future test_applyChanges_change_range() { |
| 243 SourcesChangedListener listener = new SourcesChangedListener(); |
| 244 context.onSourcesChanged.listen(listener.onData); |
| 245 expect(context.sourcesNeedingProcessing, isEmpty); |
| 246 Source source = newSource('/test.dart'); |
| 247 ChangeSet changeSet1 = new ChangeSet(); |
| 248 changeSet1.addedSource(source); |
| 249 context.applyChanges(changeSet1); |
| 250 expect(context.sourcesNeedingProcessing, contains(source)); |
| 251 Source source2 = newSource('/test2.dart'); |
| 252 ChangeSet changeSet2 = new ChangeSet(); |
| 253 changeSet2.addedSource(source2); |
| 254 changeSet2.changedRange(source, 'library test;', 0, 0, 13); |
| 255 context.applyChanges(changeSet2); |
| 256 return pumpEventQueue().then((_) { |
| 257 listener.assertEvent(wereSourcesAdded: true); |
| 258 listener.assertEvent(wereSourcesAdded: true, changedSources: [source]); |
| 259 listener.assertNoMoreEvents(); |
| 260 }); |
| 261 } |
| 262 |
| 263 void test_applyChanges_empty() { |
| 264 context.applyChanges(new ChangeSet()); |
| 265 expect(context.performAnalysisTask().changeNotices, isNull); |
| 266 } |
| 267 |
| 268 void test_applyChanges_overriddenSource() { |
| 269 // Note: addSource adds the source to the contentCache. |
| 270 Source source = addSource("/test.dart", "library test;"); |
| 271 context.computeErrors(source); |
| 272 while (!context.sourcesNeedingProcessing.isEmpty) { |
| 273 context.performAnalysisTask(); |
| 274 } |
| 275 // Adding the source as a changedSource should have no effect since |
| 276 // it is already overridden in the content cache. |
| 277 ChangeSet changeSet = new ChangeSet(); |
| 278 changeSet.changedSource(source); |
| 279 context.applyChanges(changeSet); |
| 280 expect(context.sourcesNeedingProcessing, hasLength(0)); |
| 281 } |
| 282 |
| 283 Future test_applyChanges_remove() { |
| 284 SourcesChangedListener listener = new SourcesChangedListener(); |
| 285 context.onSourcesChanged.listen(listener.onData); |
| 286 String libAContents = r''' |
| 287 library libA; |
| 288 import 'libB.dart';'''; |
| 289 Source libA = addSource("/libA.dart", libAContents); |
| 290 String libBContents = "library libB;"; |
| 291 Source libB = addSource("/libB.dart", libBContents); |
| 292 LibraryElement libAElement = context.computeLibraryElement(libA); |
| 293 expect(libAElement, isNotNull); |
| 294 List<LibraryElement> importedLibraries = libAElement.importedLibraries; |
| 295 expect(importedLibraries, hasLength(2)); |
| 296 context.computeErrors(libA); |
| 297 context.computeErrors(libB); |
| 298 expect(context.sourcesNeedingProcessing, hasLength(0)); |
| 299 context.setContents(libB, null); |
| 300 _removeSource(libB); |
| 301 List<Source> sources = context.sourcesNeedingProcessing; |
| 302 expect(sources, hasLength(1)); |
| 303 expect(sources[0], same(libA)); |
| 304 libAElement = context.computeLibraryElement(libA); |
| 305 importedLibraries = libAElement.importedLibraries; |
| 306 expect(importedLibraries, hasLength(1)); |
| 307 return pumpEventQueue().then((_) { |
| 308 listener.assertEvent(wereSourcesAdded: true); |
| 309 listener.assertEvent(wereSourcesAdded: true); |
| 310 listener.assertEvent(wereSourcesRemovedOrDeleted: true); |
| 311 listener.assertNoMoreEvents(); |
| 312 }); |
| 313 } |
| 314 |
| 315 /** |
| 316 * IDEA uses the following scenario: |
| 317 * 1. Add overlay. |
| 318 * 2. Change overlay. |
| 319 * 3. If the contents of the document buffer is the same as the contents |
| 320 * of the file, remove overlay. |
| 321 * So, we need to try to use incremental resolution for removing overlays too. |
| 322 */ |
| 323 void test_applyChanges_remove_incremental() { |
| 324 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); |
| 325 Source source = resourceProvider |
| 326 .newFile( |
| 327 '/test.dart', |
| 328 r''' |
| 329 main() { |
| 330 print(1); |
| 331 } |
| 332 ''') |
| 333 .createSource(); |
| 334 context.analysisOptions = new AnalysisOptionsImpl()..incremental = true; |
| 335 context.applyChanges(new ChangeSet()..addedSource(source)); |
| 336 // remember compilation unit |
| 337 _analyzeAll_assertFinished(); |
| 338 CompilationUnit unit = context.getResolvedCompilationUnit2(source, source); |
| 339 // add overlay |
| 340 context.setContents( |
| 341 source, |
| 342 r''' |
| 343 main() { |
| 344 print(12); |
| 345 } |
| 346 '''); |
| 347 _analyzeAll_assertFinished(); |
| 348 expect(context.getResolvedCompilationUnit2(source, source), unit); |
| 349 // remove overlay |
| 350 context.setContents(source, null); |
| 351 context.validateCacheConsistency(); |
| 352 _analyzeAll_assertFinished(); |
| 353 expect(context.getResolvedCompilationUnit2(source, source), unit); |
| 354 } |
| 355 |
| 356 Future test_applyChanges_removeContainer() { |
| 357 SourcesChangedListener listener = new SourcesChangedListener(); |
| 358 context.onSourcesChanged.listen(listener.onData); |
| 359 String libAContents = r''' |
| 360 library libA; |
| 361 import 'libB.dart';'''; |
| 362 Source libA = addSource("/libA.dart", libAContents); |
| 363 String libBContents = "library libB;"; |
| 364 Source libB = addSource("/libB.dart", libBContents); |
| 365 context.computeLibraryElement(libA); |
| 366 context.computeErrors(libA); |
| 367 context.computeErrors(libB); |
| 368 expect(context.sourcesNeedingProcessing, hasLength(0)); |
| 369 ChangeSet changeSet = new ChangeSet(); |
| 370 SourceContainer removedContainer = |
| 371 new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB); |
| 372 changeSet.removedContainer(removedContainer); |
| 373 context.applyChanges(changeSet); |
| 374 List<Source> sources = context.sourcesNeedingProcessing; |
| 375 expect(sources, hasLength(1)); |
| 376 expect(sources[0], same(libA)); |
| 377 return pumpEventQueue().then((_) { |
| 378 listener.assertEvent(wereSourcesAdded: true); |
| 379 listener.assertEvent(wereSourcesAdded: true); |
| 380 listener.assertEvent(wereSourcesRemovedOrDeleted: true); |
| 381 listener.assertNoMoreEvents(); |
| 382 }); |
| 383 } |
| 384 |
| 385 void test_computeDocumentationComment_block() { |
| 386 String comment = "/** Comment */"; |
| 387 Source source = addSource( |
| 388 "/test.dart", |
| 389 """ |
| 390 $comment |
| 391 class A {}"""); |
| 392 LibraryElement libraryElement = context.computeLibraryElement(source); |
| 393 expect(libraryElement, isNotNull); |
| 394 ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; |
| 395 expect(libraryElement, isNotNull); |
| 396 expect(context.computeDocumentationComment(classElement), comment); |
| 397 } |
| 398 |
| 399 void test_computeDocumentationComment_none() { |
| 400 Source source = addSource("/test.dart", "class A {}"); |
| 401 LibraryElement libraryElement = context.computeLibraryElement(source); |
| 402 expect(libraryElement, isNotNull); |
| 403 ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; |
| 404 expect(libraryElement, isNotNull); |
| 405 expect(context.computeDocumentationComment(classElement), isNull); |
| 406 } |
| 407 |
| 408 void test_computeDocumentationComment_null() { |
| 409 expect(context.computeDocumentationComment(null), isNull); |
| 410 } |
| 411 |
| 412 void test_computeDocumentationComment_singleLine_multiple_EOL_n() { |
| 413 String comment = "/// line 1\n/// line 2\n/// line 3\n"; |
| 414 Source source = addSource("/test.dart", "${comment}class A {}"); |
| 415 LibraryElement libraryElement = context.computeLibraryElement(source); |
| 416 expect(libraryElement, isNotNull); |
| 417 ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; |
| 418 expect(libraryElement, isNotNull); |
| 419 String actual = context.computeDocumentationComment(classElement); |
| 420 expect(actual, "/// line 1\n/// line 2\n/// line 3"); |
| 421 } |
| 422 |
| 423 void test_computeDocumentationComment_singleLine_multiple_EOL_rn() { |
| 424 String comment = "/// line 1\r\n/// line 2\r\n/// line 3\r\n"; |
| 425 Source source = addSource("/test.dart", "${comment}class A {}"); |
| 426 LibraryElement libraryElement = context.computeLibraryElement(source); |
| 427 expect(libraryElement, isNotNull); |
| 428 ClassElement classElement = libraryElement.definingCompilationUnit.types[0]; |
| 429 expect(libraryElement, isNotNull); |
| 430 String actual = context.computeDocumentationComment(classElement); |
| 431 expect(actual, "/// line 1\n/// line 2\n/// line 3"); |
| 432 } |
| 433 |
| 434 void test_computeErrors_dart_none() { |
| 435 Source source = addSource("/lib.dart", "library lib;"); |
| 436 List<AnalysisError> errors = context.computeErrors(source); |
| 437 expect(errors, hasLength(0)); |
| 438 } |
| 439 |
| 440 void test_computeErrors_dart_part() { |
| 441 Source librarySource = |
| 442 addSource("/lib.dart", "library lib; part 'part.dart';"); |
| 443 Source partSource = addSource("/part.dart", "part of 'lib';"); |
| 444 context.parseCompilationUnit(librarySource); |
| 445 List<AnalysisError> errors = context.computeErrors(partSource); |
| 446 expect(errors, isNotNull); |
| 447 expect(errors.length > 0, isTrue); |
| 448 } |
| 449 |
| 450 void test_computeErrors_dart_some() { |
| 451 Source source = addSource("/lib.dart", "library 'lib';"); |
| 452 List<AnalysisError> errors = context.computeErrors(source); |
| 453 expect(errors, isNotNull); |
| 454 expect(errors.length > 0, isTrue); |
| 455 } |
| 456 |
| 457 void test_computeErrors_html_none() { |
| 458 Source source = addSource("/test.html", "<!DOCTYPE html><html></html>"); |
| 459 List<AnalysisError> errors = context.computeErrors(source); |
| 460 expect(errors, hasLength(0)); |
| 461 } |
| 462 |
| 463 void test_computeExportedLibraries_none() { |
| 464 Source source = addSource("/test.dart", "library test;"); |
| 465 expect(context.computeExportedLibraries(source), hasLength(0)); |
| 466 } |
| 467 |
| 468 void test_computeExportedLibraries_some() { |
| 469 // addSource("/lib1.dart", "library lib1;"); |
| 470 // addSource("/lib2.dart", "library lib2;"); |
| 471 Source source = addSource( |
| 472 "/test.dart", "library test; export 'lib1.dart'; export 'lib2.dart';"); |
| 473 expect(context.computeExportedLibraries(source), hasLength(2)); |
| 474 } |
| 475 |
| 476 void test_computeImportedLibraries_none() { |
| 477 Source source = addSource("/test.dart", "library test;"); |
| 478 expect(context.computeImportedLibraries(source), hasLength(0)); |
| 479 } |
| 480 |
| 481 void test_computeImportedLibraries_some() { |
| 482 Source source = addSource( |
| 483 "/test.dart", "library test; import 'lib1.dart'; import 'lib2.dart';"); |
| 484 expect(context.computeImportedLibraries(source), hasLength(2)); |
| 485 } |
| 486 |
| 487 void test_computeKindOf_html() { |
| 488 Source source = addSource("/test.html", ""); |
| 489 expect(context.computeKindOf(source), same(SourceKind.HTML)); |
| 490 } |
| 491 |
| 492 void test_computeKindOf_library() { |
| 493 Source source = addSource("/test.dart", "library lib;"); |
| 494 expect(context.computeKindOf(source), same(SourceKind.LIBRARY)); |
| 495 } |
| 496 |
| 497 void test_computeKindOf_libraryAndPart() { |
| 498 Source source = addSource("/test.dart", "library lib; part of lib;"); |
| 499 expect(context.computeKindOf(source), same(SourceKind.LIBRARY)); |
| 500 } |
| 501 |
| 502 void test_computeKindOf_part() { |
| 503 Source source = addSource("/test.dart", "part of lib;"); |
| 504 expect(context.computeKindOf(source), same(SourceKind.PART)); |
| 505 } |
| 506 |
| 507 void test_computeLibraryElement() { |
| 508 Source source = addSource("/test.dart", "library lib;"); |
| 509 LibraryElement element = context.computeLibraryElement(source); |
| 510 expect(element, isNotNull); |
| 511 } |
| 512 |
| 513 void test_computeLineInfo_dart() { |
| 514 Source source = addSource( |
| 515 "/test.dart", |
| 516 r''' |
| 517 library lib; |
| 518 |
| 519 main() {}'''); |
| 520 LineInfo info = context.computeLineInfo(source); |
| 521 expect(info, isNotNull); |
| 522 } |
| 523 |
| 524 void test_computeLineInfo_html() { |
| 525 Source source = addSource( |
| 526 "/test.html", |
| 527 r''' |
| 528 <html> |
| 529 <body> |
| 530 <h1>A</h1> |
| 531 </body> |
| 532 </html>'''); |
| 533 LineInfo info = context.computeLineInfo(source); |
| 534 expect(info, isNotNull); |
| 535 } |
| 536 |
| 537 Future test_computeResolvedCompilationUnitAsync() { |
| 538 Source source = addSource("/lib.dart", "library lib;"); |
| 539 // Complete all pending analysis tasks and flush the AST so that it won't |
| 540 // be available immediately. |
| 541 _performPendingAnalysisTasks(); |
| 542 _flushAst(source); |
| 543 bool completed = false; |
| 544 context |
| 545 .computeResolvedCompilationUnitAsync(source, source) |
| 546 .then((CompilationUnit unit) { |
| 547 expect(unit, isNotNull); |
| 548 completed = true; |
| 549 }); |
| 550 return pumpEventQueue().then((_) { |
| 551 expect(completed, isFalse); |
| 552 _performPendingAnalysisTasks(); |
| 553 }).then((_) => pumpEventQueue()).then((_) { |
| 554 expect(completed, isTrue); |
| 555 }); |
| 556 } |
| 557 |
| 558 Future test_computeResolvedCompilationUnitAsync_afterDispose() { |
| 559 Source source = addSource("/lib.dart", "library lib;"); |
| 560 // Complete all pending analysis tasks and flush the AST so that it won't |
| 561 // be available immediately. |
| 562 _performPendingAnalysisTasks(); |
| 563 _flushAst(source); |
| 564 // Dispose of the context. |
| 565 context.dispose(); |
| 566 // Any attempt to start an asynchronous computation should return a future |
| 567 // which completes with error. |
| 568 CancelableFuture<CompilationUnit> future = |
| 569 context.computeResolvedCompilationUnitAsync(source, source); |
| 570 bool completed = false; |
| 571 future.then((CompilationUnit unit) { |
| 572 fail('Future should have completed with error'); |
| 573 }, onError: (error) { |
| 574 expect(error, new isInstanceOf<AnalysisNotScheduledError>()); |
| 575 completed = true; |
| 576 }); |
| 577 return pumpEventQueue().then((_) { |
| 578 expect(completed, isTrue); |
| 579 }); |
| 580 } |
| 581 |
| 582 Future test_computeResolvedCompilationUnitAsync_cancel() { |
| 583 Source source = addSource("/lib.dart", "library lib;"); |
| 584 // Complete all pending analysis tasks and flush the AST so that it won't |
| 585 // be available immediately. |
| 586 _performPendingAnalysisTasks(); |
| 587 _flushAst(source); |
| 588 CancelableFuture<CompilationUnit> future = |
| 589 context.computeResolvedCompilationUnitAsync(source, source); |
| 590 bool completed = false; |
| 591 future.then((CompilationUnit unit) { |
| 592 fail('Future should have been canceled'); |
| 593 }, onError: (error) { |
| 594 expect(error, new isInstanceOf<FutureCanceledError>()); |
| 595 completed = true; |
| 596 }); |
| 597 expect(completed, isFalse); |
| 598 expect(context.pendingFutureSources_forTesting, isNotEmpty); |
| 599 future.cancel(); |
| 600 expect(context.pendingFutureSources_forTesting, isEmpty); |
| 601 return pumpEventQueue().then((_) { |
| 602 expect(completed, isTrue); |
| 603 expect(context.pendingFutureSources_forTesting, isEmpty); |
| 604 }); |
| 605 } |
| 606 |
| 607 Future test_computeResolvedCompilationUnitAsync_dispose() { |
| 608 Source source = addSource("/lib.dart", "library lib;"); |
| 609 // Complete all pending analysis tasks and flush the AST so that it won't |
| 610 // be available immediately. |
| 611 _performPendingAnalysisTasks(); |
| 612 _flushAst(source); |
| 613 bool completed = false; |
| 614 CancelableFuture<CompilationUnit> future = |
| 615 context.computeResolvedCompilationUnitAsync(source, source); |
| 616 future.then((CompilationUnit unit) { |
| 617 fail('Future should have completed with error'); |
| 618 }, onError: (error) { |
| 619 expect(error, new isInstanceOf<AnalysisNotScheduledError>()); |
| 620 completed = true; |
| 621 }); |
| 622 expect(completed, isFalse); |
| 623 expect(context.pendingFutureSources_forTesting, isNotEmpty); |
| 624 // Disposing of the context should cause all pending futures to complete |
| 625 // with AnalysisNotScheduled, so that no clients are left hanging. |
| 626 context.dispose(); |
| 627 expect(context.pendingFutureSources_forTesting, isEmpty); |
| 628 return pumpEventQueue().then((_) { |
| 629 expect(completed, isTrue); |
| 630 expect(context.pendingFutureSources_forTesting, isEmpty); |
| 631 }); |
| 632 } |
| 633 |
| 634 Future test_computeResolvedCompilationUnitAsync_noCacheEntry() { |
| 635 Source librarySource = addSource("/lib.dart", "library lib;"); |
| 636 Source partSource = addSource("/part.dart", "part of foo;"); |
| 637 bool completed = false; |
| 638 context |
| 639 .computeResolvedCompilationUnitAsync(partSource, librarySource) |
| 640 .then((CompilationUnit unit) { |
| 641 expect(unit, isNotNull); |
| 642 completed = true; |
| 643 }); |
| 644 return pumpEventQueue().then((_) { |
| 645 expect(completed, isFalse); |
| 646 _performPendingAnalysisTasks(); |
| 647 }).then((_) => pumpEventQueue()).then((_) { |
| 648 expect(completed, isTrue); |
| 649 }); |
| 650 } |
| 651 |
| 652 void test_dispose() { |
| 653 expect(context.isDisposed, isFalse); |
| 654 context.dispose(); |
| 655 expect(context.isDisposed, isTrue); |
| 656 } |
| 657 |
| 658 void test_ensureResolvedDartUnits_definingUnit_hasResolved() { |
| 659 Source source = addSource('/test.dart', ''); |
| 660 LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source); |
| 661 analysisDriver.computeResult(libTarget, RESOLVED_UNIT); |
| 662 CompilationUnit unit = |
| 663 context.getCacheEntry(libTarget).getValue(RESOLVED_UNIT); |
| 664 List<CompilationUnit> units = context.ensureResolvedDartUnits(source); |
| 665 expect(units, unorderedEquals([unit])); |
| 666 } |
| 667 |
| 668 void test_ensureResolvedDartUnits_definingUnit_notResolved() { |
| 669 Source source = addSource('/test.dart', ''); |
| 670 LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source); |
| 671 analysisDriver.computeResult(libTarget, RESOLVED_UNIT); |
| 672 // flush |
| 673 context |
| 674 .getCacheEntry(libTarget) |
| 675 .setState(RESOLVED_UNIT, CacheState.FLUSHED); |
| 676 // schedule recomputing |
| 677 List<CompilationUnit> units = context.ensureResolvedDartUnits(source); |
| 678 expect(units, isNull); |
| 679 // should be the next result to compute |
| 680 TargetedResult nextResult = context.dartWorkManager.getNextResult(); |
| 681 expect(nextResult.target, libTarget); |
| 682 expect(nextResult.result, RESOLVED_UNIT); |
| 683 } |
| 684 |
| 685 void test_ensureResolvedDartUnits_partUnit_hasResolved() { |
| 686 Source libSource1 = addSource( |
| 687 '/lib1.dart', |
| 688 r''' |
| 689 library lib; |
| 690 part 'part.dart'; |
| 691 '''); |
| 692 Source libSource2 = addSource( |
| 693 '/lib2.dart', |
| 694 r''' |
| 695 library lib; |
| 696 part 'part.dart'; |
| 697 '''); |
| 698 Source partSource = addSource( |
| 699 '/part.dart', |
| 700 r''' |
| 701 part of lib; |
| 702 '''); |
| 703 LibrarySpecificUnit partTarget1 = |
| 704 new LibrarySpecificUnit(libSource1, partSource); |
| 705 LibrarySpecificUnit partTarget2 = |
| 706 new LibrarySpecificUnit(libSource2, partSource); |
| 707 analysisDriver.computeResult(partTarget1, RESOLVED_UNIT); |
| 708 analysisDriver.computeResult(partTarget2, RESOLVED_UNIT); |
| 709 CompilationUnit unit1 = |
| 710 context.getCacheEntry(partTarget1).getValue(RESOLVED_UNIT); |
| 711 CompilationUnit unit2 = |
| 712 context.getCacheEntry(partTarget2).getValue(RESOLVED_UNIT); |
| 713 List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource); |
| 714 expect(units, unorderedEquals([unit1, unit2])); |
| 715 } |
| 716 |
| 717 void test_ensureResolvedDartUnits_partUnit_notResolved() { |
| 718 Source libSource1 = addSource( |
| 719 '/lib1.dart', |
| 720 r''' |
| 721 library lib; |
| 722 part 'part.dart'; |
| 723 '''); |
| 724 Source libSource2 = addSource( |
| 725 '/lib2.dart', |
| 726 r''' |
| 727 library lib; |
| 728 part 'part.dart'; |
| 729 '''); |
| 730 Source partSource = addSource( |
| 731 '/part.dart', |
| 732 r''' |
| 733 part of lib; |
| 734 '''); |
| 735 LibrarySpecificUnit partTarget1 = |
| 736 new LibrarySpecificUnit(libSource1, partSource); |
| 737 LibrarySpecificUnit partTarget2 = |
| 738 new LibrarySpecificUnit(libSource2, partSource); |
| 739 analysisDriver.computeResult(partTarget1, RESOLVED_UNIT); |
| 740 analysisDriver.computeResult(partTarget2, RESOLVED_UNIT); |
| 741 // flush |
| 742 context |
| 743 .getCacheEntry(partTarget1) |
| 744 .setState(RESOLVED_UNIT, CacheState.FLUSHED); |
| 745 context |
| 746 .getCacheEntry(partTarget2) |
| 747 .setState(RESOLVED_UNIT, CacheState.FLUSHED); |
| 748 // schedule recomputing |
| 749 List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource); |
| 750 expect(units, isNull); |
| 751 // should be the next result to compute |
| 752 TargetedResult nextResult = context.dartWorkManager.getNextResult(); |
| 753 expect(nextResult.target, anyOf(partTarget1, partTarget2)); |
| 754 expect(nextResult.result, RESOLVED_UNIT); |
| 755 } |
| 756 |
| 757 void test_exists_false() { |
| 758 TestSource source = new TestSource(); |
| 759 source.exists2 = false; |
| 760 expect(context.exists(source), isFalse); |
| 761 } |
| 762 |
| 763 void test_exists_null() { |
| 764 expect(context.exists(null), isFalse); |
| 765 } |
| 766 |
| 767 void test_exists_overridden() { |
| 768 Source source = new TestSource(); |
| 769 context.setContents(source, ""); |
| 770 expect(context.exists(source), isTrue); |
| 771 } |
| 772 |
| 773 void test_exists_true() { |
| 774 expect(context.exists(new AnalysisContextImplTest_Source_exists_true()), |
| 775 isTrue); |
| 776 } |
| 777 |
| 778 void test_getAnalysisOptions() { |
| 779 expect(context.analysisOptions, isNotNull); |
| 780 } |
| 781 |
| 782 void test_getContents_fromSource() { |
| 783 String content = "library lib;"; |
| 784 TimestampedData<String> contents = |
| 785 context.getContents(new TestSource('/test.dart', content)); |
| 786 expect(contents.data.toString(), content); |
| 787 } |
| 788 |
| 789 void test_getContents_overridden() { |
| 790 String content = "library lib;"; |
| 791 Source source = new TestSource(); |
| 792 context.setContents(source, content); |
| 793 TimestampedData<String> contents = context.getContents(source); |
| 794 expect(contents.data.toString(), content); |
| 795 } |
| 796 |
| 797 void test_getContents_unoverridden() { |
| 798 String content = "library lib;"; |
| 799 Source source = new TestSource('/test.dart', content); |
| 800 context.setContents(source, "part of lib;"); |
| 801 context.setContents(source, null); |
| 802 TimestampedData<String> contents = context.getContents(source); |
| 803 expect(contents.data.toString(), content); |
| 804 } |
| 805 |
| 806 void test_getDeclaredVariables() { |
| 807 expect(context.declaredVariables, isNotNull); |
| 808 } |
| 809 |
| 810 void test_getElement() { |
| 811 LibraryElement core = |
| 812 context.computeLibraryElement(sourceFactory.forUri("dart:core")); |
| 813 expect(core, isNotNull); |
| 814 ClassElement classObject = |
| 815 _findClass(core.definingCompilationUnit, "Object"); |
| 816 expect(classObject, isNotNull); |
| 817 ElementLocation location = classObject.location; |
| 818 Element element = context.getElement(location); |
| 819 expect(element, same(classObject)); |
| 820 } |
| 821 |
| 822 void test_getElement_constructor_named() { |
| 823 Source source = addSource( |
| 824 "/lib.dart", |
| 825 r''' |
| 826 class A { |
| 827 A.named() {} |
| 828 }'''); |
| 829 _analyzeAll_assertFinished(); |
| 830 LibraryElement library = context.computeLibraryElement(source); |
| 831 ClassElement classA = _findClass(library.definingCompilationUnit, "A"); |
| 832 ConstructorElement constructor = classA.constructors[0]; |
| 833 ElementLocation location = constructor.location; |
| 834 Element element = context.getElement(location); |
| 835 expect(element, same(constructor)); |
| 836 } |
| 837 |
| 838 void test_getElement_constructor_unnamed() { |
| 839 Source source = addSource( |
| 840 "/lib.dart", |
| 841 r''' |
| 842 class A { |
| 843 A() {} |
| 844 }'''); |
| 845 _analyzeAll_assertFinished(); |
| 846 LibraryElement library = context.computeLibraryElement(source); |
| 847 ClassElement classA = _findClass(library.definingCompilationUnit, "A"); |
| 848 ConstructorElement constructor = classA.constructors[0]; |
| 849 ElementLocation location = constructor.location; |
| 850 Element element = context.getElement(location); |
| 851 expect(element, same(constructor)); |
| 852 } |
| 853 |
| 854 void test_getElement_enum() { |
| 855 Source source = addSource('/test.dart', 'enum MyEnum {A, B, C}'); |
| 856 _analyzeAll_assertFinished(); |
| 857 LibraryElement library = context.computeLibraryElement(source); |
| 858 ClassElement myEnum = library.definingCompilationUnit.getEnum('MyEnum'); |
| 859 ElementLocation location = myEnum.location; |
| 860 Element element = context.getElement(location); |
| 861 expect(element, same(myEnum)); |
| 862 } |
| 863 |
| 864 void test_getErrors_dart_none() { |
| 865 Source source = addSource("/lib.dart", "library lib;"); |
| 866 var errorInfo = context.getErrors(source); |
| 867 expect(errorInfo, isNotNull); |
| 868 List<AnalysisError> errors = errorInfo.errors; |
| 869 expect(errors, hasLength(0)); |
| 870 context.computeErrors(source); |
| 871 errors = errorInfo.errors; |
| 872 expect(errors, hasLength(0)); |
| 873 } |
| 874 |
| 875 void test_getErrors_dart_some() { |
| 876 Source source = addSource("/lib.dart", "library 'lib';"); |
| 877 var errorInfo = context.getErrors(source); |
| 878 expect(errorInfo, isNotNull); |
| 879 List<AnalysisError> errors = errorInfo.errors; |
| 880 expect(errors, hasLength(0)); |
| 881 errors = context.computeErrors(source); |
| 882 expect(errors, hasLength(1)); |
| 883 } |
| 884 |
| 885 void test_getErrors_html_none() { |
| 886 Source source = addSource("/test.html", "<html></html>"); |
| 887 AnalysisErrorInfo errorInfo = context.getErrors(source); |
| 888 expect(errorInfo, isNotNull); |
| 889 List<AnalysisError> errors = errorInfo.errors; |
| 890 expect(errors, hasLength(0)); |
| 891 context.computeErrors(source); |
| 892 errors = errorInfo.errors; |
| 893 expect(errors, hasLength(0)); |
| 894 } |
| 895 |
| 896 void test_getErrors_html_some() { |
| 897 Source source = addSource( |
| 898 "/test.html", |
| 899 r''' |
| 900 <html><head> |
| 901 <script type='application/dart' src='test.dart'/> |
| 902 </head></html>'''); |
| 903 AnalysisErrorInfo errorInfo = context.getErrors(source); |
| 904 expect(errorInfo, isNotNull); |
| 905 List<AnalysisError> errors = errorInfo.errors; |
| 906 expect(errors, hasLength(0)); |
| 907 errors = context.computeErrors(source); |
| 908 expect(errors, hasLength(3)); |
| 909 } |
| 910 |
| 911 void test_getHtmlFilesReferencing_html() { |
| 912 Source htmlSource = addSource( |
| 913 "/test.html", |
| 914 r''' |
| 915 <html><head> |
| 916 <script type='application/dart' src='test.dart'/> |
| 917 <script type='application/dart' src='test.js'/> |
| 918 </head></html>'''); |
| 919 Source librarySource = addSource("/test.dart", "library lib;"); |
| 920 Source secondHtmlSource = addSource("/test.html", "<html></html>"); |
| 921 context.computeLibraryElement(librarySource); |
| 922 List<Source> result = context.getHtmlFilesReferencing(secondHtmlSource); |
| 923 expect(result, hasLength(0)); |
| 924 context.parseHtmlDocument(htmlSource); |
| 925 result = context.getHtmlFilesReferencing(secondHtmlSource); |
| 926 expect(result, hasLength(0)); |
| 927 } |
| 928 |
| 929 void test_getHtmlFilesReferencing_library() { |
| 930 Source htmlSource = addSource( |
| 931 "/test.html", |
| 932 r''' |
| 933 <!DOCTYPE html> |
| 934 <html><head> |
| 935 <script type='application/dart' src='test.dart'/> |
| 936 <script type='application/dart' src='test.js'/> |
| 937 </head></html>'''); |
| 938 Source librarySource = addSource("/test.dart", "library lib;"); |
| 939 context.computeLibraryElement(librarySource); |
| 940 List<Source> result = context.getHtmlFilesReferencing(librarySource); |
| 941 expect(result, hasLength(0)); |
| 942 // Indirectly force the data to be computed. |
| 943 context.computeErrors(htmlSource); |
| 944 result = context.getHtmlFilesReferencing(librarySource); |
| 945 expect(result, hasLength(1)); |
| 946 expect(result[0], htmlSource); |
| 947 } |
| 948 |
| 949 void test_getHtmlFilesReferencing_part() { |
| 950 Source htmlSource = addSource( |
| 951 "/test.html", |
| 952 r''' |
| 953 <!DOCTYPE html> |
| 954 <html><head> |
| 955 <script type='application/dart' src='test.dart'/> |
| 956 <script type='application/dart' src='test.js'/> |
| 957 </head></html>'''); |
| 958 Source librarySource = |
| 959 addSource("/test.dart", "library lib; part 'part.dart';"); |
| 960 Source partSource = addSource("/part.dart", "part of lib;"); |
| 961 context.computeLibraryElement(librarySource); |
| 962 List<Source> result = context.getHtmlFilesReferencing(partSource); |
| 963 expect(result, hasLength(0)); |
| 964 // Indirectly force the data to be computed. |
| 965 context.computeErrors(htmlSource); |
| 966 result = context.getHtmlFilesReferencing(partSource); |
| 967 expect(result, hasLength(1)); |
| 968 expect(result[0], htmlSource); |
| 969 } |
| 970 |
| 971 void test_getHtmlSources() { |
| 972 List<Source> sources = context.htmlSources; |
| 973 expect(sources, hasLength(0)); |
| 974 Source source = addSource("/test.html", ""); |
| 975 sources = context.htmlSources; |
| 976 expect(sources, hasLength(1)); |
| 977 expect(sources[0], source); |
| 978 } |
| 979 |
| 980 void test_getKindOf_html() { |
| 981 Source source = addSource("/test.html", ""); |
| 982 expect(context.getKindOf(source), same(SourceKind.HTML)); |
| 983 } |
| 984 |
| 985 void test_getKindOf_library() { |
| 986 Source source = addSource("/test.dart", "library lib;"); |
| 987 expect(context.getKindOf(source), same(SourceKind.UNKNOWN)); |
| 988 context.computeKindOf(source); |
| 989 expect(context.getKindOf(source), same(SourceKind.LIBRARY)); |
| 990 } |
| 991 |
| 992 void test_getKindOf_part() { |
| 993 Source source = addSource("/test.dart", "part of lib;"); |
| 994 expect(context.getKindOf(source), same(SourceKind.UNKNOWN)); |
| 995 context.computeKindOf(source); |
| 996 expect(context.getKindOf(source), same(SourceKind.PART)); |
| 997 } |
| 998 |
| 999 void test_getKindOf_unknown() { |
| 1000 Source source = addSource("/test.css", ""); |
| 1001 expect(context.getKindOf(source), same(SourceKind.UNKNOWN)); |
| 1002 } |
| 1003 |
| 1004 void test_getLaunchableClientLibrarySources_doesNotImportHtml() { |
| 1005 Source source = addSource( |
| 1006 "/test.dart", |
| 1007 r''' |
| 1008 main() {}'''); |
| 1009 context.computeLibraryElement(source); |
| 1010 List<Source> sources = context.launchableClientLibrarySources; |
| 1011 expect(sources, isEmpty); |
| 1012 } |
| 1013 |
| 1014 void test_getLaunchableClientLibrarySources_importsHtml_explicitly() { |
| 1015 List<Source> sources = context.launchableClientLibrarySources; |
| 1016 expect(sources, isEmpty); |
| 1017 Source source = addSource( |
| 1018 "/test.dart", |
| 1019 r''' |
| 1020 import 'dart:html'; |
| 1021 main() {}'''); |
| 1022 context.computeLibraryElement(source); |
| 1023 sources = context.launchableClientLibrarySources; |
| 1024 expect(sources, unorderedEquals([source])); |
| 1025 } |
| 1026 |
| 1027 void test_getLaunchableClientLibrarySources_importsHtml_implicitly() { |
| 1028 List<Source> sources = context.launchableClientLibrarySources; |
| 1029 expect(sources, isEmpty); |
| 1030 addSource( |
| 1031 "/a.dart", |
| 1032 r''' |
| 1033 import 'dart:html'; |
| 1034 '''); |
| 1035 Source source = addSource( |
| 1036 "/test.dart", |
| 1037 r''' |
| 1038 import 'a.dart'; |
| 1039 main() {}'''); |
| 1040 context.computeLibraryElement(source); |
| 1041 sources = context.launchableClientLibrarySources; |
| 1042 expect(sources, unorderedEquals([source])); |
| 1043 } |
| 1044 |
| 1045 void test_getLaunchableClientLibrarySources_importsHtml_implicitly2() { |
| 1046 List<Source> sources = context.launchableClientLibrarySources; |
| 1047 expect(sources, isEmpty); |
| 1048 addSource( |
| 1049 "/a.dart", |
| 1050 r''' |
| 1051 export 'dart:html'; |
| 1052 '''); |
| 1053 Source source = addSource( |
| 1054 "/test.dart", |
| 1055 r''' |
| 1056 import 'a.dart'; |
| 1057 main() {}'''); |
| 1058 context.computeLibraryElement(source); |
| 1059 sources = context.launchableClientLibrarySources; |
| 1060 expect(sources, unorderedEquals([source])); |
| 1061 } |
| 1062 |
| 1063 void test_getLaunchableServerLibrarySources() { |
| 1064 expect(context.launchableServerLibrarySources, isEmpty); |
| 1065 Source source = addSource("/test.dart", "main() {}"); |
| 1066 context.computeLibraryElement(source); |
| 1067 expect(context.launchableServerLibrarySources, unorderedEquals([source])); |
| 1068 } |
| 1069 |
| 1070 void test_getLaunchableServerLibrarySources_importsHtml_explicitly() { |
| 1071 Source source = addSource( |
| 1072 "/test.dart", |
| 1073 r''' |
| 1074 import 'dart:html'; |
| 1075 main() {} |
| 1076 '''); |
| 1077 context.computeLibraryElement(source); |
| 1078 expect(context.launchableServerLibrarySources, isEmpty); |
| 1079 } |
| 1080 |
| 1081 void test_getLaunchableServerLibrarySources_importsHtml_implicitly() { |
| 1082 addSource( |
| 1083 "/imports_html.dart", |
| 1084 r''' |
| 1085 import 'dart:html'; |
| 1086 '''); |
| 1087 Source source = addSource( |
| 1088 "/test.dart", |
| 1089 r''' |
| 1090 import 'imports_html.dart'; |
| 1091 main() {}'''); |
| 1092 context.computeLibraryElement(source); |
| 1093 expect(context.launchableServerLibrarySources, isEmpty); |
| 1094 } |
| 1095 |
| 1096 void test_getLaunchableServerLibrarySources_noMain() { |
| 1097 Source source = addSource("/test.dart", ''); |
| 1098 context.computeLibraryElement(source); |
| 1099 expect(context.launchableServerLibrarySources, isEmpty); |
| 1100 } |
| 1101 |
| 1102 void test_getLibrariesContaining() { |
| 1103 Source librarySource = addSource( |
| 1104 "/lib.dart", |
| 1105 r''' |
| 1106 library lib; |
| 1107 part 'part.dart';'''); |
| 1108 Source partSource = addSource("/part.dart", "part of lib;"); |
| 1109 context.computeLibraryElement(librarySource); |
| 1110 List<Source> result = context.getLibrariesContaining(librarySource); |
| 1111 expect(result, hasLength(1)); |
| 1112 expect(result[0], librarySource); |
| 1113 result = context.getLibrariesContaining(partSource); |
| 1114 expect(result, hasLength(1)); |
| 1115 expect(result[0], librarySource); |
| 1116 } |
| 1117 |
| 1118 void test_getLibrariesDependingOn() { |
| 1119 Source libASource = addSource("/libA.dart", "library libA;"); |
| 1120 addSource("/libB.dart", "library libB;"); |
| 1121 Source lib1Source = addSource( |
| 1122 "/lib1.dart", |
| 1123 r''' |
| 1124 library lib1; |
| 1125 import 'libA.dart'; |
| 1126 export 'libB.dart';'''); |
| 1127 Source lib2Source = addSource( |
| 1128 "/lib2.dart", |
| 1129 r''' |
| 1130 library lib2; |
| 1131 import 'libB.dart'; |
| 1132 export 'libA.dart';'''); |
| 1133 context.computeLibraryElement(lib1Source); |
| 1134 context.computeLibraryElement(lib2Source); |
| 1135 List<Source> result = context.getLibrariesDependingOn(libASource); |
| 1136 expect(result, unorderedEquals([lib1Source, lib2Source])); |
| 1137 } |
| 1138 |
| 1139 void test_getLibrariesReferencedFromHtml() { |
| 1140 Source htmlSource = addSource( |
| 1141 "/test.html", |
| 1142 r''' |
| 1143 <!DOCTYPE html> |
| 1144 <html><head> |
| 1145 <script type='application/dart' src='test.dart'/> |
| 1146 <script type='application/dart' src='test.js'/> |
| 1147 </head></html>'''); |
| 1148 Source librarySource = addSource("/test.dart", "library lib;"); |
| 1149 context.computeLibraryElement(librarySource); |
| 1150 // Indirectly force the data to be computed. |
| 1151 context.computeErrors(htmlSource); |
| 1152 List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource); |
| 1153 expect(result, hasLength(1)); |
| 1154 expect(result[0], librarySource); |
| 1155 } |
| 1156 |
| 1157 void test_getLibrariesReferencedFromHtml_none() { |
| 1158 Source htmlSource = addSource( |
| 1159 "/test.html", |
| 1160 r''' |
| 1161 <html><head> |
| 1162 <script type='application/dart' src='test.js'/> |
| 1163 </head></html>'''); |
| 1164 addSource("/test.dart", "library lib;"); |
| 1165 context.parseHtmlDocument(htmlSource); |
| 1166 List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource); |
| 1167 expect(result, hasLength(0)); |
| 1168 } |
| 1169 |
| 1170 void test_getLibraryElement() { |
| 1171 Source source = addSource("/test.dart", "library lib;"); |
| 1172 LibraryElement element = context.getLibraryElement(source); |
| 1173 expect(element, isNull); |
| 1174 context.computeLibraryElement(source); |
| 1175 element = context.getLibraryElement(source); |
| 1176 expect(element, isNotNull); |
| 1177 } |
| 1178 |
| 1179 void test_getLibrarySources() { |
| 1180 List<Source> sources = context.librarySources; |
| 1181 int originalLength = sources.length; |
| 1182 Source source = addSource("/test.dart", "library lib;"); |
| 1183 context.computeKindOf(source); |
| 1184 sources = context.librarySources; |
| 1185 expect(sources, hasLength(originalLength + 1)); |
| 1186 for (Source returnedSource in sources) { |
| 1187 if (returnedSource == source) { |
| 1188 return; |
| 1189 } |
| 1190 } |
| 1191 fail("The added source was not in the list of library sources"); |
| 1192 } |
| 1193 |
| 1194 void test_getLineInfo() { |
| 1195 Source source = addSource( |
| 1196 "/test.dart", |
| 1197 r''' |
| 1198 library lib; |
| 1199 |
| 1200 main() {}'''); |
| 1201 LineInfo info = context.getLineInfo(source); |
| 1202 expect(info, isNull); |
| 1203 context.parseCompilationUnit(source); |
| 1204 info = context.getLineInfo(source); |
| 1205 expect(info, isNotNull); |
| 1206 } |
| 1207 |
| 1208 void test_getModificationStamp_fromSource() { |
| 1209 int stamp = 42; |
| 1210 expect( |
| 1211 context.getModificationStamp( |
| 1212 new AnalysisContextImplTest_Source_getModificationStamp_fromSource( |
| 1213 stamp)), |
| 1214 stamp); |
| 1215 } |
| 1216 |
| 1217 void test_getModificationStamp_overridden() { |
| 1218 int stamp = 42; |
| 1219 Source source = |
| 1220 new AnalysisContextImplTest_Source_getModificationStamp_overridden( |
| 1221 stamp); |
| 1222 context.setContents(source, ""); |
| 1223 expect(stamp != context.getModificationStamp(source), isTrue); |
| 1224 } |
| 1225 |
| 1226 void test_getPublicNamespace_element() { |
| 1227 Source source = addSource("/test.dart", "class A {}"); |
| 1228 LibraryElement library = context.computeLibraryElement(source); |
| 1229 expect(library, isNotNull); |
| 1230 Namespace namespace = context.getPublicNamespace(library); |
| 1231 expect(namespace, isNotNull); |
| 1232 EngineTestCase.assertInstanceOf( |
| 1233 (obj) => obj is ClassElement, ClassElement, namespace.get("A")); |
| 1234 } |
| 1235 |
| 1236 void test_getResolvedCompilationUnit_library() { |
| 1237 Source source = addSource("/lib.dart", "library libb;"); |
| 1238 LibraryElement library = context.computeLibraryElement(source); |
| 1239 context.computeErrors(source); // Force the resolved unit to be built. |
| 1240 expect(context.getResolvedCompilationUnit(source, library), isNotNull); |
| 1241 context.setContents(source, "library lib;"); |
| 1242 expect(context.getResolvedCompilationUnit(source, library), isNull); |
| 1243 } |
| 1244 |
| 1245 void test_getResolvedCompilationUnit_library_null() { |
| 1246 Source source = addSource("/lib.dart", "library lib;"); |
| 1247 expect(context.getResolvedCompilationUnit(source, null), isNull); |
| 1248 } |
| 1249 |
| 1250 void test_getResolvedCompilationUnit_source_dart() { |
| 1251 Source source = addSource("/lib.dart", "library lib;"); |
| 1252 expect(context.getResolvedCompilationUnit2(source, source), isNull); |
| 1253 context.resolveCompilationUnit2(source, source); |
| 1254 expect(context.getResolvedCompilationUnit2(source, source), isNotNull); |
| 1255 } |
| 1256 |
| 1257 void test_getSourceFactory() { |
| 1258 expect(context.sourceFactory, same(sourceFactory)); |
| 1259 } |
| 1260 |
| 1261 void test_getSourcesWithFullName() { |
| 1262 String filePath = '/foo/lib/file.dart'; |
| 1263 List<Source> expected = <Source>[]; |
| 1264 ChangeSet changeSet = new ChangeSet(); |
| 1265 |
| 1266 TestSourceWithUri source1 = |
| 1267 new TestSourceWithUri(filePath, Uri.parse('file://$filePath')); |
| 1268 expected.add(source1); |
| 1269 changeSet.addedSource(source1); |
| 1270 |
| 1271 TestSourceWithUri source2 = |
| 1272 new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart')); |
| 1273 expected.add(source2); |
| 1274 changeSet.addedSource(source2); |
| 1275 |
| 1276 context.applyChanges(changeSet); |
| 1277 expect(context.getSourcesWithFullName(filePath), unorderedEquals(expected)); |
| 1278 } |
| 1279 |
| 1280 void test_getStatistics() { |
| 1281 AnalysisContextStatistics statistics = context.statistics; |
| 1282 expect(statistics, isNotNull); |
| 1283 // The following lines are fragile. |
| 1284 // The values depend on the number of libraries in the SDK. |
| 1285 // assertLength(0, statistics.getCacheRows()); |
| 1286 // assertLength(0, statistics.getExceptions()); |
| 1287 // assertLength(0, statistics.getSources()); |
| 1288 } |
| 1289 |
| 1290 void test_handleContentsChanged() { |
| 1291 ContentCache contentCache = new ContentCache(); |
| 1292 context.contentCache = contentCache; |
| 1293 String oldContents = 'foo() {}'; |
| 1294 String newContents = 'bar() {}'; |
| 1295 // old contents |
| 1296 Source source = addSource("/test.dart", oldContents); |
| 1297 _analyzeAll_assertFinished(); |
| 1298 expect(context.getResolvedCompilationUnit2(source, source), isNotNull); |
| 1299 // new contents |
| 1300 contentCache.setContents(source, newContents); |
| 1301 context.handleContentsChanged(source, oldContents, newContents, true); |
| 1302 // there is some work to do |
| 1303 AnalysisResult analysisResult = context.performAnalysisTask(); |
| 1304 expect(analysisResult.changeNotices, isNotNull); |
| 1305 } |
| 1306 |
| 1307 Future test_implicitAnalysisEvents_added() async { |
| 1308 AnalyzedSourcesListener listener = new AnalyzedSourcesListener(); |
| 1309 context.implicitAnalysisEvents.listen(listener.onData); |
| 1310 // |
| 1311 // Create a file that references an file that is not explicitly being |
| 1312 // analyzed and fully analyze it. Ensure that the listener is told about |
| 1313 // the implicitly analyzed file. |
| 1314 // |
| 1315 Source sourceA = newSource('/a.dart', "library a; import 'b.dart';"); |
| 1316 Source sourceB = newSource('/b.dart', "library b;"); |
| 1317 ChangeSet changeSet = new ChangeSet(); |
| 1318 changeSet.addedSource(sourceA); |
| 1319 context.applyChanges(changeSet); |
| 1320 context.computeErrors(sourceA); |
| 1321 await pumpEventQueue(); |
| 1322 listener.expectAnalyzed(sourceB); |
| 1323 } |
| 1324 |
| 1325 void test_isClientLibrary_dart() { |
| 1326 Source source = addSource( |
| 1327 "/test.dart", |
| 1328 r''' |
| 1329 import 'dart:html'; |
| 1330 |
| 1331 main() {}'''); |
| 1332 expect(context.isClientLibrary(source), isFalse); |
| 1333 expect(context.isServerLibrary(source), isFalse); |
| 1334 context.computeLibraryElement(source); |
| 1335 expect(context.isClientLibrary(source), isTrue); |
| 1336 expect(context.isServerLibrary(source), isFalse); |
| 1337 } |
| 1338 |
| 1339 void test_isClientLibrary_html() { |
| 1340 Source source = addSource("/test.html", "<html></html>"); |
| 1341 expect(context.isClientLibrary(source), isFalse); |
| 1342 } |
| 1343 |
| 1344 void test_isServerLibrary_dart() { |
| 1345 Source source = addSource( |
| 1346 "/test.dart", |
| 1347 r''' |
| 1348 library lib; |
| 1349 |
| 1350 main() {}'''); |
| 1351 expect(context.isClientLibrary(source), isFalse); |
| 1352 expect(context.isServerLibrary(source), isFalse); |
| 1353 context.computeLibraryElement(source); |
| 1354 expect(context.isClientLibrary(source), isFalse); |
| 1355 expect(context.isServerLibrary(source), isTrue); |
| 1356 } |
| 1357 |
| 1358 void test_isServerLibrary_html() { |
| 1359 Source source = addSource("/test.html", "<html></html>"); |
| 1360 expect(context.isServerLibrary(source), isFalse); |
| 1361 } |
| 1362 |
| 1363 void test_parseCompilationUnit_errors() { |
| 1364 Source source = addSource("/lib.dart", "library {"); |
| 1365 CompilationUnit compilationUnit = context.parseCompilationUnit(source); |
| 1366 expect(compilationUnit, isNotNull); |
| 1367 var errorInfo = context.getErrors(source); |
| 1368 expect(errorInfo, isNotNull); |
| 1369 List<AnalysisError> errors = errorInfo.errors; |
| 1370 expect(errors, isNotNull); |
| 1371 expect(errors.length > 0, isTrue); |
| 1372 } |
| 1373 |
| 1374 void test_parseCompilationUnit_exception() { |
| 1375 Source source = _addSourceWithException("/test.dart"); |
| 1376 try { |
| 1377 context.parseCompilationUnit(source); |
| 1378 fail("Expected AnalysisException"); |
| 1379 } on AnalysisException { |
| 1380 // Expected |
| 1381 } |
| 1382 } |
| 1383 |
| 1384 void test_parseCompilationUnit_html() { |
| 1385 Source source = addSource("/test.html", "<html></html>"); |
| 1386 expect(context.parseCompilationUnit(source), isNull); |
| 1387 } |
| 1388 |
| 1389 void test_parseCompilationUnit_noErrors() { |
| 1390 Source source = addSource("/lib.dart", "library lib;"); |
| 1391 CompilationUnit compilationUnit = context.parseCompilationUnit(source); |
| 1392 expect(compilationUnit, isNotNull); |
| 1393 AnalysisErrorInfo errorInfo = context.getErrors(source); |
| 1394 expect(errorInfo, isNotNull); |
| 1395 expect(errorInfo.errors, hasLength(0)); |
| 1396 } |
| 1397 |
| 1398 void test_parseCompilationUnit_nonExistentSource() { |
| 1399 Source source = newSource('/test.dart'); |
| 1400 resourceProvider.deleteFile('/test.dart'); |
| 1401 try { |
| 1402 context.parseCompilationUnit(source); |
| 1403 fail("Expected AnalysisException because file does not exist"); |
| 1404 } on AnalysisException { |
| 1405 // Expected result |
| 1406 } |
| 1407 } |
| 1408 |
| 1409 void test_parseHtmlDocument() { |
| 1410 Source source = addSource("/lib.html", "<!DOCTYPE html><html></html>"); |
| 1411 Document document = context.parseHtmlDocument(source); |
| 1412 expect(document, isNotNull); |
| 1413 } |
| 1414 |
| 1415 void test_parseHtmlUnit_resolveDirectives() { |
| 1416 Source libSource = addSource( |
| 1417 "/lib.dart", |
| 1418 r''' |
| 1419 library lib; |
| 1420 class ClassA {}'''); |
| 1421 Source source = addSource( |
| 1422 "/lib.html", |
| 1423 r''' |
| 1424 <!DOCTYPE html> |
| 1425 <html> |
| 1426 <head> |
| 1427 <script type='application/dart'> |
| 1428 import 'lib.dart'; |
| 1429 ClassA v = null; |
| 1430 </script> |
| 1431 </head> |
| 1432 <body> |
| 1433 </body> |
| 1434 </html>'''); |
| 1435 Document document = context.parseHtmlDocument(source); |
| 1436 expect(document, isNotNull); |
| 1437 List<DartScript> scripts = context.computeResult(source, DART_SCRIPTS); |
| 1438 expect(scripts, hasLength(1)); |
| 1439 CompilationUnit unit = context.computeResult(scripts[0], PARSED_UNIT); |
| 1440 ImportDirective importNode = unit.directives[0] as ImportDirective; |
| 1441 expect(importNode.uriContent, isNotNull); |
| 1442 expect(importNode.source, libSource); |
| 1443 } |
| 1444 |
| 1445 void test_performAnalysisTask_addPart() { |
| 1446 Source libSource = addSource( |
| 1447 "/lib.dart", |
| 1448 r''' |
| 1449 library lib; |
| 1450 part 'part.dart';'''); |
| 1451 // run all tasks without part |
| 1452 _analyzeAll_assertFinished(); |
| 1453 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)), |
| 1454 isTrue, |
| 1455 reason: "lib has errors"); |
| 1456 // add part and run all tasks |
| 1457 Source partSource = addSource( |
| 1458 "/part.dart", |
| 1459 r''' |
| 1460 part of lib; |
| 1461 '''); |
| 1462 _analyzeAll_assertFinished(); |
| 1463 // "libSource" should be here |
| 1464 List<Source> librariesWithPart = context.getLibrariesContaining(partSource); |
| 1465 expect(librariesWithPart, unorderedEquals([libSource])); |
| 1466 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)), |
| 1467 isFalse, |
| 1468 reason: "lib doesn't have errors"); |
| 1469 expect( |
| 1470 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1471 reason: "part resolved"); |
| 1472 } |
| 1473 |
| 1474 void test_performAnalysisTask_changeLibraryContents() { |
| 1475 Source libSource = |
| 1476 addSource("/test.dart", "library lib; part 'test-part.dart';"); |
| 1477 Source partSource = addSource("/test-part.dart", "part of lib;"); |
| 1478 _analyzeAll_assertFinished(); |
| 1479 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1480 reason: "library resolved 1"); |
| 1481 expect( |
| 1482 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1483 reason: "part resolved 1"); |
| 1484 // update and analyze #1 |
| 1485 context.setContents(libSource, "library lib;"); |
| 1486 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, |
| 1487 reason: "library changed 2"); |
| 1488 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1489 reason: "part changed 2"); |
| 1490 _analyzeAll_assertFinished(); |
| 1491 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1492 reason: "library resolved 2"); |
| 1493 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1494 reason: "part resolved 2"); |
| 1495 // update and analyze #2 |
| 1496 context.setContents(libSource, "library lib; part 'test-part.dart';"); |
| 1497 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, |
| 1498 reason: "library changed 3"); |
| 1499 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1500 reason: "part changed 3"); |
| 1501 _analyzeAll_assertFinished(); |
| 1502 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1503 reason: "library resolved 3"); |
| 1504 expect( |
| 1505 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1506 reason: "part resolved 3"); |
| 1507 } |
| 1508 |
| 1509 void test_performAnalysisTask_changeLibraryThenPartContents() { |
| 1510 Source libSource = |
| 1511 addSource("/test.dart", "library lib; part 'test-part.dart';"); |
| 1512 Source partSource = addSource("/test-part.dart", "part of lib;"); |
| 1513 _analyzeAll_assertFinished(); |
| 1514 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1515 reason: "library resolved 1"); |
| 1516 expect( |
| 1517 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1518 reason: "part resolved 1"); |
| 1519 // update and analyze #1 |
| 1520 context.setContents(libSource, "library lib;"); |
| 1521 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, |
| 1522 reason: "library changed 2"); |
| 1523 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1524 reason: "part changed 2"); |
| 1525 _analyzeAll_assertFinished(); |
| 1526 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1527 reason: "library resolved 2"); |
| 1528 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1529 reason: "part resolved 2"); |
| 1530 // update and analyze #2 |
| 1531 context.setContents(partSource, "part of lib; // 1"); |
| 1532 // Assert that changing the part's content does not effect the library |
| 1533 // now that it is no longer part of that library |
| 1534 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1535 reason: "library changed 3"); |
| 1536 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1537 reason: "part changed 3"); |
| 1538 _analyzeAll_assertFinished(); |
| 1539 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1540 reason: "library resolved 3"); |
| 1541 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1542 reason: "part resolved 3"); |
| 1543 } |
| 1544 |
| 1545 void test_performAnalysisTask_changePartContents_makeItAPart() { |
| 1546 Source libSource = addSource( |
| 1547 "/lib.dart", |
| 1548 r''' |
| 1549 library lib; |
| 1550 part 'part.dart'; |
| 1551 void f(x) {}'''); |
| 1552 Source partSource = addSource("/part.dart", "void g() { f(null); }"); |
| 1553 _analyzeAll_assertFinished(); |
| 1554 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1555 reason: "library resolved 1"); |
| 1556 expect( |
| 1557 context.getResolvedCompilationUnit2(partSource, partSource), isNotNull, |
| 1558 reason: "part resolved 1"); |
| 1559 // update and analyze |
| 1560 context.setContents( |
| 1561 partSource, |
| 1562 r''' |
| 1563 part of lib; |
| 1564 void g() { f(null); }'''); |
| 1565 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, |
| 1566 reason: "library changed 2"); |
| 1567 expect(context.getResolvedCompilationUnit2(partSource, partSource), isNull, |
| 1568 reason: "part changed 2"); |
| 1569 _analyzeAll_assertFinished(); |
| 1570 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1571 reason: "library resolved 2"); |
| 1572 expect( |
| 1573 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1574 reason: "part resolved 2"); |
| 1575 expect(context.getErrors(libSource).errors, hasLength(0)); |
| 1576 expect(context.getErrors(partSource).errors, hasLength(0)); |
| 1577 } |
| 1578 |
| 1579 /** |
| 1580 * https://code.google.com/p/dart/issues/detail?id=12424 |
| 1581 */ |
| 1582 void test_performAnalysisTask_changePartContents_makeItNotPart() { |
| 1583 Source libSource = addSource( |
| 1584 "/lib.dart", |
| 1585 r''' |
| 1586 library lib; |
| 1587 part 'part.dart'; |
| 1588 void f(x) {}'''); |
| 1589 Source partSource = addSource( |
| 1590 "/part.dart", |
| 1591 r''' |
| 1592 part of lib; |
| 1593 void g() { f(null); }'''); |
| 1594 _analyzeAll_assertFinished(); |
| 1595 expect(context.getErrors(libSource).errors, hasLength(0)); |
| 1596 expect(context.getErrors(partSource).errors, hasLength(0)); |
| 1597 // Remove 'part' directive, which should make "f(null)" an error. |
| 1598 context.setContents( |
| 1599 partSource, |
| 1600 r''' |
| 1601 //part of lib; |
| 1602 void g() { f(null); }'''); |
| 1603 _analyzeAll_assertFinished(); |
| 1604 expect(context.getErrors(libSource).errors.length != 0, isTrue); |
| 1605 } |
| 1606 |
| 1607 void test_performAnalysisTask_changePartContents_noSemanticChanges() { |
| 1608 Source libSource = |
| 1609 addSource("/test.dart", "library lib; part 'test-part.dart';"); |
| 1610 Source partSource = addSource("/test-part.dart", "part of lib;"); |
| 1611 _analyzeAll_assertFinished(); |
| 1612 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1613 reason: "library resolved 1"); |
| 1614 expect( |
| 1615 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1616 reason: "part resolved 1"); |
| 1617 // update and analyze #1 |
| 1618 context.setContents(partSource, "part of lib; // 1"); |
| 1619 if (AnalysisEngine.instance.limitInvalidationInTaskModel) { |
| 1620 expect( |
| 1621 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1622 reason: "library changed 2"); |
| 1623 expect( |
| 1624 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1625 reason: "part changed 2"); |
| 1626 } else { |
| 1627 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, |
| 1628 reason: "library changed 2"); |
| 1629 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1630 reason: "part changed 2"); |
| 1631 _analyzeAll_assertFinished(); |
| 1632 expect( |
| 1633 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1634 reason: "library resolved 2"); |
| 1635 expect( |
| 1636 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1637 reason: "part resolved 2"); |
| 1638 } |
| 1639 // update and analyze #2 |
| 1640 context.setContents(partSource, "part of lib; // 12"); |
| 1641 if (AnalysisEngine.instance.limitInvalidationInTaskModel) { |
| 1642 expect( |
| 1643 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1644 reason: "library changed 3"); |
| 1645 expect( |
| 1646 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1647 reason: "part changed 3"); |
| 1648 } else { |
| 1649 expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull, |
| 1650 reason: "library changed 3"); |
| 1651 expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull, |
| 1652 reason: "part changed 3"); |
| 1653 _analyzeAll_assertFinished(); |
| 1654 expect( |
| 1655 context.getResolvedCompilationUnit2(libSource, libSource), isNotNull, |
| 1656 reason: "library resolved 3"); |
| 1657 expect( |
| 1658 context.getResolvedCompilationUnit2(partSource, libSource), isNotNull, |
| 1659 reason: "part resolved 3"); |
| 1660 } |
| 1661 } |
| 1662 |
| 1663 void test_performAnalysisTask_getContentException_dart() { |
| 1664 Source source = _addSourceWithException('test.dart'); |
| 1665 // prepare errors |
| 1666 _analyzeAll_assertFinished(); |
| 1667 List<AnalysisError> errors = context.getErrors(source).errors; |
| 1668 // validate errors |
| 1669 expect(errors, hasLength(1)); |
| 1670 AnalysisError error = errors[0]; |
| 1671 expect(error.source, same(source)); |
| 1672 expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT); |
| 1673 } |
| 1674 |
| 1675 void test_performAnalysisTask_getContentException_html() { |
| 1676 Source source = _addSourceWithException('test.html'); |
| 1677 // prepare errors |
| 1678 _analyzeAll_assertFinished(); |
| 1679 List<AnalysisError> errors = context.getErrors(source).errors; |
| 1680 // validate errors |
| 1681 expect(errors, hasLength(1)); |
| 1682 AnalysisError error = errors[0]; |
| 1683 expect(error.source, same(source)); |
| 1684 expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT); |
| 1685 } |
| 1686 |
| 1687 void test_performAnalysisTask_importedLibraryAdd() { |
| 1688 Source libASource = |
| 1689 addSource("/libA.dart", "library libA; import 'libB.dart';"); |
| 1690 _analyzeAll_assertFinished(); |
| 1691 expect( |
| 1692 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, |
| 1693 reason: "libA resolved 1"); |
| 1694 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), |
| 1695 isTrue, |
| 1696 reason: "libA has an error"); |
| 1697 // add libB.dart and analyze |
| 1698 Source libBSource = addSource("/libB.dart", "library libB;"); |
| 1699 _analyzeAll_assertFinished(); |
| 1700 expect( |
| 1701 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, |
| 1702 reason: "libA resolved 2"); |
| 1703 expect( |
| 1704 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, |
| 1705 reason: "libB resolved 2"); |
| 1706 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), |
| 1707 isFalse, |
| 1708 reason: "libA doesn't have errors"); |
| 1709 } |
| 1710 |
| 1711 void test_performAnalysisTask_importedLibraryAdd_html() { |
| 1712 Source htmlSource = addSource( |
| 1713 "/page.html", |
| 1714 r''' |
| 1715 <html><body><script type="application/dart"> |
| 1716 import '/libB.dart'; |
| 1717 main() {print('hello dart');} |
| 1718 </script></body></html>'''); |
| 1719 _analyzeAll_assertFinished(); |
| 1720 context.computeErrors(htmlSource); |
| 1721 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)), |
| 1722 isTrue, |
| 1723 reason: "htmlSource has an error"); |
| 1724 // add libB.dart and analyze |
| 1725 Source libBSource = addSource("/libB.dart", "library libB;"); |
| 1726 _analyzeAll_assertFinished(); |
| 1727 expect( |
| 1728 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, |
| 1729 reason: "libB resolved 2"); |
| 1730 // TODO (danrubel) commented out to fix red bots |
| 1731 // context.computeErrors(htmlSource); |
| 1732 // AnalysisErrorInfo errors = _context.getErrors(htmlSource); |
| 1733 // expect( |
| 1734 // !_hasAnalysisErrorWithErrorSeverity(errors), |
| 1735 // isTrue, |
| 1736 // reason: "htmlSource doesn't have errors"); |
| 1737 } |
| 1738 |
| 1739 void test_performAnalysisTask_importedLibraryDelete() { |
| 1740 Source libASource = |
| 1741 addSource("/libA.dart", "library libA; import 'libB.dart';"); |
| 1742 Source libBSource = addSource("/libB.dart", "library libB;"); |
| 1743 _analyzeAll_assertFinished(); |
| 1744 expect( |
| 1745 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, |
| 1746 reason: "libA resolved 1"); |
| 1747 expect( |
| 1748 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, |
| 1749 reason: "libB resolved 1"); |
| 1750 expect(!_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), |
| 1751 isTrue, |
| 1752 reason: "libA doesn't have errors"); |
| 1753 // remove libB.dart and analyze |
| 1754 _removeSource(libBSource); |
| 1755 _analyzeAll_assertFinished(); |
| 1756 expect( |
| 1757 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, |
| 1758 reason: "libA resolved 2"); |
| 1759 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), |
| 1760 isTrue, |
| 1761 reason: "libA has an error"); |
| 1762 } |
| 1763 |
| 1764 void test_performAnalysisTask_IOException() { |
| 1765 TestSource source = _addSourceWithException2("/test.dart", "library test;"); |
| 1766 source.generateExceptionOnRead = false; |
| 1767 _analyzeAll_assertFinished(); |
| 1768 expect(source.readCount, 2); |
| 1769 _changeSource(source, ""); |
| 1770 source.generateExceptionOnRead = true; |
| 1771 _analyzeAll_assertFinished(); |
| 1772 if (AnalysisEngine.instance.limitInvalidationInTaskModel) { |
| 1773 expect(source.readCount, 7); |
| 1774 } else { |
| 1775 expect(source.readCount, 5); |
| 1776 } |
| 1777 } |
| 1778 |
| 1779 void test_performAnalysisTask_missingPart() { |
| 1780 Source source = |
| 1781 addSource("/test.dart", "library lib; part 'no-such-file.dart';"); |
| 1782 _analyzeAll_assertFinished(); |
| 1783 expect(context.getLibraryElement(source), isNotNull, |
| 1784 reason: "performAnalysisTask failed to compute an element model"); |
| 1785 } |
| 1786 |
| 1787 void test_performAnalysisTask_modifiedAfterParse() { |
| 1788 // TODO(scheglov) no threads in Dart |
| 1789 // Source source = _addSource("/test.dart", "library lib;"); |
| 1790 // int initialTime = _context.getModificationStamp(source); |
| 1791 // List<Source> sources = <Source>[]; |
| 1792 // sources.add(source); |
| 1793 // _context.analysisPriorityOrder = sources; |
| 1794 // _context.parseCompilationUnit(source); |
| 1795 // while (initialTime == JavaSystem.currentTimeMillis()) { |
| 1796 // Thread.sleep(1); |
| 1797 // // Force the modification time to be different. |
| 1798 // } |
| 1799 // _context.setContents(source, "library test;"); |
| 1800 // JUnitTestCase.assertTrue(initialTime != _context.getModificationStamp(sour
ce)); |
| 1801 // _analyzeAll_assertFinished(); |
| 1802 // JUnitTestCase.assertNotNullMsg("performAnalysisTask failed to compute an e
lement model", _context.getLibraryElement(source)); |
| 1803 } |
| 1804 |
| 1805 void test_performAnalysisTask_onResultComputed() { |
| 1806 Set<String> libraryElementUris = new Set<String>(); |
| 1807 Set<String> parsedUnitUris = new Set<String>(); |
| 1808 Set<String> resolvedUnitUris = new Set<String>(); |
| 1809 // listen |
| 1810 context.onResultComputed(LIBRARY_ELEMENT).listen((event) { |
| 1811 Source librarySource = event.target; |
| 1812 libraryElementUris.add(librarySource.uri.toString()); |
| 1813 }); |
| 1814 context.onResultComputed(PARSED_UNIT).listen((event) { |
| 1815 Source source = event.target; |
| 1816 parsedUnitUris.add(source.uri.toString()); |
| 1817 }); |
| 1818 context.onResultComputed(RESOLVED_UNIT).listen((event) { |
| 1819 LibrarySpecificUnit target = event.target; |
| 1820 Source librarySource = target.library; |
| 1821 resolvedUnitUris.add(librarySource.uri.toString()); |
| 1822 }); |
| 1823 // analyze |
| 1824 addSource('/test.dart', 'main() {}'); |
| 1825 _analyzeAll_assertFinished(); |
| 1826 // verify |
| 1827 expect(libraryElementUris, contains('dart:core')); |
| 1828 expect(libraryElementUris, contains('file:///test.dart')); |
| 1829 expect(parsedUnitUris, contains('dart:core')); |
| 1830 expect(parsedUnitUris, contains('file:///test.dart')); |
| 1831 expect(resolvedUnitUris, contains('dart:core')); |
| 1832 expect(resolvedUnitUris, contains('file:///test.dart')); |
| 1833 } |
| 1834 |
| 1835 void test_resolveCompilationUnit_import_relative() { |
| 1836 Source sourceA = |
| 1837 addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}"); |
| 1838 addSource("/libB.dart", "library libB; class B{}"); |
| 1839 CompilationUnit compilationUnit = |
| 1840 context.resolveCompilationUnit2(sourceA, sourceA); |
| 1841 expect(compilationUnit, isNotNull); |
| 1842 LibraryElement library = compilationUnit.element.library; |
| 1843 List<LibraryElement> importedLibraries = library.importedLibraries; |
| 1844 assertNamedElements(importedLibraries, ["dart.core", "libB"]); |
| 1845 List<LibraryElement> visibleLibraries = library.visibleLibraries; |
| 1846 assertNamedElements(visibleLibraries, |
| 1847 ["dart.core", "dart.async", "dart.math", "libA", "libB"]); |
| 1848 } |
| 1849 |
| 1850 void test_resolveCompilationUnit_import_relative_cyclic() { |
| 1851 Source sourceA = |
| 1852 addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}"); |
| 1853 addSource("/libB.dart", "library libB; import 'libA.dart'; class B{}"); |
| 1854 CompilationUnit compilationUnit = |
| 1855 context.resolveCompilationUnit2(sourceA, sourceA); |
| 1856 expect(compilationUnit, isNotNull); |
| 1857 LibraryElement library = compilationUnit.element.library; |
| 1858 List<LibraryElement> importedLibraries = library.importedLibraries; |
| 1859 assertNamedElements(importedLibraries, ["dart.core", "libB"]); |
| 1860 List<LibraryElement> visibleLibraries = library.visibleLibraries; |
| 1861 assertNamedElements(visibleLibraries, |
| 1862 ["dart.core", "dart.async", "dart.math", "libA", "libB"]); |
| 1863 } |
| 1864 |
| 1865 void test_resolveCompilationUnit_library() { |
| 1866 Source source = addSource("/lib.dart", "library lib;"); |
| 1867 LibraryElement library = context.computeLibraryElement(source); |
| 1868 CompilationUnit compilationUnit = |
| 1869 context.resolveCompilationUnit(source, library); |
| 1870 expect(compilationUnit, isNotNull); |
| 1871 expect(compilationUnit.element, isNotNull); |
| 1872 } |
| 1873 |
| 1874 // void test_resolveCompilationUnit_sourceChangeDuringResolution() { |
| 1875 // _context = new _AnalysisContext_sourceChangeDuringResolution(); |
| 1876 // AnalysisContextFactory.initContextWithCore(_context); |
| 1877 // _sourceFactory = _context.sourceFactory; |
| 1878 // Source source = _addSource("/lib.dart", "library lib;"); |
| 1879 // CompilationUnit compilationUnit = |
| 1880 // _context.resolveCompilationUnit2(source, source); |
| 1881 // expect(compilationUnit, isNotNull); |
| 1882 // expect(_context.getLineInfo(source), isNotNull); |
| 1883 // } |
| 1884 |
| 1885 void test_resolveCompilationUnit_source() { |
| 1886 Source source = addSource("/lib.dart", "library lib;"); |
| 1887 CompilationUnit compilationUnit = |
| 1888 context.resolveCompilationUnit2(source, source); |
| 1889 expect(compilationUnit, isNotNull); |
| 1890 } |
| 1891 |
| 1892 void test_setAnalysisOptions() { |
| 1893 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 1894 options.cacheSize = 42; |
| 1895 options.dart2jsHint = false; |
| 1896 options.hint = false; |
| 1897 context.analysisOptions = options; |
| 1898 AnalysisOptions result = context.analysisOptions; |
| 1899 expect(result.cacheSize, options.cacheSize); |
| 1900 expect(result.dart2jsHint, options.dart2jsHint); |
| 1901 expect(result.hint, options.hint); |
| 1902 } |
| 1903 |
| 1904 void test_setAnalysisPriorityOrder() { |
| 1905 int priorityCount = 4; |
| 1906 List<Source> sources = <Source>[]; |
| 1907 for (int index = 0; index < priorityCount; index++) { |
| 1908 sources.add(addSource("/lib.dart$index", "")); |
| 1909 } |
| 1910 context.analysisPriorityOrder = sources; |
| 1911 expect(_getPriorityOrder(context).length, priorityCount); |
| 1912 } |
| 1913 |
| 1914 void test_setAnalysisPriorityOrder_empty() { |
| 1915 context.analysisPriorityOrder = <Source>[]; |
| 1916 } |
| 1917 |
| 1918 void test_setAnalysisPriorityOrder_nonEmpty() { |
| 1919 List<Source> sources = <Source>[]; |
| 1920 sources.add(addSource("/lib.dart", "library lib;")); |
| 1921 context.analysisPriorityOrder = sources; |
| 1922 } |
| 1923 |
| 1924 void test_setAnalysisPriorityOrder_resetAnalysisDriver() { |
| 1925 Source source = addSource('/lib.dart', 'library lib;'); |
| 1926 // start analysis |
| 1927 context.performAnalysisTask(); |
| 1928 expect(context.driver.currentWorkOrder, isNotNull); |
| 1929 // set priority sources, AnalysisDriver is reset |
| 1930 context.analysisPriorityOrder = <Source>[source]; |
| 1931 expect(context.driver.currentWorkOrder, isNull); |
| 1932 // analysis continues |
| 1933 context.performAnalysisTask(); |
| 1934 expect(context.driver.currentWorkOrder, isNotNull); |
| 1935 } |
| 1936 |
| 1937 Future test_setChangedContents_libraryWithPart() { |
| 1938 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 1939 options.incremental = true; |
| 1940 context.analysisOptions = options; |
| 1941 SourcesChangedListener listener = new SourcesChangedListener(); |
| 1942 context.onSourcesChanged.listen(listener.onData); |
| 1943 String oldCode = r''' |
| 1944 library lib; |
| 1945 part 'part.dart'; |
| 1946 int a = 0;'''; |
| 1947 Source librarySource = addSource("/lib.dart", oldCode); |
| 1948 String partContents = r''' |
| 1949 part of lib; |
| 1950 int b = a;'''; |
| 1951 Source partSource = addSource("/part.dart", partContents); |
| 1952 LibraryElement element = context.computeLibraryElement(librarySource); |
| 1953 CompilationUnit unit = |
| 1954 context.resolveCompilationUnit(librarySource, element); |
| 1955 expect(unit, isNotNull); |
| 1956 int offset = oldCode.indexOf("int a") + 4; |
| 1957 String newCode = r''' |
| 1958 library lib; |
| 1959 part 'part.dart'; |
| 1960 int ya = 0;'''; |
| 1961 context.setChangedContents(librarySource, newCode, offset, 0, 1); |
| 1962 expect(context.getContents(librarySource).data, newCode); |
| 1963 expect( |
| 1964 context.getResolvedCompilationUnit2(partSource, librarySource), isNull); |
| 1965 return pumpEventQueue().then((_) { |
| 1966 listener.assertEvent(wereSourcesAdded: true); |
| 1967 listener.assertEvent(wereSourcesAdded: true); |
| 1968 listener.assertEvent(changedSources: [librarySource]); |
| 1969 listener.assertNoMoreEvents(); |
| 1970 }); |
| 1971 } |
| 1972 |
| 1973 void test_setChangedContents_notResolved() { |
| 1974 AnalysisOptionsImpl options = |
| 1975 new AnalysisOptionsImpl.from(context.analysisOptions); |
| 1976 options.incremental = true; |
| 1977 context.analysisOptions = options; |
| 1978 String oldCode = r''' |
| 1979 library lib; |
| 1980 int a = 0;'''; |
| 1981 Source librarySource = addSource("/lib.dart", oldCode); |
| 1982 int offset = oldCode.indexOf("int a") + 4; |
| 1983 String newCode = r''' |
| 1984 library lib; |
| 1985 int ya = 0;'''; |
| 1986 context.setChangedContents(librarySource, newCode, offset, 0, 1); |
| 1987 expect(context.getContents(librarySource).data, newCode); |
| 1988 } |
| 1989 |
| 1990 Future test_setContents_libraryWithPart() { |
| 1991 SourcesChangedListener listener = new SourcesChangedListener(); |
| 1992 context.onSourcesChanged.listen(listener.onData); |
| 1993 String libraryContents1 = r''' |
| 1994 library lib; |
| 1995 part 'part.dart'; |
| 1996 int a = 0;'''; |
| 1997 Source librarySource = addSource("/lib.dart", libraryContents1); |
| 1998 String partContents1 = r''' |
| 1999 part of lib; |
| 2000 int b = a;'''; |
| 2001 Source partSource = addSource("/part.dart", partContents1); |
| 2002 context.computeLibraryElement(librarySource); |
| 2003 String libraryContents2 = r''' |
| 2004 library lib; |
| 2005 part 'part.dart'; |
| 2006 int aa = 0;'''; |
| 2007 context.setContents(librarySource, libraryContents2); |
| 2008 expect( |
| 2009 context.getResolvedCompilationUnit2(partSource, librarySource), isNull); |
| 2010 return pumpEventQueue().then((_) { |
| 2011 listener.assertEvent(wereSourcesAdded: true); |
| 2012 listener.assertEvent(wereSourcesAdded: true); |
| 2013 listener.assertEvent(changedSources: [librarySource]); |
| 2014 listener.assertNoMoreEvents(); |
| 2015 }); |
| 2016 } |
| 2017 |
| 2018 void test_setContents_null() { |
| 2019 Source librarySource = addSource( |
| 2020 "/lib.dart", |
| 2021 r''' |
| 2022 library lib; |
| 2023 int a = 0;'''); |
| 2024 context.setContents(librarySource, '// different'); |
| 2025 context.computeLibraryElement(librarySource); |
| 2026 context.setContents(librarySource, null); |
| 2027 expect(context.getResolvedCompilationUnit2(librarySource, librarySource), |
| 2028 isNull); |
| 2029 } |
| 2030 |
| 2031 void test_setContents_unchanged_consistentModificationTime() { |
| 2032 String contents = "// foo"; |
| 2033 Source source = addSource("/test.dart", contents); |
| 2034 context.setContents(source, contents); |
| 2035 // do all, no tasks |
| 2036 _analyzeAll_assertFinished(); |
| 2037 { |
| 2038 AnalysisResult result = context.performAnalysisTask(); |
| 2039 expect(result.changeNotices, isNull); |
| 2040 } |
| 2041 // set the same contents, still no tasks |
| 2042 context.setContents(source, contents); |
| 2043 { |
| 2044 AnalysisResult result = context.performAnalysisTask(); |
| 2045 expect(result.changeNotices, isNull); |
| 2046 } |
| 2047 } |
| 2048 |
| 2049 void test_setSourceFactory() { |
| 2050 expect(context.sourceFactory, sourceFactory); |
| 2051 SourceFactory factory = new SourceFactory([]); |
| 2052 context.sourceFactory = factory; |
| 2053 expect(context.sourceFactory, factory); |
| 2054 } |
| 2055 |
| 2056 void test_updateAnalysis() { |
| 2057 expect(context.sourcesNeedingProcessing, isEmpty); |
| 2058 Source source = newSource('/test.dart'); |
| 2059 AnalysisDelta delta = new AnalysisDelta(); |
| 2060 delta.setAnalysisLevel(source, AnalysisLevel.ALL); |
| 2061 context.applyAnalysisDelta(delta); |
| 2062 expect(context.sourcesNeedingProcessing, contains(source)); |
| 2063 delta = new AnalysisDelta(); |
| 2064 delta.setAnalysisLevel(source, AnalysisLevel.NONE); |
| 2065 context.applyAnalysisDelta(delta); |
| 2066 expect(context.sourcesNeedingProcessing.contains(source), isFalse); |
| 2067 } |
| 2068 |
| 2069 void test_validateCacheConsistency_deletedSource() { |
| 2070 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); |
| 2071 var fileA = resourceProvider.newFile('/a.dart', ""); |
| 2072 var fileB = resourceProvider.newFile('/b.dart', "import 'a.dart';"); |
| 2073 Source sourceA = fileA.createSource(); |
| 2074 Source sourceB = fileB.createSource(); |
| 2075 context.applyChanges( |
| 2076 new ChangeSet()..addedSource(sourceA)..addedSource(sourceB)); |
| 2077 // analyze everything |
| 2078 _analyzeAll_assertFinished(); |
| 2079 // delete a.dart |
| 2080 resourceProvider.deleteFile('/a.dart'); |
| 2081 // analysis should eventually stop |
| 2082 _analyzeAll_assertFinished(); |
| 2083 } |
| 2084 |
| 2085 void xtest_performAnalysisTask_stress() { |
| 2086 int maxCacheSize = 4; |
| 2087 AnalysisOptionsImpl options = |
| 2088 new AnalysisOptionsImpl.from(context.analysisOptions); |
| 2089 options.cacheSize = maxCacheSize; |
| 2090 context.analysisOptions = options; |
| 2091 int sourceCount = maxCacheSize + 2; |
| 2092 List<Source> sources = <Source>[]; |
| 2093 ChangeSet changeSet = new ChangeSet(); |
| 2094 for (int i = 0; i < sourceCount; i++) { |
| 2095 Source source = addSource("/lib$i.dart", "library lib$i;"); |
| 2096 sources.add(source); |
| 2097 changeSet.addedSource(source); |
| 2098 } |
| 2099 context.applyChanges(changeSet); |
| 2100 context.analysisPriorityOrder = sources; |
| 2101 for (int i = 0; i < 1000; i++) { |
| 2102 List<ChangeNotice> notice = context.performAnalysisTask().changeNotices; |
| 2103 if (notice == null) { |
| 2104 //System.out.println("test_performAnalysisTask_stress: " + i); |
| 2105 break; |
| 2106 } |
| 2107 } |
| 2108 List<ChangeNotice> notice = context.performAnalysisTask().changeNotices; |
| 2109 if (notice != null) { |
| 2110 fail( |
| 2111 "performAnalysisTask failed to terminate after analyzing all sources")
; |
| 2112 } |
| 2113 } |
| 2114 |
| 2115 TestSource _addSourceWithException(String fileName) { |
| 2116 return _addSourceWithException2(fileName, ""); |
| 2117 } |
| 2118 |
| 2119 TestSource _addSourceWithException2(String fileName, String contents) { |
| 2120 TestSource source = new TestSource(fileName, contents); |
| 2121 source.generateExceptionOnRead = true; |
| 2122 ChangeSet changeSet = new ChangeSet(); |
| 2123 changeSet.addedSource(source); |
| 2124 context.applyChanges(changeSet); |
| 2125 return source; |
| 2126 } |
| 2127 |
| 2128 /** |
| 2129 * Perform analysis tasks up to 512 times and assert that it was enough. |
| 2130 */ |
| 2131 void _analyzeAll_assertFinished([int maxIterations = 512]) { |
| 2132 for (int i = 0; i < maxIterations; i++) { |
| 2133 List<ChangeNotice> notice = context.performAnalysisTask().changeNotices; |
| 2134 if (notice == null) { |
| 2135 bool inconsistent = context.validateCacheConsistency(); |
| 2136 if (!inconsistent) { |
| 2137 return; |
| 2138 } |
| 2139 } |
| 2140 } |
| 2141 fail("performAnalysisTask failed to terminate after analyzing all sources"); |
| 2142 } |
| 2143 |
| 2144 void _changeSource(TestSource source, String contents) { |
| 2145 source.setContents(contents); |
| 2146 ChangeSet changeSet = new ChangeSet(); |
| 2147 changeSet.changedSource(source); |
| 2148 context.applyChanges(changeSet); |
| 2149 } |
| 2150 |
| 2151 /** |
| 2152 * Search the given compilation unit for a class with the given name. Return t
he class with the |
| 2153 * given name, or `null` if the class cannot be found. |
| 2154 * |
| 2155 * @param unit the compilation unit being searched |
| 2156 * @param className the name of the class being searched for |
| 2157 * @return the class with the given name |
| 2158 */ |
| 2159 ClassElement _findClass(CompilationUnitElement unit, String className) { |
| 2160 for (ClassElement classElement in unit.types) { |
| 2161 if (classElement.displayName == className) { |
| 2162 return classElement; |
| 2163 } |
| 2164 } |
| 2165 return null; |
| 2166 } |
| 2167 |
| 2168 void _flushAst(Source source) { |
| 2169 CacheEntry entry = |
| 2170 context.getCacheEntry(new LibrarySpecificUnit(source, source)); |
| 2171 entry.setState(RESOLVED_UNIT, CacheState.FLUSHED); |
| 2172 } |
| 2173 |
| 2174 List<Source> _getPriorityOrder(AnalysisContextImpl context) { |
| 2175 return context.test_priorityOrder; |
| 2176 } |
| 2177 |
| 2178 void _performPendingAnalysisTasks([int maxTasks = 512]) { |
| 2179 for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) { |
| 2180 if (i > maxTasks) { |
| 2181 fail('Analysis did not terminate.'); |
| 2182 } |
| 2183 } |
| 2184 } |
| 2185 |
| 2186 void _removeSource(Source source) { |
| 2187 resourceProvider.deleteFile(source.fullName); |
| 2188 ChangeSet changeSet = new ChangeSet(); |
| 2189 changeSet.removedSource(source); |
| 2190 context.applyChanges(changeSet); |
| 2191 } |
| 2192 |
| 2193 /** |
| 2194 * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in |
| 2195 * the given [AnalysisErrorInfo]. |
| 2196 */ |
| 2197 static bool _hasAnalysisErrorWithErrorSeverity(AnalysisErrorInfo errorInfo) { |
| 2198 List<AnalysisError> errors = errorInfo.errors; |
| 2199 for (AnalysisError analysisError in errors) { |
| 2200 if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) { |
| 2201 return true; |
| 2202 } |
| 2203 } |
| 2204 return false; |
| 2205 } |
| 2206 } |
| 2207 |
| 2208 @reflectiveTest |
| 2209 class LimitedInvalidateTest extends AbstractContextTest { |
| 2210 @override |
| 2211 void setUp() { |
| 2212 AnalysisEngine.instance.limitInvalidationInTaskModel = true; |
| 2213 super.setUp(); |
| 2214 AnalysisOptionsImpl options = |
| 2215 new AnalysisOptionsImpl.from(context.analysisOptions); |
| 2216 options.incremental = true; |
| 2217 context.analysisOptions = options; |
| 2218 } |
| 2219 |
| 2220 @override |
| 2221 void tearDown() { |
| 2222 AnalysisEngine.instance.limitInvalidationInTaskModel = false; |
| 2223 super.tearDown(); |
| 2224 } |
| 2225 |
| 2226 void test_noChange_thenChange() { |
| 2227 Source sourceA = addSource( |
| 2228 "/a.dart", |
| 2229 r''' |
| 2230 library lib_a; |
| 2231 |
| 2232 class A { |
| 2233 A(); |
| 2234 } |
| 2235 class B { |
| 2236 B(); |
| 2237 } |
| 2238 '''); |
| 2239 Source sourceB = addSource( |
| 2240 "/b.dart", |
| 2241 r''' |
| 2242 library lib_b; |
| 2243 import 'a.dart'; |
| 2244 main() { |
| 2245 new A(); |
| 2246 } |
| 2247 '''); |
| 2248 _performPendingAnalysisTasks(); |
| 2249 expect(context.getErrors(sourceA).errors, hasLength(0)); |
| 2250 expect(context.getErrors(sourceB).errors, hasLength(0)); |
| 2251 var unitA = context.getResolvedCompilationUnit2(sourceA, sourceA); |
| 2252 var unitElementA = unitA.element; |
| 2253 var libraryElementA = unitElementA.library; |
| 2254 // Update a.dart, no declaration changes. |
| 2255 context.setContents( |
| 2256 sourceA, |
| 2257 r''' |
| 2258 library lib_a; |
| 2259 class A { |
| 2260 A(); |
| 2261 } |
| 2262 class B { |
| 2263 B(); |
| 2264 } |
| 2265 '''); |
| 2266 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2267 _assertValid(sourceB, LIBRARY_ELEMENT); |
| 2268 // The a.dart's unit and element are updated incrementally. |
| 2269 // They are the same instances as initially. |
| 2270 // So, all the references from other units are still valid. |
| 2271 { |
| 2272 LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA); |
| 2273 expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA)); |
| 2274 expect(unitA.element, same(unitElementA)); |
| 2275 expect(unitElementA.library, same(libraryElementA)); |
| 2276 } |
| 2277 // Analyze. |
| 2278 _performPendingAnalysisTasks(); |
| 2279 expect(context.getErrors(sourceA).errors, hasLength(0)); |
| 2280 expect(context.getErrors(sourceB).errors, hasLength(0)); |
| 2281 // The a.dart's unit and element are the same. |
| 2282 { |
| 2283 LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA); |
| 2284 expect(analysisCache.getValue(target, RESOLVED_UNIT), same(unitA)); |
| 2285 expect(unitA.element, same(unitElementA)); |
| 2286 expect(unitElementA.library, same(libraryElementA)); |
| 2287 } |
| 2288 // Update a.dart, rename A to A2, invalidates b.dart, so |
| 2289 // we know that the previous update did not damage dependencies. |
| 2290 context.setContents( |
| 2291 sourceA, |
| 2292 r''' |
| 2293 library lib_a; |
| 2294 class A { |
| 2295 A(); |
| 2296 m() {} |
| 2297 } |
| 2298 class B { |
| 2299 B(); |
| 2300 } |
| 2301 '''); |
| 2302 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2303 _assertInvalid(sourceB, LIBRARY_ELEMENT); |
| 2304 // The a.dart's unit and element are the same. |
| 2305 { |
| 2306 LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA); |
| 2307 expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA)); |
| 2308 expect(unitA.element, same(unitElementA)); |
| 2309 expect(unitElementA.library, same(libraryElementA)); |
| 2310 } |
| 2311 // Analyze. |
| 2312 _performPendingAnalysisTasks(); |
| 2313 expect(context.getErrors(sourceA).errors, hasLength(0)); |
| 2314 expect(context.getErrors(sourceB).errors, hasLength(0)); |
| 2315 } |
| 2316 |
| 2317 void test_unusedName() { |
| 2318 Source sourceA = addSource( |
| 2319 "/a.dart", |
| 2320 r''' |
| 2321 library lib_a; |
| 2322 class A {} |
| 2323 class B {} |
| 2324 class C {} |
| 2325 '''); |
| 2326 Source sourceB = addSource( |
| 2327 "/b.dart", |
| 2328 r''' |
| 2329 library lib_b; |
| 2330 import 'a.dart'; |
| 2331 main() { |
| 2332 new A(); |
| 2333 new C(); |
| 2334 } |
| 2335 '''); |
| 2336 _performPendingAnalysisTasks(); |
| 2337 // Update A. |
| 2338 context.setContents( |
| 2339 sourceA, |
| 2340 r''' |
| 2341 library lib_a; |
| 2342 class A {} |
| 2343 class B2 {} |
| 2344 class C {} |
| 2345 '''); |
| 2346 // Only a.dart is invalidated. |
| 2347 // Because b.dart does not use B, so it is valid. |
| 2348 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2349 _assertValid(sourceB, LIBRARY_ERRORS_READY); |
| 2350 } |
| 2351 |
| 2352 void test_usedName_directUser() { |
| 2353 Source sourceA = addSource( |
| 2354 "/a.dart", |
| 2355 r''' |
| 2356 library lib_a; |
| 2357 class A {} |
| 2358 class B {} |
| 2359 class C {} |
| 2360 '''); |
| 2361 Source sourceB = addSource( |
| 2362 "/b.dart", |
| 2363 r''' |
| 2364 library lib_b; |
| 2365 import 'a.dart'; |
| 2366 main() { |
| 2367 new A(); |
| 2368 new C2(); |
| 2369 } |
| 2370 '''); |
| 2371 _performPendingAnalysisTasks(); |
| 2372 expect(context.getErrors(sourceB).errors, hasLength(1)); |
| 2373 // Update a.dart, invalidates b.dart because it references "C2". |
| 2374 context.setContents( |
| 2375 sourceA, |
| 2376 r''' |
| 2377 library lib_a; |
| 2378 class A {} |
| 2379 class B {} |
| 2380 class C2 {} |
| 2381 '''); |
| 2382 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2383 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2384 // Now b.dart is analyzed and the error is fixed. |
| 2385 _performPendingAnalysisTasks(); |
| 2386 expect(context.getErrors(sourceB).errors, hasLength(0)); |
| 2387 // Update a.dart, invalidates b.dart because it references "C". |
| 2388 context.setContents( |
| 2389 sourceA, |
| 2390 r''' |
| 2391 library lib_a; |
| 2392 class A {} |
| 2393 class B {} |
| 2394 class C {} |
| 2395 '''); |
| 2396 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2397 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2398 _performPendingAnalysisTasks(); |
| 2399 // Now b.dart is analyzed and it again has the error. |
| 2400 expect(context.getErrors(sourceB).errors, hasLength(1)); |
| 2401 } |
| 2402 |
| 2403 void test_usedName_directUser_withIncremental() { |
| 2404 Source sourceA = addSource( |
| 2405 "/a.dart", |
| 2406 r''' |
| 2407 library lib_a; |
| 2408 class A { |
| 2409 m() {} |
| 2410 } |
| 2411 '''); |
| 2412 Source sourceB = addSource( |
| 2413 "/b.dart", |
| 2414 r''' |
| 2415 library lib_b; |
| 2416 import 'a.dart'; |
| 2417 main() { |
| 2418 A a = new A(); |
| 2419 a.m(); |
| 2420 } |
| 2421 '''); |
| 2422 _performPendingAnalysisTasks(); |
| 2423 // Update A. |
| 2424 context.setContents( |
| 2425 sourceA, |
| 2426 r''' |
| 2427 library lib_a; |
| 2428 class A { |
| 2429 m2() {} |
| 2430 } |
| 2431 '''); |
| 2432 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2433 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2434 } |
| 2435 |
| 2436 void test_usedName_indirectUser() { |
| 2437 Source sourceA = addSource( |
| 2438 "/a.dart", |
| 2439 r''' |
| 2440 library lib_a; |
| 2441 class A { |
| 2442 m() {} |
| 2443 } |
| 2444 '''); |
| 2445 Source sourceB = addSource( |
| 2446 "/b.dart", |
| 2447 r''' |
| 2448 library lib_b; |
| 2449 import 'a.dart'; |
| 2450 class B extends A {} |
| 2451 '''); |
| 2452 Source sourceC = addSource( |
| 2453 "/c.dart", |
| 2454 r''' |
| 2455 library lib_c; |
| 2456 import 'b.dart'; |
| 2457 class C extends B { |
| 2458 main() { |
| 2459 m(); |
| 2460 } |
| 2461 } |
| 2462 '''); |
| 2463 // No errors, "A.m" exists. |
| 2464 _performPendingAnalysisTasks(); |
| 2465 expect(context.getErrors(sourceC).errors, hasLength(0)); |
| 2466 // Replace "A.m" with "A.m2", invalidate both b.dart and c.dart files. |
| 2467 context.setContents( |
| 2468 sourceA, |
| 2469 r''' |
| 2470 library lib_a; |
| 2471 class A { |
| 2472 m2() {} |
| 2473 } |
| 2474 '''); |
| 2475 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2476 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2477 _assertInvalid(sourceC, LIBRARY_ERRORS_READY); |
| 2478 // There is an error in c.dart, "A.m" does not exist. |
| 2479 _performPendingAnalysisTasks(); |
| 2480 expect(context.getErrors(sourceB).errors, hasLength(0)); |
| 2481 expect(context.getErrors(sourceC).errors, hasLength(1)); |
| 2482 // Restore "A.m", invalidate both b.dart and c.dart files. |
| 2483 context.setContents( |
| 2484 sourceA, |
| 2485 r''' |
| 2486 library lib_a; |
| 2487 class A { |
| 2488 m() {} |
| 2489 } |
| 2490 '''); |
| 2491 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2492 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2493 _assertInvalid(sourceC, LIBRARY_ERRORS_READY); |
| 2494 // No errors, "A.m" exists. |
| 2495 _performPendingAnalysisTasks(); |
| 2496 expect(context.getErrors(sourceC).errors, hasLength(0)); |
| 2497 } |
| 2498 |
| 2499 void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 2500 CacheState state = analysisCache.getState(target, descriptor); |
| 2501 expect(state, CacheState.INVALID); |
| 2502 } |
| 2503 |
| 2504 void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 2505 CacheState state = analysisCache.getState(target, descriptor); |
| 2506 expect(state, CacheState.VALID); |
| 2507 } |
| 2508 |
| 2509 void _performPendingAnalysisTasks([int maxTasks = 512]) { |
| 2510 for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) { |
| 2511 if (i > maxTasks) { |
| 2512 fail('Analysis did not terminate.'); |
| 2513 } |
| 2514 } |
| 2515 } |
| 2516 } |
| 2517 |
| 2518 class _AnalysisContextImplTest_test_applyChanges_removeContainer |
| 2519 implements SourceContainer { |
| 2520 Source libB; |
| 2521 _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB); |
| 2522 @override |
| 2523 bool contains(Source source) => source == libB; |
| 2524 } |
OLD | NEW |