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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/apiimpl.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, 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 leg_apiimpl;
6
7 import 'dart:async';
8
9 import '../compiler.dart' as api;
10 import 'dart2jslib.dart' as leg;
11 import 'tree/tree.dart' as tree;
12 import 'elements/elements.dart' as elements;
13 import '../../libraries.dart';
14 import 'source_file.dart';
15
16 const bool forceIncrementalSupport =
17 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
18
19 class Compiler extends leg.Compiler {
20 api.CompilerInputProvider provider;
21 api.DiagnosticHandler handler;
22 final Uri libraryRoot;
23 final Uri packageRoot;
24 List<String> options;
25 Map<String, dynamic> environment;
26 bool mockableLibraryUsed = false;
27 final Set<String> allowedLibraryCategories;
28
29 leg.GenericTask userHandlerTask;
30 leg.GenericTask userProviderTask;
31
32 Compiler(this.provider,
33 api.CompilerOutputProvider outputProvider,
34 this.handler,
35 this.libraryRoot,
36 this.packageRoot,
37 List<String> options,
38 this.environment)
39 : this.options = options,
40 this.allowedLibraryCategories = getAllowedLibraryCategories(options),
41 super(
42 outputProvider: outputProvider,
43 enableTypeAssertions: hasOption(options, '--enable-checked-mode'),
44 enableUserAssertions: hasOption(options, '--enable-checked-mode'),
45 trustTypeAnnotations:
46 hasOption(options, '--trust-type-annotations'),
47 enableMinification: hasOption(options, '--minify'),
48 preserveUris: hasOption(options, '--preserve-uris'),
49 enableNativeLiveTypeAnalysis:
50 !hasOption(options, '--disable-native-live-type-analysis'),
51 emitJavaScript: !(hasOption(options, '--output-type=dart') ||
52 hasOption(options, '--output-type=dart-multi')),
53 dart2dartMultiFile: hasOption(options, '--output-type=dart-multi'),
54 generateSourceMap: !hasOption(options, '--no-source-maps'),
55 analyzeAllFlag: hasOption(options, '--analyze-all'),
56 analyzeOnly: hasOption(options, '--analyze-only'),
57 analyzeMain: hasOption(options, '--analyze-main'),
58 analyzeSignaturesOnly:
59 hasOption(options, '--analyze-signatures-only'),
60 strips: extractCsvOption(options, '--force-strip='),
61 enableConcreteTypeInference:
62 hasOption(options, '--enable-concrete-type-inference'),
63 disableTypeInferenceFlag:
64 hasOption(options, '--disable-type-inference'),
65 preserveComments: hasOption(options, '--preserve-comments'),
66 verbose: hasOption(options, '--verbose'),
67 sourceMapUri: extractUriOption(options, '--source-map='),
68 outputUri: extractUriOption(options, '--out='),
69 terseDiagnostics: hasOption(options, '--terse'),
70 dumpInfo: hasOption(options, '--dump-info'),
71 buildId: extractStringOption(
72 options, '--build-id=',
73 "build number could not be determined"),
74 showPackageWarnings:
75 hasOption(options, '--show-package-warnings'),
76 useContentSecurityPolicy: hasOption(options, '--csp'),
77 hasIncrementalSupport:
78 forceIncrementalSupport ||
79 hasOption(options, '--incremental-support'),
80 suppressWarnings: hasOption(options, '--suppress-warnings'),
81 enableAsyncAwait: hasOption(options, '--enable-async')) {
82 tasks.addAll([
83 userHandlerTask = new leg.GenericTask('Diagnostic handler', this),
84 userProviderTask = new leg.GenericTask('Input provider', this),
85 ]);
86 if (!libraryRoot.path.endsWith("/")) {
87 throw new ArgumentError("libraryRoot must end with a /");
88 }
89 if (packageRoot != null && !packageRoot.path.endsWith("/")) {
90 throw new ArgumentError("packageRoot must end with a /");
91 }
92 if (enableAsyncAwait && !analyzeOnly) {
93 throw new ArgumentError(
94 "--enable-async is currently only supported with --analyze-only");
95 }
96 }
97
98 static String extractStringOption(List<String> options,
99 String prefix,
100 String defaultValue) {
101 for (String option in options) {
102 if (option.startsWith(prefix)) {
103 return option.substring(prefix.length);
104 }
105 }
106 return defaultValue;
107 }
108
109 static Uri extractUriOption(List<String> options, String prefix) {
110 var option = extractStringOption(options, prefix, null);
111 return (option == null) ? null : Uri.parse(option);
112 }
113
114 // CSV: Comma separated values.
115 static List<String> extractCsvOption(List<String> options, String prefix) {
116 for (String option in options) {
117 if (option.startsWith(prefix)) {
118 return option.substring(prefix.length).split(',');
119 }
120 }
121 return const <String>[];
122 }
123
124 static Set<String> getAllowedLibraryCategories(List<String> options) {
125 var result = extractCsvOption(options, '--categories=');
126 if (result.isEmpty) {
127 result = ['Client'];
128 }
129 result.add('Shared');
130 result.add('Internal');
131 return new Set<String>.from(result);
132 }
133
134 static bool hasOption(List<String> options, String option) {
135 return options.indexOf(option) >= 0;
136 }
137
138 // TODO(johnniwinther): Merge better with [translateDartUri] when
139 // [scanBuiltinLibrary] is removed.
140 String lookupLibraryPath(String dartLibraryName) {
141 LibraryInfo info = LIBRARIES[dartLibraryName];
142 if (info == null) return null;
143 if (!info.isDart2jsLibrary) return null;
144 if (!allowedLibraryCategories.contains(info.category)) return null;
145 String path = info.dart2jsPath;
146 if (path == null) {
147 path = info.path;
148 }
149 return "lib/$path";
150 }
151
152 String lookupPatchPath(String dartLibraryName) {
153 LibraryInfo info = LIBRARIES[dartLibraryName];
154 if (info == null) return null;
155 if (!info.isDart2jsLibrary) return null;
156 String path = info.dart2jsPatchPath;
157 if (path == null) return null;
158 return "lib/$path";
159 }
160
161 void log(message) {
162 handler(null, null, null, message, api.Diagnostic.VERBOSE_INFO);
163 }
164
165 /// See [leg.Compiler.translateResolvedUri].
166 Uri translateResolvedUri(elements.LibraryElement importingLibrary,
167 Uri resolvedUri, tree.Node node) {
168 if (resolvedUri.scheme == 'dart') {
169 return translateDartUri(importingLibrary, resolvedUri, node);
170 }
171 return resolvedUri;
172 }
173
174 /**
175 * Reads the script designated by [readableUri].
176 */
177 Future<leg.Script> readScript(leg.Spannable node, Uri readableUri) {
178 if (!readableUri.isAbsolute) {
179 if (node == null) node = leg.NO_LOCATION_SPANNABLE;
180 internalError(node,
181 'Relative uri $readableUri provided to readScript(Uri).');
182 }
183
184 // We need to store the current element since we are reporting read errors
185 // asynchronously and therefore need to restore the current element for
186 // [node] to be valid.
187 elements.Element element = currentElement;
188 void reportReadError(exception) {
189 withCurrentElement(element, () {
190 reportError(node,
191 leg.MessageKind.READ_SCRIPT_ERROR,
192 {'uri': readableUri, 'exception': exception});
193 });
194 }
195
196 Uri resourceUri = translateUri(node, readableUri);
197 // TODO(johnniwinther): Wrap the result from [provider] in a specialized
198 // [Future] to ensure that we never execute an asynchronous action without
199 // setting up the current element of the compiler.
200 return new Future.sync(() => callUserProvider(resourceUri)).then((data) {
201 SourceFile sourceFile;
202 String resourceUriString = resourceUri.toString();
203 if (data is List<int>) {
204 sourceFile = new Utf8BytesSourceFile(resourceUriString, data);
205 } else if (data is String) {
206 sourceFile = new StringSourceFile(resourceUriString, data);
207 } else {
208 String message = "Expected a 'String' or a 'List<int>' from the input "
209 "provider, but got: ${Error.safeToString(data)}.";
210 reportReadError(message);
211 }
212 // We use [readableUri] as the URI for the script since need to preserve
213 // the scheme in the script because [Script.uri] is used for resolving
214 // relative URIs mentioned in the script. See the comment on
215 // [LibraryLoader] for more details.
216 return new leg.Script(readableUri, resourceUri, sourceFile);
217 }).catchError((error) {
218 reportReadError(error);
219 return null;
220 });
221 }
222
223 /**
224 * Translates a readable URI into a resource URI.
225 *
226 * See [LibraryLoader] for terminology on URIs.
227 */
228 Uri translateUri(leg.Spannable node, Uri readableUri) {
229 switch (readableUri.scheme) {
230 case 'package': return translatePackageUri(node, readableUri);
231 default: return readableUri;
232 }
233 }
234
235 Uri translateDartUri(elements.LibraryElement importingLibrary,
236 Uri resolvedUri, tree.Node node) {
237 LibraryInfo libraryInfo = LIBRARIES[resolvedUri.path];
238 String path = lookupLibraryPath(resolvedUri.path);
239 if (libraryInfo != null &&
240 libraryInfo.category == "Internal") {
241 bool allowInternalLibraryAccess = false;
242 if (importingLibrary != null) {
243 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) {
244 allowInternalLibraryAccess = true;
245 } else if (importingLibrary.canonicalUri.path.contains(
246 'dart/tests/compiler/dart2js_native')) {
247 allowInternalLibraryAccess = true;
248 }
249 }
250 if (!allowInternalLibraryAccess) {
251 if (importingLibrary != null) {
252 reportError(
253 node,
254 leg.MessageKind.INTERNAL_LIBRARY_FROM,
255 {'resolvedUri': resolvedUri,
256 'importingUri': importingLibrary.canonicalUri});
257 } else {
258 reportError(
259 node,
260 leg.MessageKind.INTERNAL_LIBRARY,
261 {'resolvedUri': resolvedUri});
262 }
263 }
264 }
265 if (path == null) {
266 reportError(node, leg.MessageKind.LIBRARY_NOT_FOUND,
267 {'resolvedUri': resolvedUri});
268 return null;
269 }
270 if (resolvedUri.path == 'html' ||
271 resolvedUri.path == 'io') {
272 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart
273 // supports this use case better.
274 mockableLibraryUsed = true;
275 }
276 return libraryRoot.resolve(path);
277 }
278
279 Uri resolvePatchUri(String dartLibraryPath) {
280 String patchPath = lookupPatchPath(dartLibraryPath);
281 if (patchPath == null) return null;
282 return libraryRoot.resolve(patchPath);
283 }
284
285 Uri translatePackageUri(leg.Spannable node, Uri uri) {
286 if (packageRoot == null) {
287 reportFatalError(
288 node, leg.MessageKind.PACKAGE_ROOT_NOT_SET, {'uri': uri});
289 }
290 return packageRoot.resolve(uri.path);
291 }
292
293 Future<bool> run(Uri uri) {
294 log('Allowed library categories: $allowedLibraryCategories');
295 return super.run(uri).then((bool success) {
296 int cumulated = 0;
297 for (final task in tasks) {
298 int elapsed = task.timing;
299 if (elapsed != 0) {
300 cumulated += elapsed;
301 log('${task.name} took ${elapsed}msec');
302 }
303 }
304 int total = totalCompileTime.elapsedMilliseconds;
305 log('Total compile-time ${total}msec;'
306 ' unaccounted ${total - cumulated}msec');
307 return success;
308 });
309 }
310
311 void reportDiagnostic(leg.Spannable node,
312 leg.Message message,
313 api.Diagnostic kind) {
314 leg.SourceSpan span = spanFromSpannable(node);
315 if (identical(kind, api.Diagnostic.ERROR)
316 || identical(kind, api.Diagnostic.CRASH)) {
317 compilationFailed = true;
318 }
319 // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For
320 // instance in the [Types] constructor in typechecker.dart.
321 if (span == null || span.uri == null) {
322 callUserHandler(null, null, null, '$message', kind);
323 } else {
324 callUserHandler(
325 translateUri(null, span.uri), span.begin, span.end, '$message', kind);
326 }
327 }
328
329 bool get isMockCompilation {
330 return mockableLibraryUsed
331 && (options.indexOf('--allow-mock-compilation') != -1);
332 }
333
334 void callUserHandler(Uri uri, int begin, int end,
335 String message, api.Diagnostic kind) {
336 try {
337 userHandlerTask.measure(() {
338 handler(uri, begin, end, message, kind);
339 });
340 } catch (ex, s) {
341 diagnoseCrashInUserCode(
342 'Uncaught exception in diagnostic handler', ex, s);
343 rethrow;
344 }
345 }
346
347 Future callUserProvider(Uri uri) {
348 try {
349 return userProviderTask.measure(() => provider(uri));
350 } catch (ex, s) {
351 diagnoseCrashInUserCode('Uncaught exception in input provider', ex, s);
352 rethrow;
353 }
354 }
355
356 void diagnoseCrashInUserCode(String message, exception, stackTrace) {
357 hasCrashed = true;
358 print('$message: ${tryToString(exception)}');
359 print(tryToString(stackTrace));
360 }
361
362 fromEnvironment(String name) => environment[name];
363 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/README.txt ('k') | sdk/lib/_internal/compiler/implementation/cache_strategy.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698