| 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 dart2js.compiler_base; | 5 library dart2js.compiler_base; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import '../compiler_new.dart' as api; | 9 import '../compiler_new.dart' as api; |
| 10 import 'closure.dart' as closureMapping show ClosureTask; | 10 import 'closure.dart' as closureMapping show ClosureTask; |
| 11 import 'common/names.dart' show Selectors; | 11 import 'common/names.dart' show Selectors; |
| 12 import 'common/names.dart' show Identifiers, Uris; | 12 import 'common/names.dart' show Uris; |
| 13 import 'common/resolution.dart' | 13 import 'common/resolution.dart' |
| 14 show | 14 show |
| 15 ParsingContext, | 15 ParsingContext, |
| 16 Resolution, | 16 Resolution, |
| 17 ResolutionWorkItem, | 17 ResolutionWorkItem, |
| 18 ResolutionImpact, | 18 ResolutionImpact, |
| 19 Target; | 19 Target; |
| 20 import 'common/tasks.dart' show CompilerTask, GenericTask, Measurer; | 20 import 'common/tasks.dart' show CompilerTask, GenericTask, Measurer; |
| 21 import 'common/work.dart' show WorkItem; | 21 import 'common/work.dart' show WorkItem; |
| 22 import 'common.dart'; | 22 import 'common.dart'; |
| 23 import 'compile_time_constants.dart'; | 23 import 'compile_time_constants.dart'; |
| 24 import 'constants/values.dart'; | 24 import 'constants/values.dart'; |
| 25 import 'common_elements.dart' show CommonElements, ElementEnvironment; | 25 import 'common_elements.dart' show CommonElements, ElementEnvironment; |
| 26 import 'deferred_load.dart' show DeferredLoadTask; | 26 import 'deferred_load.dart' show DeferredLoadTask; |
| 27 import 'diagnostics/code_location.dart'; | 27 import 'diagnostics/code_location.dart'; |
| 28 import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter; | 28 import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter; |
| 29 import 'diagnostics/invariant.dart' show REPORT_EXCESS_RESOLUTION; | 29 import 'diagnostics/invariant.dart' show REPORT_EXCESS_RESOLUTION; |
| 30 import 'diagnostics/messages.dart' show Message, MessageTemplate; | 30 import 'diagnostics/messages.dart' show Message, MessageTemplate; |
| 31 import 'dump_info.dart' show DumpInfoTask; | 31 import 'dump_info.dart' show DumpInfoTask; |
| 32 import 'elements/elements.dart'; | 32 import 'elements/elements.dart'; |
| 33 import 'elements/entities.dart'; | 33 import 'elements/entities.dart'; |
| 34 import 'elements/modelx.dart' show ErroneousElementX; | |
| 35 import 'elements/resolution_types.dart' show ResolutionDartType, Types; | 34 import 'elements/resolution_types.dart' show ResolutionDartType, Types; |
| 36 import 'elements/types.dart' show DartTypes; | 35 import 'elements/types.dart' show DartTypes; |
| 37 import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer; | 36 import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer; |
| 38 import 'environment.dart'; | 37 import 'environment.dart'; |
| 39 import 'frontend_strategy.dart'; | 38 import 'frontend_strategy.dart'; |
| 40 import 'id_generator.dart'; | 39 import 'id_generator.dart'; |
| 41 import 'io/source_information.dart' show SourceInformation; | 40 import 'io/source_information.dart' show SourceInformation; |
| 42 import 'js_backend/backend.dart' show JavaScriptBackend; | 41 import 'js_backend/backend.dart' show JavaScriptBackend; |
| 43 import 'kernel/kernel_strategy.dart'; | 42 import 'kernel/kernel_strategy.dart'; |
| 44 import 'library_loader.dart' | 43 import 'library_loader.dart' |
| (...skipping 14 matching lines...) Expand all Loading... |
| 59 import 'resolved_uri_translator.dart'; | 58 import 'resolved_uri_translator.dart'; |
| 60 import 'scanner/scanner_task.dart' show ScannerTask; | 59 import 'scanner/scanner_task.dart' show ScannerTask; |
| 61 import 'script.dart' show Script; | 60 import 'script.dart' show Script; |
| 62 import 'serialization/task.dart' show SerializationTask; | 61 import 'serialization/task.dart' show SerializationTask; |
| 63 import 'ssa/nodes.dart' show HInstruction; | 62 import 'ssa/nodes.dart' show HInstruction; |
| 64 import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token; | 63 import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token; |
| 65 import 'tokens/token_map.dart' show TokenMap; | 64 import 'tokens/token_map.dart' show TokenMap; |
| 66 import 'tree/tree.dart' show Node, TypeAnnotation; | 65 import 'tree/tree.dart' show Node, TypeAnnotation; |
| 67 import 'typechecker.dart' show TypeCheckerTask; | 66 import 'typechecker.dart' show TypeCheckerTask; |
| 68 import 'types/types.dart' show GlobalTypeInferenceTask; | 67 import 'types/types.dart' show GlobalTypeInferenceTask; |
| 69 import 'universe/call_structure.dart' show CallStructure; | |
| 70 import 'universe/selector.dart' show Selector; | 68 import 'universe/selector.dart' show Selector; |
| 71 import 'universe/world_builder.dart' | 69 import 'universe/world_builder.dart' |
| 72 show ResolutionWorldBuilder, CodegenWorldBuilder; | 70 show ResolutionWorldBuilder, CodegenWorldBuilder; |
| 73 import 'universe/use.dart' show StaticUse, TypeUse; | 71 import 'universe/use.dart' show StaticUse, TypeUse; |
| 74 import 'universe/world_impact.dart' | 72 import 'universe/world_impact.dart' |
| 75 show ImpactStrategy, WorldImpact, WorldImpactBuilderImpl; | 73 show ImpactStrategy, WorldImpact, WorldImpactBuilderImpl; |
| 76 import 'util/util.dart' show Link; | 74 import 'util/util.dart' show Link; |
| 77 import 'world.dart' show ClosedWorld, ClosedWorldRefiner, ClosedWorldImpl; | 75 import 'world.dart' show ClosedWorld, ClosedWorldRefiner, ClosedWorldImpl; |
| 78 | 76 |
| 79 typedef CompilerDiagnosticReporter MakeReporterFunction( | 77 typedef CompilerDiagnosticReporter MakeReporterFunction( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 107 */ | 105 */ |
| 108 bool stopAfterTypeInference = false; | 106 bool stopAfterTypeInference = false; |
| 109 | 107 |
| 110 /// Output provider from user of Compiler API. | 108 /// Output provider from user of Compiler API. |
| 111 api.CompilerOutput userOutputProvider; | 109 api.CompilerOutput userOutputProvider; |
| 112 | 110 |
| 113 List<Uri> librariesToAnalyzeWhenRun; | 111 List<Uri> librariesToAnalyzeWhenRun; |
| 114 | 112 |
| 115 ResolvedUriTranslator get resolvedUriTranslator; | 113 ResolvedUriTranslator get resolvedUriTranslator; |
| 116 | 114 |
| 117 LibraryElement mainApp; | 115 LibraryEntity mainApp; |
| 118 MethodElement mainFunction; | 116 FunctionEntity mainFunction; |
| 119 | 117 |
| 120 DiagnosticReporter get reporter => _reporter; | 118 DiagnosticReporter get reporter => _reporter; |
| 121 ElementEnvironment get elementEnvironment => _elementEnvironment; | 119 ElementEnvironment get elementEnvironment => _elementEnvironment; |
| 122 CommonElements get commonElements => _commonElements; | 120 CommonElements get commonElements => _commonElements; |
| 123 Resolution get resolution => _resolution; | 121 Resolution get resolution => _resolution; |
| 124 ParsingContext get parsingContext => _parsingContext; | 122 ParsingContext get parsingContext => _parsingContext; |
| 125 | 123 |
| 126 // TODO(zarah): Remove this map and incorporate compile-time errors | 124 // TODO(zarah): Remove this map and incorporate compile-time errors |
| 127 // in the model. | 125 // in the model. |
| 128 /// Tracks elements with compile-time errors. | 126 /// Tracks elements with compile-time errors. |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 if (uri != null) { | 457 if (uri != null) { |
| 460 if (options.analyzeOnly) { | 458 if (options.analyzeOnly) { |
| 461 reporter.log('Analyzing $uri (${options.buildId})'); | 459 reporter.log('Analyzing $uri (${options.buildId})'); |
| 462 } else { | 460 } else { |
| 463 reporter.log('Compiling $uri (${options.buildId})'); | 461 reporter.log('Compiling $uri (${options.buildId})'); |
| 464 } | 462 } |
| 465 LoadedLibraries libraries = await libraryLoader.loadLibrary(uri); | 463 LoadedLibraries libraries = await libraryLoader.loadLibrary(uri); |
| 466 processLoadedLibraries(libraries); | 464 processLoadedLibraries(libraries); |
| 467 mainApp = libraries.rootLibrary; | 465 mainApp = libraries.rootLibrary; |
| 468 } | 466 } |
| 469 compileLoadedLibraries(); | 467 compileLoadedLibraries(mainApp); |
| 470 } | |
| 471 | |
| 472 WorldImpact computeMain() { | |
| 473 if (mainApp == null) return const WorldImpact(); | |
| 474 | |
| 475 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | |
| 476 Element main = mainApp.findExported(Identifiers.main); | |
| 477 ErroneousElement errorElement = null; | |
| 478 if (main == null) { | |
| 479 if (options.analyzeOnly) { | |
| 480 if (!analyzeAll) { | |
| 481 errorElement = new ErroneousElementX(MessageKind.CONSIDER_ANALYZE_ALL, | |
| 482 {'main': Identifiers.main}, Identifiers.main, mainApp); | |
| 483 } | |
| 484 } else { | |
| 485 // Compilation requires a main method. | |
| 486 errorElement = new ErroneousElementX(MessageKind.MISSING_MAIN, | |
| 487 {'main': Identifiers.main}, Identifiers.main, mainApp); | |
| 488 } | |
| 489 mainFunction = backend.helperForMissingMain(); | |
| 490 } else if (main.isError && main.isSynthesized) { | |
| 491 if (main is ErroneousElement) { | |
| 492 errorElement = main; | |
| 493 } else { | |
| 494 reporter.internalError(main, 'Problem with ${Identifiers.main}.'); | |
| 495 } | |
| 496 mainFunction = backend.helperForBadMain(); | |
| 497 } else if (!main.isFunction) { | |
| 498 errorElement = new ErroneousElementX(MessageKind.MAIN_NOT_A_FUNCTION, | |
| 499 {'main': Identifiers.main}, Identifiers.main, main); | |
| 500 mainFunction = backend.helperForBadMain(); | |
| 501 } else { | |
| 502 mainFunction = main; | |
| 503 mainFunction.computeType(resolution); | |
| 504 FunctionSignature parameters = mainFunction.functionSignature; | |
| 505 if (parameters.requiredParameterCount > 2) { | |
| 506 int index = 0; | |
| 507 parameters.orderedForEachParameter((Element parameter) { | |
| 508 if (index++ < 2) return; | |
| 509 errorElement = new ErroneousElementX( | |
| 510 MessageKind.MAIN_WITH_EXTRA_PARAMETER, | |
| 511 {'main': Identifiers.main}, | |
| 512 Identifiers.main, | |
| 513 parameter); | |
| 514 // Don't warn about main not being used: | |
| 515 impactBuilder.registerStaticUse( | |
| 516 new StaticUse.staticInvoke(mainFunction, CallStructure.NO_ARGS)); | |
| 517 | |
| 518 mainFunction = backend.helperForMainArity(); | |
| 519 }); | |
| 520 } | |
| 521 } | |
| 522 if (mainFunction == null) { | |
| 523 if (errorElement == null && !options.analyzeOnly && !analyzeAll) { | |
| 524 reporter.internalError(mainApp, "Problem with '${Identifiers.main}'."); | |
| 525 } else { | |
| 526 mainFunction = errorElement; | |
| 527 } | |
| 528 } | |
| 529 if (errorElement != null && | |
| 530 errorElement.isSynthesized && | |
| 531 !mainApp.isSynthesized) { | |
| 532 reporter.reportWarningMessage(errorElement, errorElement.messageKind, | |
| 533 errorElement.messageArguments); | |
| 534 } | |
| 535 return impactBuilder; | |
| 536 } | 468 } |
| 537 | 469 |
| 538 /// Analyze all members of the library in [libraryUri]. | 470 /// Analyze all members of the library in [libraryUri]. |
| 539 /// | 471 /// |
| 540 /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the | 472 /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the |
| 541 /// library has a `part of` tag, assuming it is a part and not a library. | 473 /// library has a `part of` tag, assuming it is a part and not a library. |
| 542 /// | 474 /// |
| 543 /// This operation assumes an unclosed resolution queue and is only supported | 475 /// This operation assumes an unclosed resolution queue and is only supported |
| 544 /// when the '--analyze-main' option is used. | 476 /// when the '--analyze-main' option is used. |
| 545 Future<LibraryElement> analyzeUri(Uri libraryUri, | 477 Future<LibraryElement> analyzeUri(Uri libraryUri, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 569 resolutionEnqueuer = enqueuer.resolution; | 501 resolutionEnqueuer = enqueuer.resolution; |
| 570 } else { | 502 } else { |
| 571 resolutionEnqueuer = enqueuer.createResolutionEnqueuer(); | 503 resolutionEnqueuer = enqueuer.createResolutionEnqueuer(); |
| 572 backend.onResolutionStart(resolutionEnqueuer); | 504 backend.onResolutionStart(resolutionEnqueuer); |
| 573 } | 505 } |
| 574 resolutionEnqueuer.addDeferredActions(libraryLoader.pullDeferredActions()); | 506 resolutionEnqueuer.addDeferredActions(libraryLoader.pullDeferredActions()); |
| 575 return resolutionEnqueuer; | 507 return resolutionEnqueuer; |
| 576 } | 508 } |
| 577 | 509 |
| 578 /// Performs the compilation when all libraries have been loaded. | 510 /// Performs the compilation when all libraries have been loaded. |
| 579 void compileLoadedLibraries() => | 511 void compileLoadedLibraries(LibraryEntity rootLibrary) => |
| 580 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { | 512 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { |
| 581 ResolutionEnqueuer resolutionEnqueuer = startResolution(); | 513 ResolutionEnqueuer resolutionEnqueuer = startResolution(); |
| 582 WorldImpact mainImpact = computeMain(); | 514 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); |
| 515 mainFunction = frontEndStrategy.computeMain(rootLibrary, mainImpact); |
| 583 | 516 |
| 584 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 517 mirrorUsageAnalyzerTask.analyzeUsage(rootLibrary); |
| 585 | 518 |
| 586 // In order to see if a library is deferred, we must compute the | 519 // In order to see if a library is deferred, we must compute the |
| 587 // compile-time constants that are metadata. This means adding | 520 // compile-time constants that are metadata. This means adding |
| 588 // something to the resolution queue. So we cannot wait with | 521 // something to the resolution queue. So we cannot wait with |
| 589 // this until after the resolution queue is processed. | 522 // this until after the resolution queue is processed. |
| 590 deferredLoadTask.beforeResolution(this); | 523 deferredLoadTask.beforeResolution(this); |
| 591 impactStrategy = backend.createImpactStrategy( | 524 impactStrategy = backend.createImpactStrategy( |
| 592 supportDeferredLoad: deferredLoadTask.isProgramSplit, | 525 supportDeferredLoad: deferredLoadTask.isProgramSplit, |
| 593 supportDumpInfo: options.dumpInfo, | 526 supportDumpInfo: options.dumpInfo, |
| 594 supportSerialization: serialization.supportSerialization); | 527 supportSerialization: serialization.supportSerialization); |
| 595 | 528 |
| 596 phase = PHASE_RESOLVING; | 529 phase = PHASE_RESOLVING; |
| 597 resolutionEnqueuer.applyImpact(mainImpact); | 530 resolutionEnqueuer.applyImpact(mainImpact); |
| 598 if (options.resolveOnly) { | 531 if (options.resolveOnly) { |
| 599 libraryLoader.libraries.where((LibraryEntity library) { | 532 libraryLoader.libraries.where((LibraryEntity library) { |
| 600 return !serialization.isDeserialized(library); | 533 return !serialization.isDeserialized(library); |
| 601 }).forEach((LibraryEntity library) { | 534 }).forEach((LibraryEntity library) { |
| 602 reporter.log('Enqueuing ${library.canonicalUri}'); | 535 reporter.log('Enqueuing ${library.canonicalUri}'); |
| 603 resolutionEnqueuer.applyImpact(computeImpactForLibrary(library)); | 536 resolutionEnqueuer.applyImpact(computeImpactForLibrary(library)); |
| 604 }); | 537 }); |
| 605 } else if (analyzeAll) { | 538 } else if (analyzeAll) { |
| 606 libraryLoader.libraries.forEach((LibraryEntity library) { | 539 libraryLoader.libraries.forEach((LibraryEntity library) { |
| 607 reporter.log('Enqueuing ${library.canonicalUri}'); | 540 reporter.log('Enqueuing ${library.canonicalUri}'); |
| 608 resolutionEnqueuer.applyImpact(computeImpactForLibrary(library)); | 541 resolutionEnqueuer.applyImpact(computeImpactForLibrary(library)); |
| 609 }); | 542 }); |
| 610 } else if (options.analyzeMain) { | 543 } else if (options.analyzeMain) { |
| 611 if (mainApp != null) { | 544 if (rootLibrary != null) { |
| 612 resolutionEnqueuer.applyImpact(computeImpactForLibrary(mainApp)); | 545 resolutionEnqueuer |
| 546 .applyImpact(computeImpactForLibrary(rootLibrary)); |
| 613 } | 547 } |
| 614 if (librariesToAnalyzeWhenRun != null) { | 548 if (librariesToAnalyzeWhenRun != null) { |
| 615 for (Uri libraryUri in librariesToAnalyzeWhenRun) { | 549 for (Uri libraryUri in librariesToAnalyzeWhenRun) { |
| 616 resolutionEnqueuer.applyImpact(computeImpactForLibrary( | 550 resolutionEnqueuer.applyImpact(computeImpactForLibrary( |
| 617 libraryLoader.lookupLibrary(libraryUri))); | 551 libraryLoader.lookupLibrary(libraryUri))); |
| 618 } | 552 } |
| 619 } | 553 } |
| 620 } | 554 } |
| 621 resolveLibraryMetadata(); | 555 resolveLibraryMetadata(); |
| 622 reporter.log('Resolving...'); | 556 reporter.log('Resolving...'); |
| 623 MethodElement mainMethod; | |
| 624 if (mainFunction != null && !mainFunction.isMalformed) { | |
| 625 mainFunction.computeType(resolution); | |
| 626 mainMethod = mainFunction; | |
| 627 } | |
| 628 | 557 |
| 629 processQueue(resolutionEnqueuer, mainMethod, libraryLoader.libraries, | 558 processQueue(resolutionEnqueuer, mainFunction, libraryLoader.libraries, |
| 630 onProgress: showResolutionProgress); | 559 onProgress: showResolutionProgress); |
| 631 backend.onResolutionEnd(); | 560 backend.onResolutionEnd(); |
| 632 resolutionEnqueuer.logSummary(reporter.log); | 561 resolutionEnqueuer.logSummary(reporter.log); |
| 633 | 562 |
| 634 _reporter.reportSuppressedMessagesSummary(); | 563 _reporter.reportSuppressedMessagesSummary(); |
| 635 | 564 |
| 636 if (compilationFailed) { | 565 if (compilationFailed) { |
| 637 if (!options.generateCodeWithCompileTimeErrors) return; | 566 if (!options.generateCodeWithCompileTimeErrors) return; |
| 567 if (mainFunction == null) return; |
| 638 if (!backend | 568 if (!backend |
| 639 .enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { | 569 .enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { |
| 640 return; | 570 return; |
| 641 } | 571 } |
| 642 } | 572 } |
| 643 | 573 |
| 644 if (options.resolveOnly && !compilationFailed) { | 574 if (options.resolveOnly && !compilationFailed) { |
| 645 reporter.log('Serializing to ${options.resolutionOutput}'); | 575 reporter.log('Serializing to ${options.resolutionOutput}'); |
| 646 serialization.serializeToSink( | 576 serialization.serializeToSink( |
| 647 userOutputProvider.createOutputSink( | 577 userOutputProvider.createOutputSink( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 669 | 599 |
| 670 Enqueuer codegenEnqueuer = enqueuer.createCodegenEnqueuer(closedWorld); | 600 Enqueuer codegenEnqueuer = enqueuer.createCodegenEnqueuer(closedWorld); |
| 671 _codegenWorldBuilder = codegenEnqueuer.worldBuilder; | 601 _codegenWorldBuilder = codegenEnqueuer.worldBuilder; |
| 672 codegenEnqueuer.applyImpact( | 602 codegenEnqueuer.applyImpact( |
| 673 backend.onCodegenStart(closedWorld, _codegenWorldBuilder)); | 603 backend.onCodegenStart(closedWorld, _codegenWorldBuilder)); |
| 674 if (compileAll) { | 604 if (compileAll) { |
| 675 libraryLoader.libraries.forEach((LibraryEntity library) { | 605 libraryLoader.libraries.forEach((LibraryEntity library) { |
| 676 codegenEnqueuer.applyImpact(computeImpactForLibrary(library)); | 606 codegenEnqueuer.applyImpact(computeImpactForLibrary(library)); |
| 677 }); | 607 }); |
| 678 } | 608 } |
| 679 processQueue(codegenEnqueuer, mainMethod, libraryLoader.libraries, | 609 processQueue(codegenEnqueuer, mainFunction, libraryLoader.libraries, |
| 680 onProgress: showCodegenProgress); | 610 onProgress: showCodegenProgress); |
| 681 codegenEnqueuer.logSummary(reporter.log); | 611 codegenEnqueuer.logSummary(reporter.log); |
| 682 | 612 |
| 683 int programSize = backend.assembleProgram(closedWorld); | 613 int programSize = backend.assembleProgram(closedWorld); |
| 684 | 614 |
| 685 if (options.dumpInfo) { | 615 if (options.dumpInfo) { |
| 686 dumpInfoTask.reportSize(programSize); | 616 dumpInfoTask.reportSize(programSize); |
| 687 dumpInfoTask.dumpInfo(closedWorld); | 617 dumpInfoTask.dumpInfo(closedWorld); |
| 688 } | 618 } |
| 689 | 619 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 } | 690 } |
| 761 }); | 691 }); |
| 762 } | 692 } |
| 763 return impactBuilder; | 693 return impactBuilder; |
| 764 } | 694 } |
| 765 | 695 |
| 766 // Resolves metadata on library elements. This is necessary in order to | 696 // Resolves metadata on library elements. This is necessary in order to |
| 767 // resolve metadata classes referenced only from metadata on library tags. | 697 // resolve metadata classes referenced only from metadata on library tags. |
| 768 // TODO(ahe): Figure out how to do this lazily. | 698 // TODO(ahe): Figure out how to do this lazily. |
| 769 void resolveLibraryMetadata() { | 699 void resolveLibraryMetadata() { |
| 700 if (commonElements.mirrorsLibrary == null) return; |
| 770 for (LibraryElement library in libraryLoader.libraries) { | 701 for (LibraryElement library in libraryLoader.libraries) { |
| 771 if (library.metadata != null) { | 702 if (library.metadata != null) { |
| 772 for (MetadataAnnotation metadata in library.metadata) { | 703 for (MetadataAnnotation metadata in library.metadata) { |
| 773 metadata.ensureResolved(resolution); | 704 metadata.ensureResolved(resolution); |
| 774 } | 705 } |
| 775 } | 706 } |
| 776 } | 707 } |
| 777 } | 708 } |
| 778 | 709 |
| 779 /** | 710 /** |
| 780 * Empty the [enqueuer] queue. | 711 * Empty the [enqueuer] queue. |
| 781 */ | 712 */ |
| 782 void emptyQueue(Enqueuer enqueuer, {void onProgress(Enqueuer enqueuer)}) { | 713 void emptyQueue(Enqueuer enqueuer, {void onProgress(Enqueuer enqueuer)}) { |
| 783 selfTask.measureSubtask("Compiler.emptyQueue", () { | 714 selfTask.measureSubtask("Compiler.emptyQueue", () { |
| 784 enqueuer.forEach((WorkItem work) { | 715 enqueuer.forEach((WorkItem work) { |
| 785 if (onProgress != null) { | 716 if (onProgress != null) { |
| 786 onProgress(enqueuer); | 717 onProgress(enqueuer); |
| 787 } | 718 } |
| 788 reporter.withCurrentElement( | 719 reporter.withCurrentElement( |
| 789 work.element, | 720 work.element, |
| 790 () => selfTask.measureSubtask("world.applyImpact", () { | 721 () => selfTask.measureSubtask("world.applyImpact", () { |
| 791 enqueuer.applyImpact( | 722 enqueuer.applyImpact( |
| 792 selfTask.measureSubtask("work.run", () => work.run()), | 723 selfTask.measureSubtask("work.run", () => work.run()), |
| 793 impactSource: work.element); | 724 impactSource: work.element); |
| 794 })); | 725 })); |
| 795 }); | 726 }); |
| 796 }); | 727 }); |
| 797 } | 728 } |
| 798 | 729 |
| 799 void processQueue(Enqueuer enqueuer, MethodElement mainMethod, | 730 void processQueue(Enqueuer enqueuer, FunctionEntity mainMethod, |
| 800 Iterable<LibraryEntity> libraries, | 731 Iterable<LibraryEntity> libraries, |
| 801 {void onProgress(Enqueuer enqueuer)}) { | 732 {void onProgress(Enqueuer enqueuer)}) { |
| 802 selfTask.measureSubtask("Compiler.processQueue", () { | 733 selfTask.measureSubtask("Compiler.processQueue", () { |
| 803 enqueuer.open(impactStrategy, mainMethod, libraries); | 734 enqueuer.open(impactStrategy, mainMethod, libraries); |
| 804 if (options.verbose) { | 735 if (options.verbose) { |
| 805 progress.reset(); | 736 progress.reset(); |
| 806 } | 737 } |
| 807 emptyQueue(enqueuer, onProgress: onProgress); | 738 emptyQueue(enqueuer, onProgress: onProgress); |
| 808 enqueuer.queueIsClosed = true; | 739 enqueuer.queueIsClosed = true; |
| 809 enqueuer.close(); | 740 enqueuer.close(); |
| 810 // Notify the impact strategy impacts are no longer needed for this | 741 // Notify the impact strategy impacts are no longer needed for this |
| 811 // enqueuer. | 742 // enqueuer. |
| 812 impactStrategy.onImpactUsed(enqueuer.impactUse); | 743 impactStrategy.onImpactUsed(enqueuer.impactUse); |
| 813 backend.onQueueClosed(); | 744 backend.onQueueClosed(); |
| 814 assert(compilationFailed || | 745 assert(compilationFailed || |
| 815 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); | 746 enqueuer.checkNoEnqueuedInvokedInstanceMethods(elementEnvironment)); |
| 816 }); | 747 }); |
| 817 } | 748 } |
| 818 | 749 |
| 819 /** | 750 /** |
| 820 * Perform various checks of the queues. This includes checking that | 751 * Perform various checks of the queues. This includes checking that |
| 821 * the queues are empty (nothing was added after we stopped | 752 * the queues are empty (nothing was added after we stopped |
| 822 * processing the queues). Also compute the number of methods that | 753 * processing the queues). Also compute the number of methods that |
| 823 * were resolved, but not compiled (aka excess resolution). | 754 * were resolved, but not compiled (aka excess resolution). |
| 824 */ | 755 */ |
| 825 checkQueues(Enqueuer resolutionEnqueuer, Enqueuer codegenEnqueuer) { | 756 checkQueues(Enqueuer resolutionEnqueuer, Enqueuer codegenEnqueuer) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 } | 928 } |
| 998 | 929 |
| 999 /// Associate [element] with a compile-time error [message]. | 930 /// Associate [element] with a compile-time error [message]. |
| 1000 void registerCompileTimeError(Element element, DiagnosticMessage message) { | 931 void registerCompileTimeError(Element element, DiagnosticMessage message) { |
| 1001 // The information is only needed if [generateCodeWithCompileTimeErrors]. | 932 // The information is only needed if [generateCodeWithCompileTimeErrors]. |
| 1002 if (options.generateCodeWithCompileTimeErrors) { | 933 if (options.generateCodeWithCompileTimeErrors) { |
| 1003 if (element == null) { | 934 if (element == null) { |
| 1004 // Record as global error. | 935 // Record as global error. |
| 1005 // TODO(zarah): Extend element model to represent compile-time | 936 // TODO(zarah): Extend element model to represent compile-time |
| 1006 // errors instead of using a map. | 937 // errors instead of using a map. |
| 1007 element = mainFunction; | 938 element = mainFunction as MethodElement; |
| 1008 } | 939 } |
| 1009 elementsWithCompileTimeErrors | 940 elementsWithCompileTimeErrors |
| 1010 .putIfAbsent(element, () => <DiagnosticMessage>[]) | 941 .putIfAbsent(element, () => <DiagnosticMessage>[]) |
| 1011 .add(message); | 942 .add(message); |
| 1012 } | 943 } |
| 1013 } | 944 } |
| 1014 | 945 |
| 1015 api.OutputSink outputProvider( | 946 api.OutputSink outputProvider( |
| 1016 String name, String extension, api.OutputType type) { | 947 String name, String extension, api.OutputType type) { |
| 1017 if (compilationFailed) { | 948 if (compilationFailed) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1029 /// Information about suppressed warnings and hints for a given library. | 960 /// Information about suppressed warnings and hints for a given library. |
| 1030 class SuppressionInfo { | 961 class SuppressionInfo { |
| 1031 int warnings = 0; | 962 int warnings = 0; |
| 1032 int hints = 0; | 963 int hints = 0; |
| 1033 } | 964 } |
| 1034 | 965 |
| 1035 class CompilerDiagnosticReporter extends DiagnosticReporter { | 966 class CompilerDiagnosticReporter extends DiagnosticReporter { |
| 1036 final Compiler compiler; | 967 final Compiler compiler; |
| 1037 final DiagnosticOptions options; | 968 final DiagnosticOptions options; |
| 1038 | 969 |
| 1039 Element _currentElement; | 970 Entity _currentElement; |
| 1040 bool hasCrashed = false; | 971 bool hasCrashed = false; |
| 1041 | 972 |
| 1042 /// `true` if the last diagnostic was filtered, in which case the | 973 /// `true` if the last diagnostic was filtered, in which case the |
| 1043 /// accompanying info message should be filtered as well. | 974 /// accompanying info message should be filtered as well. |
| 1044 bool lastDiagnosticWasFiltered = false; | 975 bool lastDiagnosticWasFiltered = false; |
| 1045 | 976 |
| 1046 /// Map containing information about the warnings and hints that have been | 977 /// Map containing information about the warnings and hints that have been |
| 1047 /// suppressed for each library. | 978 /// suppressed for each library. |
| 1048 Map<Uri, SuppressionInfo> suppressedWarnings = <Uri, SuppressionInfo>{}; | 979 Map<Uri, SuppressionInfo> suppressedWarnings = <Uri, SuppressionInfo>{}; |
| 1049 | 980 |
| 1050 CompilerDiagnosticReporter(this.compiler, this.options); | 981 CompilerDiagnosticReporter(this.compiler, this.options); |
| 1051 | 982 |
| 1052 Element get currentElement => _currentElement; | 983 Entity get currentElement => _currentElement; |
| 1053 | 984 |
| 1054 DiagnosticMessage createMessage(Spannable spannable, MessageKind messageKind, | 985 DiagnosticMessage createMessage(Spannable spannable, MessageKind messageKind, |
| 1055 [Map arguments = const {}]) { | 986 [Map arguments = const {}]) { |
| 1056 SourceSpan span = spanFromSpannable(spannable); | 987 SourceSpan span = spanFromSpannable(spannable); |
| 1057 MessageTemplate template = MessageTemplate.TEMPLATES[messageKind]; | 988 MessageTemplate template = MessageTemplate.TEMPLATES[messageKind]; |
| 1058 Message message = template.message(arguments, options.terseDiagnostics); | 989 Message message = template.message(arguments, options.terseDiagnostics); |
| 1059 return new DiagnosticMessage(span, spannable, message); | 990 return new DiagnosticMessage(span, spannable, message); |
| 1060 } | 991 } |
| 1061 | 992 |
| 1062 void reportError(DiagnosticMessage message, | 993 void reportError(DiagnosticMessage message, |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1135 } | 1066 } |
| 1136 | 1067 |
| 1137 @override | 1068 @override |
| 1138 bool get hasReportedError => compiler.compilationFailed; | 1069 bool get hasReportedError => compiler.compilationFailed; |
| 1139 | 1070 |
| 1140 /** | 1071 /** |
| 1141 * Perform an operation, [f], returning the return value from [f]. If an | 1072 * Perform an operation, [f], returning the return value from [f]. If an |
| 1142 * error occurs then report it as having occurred during compilation of | 1073 * error occurs then report it as having occurred during compilation of |
| 1143 * [element]. Can be nested. | 1074 * [element]. Can be nested. |
| 1144 */ | 1075 */ |
| 1145 withCurrentElement(Element element, f()) { | 1076 withCurrentElement(Entity element, f()) { |
| 1146 Element old = currentElement; | 1077 Entity old = currentElement; |
| 1147 _currentElement = element; | 1078 _currentElement = element; |
| 1148 try { | 1079 try { |
| 1149 return f(); | 1080 return f(); |
| 1150 } on SpannableAssertionFailure catch (ex) { | 1081 } on SpannableAssertionFailure catch (ex) { |
| 1151 if (!hasCrashed) { | 1082 if (!hasCrashed) { |
| 1152 reportAssertionFailure(ex); | 1083 reportAssertionFailure(ex); |
| 1153 pleaseReportCrash(); | 1084 pleaseReportCrash(); |
| 1154 } | 1085 } |
| 1155 hasCrashed = true; | 1086 hasCrashed = true; |
| 1156 rethrow; | 1087 rethrow; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1184 SourceSpan spanFromToken(Token token) => spanFromTokens(token, token); | 1115 SourceSpan spanFromToken(Token token) => spanFromTokens(token, token); |
| 1185 | 1116 |
| 1186 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { | 1117 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { |
| 1187 if (begin == null || end == null) { | 1118 if (begin == null || end == null) { |
| 1188 // TODO(ahe): We can almost always do better. Often it is only | 1119 // TODO(ahe): We can almost always do better. Often it is only |
| 1189 // end that is null. Otherwise, we probably know the current | 1120 // end that is null. Otherwise, we probably know the current |
| 1190 // URI. | 1121 // URI. |
| 1191 throw 'Cannot find tokens to produce error message.'; | 1122 throw 'Cannot find tokens to produce error message.'; |
| 1192 } | 1123 } |
| 1193 if (uri == null && currentElement != null) { | 1124 if (uri == null && currentElement != null) { |
| 1194 uri = currentElement.compilationUnit.script.resourceUri; | 1125 if (currentElement is! Element) { |
| 1126 throw 'Can only find tokens from an Element.'; |
| 1127 } |
| 1128 Element element = currentElement; |
| 1129 uri = element.compilationUnit.script.resourceUri; |
| 1195 assert(invariant(currentElement, () { | 1130 assert(invariant(currentElement, () { |
| 1196 bool sameToken(Token token, Token sought) { | 1131 bool sameToken(Token token, Token sought) { |
| 1197 if (token == sought) return true; | 1132 if (token == sought) return true; |
| 1198 if (token.stringValue == '>>') { | 1133 if (token.stringValue == '>>') { |
| 1199 // `>>` is converted to `>` in the parser when needed. | 1134 // `>>` is converted to `>` in the parser when needed. |
| 1200 return sought.stringValue == '>' && | 1135 return sought.stringValue == '>' && |
| 1201 token.charOffset <= sought.charOffset && | 1136 token.charOffset <= sought.charOffset && |
| 1202 sought.charOffset < token.charEnd; | 1137 sought.charOffset < token.charEnd; |
| 1203 } | 1138 } |
| 1204 return false; | 1139 return false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1221 return true; | 1156 return true; |
| 1222 } | 1157 } |
| 1223 if (token == to || token == token.next || token.next == null) { | 1158 if (token == to || token == token.next || token.next == null) { |
| 1224 break; | 1159 break; |
| 1225 } | 1160 } |
| 1226 token = token.next; | 1161 token = token.next; |
| 1227 } | 1162 } |
| 1228 | 1163 |
| 1229 // Create a good message for when the tokens were not found. | 1164 // Create a good message for when the tokens were not found. |
| 1230 StringBuffer sb = new StringBuffer(); | 1165 StringBuffer sb = new StringBuffer(); |
| 1231 sb.write('Invalid current element: $currentElement. '); | 1166 sb.write('Invalid current element: $element. '); |
| 1232 sb.write('Looking for '); | 1167 sb.write('Looking for '); |
| 1233 sb.write('[${begin} (${begin.hashCode}),'); | 1168 sb.write('[${begin} (${begin.hashCode}),'); |
| 1234 sb.write('${end} (${end.hashCode})] in'); | 1169 sb.write('${end} (${end.hashCode})] in'); |
| 1235 | 1170 |
| 1236 token = from; | 1171 token = from; |
| 1237 while (true) { | 1172 while (true) { |
| 1238 sb.write('\n ${token} (${token.hashCode})'); | 1173 sb.write('\n ${token} (${token.hashCode})'); |
| 1239 if (token == to || token == token.next || token.next == null) { | 1174 if (token == to || token == token.next || token.next == null) { |
| 1240 break; | 1175 break; |
| 1241 } | 1176 } |
| 1242 token = token.next; | 1177 token = token.next; |
| 1243 } | 1178 } |
| 1244 return sb.toString(); | 1179 return sb.toString(); |
| 1245 } | 1180 } |
| 1246 | 1181 |
| 1247 if (currentElement.enclosingClass != null && | 1182 if (element.enclosingClass != null && |
| 1248 currentElement.enclosingClass.isEnumClass) { | 1183 element.enclosingClass.isEnumClass) { |
| 1249 // Enums ASTs are synthesized (and give messed up messages). | 1184 // Enums ASTs are synthesized (and give messed up messages). |
| 1250 return true; | 1185 return true; |
| 1251 } | 1186 } |
| 1252 | 1187 |
| 1253 if (currentElement is AstElement) { | 1188 if (element is AstElement) { |
| 1254 AstElement astElement = currentElement; | 1189 AstElement astElement = element; |
| 1255 if (astElement.hasNode) { | 1190 if (astElement.hasNode) { |
| 1256 Token from = astElement.node.getBeginToken(); | 1191 Token from = astElement.node.getBeginToken(); |
| 1257 Token to = astElement.node.getEndToken(); | 1192 Token to = astElement.node.getEndToken(); |
| 1258 if (astElement.metadata.isNotEmpty) { | 1193 if (astElement.metadata.isNotEmpty) { |
| 1259 if (!astElement.metadata.first.hasNode) { | 1194 if (!astElement.metadata.first.hasNode) { |
| 1260 // We might try to report an error while parsing the metadata | 1195 // We might try to report an error while parsing the metadata |
| 1261 // itself. | 1196 // itself. |
| 1262 return true; | 1197 return true; |
| 1263 } | 1198 } |
| 1264 from = astElement.metadata.first.node.getBeginToken(); | 1199 from = astElement.metadata.first.node.getBeginToken(); |
| 1265 } | 1200 } |
| 1266 return validateToken(from, to); | 1201 return validateToken(from, to); |
| 1267 } | 1202 } |
| 1268 } | 1203 } |
| 1269 return true; | 1204 return true; |
| 1270 }, message: "Invalid current element: $currentElement [$begin,$end].")); | 1205 }, message: "Invalid current element: $element [$begin,$end].")); |
| 1271 } | 1206 } |
| 1272 return new SourceSpan.fromTokens(uri, begin, end); | 1207 return new SourceSpan.fromTokens(uri, begin, end); |
| 1273 } | 1208 } |
| 1274 | 1209 |
| 1275 SourceSpan spanFromNode(Node node) { | 1210 SourceSpan spanFromNode(Node node) { |
| 1276 return spanFromTokens(node.getBeginToken(), node.getPrefixEndToken()); | 1211 return spanFromTokens(node.getBeginToken(), node.getPrefixEndToken()); |
| 1277 } | 1212 } |
| 1278 | 1213 |
| 1279 SourceSpan spanFromElement(Element element) { | 1214 SourceSpan spanFromElement(Element element) { |
| 1280 if (element != null && element.sourcePosition != null) { | 1215 if (element != null && element.sourcePosition != null) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 | 1290 |
| 1356 internalError(Spannable node, reason) { | 1291 internalError(Spannable node, reason) { |
| 1357 String message = tryToString(reason); | 1292 String message = tryToString(reason); |
| 1358 reportDiagnosticInternal( | 1293 reportDiagnosticInternal( |
| 1359 createMessage(node, MessageKind.GENERIC, {'text': message}), | 1294 createMessage(node, MessageKind.GENERIC, {'text': message}), |
| 1360 const <DiagnosticMessage>[], | 1295 const <DiagnosticMessage>[], |
| 1361 api.Diagnostic.CRASH); | 1296 api.Diagnostic.CRASH); |
| 1362 throw 'Internal Error: $message'; | 1297 throw 'Internal Error: $message'; |
| 1363 } | 1298 } |
| 1364 | 1299 |
| 1365 void unhandledExceptionOnElement(Element element) { | 1300 void unhandledExceptionOnElement(Entity element) { |
| 1366 if (hasCrashed) return; | 1301 if (hasCrashed) return; |
| 1367 hasCrashed = true; | 1302 hasCrashed = true; |
| 1368 reportDiagnostic(createMessage(element, MessageKind.COMPILER_CRASHED), | 1303 reportDiagnostic(createMessage(element, MessageKind.COMPILER_CRASHED), |
| 1369 const <DiagnosticMessage>[], api.Diagnostic.CRASH); | 1304 const <DiagnosticMessage>[], api.Diagnostic.CRASH); |
| 1370 pleaseReportCrash(); | 1305 pleaseReportCrash(); |
| 1371 } | 1306 } |
| 1372 | 1307 |
| 1373 void pleaseReportCrash() { | 1308 void pleaseReportCrash() { |
| 1374 print(MessageTemplate.TEMPLATES[MessageKind.PLEASE_REPORT_THE_CRASH] | 1309 print(MessageTemplate.TEMPLATES[MessageKind.PLEASE_REPORT_THE_CRASH] |
| 1375 .message({'buildId': compiler.options.buildId})); | 1310 .message({'buildId': compiler.options.buildId})); |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1742 _ElementScanner(this.scanner); | 1677 _ElementScanner(this.scanner); |
| 1743 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); | 1678 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); |
| 1744 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); | 1679 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); |
| 1745 } | 1680 } |
| 1746 | 1681 |
| 1747 class _EmptyEnvironment implements Environment { | 1682 class _EmptyEnvironment implements Environment { |
| 1748 const _EmptyEnvironment(); | 1683 const _EmptyEnvironment(); |
| 1749 | 1684 |
| 1750 String valueOf(String key) => null; | 1685 String valueOf(String key) => null; |
| 1751 } | 1686 } |
| OLD | NEW |