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

Side by Side Diff: packages/analyzer/test/src/summary/bazel_summary_test.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, 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 import 'package:analyzer/dart/ast/ast.dart';
6 import 'package:analyzer/dart/ast/token.dart';
7 import 'package:analyzer/dart/element/element.dart';
8 import 'package:analyzer/error/listener.dart';
9 import 'package:analyzer/file_system/file_system.dart';
10 import 'package:analyzer/src/context/cache.dart';
11 import 'package:analyzer/src/dart/scanner/reader.dart';
12 import 'package:analyzer/src/dart/scanner/scanner.dart';
13 import 'package:analyzer/src/generated/engine.dart';
14 import 'package:analyzer/src/generated/parser.dart';
15 import 'package:analyzer/src/generated/source.dart';
16 import 'package:analyzer/src/summary/bazel_summary.dart';
17 import 'package:analyzer/src/summary/format.dart';
18 import 'package:analyzer/src/summary/idl.dart';
19 import 'package:analyzer/src/summary/summarize_ast.dart';
20 import 'package:analyzer/src/summary/summarize_elements.dart';
21 import 'package:analyzer/src/util/fast_uri.dart';
22 import 'package:analyzer/task/dart.dart';
23 import 'package:path/path.dart' as pathos;
24 import 'package:test_reflective_loader/test_reflective_loader.dart';
25 import 'package:unittest/unittest.dart';
26
27 import '../../utils.dart';
28 import '../context/abstract_context.dart';
29
30 main() {
31 initializeTestEnvironment();
32 defineReflectiveTests(BazelResultProviderTest);
33 defineReflectiveTests(SummaryProviderTest);
34 }
35
36 const OUT_ROOT = '$SRC_ROOT/bazel-bin';
37 const SRC_ROOT = '/company/src/user/project/root';
38
39 @reflectiveTest
40 class BazelResultProviderTest extends _BaseTest {
41 BazelResultProvider provider;
42
43 @override
44 void setUp() {
45 super.setUp();
46 provider = new BazelResultProvider(new SummaryProvider(
47 resourceProvider,
48 '_.temp',
49 _getOutputFolder,
50 resourceProvider.getFolder('/tmp/dart/bazel/linked'),
51 context));
52 }
53
54 test_failure_inconsistent_directDependency() {
55 _setComponentFile('aaa', 'a.dart', 'class A {}');
56 _setComponentFile(
57 'bbb',
58 'b.dart',
59 r'''
60 import 'package:components.aaa/a.dart';
61 class B extends A {}
62 ''');
63 _writeUnlinkedBundle('components.aaa');
64 _writeUnlinkedBundle('components.bbb');
65 _setComponentFile('aaa', 'a.dart', 'class A2 {}');
66 // The 'aaa' unlinked bundle in inconsistent, so 'bbb' linking fails.
67 Source source = _resolveUri('package:components.bbb/b.dart');
68 CacheEntry entry = context.getCacheEntry(source);
69 expect(provider.compute(entry, LIBRARY_ELEMENT), isFalse);
70 }
71
72 test_failure_missingDirectDependency() {
73 _setComponentFile('aaa', 'a.dart', 'class A {}');
74 _setComponentFile(
75 'bbb',
76 'b.dart',
77 r'''
78 import 'package:components.aaa/a.dart';
79 class B extends A {}
80 ''');
81 _writeUnlinkedBundle('components.bbb');
82 // We cannot find 'aaa' bundle, so 'bbb' linking fails.
83 Source source = _resolveUri('package:components.bbb/b.dart');
84 CacheEntry entry = context.getCacheEntry(source);
85 expect(provider.compute(entry, LIBRARY_ELEMENT), isFalse);
86 }
87
88 test_success_withoutDependencies() {
89 _setComponentFile('aaa', 'a.dart', 'class A {}');
90 _writeUnlinkedBundle('components.aaa');
91 // Resynthesize 'aaa' library.
92 Source source = _resolveUri('package:components.aaa/a.dart');
93 LibraryElement library = _resynthesizeLibrary(source);
94 List<ClassElement> types = library.definingCompilationUnit.types;
95 expect(types, hasLength(1));
96 expect(types.single.name, 'A');
97 }
98
99 test_withDependency_import() {
100 _setComponentFile('aaa', 'a.dart', 'class A {}');
101 _setComponentFile(
102 'bbb',
103 'b.dart',
104 r'''
105 import 'package:components.aaa/a.dart';
106 class B extends A {}
107 ''');
108 _writeUnlinkedBundle('components.aaa');
109 _writeUnlinkedBundle('components.bbb');
110 // Prepare sources.
111 Source sourceA = _resolveUri('package:components.aaa/a.dart');
112 Source sourceB = _resolveUri('package:components.bbb/b.dart');
113 // Resynthesize 'bbb' library.
114 LibraryElement libraryB = _resynthesizeLibrary(sourceB);
115 List<ClassElement> types = libraryB.definingCompilationUnit.types;
116 expect(types, hasLength(1));
117 ClassElement typeB = types.single;
118 expect(typeB.name, 'B');
119 expect(typeB.supertype.name, 'A');
120 // The LibraryElement for 'aaa' is not created at all.
121 expect(context.getResult(sourceA, LIBRARY_ELEMENT), isNull);
122 // But we can resynthesize it, and it's the same as from 'bbb'.
123 expect(provider.compute(context.getCacheEntry(sourceA), LIBRARY_ELEMENT),
124 isTrue);
125 LibraryElement libraryA = context.getResult(sourceA, LIBRARY_ELEMENT);
126 expect(libraryA, isNotNull);
127 expect(typeB.supertype.element.library, same(libraryA));
128 }
129
130 LibraryElement _resynthesizeLibrary(Source source) {
131 CacheEntry entry = context.getCacheEntry(source);
132 expect(provider.compute(entry, LIBRARY_ELEMENT), isTrue);
133 return context.getResult(source, LIBRARY_ELEMENT);
134 }
135 }
136
137 @reflectiveTest
138 class SummaryProviderTest extends _BaseTest {
139 SummaryProvider manager;
140
141 @override
142 void setUp() {
143 super.setUp();
144 _createManager();
145 }
146
147 test_getLinkedPackages_cached() {
148 _setComponentFile('aaa', 'a.dart', 'class A {}');
149 _setComponentFile(
150 'bbb',
151 'b.dart',
152 r'''
153 import 'package:components.aaa/a.dart';
154 class B extends A {}
155 ''');
156 _writeUnlinkedBundle('components.aaa');
157 _writeUnlinkedBundle('components.bbb');
158 Source source = _resolveUri('package:components.bbb/b.dart');
159
160 // Session 1.
161 // Create linked bundles and store them in files.
162 {
163 List<Package> packages = manager.getLinkedPackages(source);
164 expect(packages, hasLength(2));
165 }
166
167 // Session 2.
168 // Recreate manager (with disabled linking) and ask again.
169 {
170 _createManager(allowLinking: false);
171 List<Package> packages = manager.getLinkedPackages(source);
172 expect(packages, hasLength(2));
173 }
174 }
175
176 test_getLinkedPackages_cached_declaredVariables_export() {
177 _testImpl_getLinkedPackages_cached_declaredVariables('export');
178 }
179
180 test_getLinkedPackages_cached_declaredVariables_import() {
181 _testImpl_getLinkedPackages_cached_declaredVariables('import');
182 }
183
184 test_getLinkedPackages_null_inconsistent_directDependency() {
185 _setComponentFile('aaa', 'a.dart', 'class A {}');
186 _setComponentFile(
187 'bbb',
188 'b.dart',
189 r'''
190 import 'package:components.aaa/a.dart';
191 class B extends A {}
192 ''');
193 _writeUnlinkedBundle('components.aaa');
194 _writeUnlinkedBundle('components.bbb');
195 _setComponentFile('aaa', 'a.dart', 'class A2 {}');
196 // The 'aaa' unlinked bundle in inconsistent, so 'bbb' linking fails.
197 Source source = _resolveUri('package:components.bbb/b.dart');
198 List<Package> packages = manager.getLinkedPackages(source);
199 expect(packages, isNull);
200 }
201
202 test_getLinkedPackages_null_missingBundle() {
203 _setComponentFile('aaa', 'a.dart', 'class A {}');
204 // We don't write 'aaa', so we cannot get its package.
205 // Ask the package for the URI.
206 Source source = _resolveUri('package:components.aaa/a.dart');
207 List<Package> packages = manager.getLinkedPackages(source);
208 expect(packages, isNull);
209 }
210
211 test_getLinkedPackages_null_missingDirectDependency() {
212 _setComponentFile('aaa', 'a.dart', 'class A {}');
213 _setComponentFile(
214 'bbb',
215 'b.dart',
216 r'''
217 import 'package:components.aaa/a.dart';
218 class B extends A {}
219 ''');
220 _writeUnlinkedBundle('components.bbb');
221 // We cannot find 'aaa' bundle, so 'bbb' linking fails.
222 Source source = _resolveUri('package:components.bbb/b.dart');
223 List<Package> packages = manager.getLinkedPackages(source);
224 expect(packages, isNull);
225 }
226
227 test_getLinkedPackages_null_missingIndirectDependency() {
228 _setComponentFile('aaa', 'a.dart', 'class A {}');
229 _setComponentFile(
230 'bbb',
231 'b.dart',
232 r'''
233 import 'package:components.aaa/a.dart';
234 class B extends A {}
235 ''');
236 _setComponentFile(
237 'ccc',
238 'c.dart',
239 r'''
240 import 'package:components.bbb/b.dart';
241 class C extends B {}
242 ''');
243 _writeUnlinkedBundle('components.bbb');
244 _writeUnlinkedBundle('components.ccc');
245 // We cannot find 'aaa' bundle, so 'ccc' linking fails.
246 Source source = _resolveUri('package:components.ccc/c.dart');
247 List<Package> packages = manager.getLinkedPackages(source);
248 expect(packages, isNull);
249 }
250
251 test_getLinkedPackages_withDependency_export() {
252 _setComponentFile('aaa', 'a.dart', 'class A {}');
253 _setComponentFile(
254 'bbb',
255 'b.dart',
256 r'''
257 export 'package:components.aaa/a.dart';
258 ''');
259 _writeUnlinkedBundle('components.aaa');
260 _writeUnlinkedBundle('components.bbb');
261 Source source = _resolveUri('package:components.bbb/b.dart');
262 List<Package> packages = manager.getLinkedPackages(source);
263 expect(packages, hasLength(2));
264 }
265
266 test_getLinkedPackages_withDependency_import() {
267 _setComponentFile('aaa', 'a.dart', 'class A {}');
268 _setComponentFile(
269 'bbb',
270 'b.dart',
271 r'''
272 import 'package:components.aaa/a.dart';
273 class B extends A {}
274 ''');
275 _writeUnlinkedBundle('components.aaa');
276 _writeUnlinkedBundle('components.bbb');
277 Source source = _resolveUri('package:components.bbb/b.dart');
278 List<Package> packages = manager.getLinkedPackages(source);
279 expect(packages, hasLength(2));
280 }
281
282 test_getLinkedPackages_withDependency_import_cycle() {
283 _setComponentFile(
284 'aaa',
285 'a.dart',
286 r'''
287 import 'package:components.bbb/b.dart';
288 class A {}
289 class A2 extends B {}
290 ''');
291 _setComponentFile(
292 'bbb',
293 'b.dart',
294 r'''
295 import 'package:components.aaa/a.dart';
296 class B extends A {}
297 class B2 extends A2 {}
298 ''');
299 _writeUnlinkedBundle('components.aaa');
300 _writeUnlinkedBundle('components.bbb');
301 Source source = _resolveUri('package:components.bbb/b.dart');
302 List<Package> packages = manager.getLinkedPackages(source);
303 expect(packages, hasLength(2));
304 }
305
306 test_getLinkedPackages_withDependency_import_indirect() {
307 _setComponentFile('aaa', 'a.dart', 'class A {}');
308 _setComponentFile(
309 'bbb',
310 'b.dart',
311 r'''
312 import 'package:components.aaa/a.dart';
313 class B extends A {}
314 ''');
315 _setComponentFile(
316 'ccc',
317 'c.dart',
318 r'''
319 import 'package:components.bbb/b.dart';
320 class C extends B {}
321 ''');
322 _writeUnlinkedBundle('components.aaa');
323 _writeUnlinkedBundle('components.bbb');
324 _writeUnlinkedBundle('components.ccc');
325 Source source = _resolveUri('package:components.ccc/c.dart');
326 List<Package> packages = manager.getLinkedPackages(source);
327 expect(packages, hasLength(3));
328 }
329
330 test_getLinkedPackages_withoutDependencies() {
331 _setComponentFile('aaa', 'a.dart', 'class A {}');
332 _writeUnlinkedBundle('components.aaa');
333 // Ask the package for the URI.
334 Source source = _resolveUri('package:components.aaa/a.dart');
335 List<Package> packages = manager.getLinkedPackages(source);
336 expect(packages, hasLength(1));
337 }
338
339 test_getUnlinkedForUri() {
340 _setComponentFile('aaa', 'a1.dart', 'class A1 {}');
341 _setComponentFile('aaa', 'a2.dart', 'class A2 {}');
342 _writeUnlinkedBundle('components.aaa');
343 // Ask the package for the URI.
344 Source source1 = _resolveUri('package:components.aaa/a1.dart');
345 Source source2 = _resolveUri('package:components.aaa/a2.dart');
346 Package package = manager.getUnlinkedForUri(source1.uri);
347 expect(package, isNotNull);
348 // The same instance is returned to another URI in the same package.
349 expect(manager.getUnlinkedForUri(source2.uri), same(package));
350 }
351
352 test_getUnlinkedForUri_inconsistent_fileContent() {
353 File file1 = _setComponentFile('aaa', 'a1.dart', 'class A1 {}');
354 _setComponentFile('aaa', 'a2.dart', 'class A2 {}');
355 _writeUnlinkedBundle('components.aaa');
356 // Update one of the files, so the bundle is not consistent.
357 file1.writeAsStringSync('\nclass A1 {}');
358 Source source1 = _resolveUri('package:components.aaa/a1.dart');
359 Source source2 = _resolveUri('package:components.aaa/a2.dart');
360 expect(manager.getUnlinkedForUri(source1.uri), isNull);
361 expect(manager.getUnlinkedForUri(source2.uri), isNull);
362 }
363
364 test_getUnlinkedForUri_inconsistent_majorVersion() {
365 _setComponentFile('aaa', 'a.dart', 'class A {}');
366 _writeUnlinkedBundle('components.aaa');
367 Source source = _resolveUri('package:components.aaa/a.dart');
368
369 // Create manager with a different major version.
370 // The unlinked bundle cannot be used.
371 _createManager(majorVersion: 12345);
372 Package package = manager.getUnlinkedForUri(source.uri);
373 expect(package, isNull);
374 }
375
376 void _createManager(
377 {bool allowLinking: true,
378 int majorVersion: PackageBundleAssembler.currentMajorVersion}) {
379 manager = new SummaryProvider(resourceProvider, '_.temp', _getOutputFolder,
380 resourceProvider.getFolder('/tmp/dart/bazel/linked'), context,
381 allowLinking: allowLinking, majorVersion: majorVersion);
382 }
383
384 void _testImpl_getLinkedPackages_cached_declaredVariables(
385 String importOrExport) {
386 _setComponentFile(
387 'aaa',
388 'user.dart',
389 '''
390 $importOrExport 'foo.dart'
391 if (dart.library.io) 'foo_io.dart'
392 if (dart.library.html) 'foo_html.dart';
393 ''');
394 _setComponentFile('aaa', 'foo.dart', 'class B {}');
395 _setComponentFile('aaa', 'foo_io.dart', 'class B {}');
396 _setComponentFile('aaa', 'foo_dart.dart', 'class B {}');
397 _writeUnlinkedBundle('components.aaa');
398 Source source = _resolveUri('package:components.aaa/user.dart');
399
400 void _assertDependencyInUser(PackageBundle bundle, String shortName) {
401 for (var i = 0; i < bundle.linkedLibraryUris.length; i++) {
402 if (bundle.linkedLibraryUris[i].endsWith('user.dart')) {
403 LinkedLibrary library = bundle.linkedLibraries[i];
404 expect(library.dependencies.map((d) => d.uri),
405 unorderedEquals(['', 'dart:core', shortName]));
406 return;
407 }
408 }
409 fail('Not found user.dart in $bundle');
410 }
411
412 // Session 1.
413 // Create linked bundles and store them in files.
414 {
415 List<Package> packages = manager.getLinkedPackages(source);
416 expect(packages, hasLength(1));
417 _assertDependencyInUser(packages.single.linked, 'foo.dart');
418 }
419
420 // Session 2.
421 // Recreate manager and don't allow it to perform new linking.
422 // Set a declared variable, which is not used in the package.
423 // We still can get the cached linked bundle.
424 {
425 context.declaredVariables.define('not.used.variable', 'baz');
426 _createManager(allowLinking: false);
427 List<Package> packages = manager.getLinkedPackages(source);
428 expect(packages, hasLength(1));
429 _assertDependencyInUser(packages.single.linked, 'foo.dart');
430 }
431
432 // Session 3.
433 // Recreate manager and don't allow it to perform new linking.
434 // Set the value of a referenced declared variable.
435 // So, we cannot use the previously cached linked bundle.
436 {
437 context.declaredVariables.define('dart.library.io', 'does-not-matter');
438 _createManager(allowLinking: false);
439 List<Package> packages = manager.getLinkedPackages(source);
440 expect(packages, isEmpty);
441 }
442
443 // Session 4.
444 // Enable new linking, and configure to use 'foo_html.dart'.
445 {
446 context.declaredVariables.define('dart.library.html', 'true');
447 _createManager(allowLinking: true);
448 List<Package> packages = manager.getLinkedPackages(source);
449 expect(packages, hasLength(1));
450 _assertDependencyInUser(packages.single.linked, 'foo_html.dart');
451 }
452 }
453 }
454
455 class _BaseTest extends AbstractContextTest {
456 @override
457 void setUp() {
458 super.setUp();
459 // Include a 'package' URI resolver.
460 sourceFactory = new SourceFactory(<UriResolver>[
461 sdkResolver,
462 resourceResolver,
463 new _TestPackageResolver(resourceProvider)
464 ], null, resourceProvider);
465 context.sourceFactory = sourceFactory;
466 }
467
468 Folder _getOutputFolder(Uri absoluteUri) {
469 if (absoluteUri.scheme == 'package') {
470 List<String> segments = absoluteUri.pathSegments;
471 if (segments.isNotEmpty) {
472 String packageName = segments.first;
473 String path = OUT_ROOT + '/' + packageName.replaceAll('.', '/');
474 return resourceProvider.getFolder(path);
475 }
476 }
477 return null;
478 }
479
480 Source _resolveUri(String uri) {
481 return context.sourceFactory.resolveUri(null, uri);
482 }
483
484 File _setComponentFile(String componentName, String fileName, String code) {
485 String path = '$SRC_ROOT/components/$componentName/lib/$fileName';
486 return resourceProvider.newFile(path, code);
487 }
488
489 void _writeUnlinkedBundle(String packageName) {
490 String packagePath = packageName.replaceAll('.', '/');
491 PackageBundleBuilder unlinkedBundle = _computeUnlinkedBundle(
492 resourceProvider,
493 packageName,
494 resourceProvider.getFolder(SRC_ROOT + '/' + packagePath + '/lib'),
495 true);
496 String shortName = packageName.substring(packageName.lastIndexOf('.') + 1);
497 resourceProvider.newFileWithBytes(
498 '$OUT_ROOT/$packagePath/$shortName.full.ds', unlinkedBundle.toBuffer());
499 }
500
501 static PackageBundleBuilder _computeUnlinkedBundle(ResourceProvider provider,
502 String packageName, Folder libFolder, bool strong) {
503 var pathContext = provider.pathContext;
504 String libPath = libFolder.path + pathContext.separator;
505 PackageBundleAssembler assembler = new PackageBundleAssembler();
506
507 /**
508 * Return the `package` [Uri] for the given [path] in the `lib` folder
509 * of the current package.
510 */
511 Uri getUri(String path) {
512 String pathInLib = path.substring(libPath.length);
513 String uriPath = pathos.posix.joinAll(pathContext.split(pathInLib));
514 String uriStr = 'package:$packageName/$uriPath';
515 return FastUri.parse(uriStr);
516 }
517
518 /**
519 * If the given [file] is a Dart file, add its unlinked unit.
520 */
521 void addDartFile(File file) {
522 String path = file.path;
523 if (AnalysisEngine.isDartFileName(path)) {
524 Uri uri = getUri(path);
525 Source source = file.createSource(uri);
526 CompilationUnit unit = _parse(source, strong);
527 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
528 assembler.addUnlinkedUnit(source, unlinkedUnit);
529 }
530 }
531
532 /**
533 * Visit the [folder] recursively.
534 */
535 void addDartFiles(Folder folder) {
536 List<Resource> children = folder.getChildren();
537 for (Resource child in children) {
538 if (child is File) {
539 addDartFile(child);
540 }
541 }
542 for (Resource child in children) {
543 if (child is Folder) {
544 addDartFiles(child);
545 }
546 }
547 }
548
549 addDartFiles(libFolder);
550 return assembler.assemble();
551 }
552
553 /**
554 * Parse the given [source] into AST.
555 */
556 static CompilationUnit _parse(Source source, bool strong) {
557 String code = source.contents.data;
558 AnalysisErrorListener errorListener = AnalysisErrorListener.NULL_LISTENER;
559 CharSequenceReader reader = new CharSequenceReader(code);
560 Scanner scanner = new Scanner(source, reader, errorListener);
561 scanner.scanGenericMethodComments = strong;
562 Token token = scanner.tokenize();
563 LineInfo lineInfo = new LineInfo(scanner.lineStarts);
564 Parser parser = new Parser(source, errorListener);
565 parser.parseGenericMethodComments = strong;
566 CompilationUnit unit = parser.parseCompilationUnit(token);
567 unit.lineInfo = lineInfo;
568 return unit;
569 }
570 }
571
572 class _TestPackageResolver implements UriResolver {
573 final ResourceProvider resourceProvider;
574
575 _TestPackageResolver(this.resourceProvider);
576
577 @override
578 Source resolveAbsolute(Uri uri, [Uri actualUri]) {
579 if (uri.scheme == 'package') {
580 List<String> segments = uri.pathSegments;
581 if (segments.isNotEmpty) {
582 pathos.Context pathContext = resourceProvider.pathContext;
583 String packageName = segments.first;
584 String folderPath = pathContext.join(
585 SRC_ROOT, packageName.replaceAll('.', pathContext.separator));
586 String path = pathContext.join(
587 folderPath, 'lib', pathContext.joinAll(segments.skip(1)));
588 return resourceProvider.getFile(path).createSource(uri);
589 }
590 }
591 return null;
592 }
593
594 @override
595 Uri restoreAbsolute(Source source) {
596 throw new UnimplementedError();
597 }
598 }
OLDNEW
« no previous file with comments | « packages/analyzer/test/src/summary/api_signature_test.dart ('k') | packages/analyzer/test/src/summary/flat_buffers_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698