OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2017, 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:front_end/front_end.dart'; |
| 6 import 'package:front_end/src/testing/compiler_common.dart'; |
| 7 import 'package:kernel/ast.dart'; |
| 8 import 'package:kernel/kernel.dart'; |
| 9 |
| 10 import 'package:test/test.dart'; |
| 11 |
| 12 main() { |
| 13 test('summary has no source-info by default', () async { |
| 14 var summary = await summarize(['a.dart'], allSources); |
| 15 var program = loadProgramFromBytes(summary); |
| 16 |
| 17 // Note: the kernel representation always has an empty '' key in the map, |
| 18 // but otherwise no other data is included here. |
| 19 expect(program.uriToSource.keys.single, ''); |
| 20 }); |
| 21 |
| 22 test('summary includes declarations, but no method bodies', () async { |
| 23 var summary = await summarize(['a.dart'], allSources); |
| 24 var program = loadProgramFromBytes(summary); |
| 25 var aLib = findLibrary(program, 'a.dart'); |
| 26 expect(aLib.importUri.path, '/a/b/c/a.dart'); |
| 27 var classA = aLib.classes.first; |
| 28 expect(classA.name, 'A'); |
| 29 var fooMethod = classA.procedures.first; |
| 30 expect(fooMethod.name.name, 'foo'); |
| 31 expect(fooMethod.function.body is EmptyStatement, isTrue); |
| 32 }); |
| 33 |
| 34 test('summarized libraries are not marked external', () async { |
| 35 var summary = await summarize(['a.dart'], allSources); |
| 36 var program = loadProgramFromBytes(summary); |
| 37 var aLib = findLibrary(program, 'a.dart'); |
| 38 expect(aLib.importUri.path, '/a/b/c/a.dart'); |
| 39 expect(aLib.isExternal, isFalse); |
| 40 }); |
| 41 |
| 42 test('sdk dependencies are marked external', () async { |
| 43 // Note: by default this test is loading the SDK from summaries. |
| 44 var summary = await summarize(['a.dart'], allSources); |
| 45 var program = loadProgramFromBytes(summary); |
| 46 var coreLib = findLibrary(program, 'core'); |
| 47 expect(coreLib.isExternal, isTrue); |
| 48 }); |
| 49 |
| 50 test('non-sdk dependencies are marked external', () async { |
| 51 var summaryA = await summarize(['a.dart'], allSources); |
| 52 var sourcesWithA = new Map.from(allSources); |
| 53 sourcesWithA['a.dill'] = summaryA; |
| 54 var summaryB = |
| 55 await summarize(['b.dart'], sourcesWithA, inputSummaries: ['a.dill']); |
| 56 |
| 57 var program = loadProgramFromBytes(summaryB); |
| 58 var aLib = findLibrary(program, 'a.dart'); |
| 59 var bLib = findLibrary(program, 'b.dart'); |
| 60 expect(aLib.isExternal, isTrue); |
| 61 expect(bLib.isExternal, isFalse); |
| 62 }); |
| 63 |
| 64 test('dependencies can be combined without conflict', () async { |
| 65 var summaryA = await summarize(['a.dart'], allSources); |
| 66 var sourcesWithA = new Map.from(allSources); |
| 67 sourcesWithA['a.dill'] = summaryA; |
| 68 |
| 69 var summaryBC = await summarize(['b.dart', 'c.dart'], sourcesWithA, |
| 70 inputSummaries: ['a.dill']); |
| 71 |
| 72 var sourcesWithABC = new Map.from(sourcesWithA); |
| 73 sourcesWithABC['bc.dill'] = summaryBC; |
| 74 |
| 75 // Note: a is loaded first, bc.dill have a.dart as an external reference so |
| 76 // we want to ensure loading them here will not create a problem. |
| 77 var summaryD = await summarize(['d.dart'], sourcesWithABC, |
| 78 inputSummaries: ['a.dill', 'bc.dill']); |
| 79 |
| 80 checkDSummary(summaryD); |
| 81 }); |
| 82 |
| 83 test('dependencies can be combined in any order', () async { |
| 84 var summaryA = await summarize(['a.dart'], allSources); |
| 85 var sourcesWithA = new Map.from(allSources); |
| 86 sourcesWithA['a.dill'] = summaryA; |
| 87 |
| 88 var summaryBC = await summarize(['b.dart', 'c.dart'], sourcesWithA, |
| 89 inputSummaries: ['a.dill']); |
| 90 |
| 91 var sourcesWithABC = new Map.from(sourcesWithA); |
| 92 sourcesWithABC['bc.dill'] = summaryBC; |
| 93 |
| 94 // Note: unlinke the previous test now bc.dill is loaded first and contains |
| 95 // an external definition of library a.dart. Using this order also works |
| 96 // because we share a CanonicalName root to resolve names across multiple |
| 97 // dill files and because of how the kernel loader merges definitions. |
| 98 var summaryD = await summarize(['d.dart'], sourcesWithABC, |
| 99 inputSummaries: ['bc.dill', 'a.dill']); |
| 100 checkDSummary(summaryD); |
| 101 }); |
| 102 |
| 103 test('summarization by default is hermetic', () async { |
| 104 var errors = []; |
| 105 var options = new CompilerOptions()..onError = (e) => errors.add(e); |
| 106 await summarize(['b.dart'], allSources, options: options); |
| 107 expect(errors.first.toString(), contains('Invalid access')); |
| 108 errors.clear(); |
| 109 |
| 110 await summarize(['a.dart', 'b.dart'], allSources, options: options); |
| 111 expect(errors, isEmpty); |
| 112 }); |
| 113 |
| 114 // TODO(sigmund): test trimDependencies when it is part of the public API. |
| 115 } |
| 116 |
| 117 var allSources = { |
| 118 'a.dart': 'class A { foo() { print("hi"); } }', |
| 119 'b.dart': 'import "a.dart"; class B extends A {}', |
| 120 'c.dart': 'class C { bar() => 1; }', |
| 121 'd.dart': ''' |
| 122 import "a.dart"; |
| 123 import "b.dart"; |
| 124 import "c.dart"; |
| 125 class D extends B with C implements A { }''', |
| 126 }; |
| 127 |
| 128 /// Helper function to check that some expectations from the summary of D. |
| 129 checkDSummary(List<int> summary) { |
| 130 var program = loadProgramFromBytes(summary); |
| 131 var aLib = findLibrary(program, 'a.dart'); |
| 132 var bLib = findLibrary(program, 'b.dart'); |
| 133 var cLib = findLibrary(program, 'c.dart'); |
| 134 var dLib = findLibrary(program, 'd.dart'); |
| 135 |
| 136 // All libraries but `d.dart` are marked external. |
| 137 expect(aLib.isExternal, isTrue); |
| 138 expect(bLib.isExternal, isTrue); |
| 139 expect(cLib.isExternal, isTrue); |
| 140 expect(dLib.isExternal, isFalse); |
| 141 |
| 142 // The type-hierarchy for A, B, D is visible and correct |
| 143 var aClass = aLib.classes.firstWhere((c) => c.name == 'A'); |
| 144 var bClass = bLib.classes.firstWhere((c) => c.name == 'B'); |
| 145 expect(bClass.superclass, same(aClass)); |
| 146 |
| 147 var dClass = dLib.classes.firstWhere((c) => c.name == 'D'); |
| 148 expect(dClass.superclass.superclass, same(bClass)); |
| 149 |
| 150 var dInterface = dClass.implementedTypes.first.classNode; |
| 151 expect(dInterface, same(aClass)); |
| 152 } |
OLD | NEW |