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

Side by Side Diff: pkg/compiler/lib/src/apiimpl.dart

Issue 1819053002: Split loader from the rest of the compiler. This adds several abstractions to (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: add environment.dart Created 4 years, 9 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/compiler.dart » ('j') | pkg/compiler/lib/src/compiler.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library leg_apiimpl; 5 library leg_apiimpl;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 9
10 import 'package:package_config/packages.dart'; 10 import 'package:package_config/packages.dart';
11 import 'package:package_config/packages_file.dart' as pkgs; 11 import 'package:package_config/packages_file.dart' as pkgs;
12 import 'package:package_config/src/packages_impl.dart' show 12 import 'package:package_config/src/packages_impl.dart' show
13 MapPackages, 13 MapPackages,
14 NonFilePackagesDirectoryPackages; 14 NonFilePackagesDirectoryPackages;
15 import 'package:package_config/src/util.dart' show 15 import 'package:package_config/src/util.dart' show
16 checkValidPackageUri; 16 checkValidPackageUri;
17 17
18 import '../compiler_new.dart' as api; 18 import '../compiler_new.dart' as api;
19 import 'commandline_options.dart'; 19 import 'commandline_options.dart';
20 import 'common.dart'; 20 import 'common.dart';
21 import 'common/tasks.dart' show 21 import 'common/tasks.dart' show
22 GenericTask; 22 GenericTask;
23 import 'compiler.dart'; 23 import 'compiler.dart';
24 import 'diagnostics/diagnostic_listener.dart' show 24 import 'diagnostics/diagnostic_listener.dart' show
25 DiagnosticOptions; 25 DiagnosticOptions;
26 import 'diagnostics/messages.dart' show 26 import 'diagnostics/messages.dart' show
27 Message; 27 Message;
28 import 'elements/elements.dart' as elements; 28 import 'elements/elements.dart' as elements;
29 import 'environment.dart';
29 import 'io/source_file.dart'; 30 import 'io/source_file.dart';
30 import 'platform_configuration.dart' as platform_configuration; 31 import 'platform_configuration.dart' as platform_configuration;
31 import 'script.dart'; 32 import 'script.dart';
32 33
33 /// For every 'dart:' library, a corresponding environment variable is set
34 /// to "true". The environment variable's name is the concatenation of
35 /// this prefix and the name (without the 'dart:'.
36 ///
37 /// For example 'dart:html' has the environment variable 'dart.library.html' set
38 /// to "true".
39 const String dartLibraryEnvironmentPrefix = 'dart.library.';
40
41 34
42 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the 35 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the
43 /// sources. 36 /// sources.
44 class CompilerImpl extends Compiler { 37 class CompilerImpl extends Compiler {
45 api.CompilerInput provider; 38 api.CompilerInput provider;
46 api.CompilerDiagnostics handler; 39 api.CompilerDiagnostics handler;
47 Packages packages; 40 Packages packages;
48 bool mockableLibraryUsed = false; 41 bool mockableLibraryUsed = false;
49 42
50 /// A mapping of the dart: library-names to their location. 43 /// A mapping of the dart: library-names to their location.
51 /// 44 ///
52 /// Initialized in [setupSdk]. 45 /// Initialized in [setupSdk].
53 Map<String, Uri> sdkLibraries; 46 Map<String, Uri> sdkLibraries;
54 47
55 GenericTask userHandlerTask; 48 GenericTask userHandlerTask;
56 GenericTask userProviderTask; 49 GenericTask userProviderTask;
57 GenericTask userPackagesDiscoveryTask; 50 GenericTask userPackagesDiscoveryTask;
58 51
59 Uri get libraryRoot => options.platformConfigUri.resolve("."); 52 Uri get libraryRoot => options.platformConfigUri.resolve(".");
60 53
61 CompilerImpl(this.provider, api.CompilerOutput outputProvider, 54 CompilerImpl(this.provider, api.CompilerOutput outputProvider,
62 this.handler, api.CompilerOptions options) 55 this.handler, api.CompilerOptions options)
63 : super(options: options, outputProvider: outputProvider) { 56 : super(options: options, outputProvider: outputProvider,
57 environment: new _Environment(options.environment)) {
58 _Environment env = environment;
59 env.compiler = this;
64 tasks.addAll([ 60 tasks.addAll([
65 userHandlerTask = new GenericTask('Diagnostic handler', this), 61 userHandlerTask = new GenericTask('Diagnostic handler', this),
66 userProviderTask = new GenericTask('Input provider', this), 62 userProviderTask = new GenericTask('Input provider', this),
67 userPackagesDiscoveryTask = 63 userPackagesDiscoveryTask =
68 new GenericTask('Package discovery', this), 64 new GenericTask('Package discovery', this),
69 ]); 65 ]);
70 } 66 }
71 67
72 68
73 void log(message) { 69 void log(message) {
74 callUserHandler( 70 callUserHandler(
75 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO); 71 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
76 } 72 }
77 73
78 /// See [Compiler.translateResolvedUri]. 74 /// See [Compiler.translateResolvedUri].
79 Uri translateResolvedUri(elements.LibraryElement importingLibrary, 75 Uri translateResolvedUri(elements.LibraryElement importingLibrary,
80 Uri resolvedUri, Spannable spannable) { 76 Uri resolvedUri, Spannable spannable) {
81 if (resolvedUri.scheme == 'dart') { 77 if (resolvedUri.scheme == 'dart') {
82 return translateDartUri(importingLibrary, resolvedUri, spannable); 78 return translateDartUri(importingLibrary, resolvedUri, spannable);
83 } 79 }
84 return resolvedUri; 80 return resolvedUri;
85 } 81 }
86 82
87 /** 83 /**
88 * Reads the script designated by [readableUri]. 84 * Reads the script designated by [readableUri].
89 */ 85 */
90 Future<Script> readScript(Spannable node, Uri readableUri) { 86 Future<Script> readScript(Uri readableUri, [Spannable node]) {
91 if (!readableUri.isAbsolute) { 87 if (!readableUri.isAbsolute) {
92 if (node == null) node = NO_LOCATION_SPANNABLE; 88 if (node == null) node = NO_LOCATION_SPANNABLE;
93 reporter.internalError(node, 89 reporter.internalError(node,
94 'Relative uri $readableUri provided to readScript(Uri).'); 90 'Relative uri $readableUri provided to readScript(Uri).');
95 } 91 }
96 92
97 // We need to store the current element since we are reporting read errors 93 // We need to store the current element since we are reporting read errors
98 // asynchronously and therefore need to restore the current element for 94 // asynchronously and therefore need to restore the current element for
99 // [node] to be valid. 95 // [node] to be valid.
100 elements.Element element = currentElement; 96 elements.Element element = currentElement;
101 void reportReadError(exception) { 97 void reportReadError(exception) {
102 if (element == null || node == null) { 98 if (element == null || node == null) {
103 reporter.reportErrorMessage( 99 reporter.reportErrorMessage(
104 new SourceSpan(readableUri, 0, 0), 100 new SourceSpan(readableUri, 0, 0),
105 MessageKind.READ_SELF_ERROR, 101 MessageKind.READ_SELF_ERROR,
106 {'uri': readableUri, 'exception': exception}); 102 {'uri': readableUri, 'exception': exception});
107 } else { 103 } else {
108 reporter.withCurrentElement(element, () { 104 reporter.withCurrentElement(element, () {
109 reporter.reportErrorMessage( 105 reporter.reportErrorMessage(
110 node, 106 node,
111 MessageKind.READ_SCRIPT_ERROR, 107 MessageKind.READ_SCRIPT_ERROR,
112 {'uri': readableUri, 'exception': exception}); 108 {'uri': readableUri, 'exception': exception});
113 }); 109 });
114 } 110 }
115 } 111 }
116 112
117 Uri resourceUri = translateUri(node, readableUri); 113 Uri resourceUri = translateUri(node, readableUri);
118 if (resourceUri == null) return synthesizeScript(node, readableUri); 114 if (resourceUri == null) return _synthesizeScript(readableUri);
119 if (resourceUri.scheme == 'dart-ext') { 115 if (resourceUri.scheme == 'dart-ext') {
120 if (!options.allowNativeExtensions) { 116 if (!options.allowNativeExtensions) {
121 reporter.withCurrentElement(element, () { 117 reporter.withCurrentElement(element, () {
122 reporter.reportErrorMessage( 118 reporter.reportErrorMessage(
123 node, MessageKind.DART_EXT_NOT_SUPPORTED); 119 node, MessageKind.DART_EXT_NOT_SUPPORTED);
124 }); 120 });
125 } 121 }
126 return synthesizeScript(node, readableUri); 122 return _synthesizeScript(readableUri);
127 } 123 }
128 124
129 // TODO(johnniwinther): Wrap the result from [provider] in a specialized 125 // TODO(johnniwinther): Wrap the result from [provider] in a specialized
130 // [Future] to ensure that we never execute an asynchronous action without 126 // [Future] to ensure that we never execute an asynchronous action without
131 // setting up the current element of the compiler. 127 // setting up the current element of the compiler.
132 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { 128 return new Future.sync(() => callUserProvider(resourceUri)).then((data) {
133 SourceFile sourceFile; 129 SourceFile sourceFile;
134 if (data is List<int>) { 130 if (data is List<int>) {
135 sourceFile = new Utf8BytesSourceFile(resourceUri, data); 131 sourceFile = new Utf8BytesSourceFile(resourceUri, data);
136 } else if (data is String) { 132 } else if (data is String) {
137 sourceFile = new StringSourceFile.fromUri(resourceUri, data); 133 sourceFile = new StringSourceFile.fromUri(resourceUri, data);
138 } else { 134 } else {
139 String message = "Expected a 'String' or a 'List<int>' from the input " 135 String message = "Expected a 'String' or a 'List<int>' from the input "
140 "provider, but got: ${Error.safeToString(data)}."; 136 "provider, but got: ${Error.safeToString(data)}.";
141 reportReadError(message); 137 reportReadError(message);
142 } 138 }
143 // We use [readableUri] as the URI for the script since need to preserve 139 // We use [readableUri] as the URI for the script since need to preserve
144 // the scheme in the script because [Script.uri] is used for resolving 140 // the scheme in the script because [Script.uri] is used for resolving
145 // relative URIs mentioned in the script. See the comment on 141 // relative URIs mentioned in the script. See the comment on
146 // [LibraryLoader] for more details. 142 // [LibraryLoader] for more details.
147 return new Script(readableUri, resourceUri, sourceFile); 143 return new Script(readableUri, resourceUri, sourceFile);
148 }).catchError((error) { 144 }).catchError((error) {
149 reportReadError(error); 145 reportReadError(error);
150 return synthesizeScript(node, readableUri); 146 return _synthesizeScript(readableUri);
151 }); 147 });
152 } 148 }
153 149
154 Future<Script> synthesizeScript(Spannable node, Uri readableUri) { 150 Future<Script> _synthesizeScript(Uri readableUri) {
155 return new Future.value( 151 return new Future.value(new Script.synthetic(readableUri));
156 new Script(
157 readableUri, readableUri,
158 new StringSourceFile.fromUri(
159 readableUri,
160 "// Synthetic source file generated for '$readableUri'."),
161 isSynthesized: true));
162 } 152 }
163 153
164 /** 154 /**
165 * Translates a readable URI into a resource URI. 155 * Translates a readable URI into a resource URI.
166 * 156 *
167 * See [LibraryLoader] for terminology on URIs. 157 * See [LibraryLoader] for terminology on URIs.
168 */ 158 */
169 Uri translateUri(Spannable node, Uri readableUri) { 159 Uri translateUri(Spannable node, Uri uri) =>
170 switch (readableUri.scheme) { 160 uri.scheme == 'package' ? translatePackageUri(node, uri) : uri;
171 case 'package': return translatePackageUri(node, readableUri);
172 default: return readableUri;
173 }
174 }
175 161
176 /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative 162 /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
177 /// to `options.platformConfigUri` according to the information in the file at 163 /// to `options.platformConfigUri` according to the information in the file at
178 /// `options.platformConfigUri`. 164 /// `options.platformConfigUri`.
179 /// 165 ///
180 /// Returns null and emits an error if the library could not be found or 166 /// Returns null and emits an error if the library could not be found or
181 /// imported into [importingLibrary]. 167 /// imported into [importingLibrary].
182 /// 168 ///
183 /// Internal libraries (whose name starts with '_') can be only resolved if 169 /// Internal libraries (whose name starts with '_') can be only resolved if
184 /// [importingLibrary] is a platform or patch library. 170 /// [importingLibrary] is a platform or patch library.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 callUserHandler( 359 callUserHandler(
374 message, span.uri, span.begin, span.end, '$message', kind); 360 message, span.uri, span.begin, span.end, '$message', kind);
375 } 361 }
376 } 362 }
377 363
378 bool get isMockCompilation => 364 bool get isMockCompilation =>
379 mockableLibraryUsed && options.allowMockCompilation; 365 mockableLibraryUsed && options.allowMockCompilation;
380 366
381 void callUserHandler(Message message, Uri uri, int begin, int end, 367 void callUserHandler(Message message, Uri uri, int begin, int end,
382 String text, api.Diagnostic kind) { 368 String text, api.Diagnostic kind) {
383 try { 369 userHandlerTask.measure(() {
384 userHandlerTask.measure(() { 370 handler.report(message, uri, begin, end, text, kind);
385 handler.report(message, uri, begin, end, text, kind); 371 });
386 });
387 } catch (ex, s) {
388 diagnoseCrashInUserCode(
389 'Uncaught exception in diagnostic handler', ex, s);
390 rethrow;
391 }
392 } 372 }
393 373
394 Future callUserProvider(Uri uri) { 374 Future callUserProvider(Uri uri) {
395 try { 375 return userProviderTask.measure(() => provider.readFromUri(uri));
396 return userProviderTask.measure(() => provider.readFromUri(uri));
397 } catch (ex, s) {
398 diagnoseCrashInUserCode('Uncaught exception in input provider', ex, s);
399 rethrow;
400 }
401 } 376 }
402 377
403 Future<Packages> callUserPackagesDiscovery(Uri uri) { 378 Future<Packages> callUserPackagesDiscovery(Uri uri) {
404 try { 379 return userPackagesDiscoveryTask.measure(
405 return userPackagesDiscoveryTask.measure( 380 () => options.packagesDiscoveryProvider(uri));
406 () => options.packagesDiscoveryProvider(uri));
407 } catch (ex, s) {
408 diagnoseCrashInUserCode('Uncaught exception in package discovery', ex, s);
409 rethrow;
410 }
411 }
412
413 fromEnvironment(String name) {
414 assert(invariant(NO_LOCATION_SPANNABLE,
415 sdkLibraries != null, message: "setupSdk() has not been run"));
416
417 var result = options.environment[name];
418 if (result != null || options.environment.containsKey(name)) return result;
419 if (!name.startsWith(dartLibraryEnvironmentPrefix)) return null;
420
421 String libraryName = name.substring(dartLibraryEnvironmentPrefix.length);
422
423 // Private libraries are not exposed to the users.
424 if (libraryName.startsWith("_")) return null;
425
426 if (sdkLibraries.containsKey(libraryName)) {
427 // Dart2js always "supports" importing 'dart:mirrors' but will abort
428 // the compilation at a later point if the backend doesn't support
429 // mirrors. In this case 'mirrors' should not be in the environment.
430 if (libraryName == 'mirrors') {
431 return backend.supportsReflection ? "true" : null;
432 }
433 return "true";
434 }
435 return null;
436 } 381 }
437 382
438 Uri lookupLibraryUri(String libraryName) { 383 Uri lookupLibraryUri(String libraryName) {
439 assert(invariant(NO_LOCATION_SPANNABLE, 384 assert(invariant(NO_LOCATION_SPANNABLE,
440 sdkLibraries != null, message: "setupSdk() has not been run")); 385 sdkLibraries != null, message: "setupSdk() has not been run"));
441 return sdkLibraries[libraryName]; 386 return sdkLibraries[libraryName];
442 } 387 }
443 388
444 Uri resolvePatchUri(String libraryName) { 389 Uri resolvePatchUri(String libraryName) {
445 return backend.resolvePatchUri(libraryName, options.platformConfigUri); 390 return backend.resolvePatchUri(libraryName, options.platformConfigUri);
446 } 391 }
447 } 392 }
393
394 class _Environment implements Environment {
395 final Map<String, String> definitions;
396
397 // TODO(sigmund): break the circularity here: Compiler needs an environment to
398 // intialize the library loader, but the environment here needs to know about
399 // how the sdk is set up and about whether the backend supports mirrors.
400 CompilerImpl compiler;
401
402 _Environment(this.definitions);
403
404 String valueOf(String name) {
405 assert(invariant(NO_LOCATION_SPANNABLE,
406 compiler.sdkLibraries != null, message: "setupSdk() has not been run"));
407
408 var result = definitions[name];
409 if (result != null || definitions.containsKey(name)) return result;
410 if (!name.startsWith(_dartLibraryEnvironmentPrefix)) return null;
411
412 String libraryName = name.substring(_dartLibraryEnvironmentPrefix.length);
413
414 // Private libraries are not exposed to the users.
415 if (libraryName.startsWith("_")) return null;
416
417 if (compiler.sdkLibraries.containsKey(libraryName)) {
418 // Dart2js always "supports" importing 'dart:mirrors' but will abort
419 // the compilation at a later point if the backend doesn't support
420 // mirrors. In this case 'mirrors' should not be in the environment.
421 if (libraryName == 'mirrors') {
422 return compiler.backend.supportsReflection ? "true" : null;
423 }
424 return "true";
425 }
426 return null;
427 }
428 }
429
430 /// For every 'dart:' library, a corresponding environment variable is set
431 /// to "true". The environment variable's name is the concatenation of
432 /// this prefix and the name (without the 'dart:'.
433 ///
434 /// For example 'dart:html' has the environment variable 'dart.library.html' set
435 /// to "true".
436 const String _dartLibraryEnvironmentPrefix = 'dart.library.';
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/compiler.dart » ('j') | pkg/compiler/lib/src/compiler.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698