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 '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 import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES; | 17 import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES; |
18 import 'package:sdk_library_metadata/libraries.dart' as library_info show | 18 import 'package:sdk_library_metadata/libraries.dart' as library_info show |
19 LIBRARIES; | 19 LIBRARIES; |
20 | 20 |
21 import '../compiler_new.dart' as api; | 21 import '../compiler_new.dart' as api; |
22 import 'commandline_options.dart'; | 22 import 'commandline_options.dart'; |
23 import 'common/tasks.dart' show | 23 import 'common/tasks.dart' show |
24 GenericTask; | 24 GenericTask; |
25 import 'compiler.dart' as leg; | 25 import 'compiler.dart' as leg; |
| 26 import 'diagnostics/diagnostic_listener.dart' show |
| 27 DiagnosticMessage; |
26 import 'diagnostics/messages.dart'; | 28 import 'diagnostics/messages.dart'; |
27 import 'diagnostics/source_span.dart' show | 29 import 'diagnostics/source_span.dart' show |
28 SourceSpan; | 30 SourceSpan; |
29 import 'diagnostics/spannable.dart' show | 31 import 'diagnostics/spannable.dart' show |
30 NO_LOCATION_SPANNABLE, | 32 NO_LOCATION_SPANNABLE, |
31 Spannable; | 33 Spannable; |
32 import 'elements/elements.dart' as elements; | 34 import 'elements/elements.dart' as elements; |
33 import 'io/source_file.dart'; | 35 import 'io/source_file.dart'; |
34 import 'script.dart'; | 36 import 'script.dart'; |
35 import 'tree/tree.dart' as tree; | |
36 | 37 |
37 const bool forceIncrementalSupport = | 38 const bool forceIncrementalSupport = |
38 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); | 39 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); |
39 | 40 |
40 class Compiler extends leg.Compiler { | 41 class Compiler extends leg.Compiler { |
41 api.CompilerInput provider; | 42 api.CompilerInput provider; |
42 api.CompilerDiagnostics handler; | 43 api.CompilerDiagnostics handler; |
43 final Uri libraryRoot; | 44 final Uri libraryRoot; |
44 final Uri packageConfig; | 45 final Uri packageConfig; |
45 final Uri packageRoot; | 46 final Uri packageRoot; |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 internalError(node, | 240 internalError(node, |
240 'Relative uri $readableUri provided to readScript(Uri).'); | 241 'Relative uri $readableUri provided to readScript(Uri).'); |
241 } | 242 } |
242 | 243 |
243 // We need to store the current element since we are reporting read errors | 244 // We need to store the current element since we are reporting read errors |
244 // asynchronously and therefore need to restore the current element for | 245 // asynchronously and therefore need to restore the current element for |
245 // [node] to be valid. | 246 // [node] to be valid. |
246 elements.Element element = currentElement; | 247 elements.Element element = currentElement; |
247 void reportReadError(exception) { | 248 void reportReadError(exception) { |
248 if (element == null || node == null) { | 249 if (element == null || node == null) { |
249 reportError( | 250 reportErrorMessage( |
250 new SourceSpan(readableUri, 0, 0), | 251 new SourceSpan(readableUri, 0, 0), |
251 MessageKind.READ_SELF_ERROR, | 252 MessageKind.READ_SELF_ERROR, |
252 {'uri': readableUri, 'exception': exception}); | 253 {'uri': readableUri, 'exception': exception}); |
253 } else { | 254 } else { |
254 withCurrentElement(element, () { | 255 withCurrentElement(element, () { |
255 reportError( | 256 reportErrorMessage( |
256 node, | 257 node, |
257 MessageKind.READ_SCRIPT_ERROR, | 258 MessageKind.READ_SCRIPT_ERROR, |
258 {'uri': readableUri, 'exception': exception}); | 259 {'uri': readableUri, 'exception': exception}); |
259 }); | 260 }); |
260 } | 261 } |
261 } | 262 } |
262 | 263 |
263 Uri resourceUri = translateUri(node, readableUri); | 264 Uri resourceUri = translateUri(node, readableUri); |
264 if (resourceUri == null) return synthesizeScript(node, readableUri); | 265 if (resourceUri == null) return synthesizeScript(node, readableUri); |
265 if (resourceUri.scheme == 'dart-ext') { | 266 if (resourceUri.scheme == 'dart-ext') { |
266 if (!allowNativeExtensions) { | 267 if (!allowNativeExtensions) { |
267 withCurrentElement(element, () { | 268 withCurrentElement(element, () { |
268 reportError(node, MessageKind.DART_EXT_NOT_SUPPORTED); | 269 reportErrorMessage( |
| 270 node, MessageKind.DART_EXT_NOT_SUPPORTED); |
269 }); | 271 }); |
270 } | 272 } |
271 return synthesizeScript(node, readableUri); | 273 return synthesizeScript(node, readableUri); |
272 } | 274 } |
273 | 275 |
274 // TODO(johnniwinther): Wrap the result from [provider] in a specialized | 276 // TODO(johnniwinther): Wrap the result from [provider] in a specialized |
275 // [Future] to ensure that we never execute an asynchronous action without | 277 // [Future] to ensure that we never execute an asynchronous action without |
276 // setting up the current element of the compiler. | 278 // setting up the current element of the compiler. |
277 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { | 279 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { |
278 SourceFile sourceFile; | 280 SourceFile sourceFile; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 if (importingLibrary != null) { | 330 if (importingLibrary != null) { |
329 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { | 331 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { |
330 allowInternalLibraryAccess = true; | 332 allowInternalLibraryAccess = true; |
331 } else if (importingLibrary.canonicalUri.path.contains( | 333 } else if (importingLibrary.canonicalUri.path.contains( |
332 'sdk/tests/compiler/dart2js_native')) { | 334 'sdk/tests/compiler/dart2js_native')) { |
333 allowInternalLibraryAccess = true; | 335 allowInternalLibraryAccess = true; |
334 } | 336 } |
335 } | 337 } |
336 if (!allowInternalLibraryAccess) { | 338 if (!allowInternalLibraryAccess) { |
337 if (importingLibrary != null) { | 339 if (importingLibrary != null) { |
338 reportError( | 340 reportErrorMessage( |
339 spannable, | 341 spannable, |
340 MessageKind.INTERNAL_LIBRARY_FROM, | 342 MessageKind.INTERNAL_LIBRARY_FROM, |
341 {'resolvedUri': resolvedUri, | 343 {'resolvedUri': resolvedUri, |
342 'importingUri': importingLibrary.canonicalUri}); | 344 'importingUri': importingLibrary.canonicalUri}); |
343 } else { | 345 } else { |
344 reportError( | 346 reportErrorMessage( |
345 spannable, | 347 spannable, |
346 MessageKind.INTERNAL_LIBRARY, | 348 MessageKind.INTERNAL_LIBRARY, |
347 {'resolvedUri': resolvedUri}); | 349 {'resolvedUri': resolvedUri}); |
348 } | 350 } |
349 } | 351 } |
350 } | 352 } |
351 if (path == null) { | 353 if (path == null) { |
352 if (libraryInfo == null) { | 354 if (libraryInfo == null) { |
353 reportError(spannable, MessageKind.LIBRARY_NOT_FOUND, | 355 reportErrorMessage( |
354 {'resolvedUri': resolvedUri}); | 356 spannable, |
| 357 MessageKind.LIBRARY_NOT_FOUND, |
| 358 {'resolvedUri': resolvedUri}); |
355 } else { | 359 } else { |
356 reportError(spannable, MessageKind.LIBRARY_NOT_SUPPORTED, | 360 reportErrorMessage( |
357 {'resolvedUri': resolvedUri}); | 361 spannable, |
| 362 MessageKind.LIBRARY_NOT_SUPPORTED, |
| 363 {'resolvedUri': resolvedUri}); |
358 } | 364 } |
359 // TODO(johnniwinther): Support signaling the error through the returned | 365 // TODO(johnniwinther): Support signaling the error through the returned |
360 // value. | 366 // value. |
361 return null; | 367 return null; |
362 } | 368 } |
363 if (resolvedUri.path == 'html' || | 369 if (resolvedUri.path == 'html' || |
364 resolvedUri.path == 'io') { | 370 resolvedUri.path == 'io') { |
365 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart | 371 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart |
366 // supports this use case better. | 372 // supports this use case better. |
367 mockableLibraryUsed = true; | 373 mockableLibraryUsed = true; |
368 } | 374 } |
369 return libraryRoot.resolve(path); | 375 return libraryRoot.resolve(path); |
370 } | 376 } |
371 | 377 |
372 Uri resolvePatchUri(String dartLibraryPath) { | 378 Uri resolvePatchUri(String dartLibraryPath) { |
373 String patchPath = lookupPatchPath(dartLibraryPath); | 379 String patchPath = lookupPatchPath(dartLibraryPath); |
374 if (patchPath == null) return null; | 380 if (patchPath == null) return null; |
375 return libraryRoot.resolve(patchPath); | 381 return libraryRoot.resolve(patchPath); |
376 } | 382 } |
377 | 383 |
378 Uri translatePackageUri(Spannable node, Uri uri) { | 384 Uri translatePackageUri(Spannable node, Uri uri) { |
379 try { | 385 try { |
380 checkValidPackageUri(uri); | 386 checkValidPackageUri(uri); |
381 } on ArgumentError catch (e) { | 387 } on ArgumentError catch (e) { |
382 reportError( | 388 reportErrorMessage( |
383 node, | 389 node, |
384 MessageKind.INVALID_PACKAGE_URI, | 390 MessageKind.INVALID_PACKAGE_URI, |
385 {'uri': uri, 'exception': e.message}); | 391 {'uri': uri, 'exception': e.message}); |
386 return null; | 392 return null; |
387 } | 393 } |
388 return packages.resolve(uri, | 394 return packages.resolve(uri, |
389 notFound: (Uri notFound) { | 395 notFound: (Uri notFound) { |
390 reportError( | 396 reportErrorMessage( |
391 node, | 397 node, |
392 MessageKind.LIBRARY_NOT_FOUND, | 398 MessageKind.LIBRARY_NOT_FOUND, |
393 {'resolvedUri': uri} | 399 {'resolvedUri': uri}); |
394 ); | |
395 return null; | 400 return null; |
396 }); | 401 }); |
397 } | 402 } |
398 | 403 |
399 Future<elements.LibraryElement> analyzeUri( | 404 Future<elements.LibraryElement> analyzeUri( |
400 Uri uri, | 405 Uri uri, |
401 {bool skipLibraryWithPartOfTag: true}) { | 406 {bool skipLibraryWithPartOfTag: true}) { |
402 if (packages == null) { | 407 if (packages == null) { |
403 return setupPackages(uri).then((_) => super.analyzeUri(uri)); | 408 return setupPackages(uri).then((_) => super.analyzeUri(uri)); |
404 } | 409 } |
(...skipping 14 matching lines...) Expand all Loading... |
419 // The input provider may put a trailing 0 byte when it reads a source | 424 // The input provider may put a trailing 0 byte when it reads a source |
420 // file, which confuses the package config parser. | 425 // file, which confuses the package config parser. |
421 if (packageConfigContents.length > 0 && | 426 if (packageConfigContents.length > 0 && |
422 packageConfigContents.last == 0) { | 427 packageConfigContents.last == 0) { |
423 packageConfigContents = packageConfigContents.sublist( | 428 packageConfigContents = packageConfigContents.sublist( |
424 0, packageConfigContents.length - 1); | 429 0, packageConfigContents.length - 1); |
425 } | 430 } |
426 packages = | 431 packages = |
427 new MapPackages(pkgs.parse(packageConfigContents, packageConfig)); | 432 new MapPackages(pkgs.parse(packageConfigContents, packageConfig)); |
428 }).catchError((error) { | 433 }).catchError((error) { |
429 reportError(NO_LOCATION_SPANNABLE, MessageKind.INVALID_PACKAGE_CONFIG, | 434 reportErrorMessage( |
| 435 NO_LOCATION_SPANNABLE, |
| 436 MessageKind.INVALID_PACKAGE_CONFIG, |
430 {'uri': packageConfig, 'exception': error}); | 437 {'uri': packageConfig, 'exception': error}); |
431 packages = Packages.noPackages; | 438 packages = Packages.noPackages; |
432 }); | 439 }); |
433 } else { | 440 } else { |
434 if (packagesDiscoveryProvider == null) { | 441 if (packagesDiscoveryProvider == null) { |
435 packages = Packages.noPackages; | 442 packages = Packages.noPackages; |
436 } else { | 443 } else { |
437 return callUserPackagesDiscovery(uri).then((p) { | 444 return callUserPackagesDiscovery(uri).then((p) { |
438 packages = p; | 445 packages = p; |
439 }); | 446 }); |
(...skipping 18 matching lines...) Expand all Loading... |
458 } | 465 } |
459 } | 466 } |
460 int total = totalCompileTime.elapsedMilliseconds; | 467 int total = totalCompileTime.elapsedMilliseconds; |
461 log('Total compile-time ${total}msec;' | 468 log('Total compile-time ${total}msec;' |
462 ' unaccounted ${total - cumulated}msec'); | 469 ' unaccounted ${total - cumulated}msec'); |
463 return success; | 470 return success; |
464 }); | 471 }); |
465 }); | 472 }); |
466 } | 473 } |
467 | 474 |
468 void reportDiagnostic(Spannable node, | 475 void reportDiagnostic(DiagnosticMessage message, |
469 Message message, | 476 List<DiagnosticMessage> infos, |
470 api.Diagnostic kind) { | 477 api.Diagnostic kind) { |
471 SourceSpan span = spanFromSpannable(node); | 478 if (kind == api.Diagnostic.ERROR || |
472 if (identical(kind, api.Diagnostic.ERROR) | 479 kind == api.Diagnostic.CRASH || |
473 || identical(kind, api.Diagnostic.CRASH) | 480 (fatalWarnings && kind == api.Diagnostic.WARNING)) { |
474 || (fatalWarnings && identical(kind, api.Diagnostic.WARNING))) { | |
475 compilationFailed = true; | 481 compilationFailed = true; |
476 } | 482 } |
| 483 _reportDiagnosticMessage(message, kind); |
| 484 for (DiagnosticMessage info in infos) { |
| 485 _reportDiagnosticMessage(info, api.Diagnostic.INFO); |
| 486 } |
| 487 } |
| 488 |
| 489 void _reportDiagnosticMessage(DiagnosticMessage diagnosticMessage, |
| 490 api.Diagnostic kind) { |
477 // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For | 491 // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For |
478 // instance in the [Types] constructor in typechecker.dart. | 492 // instance in the [Types] constructor in typechecker.dart. |
| 493 SourceSpan span = diagnosticMessage.sourceSpan; |
| 494 Message message = diagnosticMessage.message; |
479 if (span == null || span.uri == null) { | 495 if (span == null || span.uri == null) { |
480 callUserHandler(message, null, null, null, '$message', kind); | 496 callUserHandler(message, null, null, null, '$message', kind); |
481 } else { | 497 } else { |
482 callUserHandler( | 498 callUserHandler( |
483 message, span.uri, span.begin, span.end, '$message', kind); | 499 message, span.uri, span.begin, span.end, '$message', kind); |
484 } | 500 } |
485 } | 501 } |
486 | 502 |
487 bool get isMockCompilation { | 503 bool get isMockCompilation { |
488 return mockableLibraryUsed | 504 return mockableLibraryUsed |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 print('$message: ${tryToString(exception)}'); | 542 print('$message: ${tryToString(exception)}'); |
527 print(tryToString(stackTrace)); | 543 print(tryToString(stackTrace)); |
528 } | 544 } |
529 | 545 |
530 fromEnvironment(String name) => environment[name]; | 546 fromEnvironment(String name) => environment[name]; |
531 | 547 |
532 LibraryInfo lookupLibraryInfo(String libraryName) { | 548 LibraryInfo lookupLibraryInfo(String libraryName) { |
533 return library_info.LIBRARIES[libraryName]; | 549 return library_info.LIBRARIES[libraryName]; |
534 } | 550 } |
535 } | 551 } |
OLD | NEW |