OLD | NEW |
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 '../compiler_new.dart' as api; |
| 11 import 'dart2jslib.dart' as leg; |
| 12 import 'tree/tree.dart' as tree; |
| 13 import 'elements/elements.dart' as elements; |
| 14 import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES; |
| 15 import 'package:sdk_library_metadata/libraries.dart' as library_info show LIBRAR
IES; |
| 16 import 'io/source_file.dart'; |
10 import 'package:package_config/packages.dart'; | 17 import 'package:package_config/packages.dart'; |
11 import 'package:package_config/packages_file.dart' as pkgs; | 18 import 'package:package_config/packages_file.dart' as pkgs; |
12 import 'package:package_config/src/packages_impl.dart' | 19 import 'package:package_config/src/packages_impl.dart' |
13 show NonFilePackagesDirectoryPackages, MapPackages; | 20 show NonFilePackagesDirectoryPackages, MapPackages; |
14 import 'package:package_config/src/util.dart' show checkValidPackageUri; | 21 import 'package:package_config/src/util.dart' show checkValidPackageUri; |
15 import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES; | |
16 import 'package:sdk_library_metadata/libraries.dart' as library_info show LIBRAR
IES; | |
17 | |
18 import '../compiler_new.dart' as api; | |
19 import 'dart2jslib.dart' as leg; | |
20 import 'elements/elements.dart' as elements; | |
21 import 'io/source_file.dart'; | |
22 import 'messages.dart'; | |
23 import 'script.dart'; | |
24 import 'tree/tree.dart' as tree; | |
25 import 'util/util.dart' show | |
26 NO_LOCATION_SPANNABLE, | |
27 Spannable; | |
28 | 22 |
29 const bool forceIncrementalSupport = | 23 const bool forceIncrementalSupport = |
30 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); | 24 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); |
31 | 25 |
32 class Compiler extends leg.Compiler { | 26 class Compiler extends leg.Compiler { |
33 api.CompilerInput provider; | 27 api.CompilerInput provider; |
34 api.CompilerDiagnostics handler; | 28 api.CompilerDiagnostics handler; |
35 final Uri libraryRoot; | 29 final Uri libraryRoot; |
36 final Uri packageConfig; | 30 final Uri packageConfig; |
37 final Uri packageRoot; | 31 final Uri packageRoot; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 Uri resolvedUri, tree.Node node) { | 206 Uri resolvedUri, tree.Node node) { |
213 if (resolvedUri.scheme == 'dart') { | 207 if (resolvedUri.scheme == 'dart') { |
214 return translateDartUri(importingLibrary, resolvedUri, node); | 208 return translateDartUri(importingLibrary, resolvedUri, node); |
215 } | 209 } |
216 return resolvedUri; | 210 return resolvedUri; |
217 } | 211 } |
218 | 212 |
219 /** | 213 /** |
220 * Reads the script designated by [readableUri]. | 214 * Reads the script designated by [readableUri]. |
221 */ | 215 */ |
222 Future<Script> readScript(Spannable node, Uri readableUri) { | 216 Future<leg.Script> readScript(leg.Spannable node, Uri readableUri) { |
223 if (!readableUri.isAbsolute) { | 217 if (!readableUri.isAbsolute) { |
224 if (node == null) node = NO_LOCATION_SPANNABLE; | 218 if (node == null) node = leg.NO_LOCATION_SPANNABLE; |
225 internalError(node, | 219 internalError(node, |
226 'Relative uri $readableUri provided to readScript(Uri).'); | 220 'Relative uri $readableUri provided to readScript(Uri).'); |
227 } | 221 } |
228 | 222 |
229 // We need to store the current element since we are reporting read errors | 223 // We need to store the current element since we are reporting read errors |
230 // asynchronously and therefore need to restore the current element for | 224 // asynchronously and therefore need to restore the current element for |
231 // [node] to be valid. | 225 // [node] to be valid. |
232 elements.Element element = currentElement; | 226 elements.Element element = currentElement; |
233 void reportReadError(exception) { | 227 void reportReadError(exception) { |
234 if (element == null || node == null) { | 228 if (element == null || node == null) { |
235 reportError( | 229 reportError( |
236 new leg.SourceSpan(readableUri, 0, 0), | 230 new leg.SourceSpan(readableUri, 0, 0), |
237 MessageKind.READ_SELF_ERROR, | 231 leg.MessageKind.READ_SELF_ERROR, |
238 {'uri': readableUri, 'exception': exception}); | 232 {'uri': readableUri, 'exception': exception}); |
239 } else { | 233 } else { |
240 withCurrentElement(element, () { | 234 withCurrentElement(element, () { |
241 reportError( | 235 reportError( |
242 node, | 236 node, |
243 MessageKind.READ_SCRIPT_ERROR, | 237 leg.MessageKind.READ_SCRIPT_ERROR, |
244 {'uri': readableUri, 'exception': exception}); | 238 {'uri': readableUri, 'exception': exception}); |
245 }); | 239 }); |
246 } | 240 } |
247 } | 241 } |
248 | 242 |
249 Uri resourceUri = translateUri(node, readableUri); | 243 Uri resourceUri = translateUri(node, readableUri); |
250 if (resourceUri == null) return synthesizeScript(node, readableUri); | 244 if (resourceUri == null) return synthesizeScript(node, readableUri); |
251 if (resourceUri.scheme == 'dart-ext') { | 245 if (resourceUri.scheme == 'dart-ext') { |
252 if (!allowNativeExtensions) { | 246 if (!allowNativeExtensions) { |
253 withCurrentElement(element, () { | 247 withCurrentElement(element, () { |
254 reportError(node, MessageKind.DART_EXT_NOT_SUPPORTED); | 248 reportError(node, leg.MessageKind.DART_EXT_NOT_SUPPORTED); |
255 }); | 249 }); |
256 } | 250 } |
257 return synthesizeScript(node, readableUri); | 251 return synthesizeScript(node, readableUri); |
258 } | 252 } |
259 | 253 |
260 // TODO(johnniwinther): Wrap the result from [provider] in a specialized | 254 // TODO(johnniwinther): Wrap the result from [provider] in a specialized |
261 // [Future] to ensure that we never execute an asynchronous action without | 255 // [Future] to ensure that we never execute an asynchronous action without |
262 // setting up the current element of the compiler. | 256 // setting up the current element of the compiler. |
263 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { | 257 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { |
264 SourceFile sourceFile; | 258 SourceFile sourceFile; |
265 if (data is List<int>) { | 259 if (data is List<int>) { |
266 sourceFile = new Utf8BytesSourceFile(resourceUri, data); | 260 sourceFile = new Utf8BytesSourceFile(resourceUri, data); |
267 } else if (data is String) { | 261 } else if (data is String) { |
268 sourceFile = new StringSourceFile.fromUri(resourceUri, data); | 262 sourceFile = new StringSourceFile.fromUri(resourceUri, data); |
269 } else { | 263 } else { |
270 String message = "Expected a 'String' or a 'List<int>' from the input " | 264 String message = "Expected a 'String' or a 'List<int>' from the input " |
271 "provider, but got: ${Error.safeToString(data)}."; | 265 "provider, but got: ${Error.safeToString(data)}."; |
272 reportReadError(message); | 266 reportReadError(message); |
273 } | 267 } |
274 // We use [readableUri] as the URI for the script since need to preserve | 268 // We use [readableUri] as the URI for the script since need to preserve |
275 // the scheme in the script because [Script.uri] is used for resolving | 269 // the scheme in the script because [Script.uri] is used for resolving |
276 // relative URIs mentioned in the script. See the comment on | 270 // relative URIs mentioned in the script. See the comment on |
277 // [LibraryLoader] for more details. | 271 // [LibraryLoader] for more details. |
278 return new Script(readableUri, resourceUri, sourceFile); | 272 return new leg.Script(readableUri, resourceUri, sourceFile); |
279 }).catchError((error) { | 273 }).catchError((error) { |
280 reportReadError(error); | 274 reportReadError(error); |
281 return synthesizeScript(node, readableUri); | 275 return synthesizeScript(node, readableUri); |
282 }); | 276 }); |
283 } | 277 } |
284 | 278 |
285 Future<Script> synthesizeScript(Spannable node, Uri readableUri) { | 279 Future<leg.Script> synthesizeScript(leg.Spannable node, Uri readableUri) { |
286 return new Future.value( | 280 return new Future.value( |
287 new Script( | 281 new leg.Script( |
288 readableUri, readableUri, | 282 readableUri, readableUri, |
289 new StringSourceFile.fromUri( | 283 new StringSourceFile.fromUri( |
290 readableUri, | 284 readableUri, |
291 "// Synthetic source file generated for '$readableUri'."), | 285 "// Synthetic source file generated for '$readableUri'."), |
292 isSynthesized: true)); | 286 isSynthesized: true)); |
293 } | 287 } |
294 | 288 |
295 /** | 289 /** |
296 * Translates a readable URI into a resource URI. | 290 * Translates a readable URI into a resource URI. |
297 * | 291 * |
298 * See [LibraryLoader] for terminology on URIs. | 292 * See [LibraryLoader] for terminology on URIs. |
299 */ | 293 */ |
300 Uri translateUri(Spannable node, Uri readableUri) { | 294 Uri translateUri(leg.Spannable node, Uri readableUri) { |
301 switch (readableUri.scheme) { | 295 switch (readableUri.scheme) { |
302 case 'package': return translatePackageUri(node, readableUri); | 296 case 'package': return translatePackageUri(node, readableUri); |
303 default: return readableUri; | 297 default: return readableUri; |
304 } | 298 } |
305 } | 299 } |
306 | 300 |
307 Uri translateDartUri(elements.LibraryElement importingLibrary, | 301 Uri translateDartUri(elements.LibraryElement importingLibrary, |
308 Uri resolvedUri, tree.Node node) { | 302 Uri resolvedUri, tree.Node node) { |
309 LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); | 303 LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); |
310 String path = lookupLibraryPath(libraryInfo); | 304 String path = lookupLibraryPath(libraryInfo); |
311 if (libraryInfo != null && | 305 if (libraryInfo != null && |
312 libraryInfo.category == "Internal") { | 306 libraryInfo.category == "Internal") { |
313 bool allowInternalLibraryAccess = false; | 307 bool allowInternalLibraryAccess = false; |
314 if (importingLibrary != null) { | 308 if (importingLibrary != null) { |
315 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { | 309 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { |
316 allowInternalLibraryAccess = true; | 310 allowInternalLibraryAccess = true; |
317 } else if (importingLibrary.canonicalUri.path.contains( | 311 } else if (importingLibrary.canonicalUri.path.contains( |
318 'sdk/tests/compiler/dart2js_native')) { | 312 'sdk/tests/compiler/dart2js_native')) { |
319 allowInternalLibraryAccess = true; | 313 allowInternalLibraryAccess = true; |
320 } | 314 } |
321 } | 315 } |
322 if (!allowInternalLibraryAccess) { | 316 if (!allowInternalLibraryAccess) { |
323 if (importingLibrary != null) { | 317 if (importingLibrary != null) { |
324 reportError( | 318 reportError( |
325 node, | 319 node, |
326 MessageKind.INTERNAL_LIBRARY_FROM, | 320 leg.MessageKind.INTERNAL_LIBRARY_FROM, |
327 {'resolvedUri': resolvedUri, | 321 {'resolvedUri': resolvedUri, |
328 'importingUri': importingLibrary.canonicalUri}); | 322 'importingUri': importingLibrary.canonicalUri}); |
329 } else { | 323 } else { |
330 reportError( | 324 reportError( |
331 node, | 325 node, |
332 MessageKind.INTERNAL_LIBRARY, | 326 leg.MessageKind.INTERNAL_LIBRARY, |
333 {'resolvedUri': resolvedUri}); | 327 {'resolvedUri': resolvedUri}); |
334 } | 328 } |
335 } | 329 } |
336 } | 330 } |
337 if (path == null) { | 331 if (path == null) { |
338 reportError(node, MessageKind.LIBRARY_NOT_FOUND, | 332 reportError(node, leg.MessageKind.LIBRARY_NOT_FOUND, |
339 {'resolvedUri': resolvedUri}); | 333 {'resolvedUri': resolvedUri}); |
340 return null; | 334 return null; |
341 } | 335 } |
342 if (resolvedUri.path == 'html' || | 336 if (resolvedUri.path == 'html' || |
343 resolvedUri.path == 'io') { | 337 resolvedUri.path == 'io') { |
344 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart | 338 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart |
345 // supports this use case better. | 339 // supports this use case better. |
346 mockableLibraryUsed = true; | 340 mockableLibraryUsed = true; |
347 } | 341 } |
348 return libraryRoot.resolve(path); | 342 return libraryRoot.resolve(path); |
349 } | 343 } |
350 | 344 |
351 Uri resolvePatchUri(String dartLibraryPath) { | 345 Uri resolvePatchUri(String dartLibraryPath) { |
352 String patchPath = lookupPatchPath(dartLibraryPath); | 346 String patchPath = lookupPatchPath(dartLibraryPath); |
353 if (patchPath == null) return null; | 347 if (patchPath == null) return null; |
354 return libraryRoot.resolve(patchPath); | 348 return libraryRoot.resolve(patchPath); |
355 } | 349 } |
356 | 350 |
357 Uri translatePackageUri(Spannable node, Uri uri) { | 351 Uri translatePackageUri(leg.Spannable node, Uri uri) { |
358 try { | 352 try { |
359 checkValidPackageUri(uri); | 353 checkValidPackageUri(uri); |
360 } on ArgumentError catch (e) { | 354 } on ArgumentError catch (e) { |
361 reportError( | 355 reportError( |
362 node, | 356 node, |
363 MessageKind.INVALID_PACKAGE_URI, | 357 leg.MessageKind.INVALID_PACKAGE_URI, |
364 {'uri': uri, 'exception': e.message}); | 358 {'uri': uri, 'exception': e.message}); |
365 return null; | 359 return null; |
366 } | 360 } |
367 return packages.resolve(uri, | 361 return packages.resolve(uri, |
368 notFound: (Uri notFound) { | 362 notFound: (Uri notFound) { |
369 reportError( | 363 reportError( |
370 node, | 364 node, |
371 MessageKind.LIBRARY_NOT_FOUND, | 365 leg.MessageKind.LIBRARY_NOT_FOUND, |
372 {'resolvedUri': uri} | 366 {'resolvedUri': uri} |
373 ); | 367 ); |
374 return null; | 368 return null; |
375 }); | 369 }); |
376 } | 370 } |
377 | 371 |
378 Future setupPackages(Uri uri) { | 372 Future setupPackages(Uri uri) { |
379 if (packageRoot != null) { | 373 if (packageRoot != null) { |
380 // Use "non-file" packages because the file version requires a [Directory] | 374 // Use "non-file" packages because the file version requires a [Directory] |
381 // and we can't depend on 'dart:io' classes. | 375 // and we can't depend on 'dart:io' classes. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 } | 410 } |
417 } | 411 } |
418 int total = totalCompileTime.elapsedMilliseconds; | 412 int total = totalCompileTime.elapsedMilliseconds; |
419 log('Total compile-time ${total}msec;' | 413 log('Total compile-time ${total}msec;' |
420 ' unaccounted ${total - cumulated}msec'); | 414 ' unaccounted ${total - cumulated}msec'); |
421 return success; | 415 return success; |
422 }); | 416 }); |
423 }); | 417 }); |
424 } | 418 } |
425 | 419 |
426 void reportDiagnostic(Spannable node, | 420 void reportDiagnostic(leg.Spannable node, |
427 Message message, | 421 leg.Message message, |
428 api.Diagnostic kind) { | 422 api.Diagnostic kind) { |
429 leg.SourceSpan span = spanFromSpannable(node); | 423 leg.SourceSpan span = spanFromSpannable(node); |
430 if (identical(kind, api.Diagnostic.ERROR) | 424 if (identical(kind, api.Diagnostic.ERROR) |
431 || identical(kind, api.Diagnostic.CRASH) | 425 || identical(kind, api.Diagnostic.CRASH) |
432 || (fatalWarnings && identical(kind, api.Diagnostic.WARNING))) { | 426 || (fatalWarnings && identical(kind, api.Diagnostic.WARNING))) { |
433 compilationFailed = true; | 427 compilationFailed = true; |
434 } | 428 } |
435 // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For | 429 // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For |
436 // instance in the [Types] constructor in typechecker.dart. | 430 // instance in the [Types] constructor in typechecker.dart. |
437 if (span == null || span.uri == null) { | 431 if (span == null || span.uri == null) { |
438 callUserHandler(message, null, null, null, '$message', kind); | 432 callUserHandler(message, null, null, null, '$message', kind); |
439 } else { | 433 } else { |
440 callUserHandler( | 434 callUserHandler( |
441 message, span.uri, span.begin, span.end, '$message', kind); | 435 message, span.uri, span.begin, span.end, '$message', kind); |
442 } | 436 } |
443 } | 437 } |
444 | 438 |
445 bool get isMockCompilation { | 439 bool get isMockCompilation { |
446 return mockableLibraryUsed | 440 return mockableLibraryUsed |
447 && (options.indexOf('--allow-mock-compilation') != -1); | 441 && (options.indexOf('--allow-mock-compilation') != -1); |
448 } | 442 } |
449 | 443 |
450 void callUserHandler(Message message, Uri uri, int begin, int end, | 444 void callUserHandler(leg.Message message, Uri uri, int begin, int end, |
451 String text, api.Diagnostic kind) { | 445 String text, api.Diagnostic kind) { |
452 try { | 446 try { |
453 userHandlerTask.measure(() { | 447 userHandlerTask.measure(() { |
454 handler.report(message, uri, begin, end, text, kind); | 448 handler.report(message, uri, begin, end, text, kind); |
455 }); | 449 }); |
456 } catch (ex, s) { | 450 } catch (ex, s) { |
457 diagnoseCrashInUserCode( | 451 diagnoseCrashInUserCode( |
458 'Uncaught exception in diagnostic handler', ex, s); | 452 'Uncaught exception in diagnostic handler', ex, s); |
459 rethrow; | 453 rethrow; |
460 } | 454 } |
(...skipping 23 matching lines...) Expand all Loading... |
484 print('$message: ${tryToString(exception)}'); | 478 print('$message: ${tryToString(exception)}'); |
485 print(tryToString(stackTrace)); | 479 print(tryToString(stackTrace)); |
486 } | 480 } |
487 | 481 |
488 fromEnvironment(String name) => environment[name]; | 482 fromEnvironment(String name) => environment[name]; |
489 | 483 |
490 LibraryInfo lookupLibraryInfo(String libraryName) { | 484 LibraryInfo lookupLibraryInfo(String libraryName) { |
491 return library_info.LIBRARIES[libraryName]; | 485 return library_info.LIBRARIES[libraryName]; |
492 } | 486 } |
493 } | 487 } |
OLD | NEW |