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 /// Defines the front-end API for converting source code to Dart Kernel objects. | |
6 library front_end.kernel_generator_impl; | |
7 | |
8 import 'dart:async' show Future; | |
9 import 'dart:async'; | |
10 | |
11 import 'package:kernel/kernel.dart' show Program, CanonicalName; | |
12 | |
13 import '../compiler_options.dart'; | |
14 import '../file_system.dart'; | |
15 import 'base/processed_options.dart'; | |
16 import 'fasta/dill/dill_target.dart' show DillTarget; | |
17 import 'fasta/errors.dart' show InputError; | |
18 import 'fasta/kernel/kernel_outline_shaker.dart'; | |
19 import 'fasta/kernel/kernel_target.dart' show KernelTarget; | |
20 import 'fasta/kernel/verifier.dart'; | |
21 import 'fasta/kernel/utils.dart'; | |
22 import 'fasta/translate_uri.dart' show TranslateUri; | |
23 import 'simple_error.dart'; | |
24 import 'fasta/errors.dart'; | |
25 | |
26 /// CODE REVIEW COMMENT: Should we expose this in the public API as well (it is | |
27 /// used to implement all 3 APIs, but also used directly in patched_sdk) | |
28 | |
29 /// Implementation for the `package:front_end/kernel_generator.dart` and | |
30 /// `package:front_end/summary_generator.dart` APIs. | |
31 Future<CompilerResult> generateKernel( | |
32 Iterable<Uri> sources, CompilerOptions options, | |
33 {bool buildSummary: false, | |
34 bool buildProgram: true, | |
35 bool trimDependencies: false}) async { | |
36 report(String msg) { | |
37 options.onError(new SimpleError(msg)); | |
ahe
2017/07/05 13:29:40
What is a SimpleError?
Siggi Cherem (dart-lang)
2017/07/05 18:42:10
An error object that needs a better name? ;-)
The
| |
38 return null; | |
39 } | |
40 | |
41 var fs = options.fileSystem; | |
42 | |
43 for (var source in sources) { | |
44 if (source.scheme == 'file' && !await fs.entityForUri(source).exists()) { | |
45 return report("Entry-point file not found: $source"); | |
46 } | |
47 } | |
48 | |
49 if (!options.chaseDependencies) { | |
50 fs = new HermeticFileSystem(sources.toSet(), fs); | |
Paul Berry
2017/06/29 18:51:07
It would be cool if we moved this logic into Proce
Siggi Cherem (dart-lang)
2017/06/30 04:12:02
Done.
I initially had discarded this idea because
Paul Berry
2017/07/04 15:12:14
I like it! Thanks :)
| |
51 } | |
52 | |
53 var pOptions = new ProcessedOptions(options); | |
54 pOptions.ticker.logMs("Parsed arguments"); | |
ahe
2017/07/05 13:29:40
This will always report that parsing arguments too
Siggi Cherem (dart-lang)
2017/07/05 18:42:11
Done - now ticker is created eagerly when allocati
| |
55 | |
56 if (!await pOptions.validateOptions()) return null; | |
57 pOptions.ticker.logMs("Validated arguments"); | |
58 | |
59 try { | |
60 TranslateUri uriTranslator = await pOptions.getUriTranslator(); | |
61 | |
62 var dillTarget = | |
63 new DillTarget(pOptions.ticker, uriTranslator, pOptions.target); | |
64 | |
65 CanonicalName nameRoot = new CanonicalName.root(); | |
66 Set<Uri> externalLibs(Program program) { | |
67 return program.libraries | |
68 .where((lib) => lib.isExternal) | |
69 .map((lib) => lib.importUri) | |
70 .toSet(); | |
71 } | |
72 | |
73 var sdkSummary = await pOptions.loadSdkSummary(nameRoot); | |
74 if (sdkSummary != null) { | |
75 var excluded = externalLibs(sdkSummary); | |
76 dillTarget.loader | |
77 .appendLibraries(sdkSummary, (uri) => !excluded.contains(uri)); | |
78 } | |
79 | |
80 // TODO(sigmund): provide better error reporting if input summaries or | |
81 // linked dependencies were listed out of order (or provide mechanism to | |
82 // sort them). | |
83 for (var inputSummary in await pOptions.loadInputSummaries(nameRoot)) { | |
84 var excluded = externalLibs(inputSummary); | |
85 dillTarget.loader | |
86 .appendLibraries(inputSummary, (uri) => !excluded.contains(uri)); | |
87 } | |
88 | |
89 // All summaries are considered external and shouldn't include source-info. | |
90 // TODO(sigmund): rather than clearing uriToSource here, it would be nice if | |
91 // the serializer could filter uriToSource as well. | |
92 dillTarget.loader.libraries.forEach((lib) => lib.isExternal = true); | |
93 dillTarget.loader.uriToSource.clear(); | |
ahe
2017/07/05 13:29:40
Why do we clear this? Have you made sure that stac
Siggi Cherem (dart-lang)
2017/07/05 18:42:10
Deleted this, but for a different reason :)
The b
| |
94 | |
95 // Linked dependencies are meant to be part of the program so they are not | |
96 // marked external. | |
97 for (var dependency in await pOptions.loadLinkDependencies(nameRoot)) { | |
98 var excluded = externalLibs(dependency); | |
99 dillTarget.loader | |
100 .appendLibraries(dependency, (uri) => !excluded.contains(uri)); | |
101 } | |
102 | |
103 await dillTarget.buildOutlines(); | |
104 | |
105 var kernelTarget = new KernelTarget(fs, dillTarget, uriTranslator); | |
106 sources.forEach(kernelTarget.read); | |
107 Program summaryProgram = | |
108 await kernelTarget.buildOutlines(nameRoot: nameRoot); | |
109 List<int> summary = null; | |
110 if (buildSummary) { | |
111 if (trimDependencies) { | |
112 // TODO(sigmund): see if it is worth supporting this. Trimming the | |
113 // program here will affect how we build the program later. To support | |
114 // both we'd have to clone the program first. | |
ahe
2017/07/05 13:29:40
To support both what?
Siggi Cherem (dart-lang)
2017/07/05 18:42:10
buildSummary & buildProgram at once + trimming dep
| |
115 assert(!buildProgram); | |
116 var excluded = | |
117 dillTarget.loader.libraries.map((lib) => lib.importUri).toSet(); | |
118 trimProgram(summaryProgram, (uri) => !excluded.contains(uri)); | |
119 } | |
120 if (options.verify) verifyProgram(summaryProgram); | |
121 if (kernelTarget.errors.isEmpty) { | |
122 summary = serializeProgram(summaryProgram, excludeUriToSource: true); | |
123 } | |
124 pOptions.ticker.logMs("Generated outline"); | |
125 } | |
126 | |
127 Program program; | |
128 if (buildProgram && kernelTarget.errors.isEmpty) { | |
129 program = await kernelTarget.buildProgram(verify: pOptions.verify); | |
130 if (trimDependencies) { | |
131 var excluded = | |
132 dillTarget.loader.libraries.map((lib) => lib.importUri).toSet(); | |
133 trimProgram(program, (uri) => !excluded.contains(uri)); | |
134 } | |
135 if (pOptions.debugDump) printProgramText(program); | |
ahe
2017/07/05 13:29:40
libraryFilter option missing here.
Siggi Cherem (dart-lang)
2017/07/05 18:42:10
Done.
| |
136 pOptions.ticker.logMs("Generated program"); | |
137 } | |
138 | |
139 if (kernelTarget.errors.isNotEmpty) { | |
140 kernelTarget.errors.forEach(report); | |
141 return null; | |
142 } | |
143 | |
144 return new CompilerResult( | |
145 summary: summary, | |
146 program: program, | |
147 deps: kernelTarget.loader.getDependencies()); | |
148 } on InputError catch (e) { | |
149 report(e.format()); | |
150 return null; | |
151 } | |
152 } | |
153 | |
154 /// Result object of [generateKernel]. | |
155 class CompilerResult { | |
156 /// The generated summary bytes, if it was requested. | |
157 final List<int> summary; | |
158 | |
159 /// The generated program, if it was requested. | |
160 final Program program; | |
161 | |
162 /// Dependencies traversed by the compiler. Used only for generating | |
163 /// dependency .GN files in the dart-sdk build system. | |
164 /// Note this might be removed when we switch to compute depencencies without | |
165 /// using the compiler itself. | |
166 final List<Uri> deps; | |
167 | |
168 CompilerResult({this.summary, this.program, this.deps}); | |
169 } | |
170 | |
171 /// A [FileSystem] that only allows access to files that have been explicitly | |
172 /// whitelisted. | |
173 class HermeticFileSystem implements FileSystem { | |
174 final Set<Uri> includedFiles; | |
175 final FileSystem _realFileSystem; | |
176 | |
177 HermeticFileSystem(this.includedFiles, this._realFileSystem); | |
178 | |
179 FileSystemEntity entityForUri(Uri uri) { | |
180 if (includedFiles.contains(uri)) return _realFileSystem.entityForUri(uri); | |
181 return inputError( | |
ahe
2017/07/05 13:29:40
Throw FileSystemException instead, then Fasta can
Siggi Cherem (dart-lang)
2017/07/05 18:42:11
Done. I like it.
| |
182 null, | |
ahe
2017/07/05 13:29:40
uri
Siggi Cherem (dart-lang)
2017/07/05 18:42:11
n/a now that I use FileSystemException.
However,
| |
183 -1, | |
184 'Invalid access to $uri: ' | |
185 'the file is accessed in a modular hermetic build ' | |
186 '(where chaseDependencies is false), but it was not ' | |
187 'explicitly listed as an input.'); | |
188 } | |
189 } | |
OLD | NEW |