| 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 | 7 import 'dart:async' show EventSink, Future; |
| 8 EventSink, | |
| 9 Future; | |
| 10 | 8 |
| 11 import '../compiler_new.dart' as api; | 9 import '../compiler_new.dart' as api; |
| 12 import 'cache_strategy.dart' show | 10 import 'cache_strategy.dart' show CacheStrategy; |
| 13 CacheStrategy; | 11 import 'closure.dart' as closureMapping show ClosureTask; |
| 14 import 'closure.dart' as closureMapping show | |
| 15 ClosureTask; | |
| 16 import 'common.dart'; | 12 import 'common.dart'; |
| 17 import 'common/backend_api.dart' show | 13 import 'common/backend_api.dart' show Backend; |
| 18 Backend; | 14 import 'common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
| 19 import 'common/codegen.dart' show | 15 import 'common/names.dart' show Identifiers, Uris; |
| 20 CodegenImpact, | 16 import 'common/registry.dart' show EagerRegistry, Registry; |
| 21 CodegenWorkItem; | 17 import 'common/resolution.dart' |
| 22 import 'common/names.dart' show | 18 show Parsing, Resolution, ResolutionWorkItem, ResolutionImpact; |
| 23 Identifiers, | 19 import 'common/tasks.dart' show CompilerTask, GenericTask; |
| 24 Uris; | 20 import 'common/work.dart' show ItemCompilationContext, WorkItem; |
| 25 import 'common/registry.dart' show | |
| 26 EagerRegistry, | |
| 27 Registry; | |
| 28 import 'common/resolution.dart' show | |
| 29 Parsing, | |
| 30 Resolution, | |
| 31 ResolutionWorkItem, | |
| 32 ResolutionImpact; | |
| 33 import 'common/tasks.dart' show | |
| 34 CompilerTask, | |
| 35 GenericTask; | |
| 36 import 'common/work.dart' show | |
| 37 ItemCompilationContext, | |
| 38 WorkItem; | |
| 39 import 'compile_time_constants.dart'; | 21 import 'compile_time_constants.dart'; |
| 40 import 'constants/values.dart'; | 22 import 'constants/values.dart'; |
| 41 import 'core_types.dart' show | 23 import 'core_types.dart' show CoreClasses, CoreTypes; |
| 42 CoreClasses, | |
| 43 CoreTypes; | |
| 44 import 'dart_backend/dart_backend.dart' as dart_backend; | 24 import 'dart_backend/dart_backend.dart' as dart_backend; |
| 45 import 'dart_types.dart' show | 25 import 'dart_types.dart' show DartType, DynamicType, InterfaceType, Types; |
| 46 DartType, | |
| 47 DynamicType, | |
| 48 InterfaceType, | |
| 49 Types; | |
| 50 import 'deferred_load.dart' show DeferredLoadTask, OutputUnit; | 26 import 'deferred_load.dart' show DeferredLoadTask, OutputUnit; |
| 51 import 'diagnostics/code_location.dart'; | 27 import 'diagnostics/code_location.dart'; |
| 52 import 'diagnostics/diagnostic_listener.dart' show | 28 import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter; |
| 53 DiagnosticReporter; | 29 import 'diagnostics/invariant.dart' show REPORT_EXCESS_RESOLUTION; |
| 54 import 'diagnostics/invariant.dart' show | 30 import 'diagnostics/messages.dart' show Message, MessageTemplate; |
| 55 REPORT_EXCESS_RESOLUTION; | 31 import 'dump_info.dart' show DumpInfoTask; |
| 56 import 'diagnostics/messages.dart' show | |
| 57 Message, | |
| 58 MessageTemplate; | |
| 59 import 'dump_info.dart' show | |
| 60 DumpInfoTask; | |
| 61 import 'elements/elements.dart'; | 32 import 'elements/elements.dart'; |
| 62 import 'elements/modelx.dart' show | 33 import 'elements/modelx.dart' |
| 63 ErroneousElementX, | 34 show |
| 64 ClassElementX, | 35 ErroneousElementX, |
| 65 CompilationUnitElementX, | 36 ClassElementX, |
| 66 DeferredLoaderGetterElementX, | 37 CompilationUnitElementX, |
| 67 MethodElementX, | 38 DeferredLoaderGetterElementX, |
| 68 LibraryElementX, | 39 MethodElementX, |
| 69 PrefixElementX; | 40 LibraryElementX, |
| 70 import 'enqueue.dart' show | 41 PrefixElementX; |
| 71 CodegenEnqueuer, | 42 import 'enqueue.dart' |
| 72 Enqueuer, | 43 show |
| 73 EnqueueTask, | 44 CodegenEnqueuer, |
| 74 ResolutionEnqueuer, | 45 Enqueuer, |
| 75 QueueFilter; | 46 EnqueueTask, |
| 47 ResolutionEnqueuer, |
| 48 QueueFilter; |
| 76 import 'environment.dart'; | 49 import 'environment.dart'; |
| 77 import 'io/source_information.dart' show | 50 import 'io/source_information.dart' show SourceInformation; |
| 78 SourceInformation; | 51 import 'js_backend/backend_helpers.dart' as js_backend show BackendHelpers; |
| 79 import 'js_backend/backend_helpers.dart' as js_backend show | 52 import 'js_backend/js_backend.dart' as js_backend show JavaScriptBackend; |
| 80 BackendHelpers; | 53 import 'library_loader.dart' |
| 81 import 'js_backend/js_backend.dart' as js_backend show | 54 show |
| 82 JavaScriptBackend; | 55 ElementScanner, |
| 83 import 'library_loader.dart' show | 56 LibraryLoader, |
| 84 ElementScanner, | 57 LibraryLoaderTask, |
| 85 LibraryLoader, | 58 LoadedLibraries, |
| 86 LibraryLoaderTask, | 59 LibraryLoaderListener, |
| 87 LoadedLibraries, | 60 ResolvedUriTranslator, |
| 88 LibraryLoaderListener, | 61 ScriptLoader; |
| 89 ResolvedUriTranslator, | 62 import 'mirrors_used.dart' show MirrorUsageAnalyzerTask; |
| 90 ScriptLoader; | 63 import 'common/names.dart' show Selectors; |
| 91 import 'mirrors_used.dart' show | 64 import 'null_compiler_output.dart' show NullCompilerOutput, NullSink; |
| 92 MirrorUsageAnalyzerTask; | 65 import 'options.dart' show CompilerOptions, DiagnosticOptions, ParserOptions; |
| 93 import 'common/names.dart' show | 66 import 'parser/diet_parser_task.dart' show DietParserTask; |
| 94 Selectors; | 67 import 'parser/element_listener.dart' show ScannerOptions; |
| 95 import 'null_compiler_output.dart' show | 68 import 'parser/parser_task.dart' show ParserTask; |
| 96 NullCompilerOutput, | 69 import 'patch_parser.dart' show PatchParserTask; |
| 97 NullSink; | 70 import 'resolution/registry.dart' show ResolutionRegistry; |
| 98 import 'options.dart' show | 71 import 'resolution/resolution.dart' show ResolverTask; |
| 99 CompilerOptions, | 72 import 'resolution/tree_elements.dart' show TreeElementMapping; |
| 100 DiagnosticOptions, | 73 import 'scanner/scanner_task.dart' show ScannerTask; |
| 101 ParserOptions; | 74 import 'serialization/task.dart' show SerializationTask; |
| 102 import 'parser/diet_parser_task.dart' show | 75 import 'script.dart' show Script; |
| 103 DietParserTask; | 76 import 'ssa/nodes.dart' show HInstruction; |
| 104 import 'parser/element_listener.dart' show | 77 import 'tracer.dart' show Tracer; |
| 105 ScannerOptions; | 78 import 'tokens/token.dart' show StringToken, Token, TokenPair; |
| 106 import 'parser/parser_task.dart' show | 79 import 'tokens/token_constants.dart' as Tokens show COMMENT_TOKEN, EOF_TOKEN; |
| 107 ParserTask; | 80 import 'tokens/token_map.dart' show TokenMap; |
| 108 import 'patch_parser.dart' show | 81 import 'tree/tree.dart' show Node, TypeAnnotation; |
| 109 PatchParserTask; | 82 import 'typechecker.dart' show TypeCheckerTask; |
| 110 import 'resolution/registry.dart' show | |
| 111 ResolutionRegistry; | |
| 112 import 'resolution/resolution.dart' show | |
| 113 ResolverTask; | |
| 114 import 'resolution/tree_elements.dart' show | |
| 115 TreeElementMapping; | |
| 116 import 'scanner/scanner_task.dart' show | |
| 117 ScannerTask; | |
| 118 import 'serialization/task.dart' show | |
| 119 SerializationTask; | |
| 120 import 'script.dart' show | |
| 121 Script; | |
| 122 import 'ssa/nodes.dart' show | |
| 123 HInstruction; | |
| 124 import 'tracer.dart' show | |
| 125 Tracer; | |
| 126 import 'tokens/token.dart' show | |
| 127 StringToken, | |
| 128 Token, | |
| 129 TokenPair; | |
| 130 import 'tokens/token_constants.dart' as Tokens show | |
| 131 COMMENT_TOKEN, | |
| 132 EOF_TOKEN; | |
| 133 import 'tokens/token_map.dart' show | |
| 134 TokenMap; | |
| 135 import 'tree/tree.dart' show | |
| 136 Node, | |
| 137 TypeAnnotation; | |
| 138 import 'typechecker.dart' show | |
| 139 TypeCheckerTask; | |
| 140 import 'types/types.dart' as ti; | 83 import 'types/types.dart' as ti; |
| 141 import 'universe/call_structure.dart' show | 84 import 'universe/call_structure.dart' show CallStructure; |
| 142 CallStructure; | 85 import 'universe/selector.dart' show Selector; |
| 143 import 'universe/selector.dart' show | 86 import 'universe/universe.dart' show Universe; |
| 144 Selector; | 87 import 'universe/use.dart' show StaticUse; |
| 145 import 'universe/universe.dart' show | 88 import 'universe/world_impact.dart' show ImpactStrategy, WorldImpact; |
| 146 Universe; | 89 import 'util/util.dart' show Link, Setlet; |
| 147 import 'universe/use.dart' show | 90 import 'world.dart' show World; |
| 148 StaticUse; | |
| 149 import 'universe/world_impact.dart' show | |
| 150 ImpactStrategy, | |
| 151 WorldImpact; | |
| 152 import 'util/util.dart' show | |
| 153 Link, | |
| 154 Setlet; | |
| 155 import 'world.dart' show | |
| 156 World; | |
| 157 | 91 |
| 158 abstract class Compiler implements LibraryLoaderListener { | 92 abstract class Compiler implements LibraryLoaderListener { |
| 159 | |
| 160 final Stopwatch totalCompileTime = new Stopwatch(); | 93 final Stopwatch totalCompileTime = new Stopwatch(); |
| 161 int nextFreeClassId = 0; | 94 int nextFreeClassId = 0; |
| 162 World world; | 95 World world; |
| 163 Types types; | 96 Types types; |
| 164 _CompilerCoreTypes _coreTypes; | 97 _CompilerCoreTypes _coreTypes; |
| 165 _CompilerDiagnosticReporter _reporter; | 98 _CompilerDiagnosticReporter _reporter; |
| 166 _CompilerResolution _resolution; | 99 _CompilerResolution _resolution; |
| 167 _CompilerParsing _parsing; | 100 _CompilerParsing _parsing; |
| 168 | 101 |
| 169 final CacheStrategy cacheStrategy; | 102 final CacheStrategy cacheStrategy; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 ConstantEnvironment constants; | 250 ConstantEnvironment constants; |
| 318 | 251 |
| 319 EnqueueTask enqueuer; | 252 EnqueueTask enqueuer; |
| 320 DeferredLoadTask deferredLoadTask; | 253 DeferredLoadTask deferredLoadTask; |
| 321 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; | 254 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; |
| 322 DumpInfoTask dumpInfoTask; | 255 DumpInfoTask dumpInfoTask; |
| 323 | 256 |
| 324 /// A customizable filter that is applied to enqueued work items. | 257 /// A customizable filter that is applied to enqueued work items. |
| 325 QueueFilter enqueuerFilter = new QueueFilter(); | 258 QueueFilter enqueuerFilter = new QueueFilter(); |
| 326 | 259 |
| 327 final Selector symbolValidatedConstructorSelector = new Selector.call( | 260 final Selector symbolValidatedConstructorSelector = |
| 328 const PublicName('validated'), CallStructure.ONE_ARG); | 261 new Selector.call(const PublicName('validated'), CallStructure.ONE_ARG); |
| 329 | 262 |
| 330 static const String CREATE_INVOCATION_MIRROR = | 263 static const String CREATE_INVOCATION_MIRROR = 'createInvocationMirror'; |
| 331 'createInvocationMirror'; | |
| 332 | 264 |
| 333 bool enabledRuntimeType = false; | 265 bool enabledRuntimeType = false; |
| 334 bool enabledFunctionApply = false; | 266 bool enabledFunctionApply = false; |
| 335 bool enabledInvokeOn = false; | 267 bool enabledInvokeOn = false; |
| 336 bool hasIsolateSupport = false; | 268 bool hasIsolateSupport = false; |
| 337 | 269 |
| 338 bool get hasCrashed => _reporter.hasCrashed; | 270 bool get hasCrashed => _reporter.hasCrashed; |
| 339 | 271 |
| 340 Stopwatch progress; | 272 Stopwatch progress; |
| 341 | 273 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 353 | 285 |
| 354 bool get compilationFailed => compilationFailedInternal; | 286 bool get compilationFailed => compilationFailedInternal; |
| 355 | 287 |
| 356 void set compilationFailed(bool value) { | 288 void set compilationFailed(bool value) { |
| 357 if (value) { | 289 if (value) { |
| 358 elementsWithCompileTimeErrors.add(currentElement); | 290 elementsWithCompileTimeErrors.add(currentElement); |
| 359 } | 291 } |
| 360 compilationFailedInternal = value; | 292 compilationFailedInternal = value; |
| 361 } | 293 } |
| 362 | 294 |
| 363 Compiler({CompilerOptions options, | 295 Compiler( |
| 364 api.CompilerOutput outputProvider, | 296 {CompilerOptions options, |
| 365 this.environment: const _EmptyEnvironment()}) | 297 api.CompilerOutput outputProvider, |
| 298 this.environment: const _EmptyEnvironment()}) |
| 366 : this.options = options, | 299 : this.options = options, |
| 367 this.cacheStrategy = new CacheStrategy(options.hasIncrementalSupport), | 300 this.cacheStrategy = new CacheStrategy(options.hasIncrementalSupport), |
| 368 this.userOutputProvider = outputProvider == null | 301 this.userOutputProvider = outputProvider == null |
| 369 ? const NullCompilerOutput() : outputProvider { | 302 ? const NullCompilerOutput() |
| 303 : outputProvider { |
| 370 world = new World(this); | 304 world = new World(this); |
| 371 // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and | 305 // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and |
| 372 // make its field final. | 306 // make its field final. |
| 373 _reporter = new _CompilerDiagnosticReporter(this, options); | 307 _reporter = new _CompilerDiagnosticReporter(this, options); |
| 374 _parsing = new _CompilerParsing(this); | 308 _parsing = new _CompilerParsing(this); |
| 375 _resolution = new _CompilerResolution(this); | 309 _resolution = new _CompilerResolution(this); |
| 376 _coreTypes = new _CompilerCoreTypes(_resolution); | 310 _coreTypes = new _CompilerCoreTypes(_resolution); |
| 377 types = new Types(_resolution); | 311 types = new Types(_resolution); |
| 378 tracer = new Tracer(this, this.outputProvider); | 312 tracer = new Tracer(this, this.outputProvider); |
| 379 | 313 |
| 380 if (options.verbose) { | 314 if (options.verbose) { |
| 381 progress = new Stopwatch()..start(); | 315 progress = new Stopwatch()..start(); |
| 382 } | 316 } |
| 383 | 317 |
| 384 // TODO(johnniwinther): Separate the dependency tracking from the enqueuing | 318 // TODO(johnniwinther): Separate the dependency tracking from the enqueuing |
| 385 // for global dependencies. | 319 // for global dependencies. |
| 386 globalDependencies = new GlobalDependencyRegistry(this); | 320 globalDependencies = new GlobalDependencyRegistry(this); |
| 387 | 321 |
| 388 if (options.emitJavaScript) { | 322 if (options.emitJavaScript) { |
| 389 js_backend.JavaScriptBackend jsBackend = | 323 js_backend.JavaScriptBackend jsBackend = new js_backend.JavaScriptBackend( |
| 390 new js_backend.JavaScriptBackend( | 324 this, |
| 391 this, generateSourceMap: options.generateSourceMap, | 325 generateSourceMap: options.generateSourceMap, |
| 392 useStartupEmitter: options.useStartupEmitter, | 326 useStartupEmitter: options.useStartupEmitter, |
| 393 useNewSourceInfo: options.useNewSourceInfo); | 327 useNewSourceInfo: options.useNewSourceInfo); |
| 394 backend = jsBackend; | 328 backend = jsBackend; |
| 395 } else { | 329 } else { |
| 396 backend = new dart_backend.DartBackend(this, options.strips, | 330 backend = new dart_backend.DartBackend(this, options.strips, |
| 397 multiFile: options.dart2dartMultiFile); | 331 multiFile: options.dart2dartMultiFile); |
| 398 if (options.dumpInfo) { | 332 if (options.dumpInfo) { |
| 399 throw new ArgumentError('--dump-info is not supported for dart2dart.'); | 333 throw new ArgumentError('--dump-info is not supported for dart2dart.'); |
| 400 } | 334 } |
| 401 } | 335 } |
| 402 | 336 |
| 403 tasks = [ | 337 tasks = [ |
| 404 dietParser = new DietParserTask(this, parsing.parserOptions), | 338 dietParser = new DietParserTask(this, parsing.parserOptions), |
| 405 scanner = createScannerTask(), | 339 scanner = createScannerTask(), |
| 406 serialization = new SerializationTask(this), | 340 serialization = new SerializationTask(this), |
| 407 libraryLoader = new LibraryLoaderTask(this, | 341 libraryLoader = new LibraryLoaderTask( |
| 342 this, |
| 408 new _ResolvedUriTranslator(this), | 343 new _ResolvedUriTranslator(this), |
| 409 new _ScriptLoader(this), | 344 new _ScriptLoader(this), |
| 410 new _ElementScanner(scanner), | 345 new _ElementScanner(scanner), |
| 411 this.serialization, | 346 this.serialization, |
| 412 this, | 347 this, |
| 413 environment), | 348 environment), |
| 414 parser = new ParserTask(this, parsing.parserOptions), | 349 parser = new ParserTask(this, parsing.parserOptions), |
| 415 patchParser = new PatchParserTask(this, parsing.parserOptions), | 350 patchParser = new PatchParserTask(this, parsing.parserOptions), |
| 416 resolver = createResolverTask(), | 351 resolver = createResolverTask(), |
| 417 closureToClassMapper = new closureMapping.ClosureTask(this), | 352 closureToClassMapper = new closureMapping.ClosureTask(this), |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 // The maximum number of imports chains to show. | 476 // The maximum number of imports chains to show. |
| 542 final int compactChainLimit = options.verbose ? 20 : 10; | 477 final int compactChainLimit = options.verbose ? 20 : 10; |
| 543 int chainCount = 0; | 478 int chainCount = 0; |
| 544 loadedLibraries.forEachImportChain(uri, | 479 loadedLibraries.forEachImportChain(uri, |
| 545 callback: (Link<Uri> importChainReversed) { | 480 callback: (Link<Uri> importChainReversed) { |
| 546 Link<CodeLocation> compactImportChain = const Link<CodeLocation>(); | 481 Link<CodeLocation> compactImportChain = const Link<CodeLocation>(); |
| 547 CodeLocation currentCodeLocation = | 482 CodeLocation currentCodeLocation = |
| 548 new UriLocation(importChainReversed.head); | 483 new UriLocation(importChainReversed.head); |
| 549 compactImportChain = compactImportChain.prepend(currentCodeLocation); | 484 compactImportChain = compactImportChain.prepend(currentCodeLocation); |
| 550 for (Link<Uri> link = importChainReversed.tail; | 485 for (Link<Uri> link = importChainReversed.tail; |
| 551 !link.isEmpty; | 486 !link.isEmpty; |
| 552 link = link.tail) { | 487 link = link.tail) { |
| 553 Uri uri = link.head; | 488 Uri uri = link.head; |
| 554 if (!currentCodeLocation.inSameLocation(uri)) { | 489 if (!currentCodeLocation.inSameLocation(uri)) { |
| 555 currentCodeLocation = | 490 currentCodeLocation = |
| 556 options.verbose ? new UriLocation(uri) : new CodeLocation(uri); | 491 options.verbose ? new UriLocation(uri) : new CodeLocation(uri); |
| 557 compactImportChain = | 492 compactImportChain = compactImportChain.prepend(currentCodeLocation); |
| 558 compactImportChain.prepend(currentCodeLocation); | |
| 559 } | 493 } |
| 560 } | 494 } |
| 561 String importChain = | 495 String importChain = compactImportChain.map((CodeLocation codeLocation) { |
| 562 compactImportChain.map((CodeLocation codeLocation) { | 496 return codeLocation.relativize(rootUri); |
| 563 return codeLocation.relativize(rootUri); | 497 }).join(' => '); |
| 564 }).join(' => '); | |
| 565 | 498 |
| 566 if (!importChains.contains(importChain)) { | 499 if (!importChains.contains(importChain)) { |
| 567 if (importChains.length > compactChainLimit) { | 500 if (importChains.length > compactChainLimit) { |
| 568 importChains.add('...'); | 501 importChains.add('...'); |
| 569 return false; | 502 return false; |
| 570 } else { | 503 } else { |
| 571 importChains.add(importChain); | 504 importChains.add(importChain); |
| 572 } | 505 } |
| 573 } | 506 } |
| 574 | 507 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 597 /// [loadedLibraries] contains the newly loaded libraries. | 530 /// [loadedLibraries] contains the newly loaded libraries. |
| 598 /// | 531 /// |
| 599 /// The method returns a [Future] allowing for the loading of additional | 532 /// The method returns a [Future] allowing for the loading of additional |
| 600 /// libraries. | 533 /// libraries. |
| 601 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 534 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
| 602 return new Future.sync(() { | 535 return new Future.sync(() { |
| 603 for (Uri uri in disallowedLibraryUris) { | 536 for (Uri uri in disallowedLibraryUris) { |
| 604 if (loadedLibraries.containsLibrary(uri)) { | 537 if (loadedLibraries.containsLibrary(uri)) { |
| 605 Set<String> importChains = | 538 Set<String> importChains = |
| 606 computeImportChainsFor(loadedLibraries, uri); | 539 computeImportChainsFor(loadedLibraries, uri); |
| 607 reporter.reportInfo(NO_LOCATION_SPANNABLE, | 540 reporter.reportInfo( |
| 608 MessageKind.DISALLOWED_LIBRARY_IMPORT, | 541 NO_LOCATION_SPANNABLE, MessageKind.DISALLOWED_LIBRARY_IMPORT, { |
| 609 {'uri': uri, | 542 'uri': uri, |
| 610 'importChain': importChains.join( | 543 'importChain': importChains |
| 611 MessageTemplate.DISALLOWED_LIBRARY_IMPORT_PADDING)}); | 544 .join(MessageTemplate.DISALLOWED_LIBRARY_IMPORT_PADDING) |
| 545 }); |
| 612 } | 546 } |
| 613 } | 547 } |
| 614 | 548 |
| 615 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { | 549 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { |
| 616 return null; | 550 return null; |
| 617 } | 551 } |
| 618 | 552 |
| 619 bool importsMirrorsLibrary = | 553 bool importsMirrorsLibrary = |
| 620 loadedLibraries.containsLibrary(Uris.dart_mirrors); | 554 loadedLibraries.containsLibrary(Uris.dart_mirrors); |
| 621 if (importsMirrorsLibrary && !backend.supportsReflection) { | 555 if (importsMirrorsLibrary && !backend.supportsReflection) { |
| 622 Set<String> importChains = | 556 Set<String> importChains = |
| 623 computeImportChainsFor(loadedLibraries, Uris.dart_mirrors); | 557 computeImportChainsFor(loadedLibraries, Uris.dart_mirrors); |
| 624 reporter.reportErrorMessage( | 558 reporter.reportErrorMessage(NO_LOCATION_SPANNABLE, |
| 625 NO_LOCATION_SPANNABLE, | 559 MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND, { |
| 626 MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND, | 560 'importChain': importChains |
| 627 {'importChain': importChains.join( | 561 .join(MessageTemplate.MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING) |
| 628 MessageTemplate.MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING)}); | 562 }); |
| 629 } else if (importsMirrorsLibrary && !options.enableExperimentalMirrors) { | 563 } else if (importsMirrorsLibrary && !options.enableExperimentalMirrors) { |
| 630 Set<String> importChains = | 564 Set<String> importChains = |
| 631 computeImportChainsFor(loadedLibraries, Uris.dart_mirrors); | 565 computeImportChainsFor(loadedLibraries, Uris.dart_mirrors); |
| 632 reporter.reportWarningMessage( | 566 reporter.reportWarningMessage( |
| 633 NO_LOCATION_SPANNABLE, | 567 NO_LOCATION_SPANNABLE, MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, { |
| 634 MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, | 568 'importChain': importChains |
| 635 {'importChain': importChains.join( | 569 .join(MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING) |
| 636 MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}); | 570 }); |
| 637 } | 571 } |
| 638 | 572 |
| 639 coreClasses.functionClass.ensureResolved(resolution); | 573 coreClasses.functionClass.ensureResolved(resolution); |
| 640 functionApplyMethod = | 574 functionApplyMethod = |
| 641 coreClasses.functionClass.lookupLocalMember('apply'); | 575 coreClasses.functionClass.lookupLocalMember('apply'); |
| 642 | 576 |
| 643 if (options.preserveComments) { | 577 if (options.preserveComments) { |
| 644 return libraryLoader.loadLibrary(Uris.dart_mirrors) | 578 return libraryLoader |
| 579 .loadLibrary(Uris.dart_mirrors) |
| 645 .then((LibraryElement libraryElement) { | 580 .then((LibraryElement libraryElement) { |
| 646 documentClass = libraryElement.find('Comment'); | 581 documentClass = libraryElement.find('Comment'); |
| 647 }); | 582 }); |
| 648 } | 583 } |
| 649 }).then((_) => backend.onLibrariesLoaded(loadedLibraries)); | 584 }).then((_) => backend.onLibrariesLoaded(loadedLibraries)); |
| 650 } | 585 } |
| 651 | 586 |
| 652 bool isProxyConstant(ConstantValue value) { | 587 bool isProxyConstant(ConstantValue value) { |
| 653 FieldElement field = coreLibrary.find('proxy'); | 588 FieldElement field = coreLibrary.find('proxy'); |
| 654 if (field == null) return false; | 589 if (field == null) return false; |
| 655 if (!resolution.hasBeenResolved(field)) return false; | 590 if (!resolution.hasBeenResolved(field)) return false; |
| 656 if (proxyConstant == null) { | 591 if (proxyConstant == null) { |
| 657 proxyConstant = | 592 proxyConstant = constants |
| 658 constants.getConstantValue( | 593 .getConstantValue(resolver.constantCompiler.compileConstant(field)); |
| 659 resolver.constantCompiler.compileConstant(field)); | |
| 660 } | 594 } |
| 661 return proxyConstant == value; | 595 return proxyConstant == value; |
| 662 } | 596 } |
| 663 | 597 |
| 664 Element findRequiredElement(LibraryElement library, String name) { | 598 Element findRequiredElement(LibraryElement library, String name) { |
| 665 var element = library.find(name); | 599 var element = library.find(name); |
| 666 if (element == null) { | 600 if (element == null) { |
| 667 reporter.internalError(library, | 601 reporter.internalError( |
| 602 library, |
| 668 "The library '${library.canonicalUri}' does not contain required " | 603 "The library '${library.canonicalUri}' does not contain required " |
| 669 "element: '$name'."); | 604 "element: '$name'."); |
| 670 } | 605 } |
| 671 return element; | 606 return element; |
| 672 } | 607 } |
| 673 | 608 |
| 674 // TODO(johnniwinther): Move this to [PatchParser] when it is moved to the | 609 // TODO(johnniwinther): Move this to [PatchParser] when it is moved to the |
| 675 // [JavaScriptBackend]. Currently needed for testing. | 610 // [JavaScriptBackend]. Currently needed for testing. |
| 676 String get patchVersion => backend.patchVersion; | 611 String get patchVersion => backend.patchVersion; |
| 677 | 612 |
| 678 void onClassResolved(ClassElement cls) { | 613 void onClassResolved(ClassElement cls) { |
| 679 if (mirrorSystemClass == cls) { | 614 if (mirrorSystemClass == cls) { |
| 680 mirrorSystemGetNameFunction = cls.lookupLocalMember('getName'); | 615 mirrorSystemGetNameFunction = cls.lookupLocalMember('getName'); |
| 681 } else if (coreClasses.symbolClass == cls) { | 616 } else if (coreClasses.symbolClass == cls) { |
| 682 symbolConstructor = cls.constructors.head; | 617 symbolConstructor = cls.constructors.head; |
| 683 } else if (symbolImplementationClass == cls) { | 618 } else if (symbolImplementationClass == cls) { |
| 684 symbolValidatedConstructor = cls.lookupConstructor( | 619 symbolValidatedConstructor = |
| 685 symbolValidatedConstructorSelector.name); | 620 cls.lookupConstructor(symbolValidatedConstructorSelector.name); |
| 686 } else if (mirrorsUsedClass == cls) { | 621 } else if (mirrorsUsedClass == cls) { |
| 687 mirrorsUsedConstructor = cls.constructors.head; | 622 mirrorsUsedConstructor = cls.constructors.head; |
| 688 } else if (coreClasses.intClass == cls) { | 623 } else if (coreClasses.intClass == cls) { |
| 689 intEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment); | 624 intEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment); |
| 690 } else if (coreClasses.stringClass == cls) { | 625 } else if (coreClasses.stringClass == cls) { |
| 691 stringEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment); | 626 stringEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment); |
| 692 } else if (coreClasses.boolClass == cls) { | 627 } else if (coreClasses.boolClass == cls) { |
| 693 boolEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment); | 628 boolEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment); |
| 694 } | 629 } |
| 695 } | 630 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 // TODO(ahe): This prevents memory leaks when invoking the compiler | 685 // TODO(ahe): This prevents memory leaks when invoking the compiler |
| 751 // multiple times. Implement a better mechanism where we can store | 686 // multiple times. Implement a better mechanism where we can store |
| 752 // such caches in the compiler and get access to them through a | 687 // such caches in the compiler and get access to them through a |
| 753 // suitably maintained static reference to the current compiler. | 688 // suitably maintained static reference to the current compiler. |
| 754 StringToken.canonicalizedSubstrings.clear(); | 689 StringToken.canonicalizedSubstrings.clear(); |
| 755 Selector.canonicalizedValues.clear(); | 690 Selector.canonicalizedValues.clear(); |
| 756 | 691 |
| 757 // The selector objects held in static fields must remain canonical. | 692 // The selector objects held in static fields must remain canonical. |
| 758 for (Selector selector in Selectors.ALL) { | 693 for (Selector selector in Selectors.ALL) { |
| 759 Selector.canonicalizedValues | 694 Selector.canonicalizedValues |
| 760 .putIfAbsent(selector.hashCode, () => <Selector>[]) | 695 .putIfAbsent(selector.hashCode, () => <Selector>[]) |
| 761 .add(selector); | 696 .add(selector); |
| 762 } | 697 } |
| 763 | 698 |
| 764 assert(uri != null || options.analyzeOnly || options.hasIncrementalSupport); | 699 assert(uri != null || options.analyzeOnly || options.hasIncrementalSupport); |
| 765 return new Future.sync(() { | 700 return new Future.sync(() { |
| 766 if (librariesToAnalyzeWhenRun != null) { | 701 if (librariesToAnalyzeWhenRun != null) { |
| 767 return Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) { | 702 return Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) { |
| 768 reporter.log('Analyzing $libraryUri (${options.buildId})'); | 703 reporter.log('Analyzing $libraryUri (${options.buildId})'); |
| 769 return libraryLoader.loadLibrary(libraryUri); | 704 return libraryLoader.loadLibrary(libraryUri); |
| 770 }); | 705 }); |
| 771 } | 706 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 786 } | 721 } |
| 787 | 722 |
| 788 void computeMain() { | 723 void computeMain() { |
| 789 if (mainApp == null) return; | 724 if (mainApp == null) return; |
| 790 | 725 |
| 791 Element main = mainApp.findExported(Identifiers.main); | 726 Element main = mainApp.findExported(Identifiers.main); |
| 792 ErroneousElement errorElement = null; | 727 ErroneousElement errorElement = null; |
| 793 if (main == null) { | 728 if (main == null) { |
| 794 if (options.analyzeOnly) { | 729 if (options.analyzeOnly) { |
| 795 if (!analyzeAll) { | 730 if (!analyzeAll) { |
| 796 errorElement = new ErroneousElementX( | 731 errorElement = new ErroneousElementX(MessageKind.CONSIDER_ANALYZE_ALL, |
| 797 MessageKind.CONSIDER_ANALYZE_ALL, {'main': Identifiers.main}, | 732 {'main': Identifiers.main}, Identifiers.main, mainApp); |
| 798 Identifiers.main, mainApp); | |
| 799 } | 733 } |
| 800 } else { | 734 } else { |
| 801 // Compilation requires a main method. | 735 // Compilation requires a main method. |
| 802 errorElement = new ErroneousElementX( | 736 errorElement = new ErroneousElementX(MessageKind.MISSING_MAIN, |
| 803 MessageKind.MISSING_MAIN, {'main': Identifiers.main}, | 737 {'main': Identifiers.main}, Identifiers.main, mainApp); |
| 804 Identifiers.main, mainApp); | |
| 805 } | 738 } |
| 806 mainFunction = backend.helperForMissingMain(); | 739 mainFunction = backend.helperForMissingMain(); |
| 807 } else if (main.isError && main.isSynthesized) { | 740 } else if (main.isError && main.isSynthesized) { |
| 808 if (main is ErroneousElement) { | 741 if (main is ErroneousElement) { |
| 809 errorElement = main; | 742 errorElement = main; |
| 810 } else { | 743 } else { |
| 811 reporter.internalError(main, 'Problem with ${Identifiers.main}.'); | 744 reporter.internalError(main, 'Problem with ${Identifiers.main}.'); |
| 812 } | 745 } |
| 813 mainFunction = backend.helperForBadMain(); | 746 mainFunction = backend.helperForBadMain(); |
| 814 } else if (!main.isFunction) { | 747 } else if (!main.isFunction) { |
| 815 errorElement = new ErroneousElementX( | 748 errorElement = new ErroneousElementX(MessageKind.MAIN_NOT_A_FUNCTION, |
| 816 MessageKind.MAIN_NOT_A_FUNCTION, {'main': Identifiers.main}, | 749 {'main': Identifiers.main}, Identifiers.main, main); |
| 817 Identifiers.main, main); | |
| 818 mainFunction = backend.helperForBadMain(); | 750 mainFunction = backend.helperForBadMain(); |
| 819 } else { | 751 } else { |
| 820 mainFunction = main; | 752 mainFunction = main; |
| 821 mainFunction.computeType(resolution); | 753 mainFunction.computeType(resolution); |
| 822 FunctionSignature parameters = mainFunction.functionSignature; | 754 FunctionSignature parameters = mainFunction.functionSignature; |
| 823 if (parameters.requiredParameterCount > 2) { | 755 if (parameters.requiredParameterCount > 2) { |
| 824 int index = 0; | 756 int index = 0; |
| 825 parameters.orderedForEachParameter((Element parameter) { | 757 parameters.orderedForEachParameter((Element parameter) { |
| 826 if (index++ < 2) return; | 758 if (index++ < 2) return; |
| 827 errorElement = new ErroneousElementX( | 759 errorElement = new ErroneousElementX( |
| 828 MessageKind.MAIN_WITH_EXTRA_PARAMETER, {'main': Identifiers.main}, | 760 MessageKind.MAIN_WITH_EXTRA_PARAMETER, |
| 761 {'main': Identifiers.main}, |
| 829 Identifiers.main, | 762 Identifiers.main, |
| 830 parameter); | 763 parameter); |
| 831 mainFunction = backend.helperForMainArity(); | 764 mainFunction = backend.helperForMainArity(); |
| 832 // Don't warn about main not being used: | 765 // Don't warn about main not being used: |
| 833 enqueuer.resolution.registerStaticUse(new StaticUse.foreignUse(main)); | 766 enqueuer.resolution.registerStaticUse(new StaticUse.foreignUse(main)); |
| 834 }); | 767 }); |
| 835 } | 768 } |
| 836 } | 769 } |
| 837 if (mainFunction == null) { | 770 if (mainFunction == null) { |
| 838 if (errorElement == null && !options.analyzeOnly && !analyzeAll) { | 771 if (errorElement == null && !options.analyzeOnly && !analyzeAll) { |
| 839 reporter.internalError(mainApp, "Problem with '${Identifiers.main}'."); | 772 reporter.internalError(mainApp, "Problem with '${Identifiers.main}'."); |
| 840 } else { | 773 } else { |
| 841 mainFunction = errorElement; | 774 mainFunction = errorElement; |
| 842 } | 775 } |
| 843 } | 776 } |
| 844 if (errorElement != null && | 777 if (errorElement != null && |
| 845 errorElement.isSynthesized && | 778 errorElement.isSynthesized && |
| 846 !mainApp.isSynthesized) { | 779 !mainApp.isSynthesized) { |
| 847 reporter.reportWarningMessage( | 780 reporter.reportWarningMessage(errorElement, errorElement.messageKind, |
| 848 errorElement, errorElement.messageKind, | |
| 849 errorElement.messageArguments); | 781 errorElement.messageArguments); |
| 850 } | 782 } |
| 851 } | 783 } |
| 852 | 784 |
| 853 /// Analyze all members of the library in [libraryUri]. | 785 /// Analyze all members of the library in [libraryUri]. |
| 854 /// | 786 /// |
| 855 /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the | 787 /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the |
| 856 /// library has a `part of` tag, assuming it is a part and not a library. | 788 /// library has a `part of` tag, assuming it is a part and not a library. |
| 857 /// | 789 /// |
| 858 /// This operation assumes an unclosed resolution queue and is only supported | 790 /// This operation assumes an unclosed resolution queue and is only supported |
| 859 /// when the '--analyze-main' option is used. | 791 /// when the '--analyze-main' option is used. |
| 860 Future<LibraryElement> analyzeUri( | 792 Future<LibraryElement> analyzeUri(Uri libraryUri, |
| 861 Uri libraryUri, | |
| 862 {bool skipLibraryWithPartOfTag: true}) { | 793 {bool skipLibraryWithPartOfTag: true}) { |
| 863 assert(options.analyzeMain); | 794 assert(options.analyzeMain); |
| 864 reporter.log('Analyzing $libraryUri (${options.buildId})'); | 795 reporter.log('Analyzing $libraryUri (${options.buildId})'); |
| 865 return libraryLoader.loadLibrary( | 796 return libraryLoader |
| 866 libraryUri, skipFileWithPartOfTag: true).then( | 797 .loadLibrary(libraryUri, skipFileWithPartOfTag: true) |
| 867 (LibraryElement library) { | 798 .then((LibraryElement library) { |
| 868 if (library == null) return null; | 799 if (library == null) return null; |
| 869 fullyEnqueueLibrary(library, enqueuer.resolution); | 800 fullyEnqueueLibrary(library, enqueuer.resolution); |
| 870 emptyQueue(enqueuer.resolution); | 801 emptyQueue(enqueuer.resolution); |
| 871 enqueuer.resolution.logSummary(reporter.log); | 802 enqueuer.resolution.logSummary(reporter.log); |
| 872 return library; | 803 return library; |
| 873 }); | 804 }); |
| 874 } | 805 } |
| 875 | 806 |
| 876 /// Performs the compilation when all libraries have been loaded. | 807 /// Performs the compilation when all libraries have been loaded. |
| 877 void compileLoadedLibraries() { | 808 void compileLoadedLibraries() { |
| 878 computeMain(); | 809 computeMain(); |
| 879 | 810 |
| 880 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 811 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
| 881 | 812 |
| 882 // In order to see if a library is deferred, we must compute the | 813 // In order to see if a library is deferred, we must compute the |
| 883 // compile-time constants that are metadata. This means adding | 814 // compile-time constants that are metadata. This means adding |
| 884 // something to the resolution queue. So we cannot wait with | 815 // something to the resolution queue. So we cannot wait with |
| 885 // this until after the resolution queue is processed. | 816 // this until after the resolution queue is processed. |
| 886 deferredLoadTask.beforeResolution(this); | 817 deferredLoadTask.beforeResolution(this); |
| 887 impactStrategy = backend.createImpactStrategy( | 818 impactStrategy = backend.createImpactStrategy( |
| 888 supportDeferredLoad: deferredLoadTask.isProgramSplit, | 819 supportDeferredLoad: deferredLoadTask.isProgramSplit, |
| 889 supportDumpInfo: options.dumpInfo, | 820 supportDumpInfo: options.dumpInfo, |
| 890 supportSerialization: serialization.supportSerialization); | 821 supportSerialization: serialization.supportSerialization); |
| 891 | 822 |
| 892 phase = PHASE_RESOLVING; | 823 phase = PHASE_RESOLVING; |
| 893 if (analyzeAll) { | 824 if (analyzeAll) { |
| 894 libraryLoader.libraries.forEach((LibraryElement library) { | 825 libraryLoader.libraries.forEach((LibraryElement library) { |
| 895 reporter.log('Enqueuing ${library.canonicalUri}'); | 826 reporter.log('Enqueuing ${library.canonicalUri}'); |
| 896 fullyEnqueueLibrary(library, enqueuer.resolution); | 827 fullyEnqueueLibrary(library, enqueuer.resolution); |
| 897 }); | 828 }); |
| 898 } else if (options.analyzeMain) { | 829 } else if (options.analyzeMain) { |
| 899 if (mainApp != null) { | 830 if (mainApp != null) { |
| 900 fullyEnqueueLibrary(mainApp, enqueuer.resolution); | 831 fullyEnqueueLibrary(mainApp, enqueuer.resolution); |
| 901 } | 832 } |
| 902 if (librariesToAnalyzeWhenRun != null) { | 833 if (librariesToAnalyzeWhenRun != null) { |
| 903 for (Uri libraryUri in librariesToAnalyzeWhenRun) { | 834 for (Uri libraryUri in librariesToAnalyzeWhenRun) { |
| 904 fullyEnqueueLibrary(libraryLoader.lookupLibrary(libraryUri), | 835 fullyEnqueueLibrary( |
| 905 enqueuer.resolution); | 836 libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution); |
| 906 } | 837 } |
| 907 } | 838 } |
| 908 } | 839 } |
| 909 // Elements required by enqueueHelpers are global dependencies | 840 // Elements required by enqueueHelpers are global dependencies |
| 910 // that are not pulled in by a particular element. | 841 // that are not pulled in by a particular element. |
| 911 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); | 842 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); |
| 912 resolveLibraryMetadata(); | 843 resolveLibraryMetadata(); |
| 913 reporter.log('Resolving...'); | 844 reporter.log('Resolving...'); |
| 914 processQueue(enqueuer.resolution, mainFunction); | 845 processQueue(enqueuer.resolution, mainFunction); |
| 915 enqueuer.resolution.logSummary(reporter.log); | 846 enqueuer.resolution.logSummary(reporter.log); |
| 916 | 847 |
| 917 _reporter.reportSuppressedMessagesSummary(); | 848 _reporter.reportSuppressedMessagesSummary(); |
| 918 | 849 |
| 919 if (compilationFailed){ | 850 if (compilationFailed) { |
| 920 if (!options.generateCodeWithCompileTimeErrors) return; | 851 if (!options.generateCodeWithCompileTimeErrors) return; |
| 921 if (!backend.enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { | 852 if (!backend.enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) { |
| 922 return; | 853 return; |
| 923 } | 854 } |
| 924 } | 855 } |
| 925 | 856 |
| 926 if (options.analyzeOnly) { | 857 if (options.analyzeOnly) { |
| 927 if (!analyzeAll && !compilationFailed) { | 858 if (!analyzeAll && !compilationFailed) { |
| 928 // No point in reporting unused code when [analyzeAll] is true: all | 859 // No point in reporting unused code when [analyzeAll] is true: all |
| 929 // code is artificially used. | 860 // code is artificially used. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 fullyEnqueueTopLevelElement(element, world); | 915 fullyEnqueueTopLevelElement(element, world); |
| 985 } | 916 } |
| 986 library.implementation.forEachLocalMember(enqueueAll); | 917 library.implementation.forEachLocalMember(enqueueAll); |
| 987 } | 918 } |
| 988 | 919 |
| 989 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { | 920 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { |
| 990 if (element.isClass) { | 921 if (element.isClass) { |
| 991 ClassElement cls = element; | 922 ClassElement cls = element; |
| 992 cls.ensureResolved(resolution); | 923 cls.ensureResolved(resolution); |
| 993 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); | 924 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); |
| 994 backend.registerInstantiatedType( | 925 backend.registerInstantiatedType(cls.rawType, world, globalDependencies); |
| 995 cls.rawType, world, globalDependencies); | |
| 996 } else { | 926 } else { |
| 997 world.addToWorkList(element); | 927 world.addToWorkList(element); |
| 998 } | 928 } |
| 999 } | 929 } |
| 1000 | 930 |
| 1001 // Resolves metadata on library elements. This is necessary in order to | 931 // Resolves metadata on library elements. This is necessary in order to |
| 1002 // resolve metadata classes referenced only from metadata on library tags. | 932 // resolve metadata classes referenced only from metadata on library tags. |
| 1003 // TODO(ahe): Figure out how to do this lazily. | 933 // TODO(ahe): Figure out how to do this lazily. |
| 1004 void resolveLibraryMetadata() { | 934 void resolveLibraryMetadata() { |
| 1005 for (LibraryElement library in libraryLoader.libraries) { | 935 for (LibraryElement library in libraryLoader.libraries) { |
| 1006 if (library.metadata != null) { | 936 if (library.metadata != null) { |
| 1007 for (MetadataAnnotation metadata in library.metadata) { | 937 for (MetadataAnnotation metadata in library.metadata) { |
| 1008 metadata.ensureResolved(resolution); | 938 metadata.ensureResolved(resolution); |
| 1009 } | 939 } |
| 1010 } | 940 } |
| 1011 } | 941 } |
| 1012 } | 942 } |
| 1013 | 943 |
| 1014 /** | 944 /** |
| 1015 * Empty the [world] queue. | 945 * Empty the [world] queue. |
| 1016 */ | 946 */ |
| 1017 void emptyQueue(Enqueuer world) { | 947 void emptyQueue(Enqueuer world) { |
| 1018 world.forEach((WorkItem work) { | 948 world.forEach((WorkItem work) { |
| 1019 reporter.withCurrentElement(work.element, () { | 949 reporter.withCurrentElement(work.element, () { |
| 1020 world.applyImpact(work.element, work.run(this, world)); | 950 world.applyImpact(work.element, work.run(this, world)); |
| 1021 }); | 951 }); |
| 1022 }); | 952 }); |
| 1023 } | 953 } |
| 1024 | 954 |
| 1025 void processQueue(Enqueuer world, Element main) { | 955 void processQueue(Enqueuer world, Element main) { |
| 1026 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); | 956 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); |
| 1027 if (main != null && !main.isMalformed) { | 957 if (main != null && !main.isMalformed) { |
| 1028 FunctionElement mainMethod = main; | 958 FunctionElement mainMethod = main; |
| 1029 mainMethod.computeType(resolution); | 959 mainMethod.computeType(resolution); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 } | 1009 } |
| 1080 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) { | 1010 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) { |
| 1081 resolved.remove(e); | 1011 resolved.remove(e); |
| 1082 } | 1012 } |
| 1083 if (backend.isBackendLibrary(e.library)) { | 1013 if (backend.isBackendLibrary(e.library)) { |
| 1084 resolved.remove(e); | 1014 resolved.remove(e); |
| 1085 } | 1015 } |
| 1086 } | 1016 } |
| 1087 reporter.log('Excess resolution work: ${resolved.length}.'); | 1017 reporter.log('Excess resolution work: ${resolved.length}.'); |
| 1088 for (Element e in resolved) { | 1018 for (Element e in resolved) { |
| 1089 reporter.reportWarningMessage(e, | 1019 reporter.reportWarningMessage(e, MessageKind.GENERIC, |
| 1090 MessageKind.GENERIC, | |
| 1091 {'text': 'Warning: $e resolved but not compiled.'}); | 1020 {'text': 'Warning: $e resolved but not compiled.'}); |
| 1092 } | 1021 } |
| 1093 } | 1022 } |
| 1094 | 1023 |
| 1095 WorldImpact analyzeElement(Element element) { | 1024 WorldImpact analyzeElement(Element element) { |
| 1096 assert(invariant(element, | 1025 assert(invariant( |
| 1097 element.impliesType || | 1026 element, |
| 1098 element.isField || | 1027 element.impliesType || |
| 1099 element.isFunction || | 1028 element.isField || |
| 1100 element.isConstructor || | 1029 element.isFunction || |
| 1101 element.isGetter || | 1030 element.isConstructor || |
| 1102 element.isSetter, | 1031 element.isGetter || |
| 1103 message: 'Unexpected element kind: ${element.kind}')); | 1032 element.isSetter, |
| 1033 message: 'Unexpected element kind: ${element.kind}')); |
| 1104 assert(invariant(element, element is AnalyzableElement, | 1034 assert(invariant(element, element is AnalyzableElement, |
| 1105 message: 'Element $element is not analyzable.')); | 1035 message: 'Element $element is not analyzable.')); |
| 1106 assert(invariant(element, element.isDeclaration)); | 1036 assert(invariant(element, element.isDeclaration)); |
| 1107 return resolution.computeWorldImpact(element); | 1037 return resolution.computeWorldImpact(element); |
| 1108 } | 1038 } |
| 1109 | 1039 |
| 1110 WorldImpact analyze(ResolutionWorkItem work, | 1040 WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) { |
| 1111 ResolutionEnqueuer world) { | |
| 1112 assert(invariant(work.element, identical(world, enqueuer.resolution))); | 1041 assert(invariant(work.element, identical(world, enqueuer.resolution))); |
| 1113 assert(invariant(work.element, !work.isAnalyzed, | 1042 assert(invariant(work.element, !work.isAnalyzed, |
| 1114 message: 'Element ${work.element} has already been analyzed')); | 1043 message: 'Element ${work.element} has already been analyzed')); |
| 1115 if (shouldPrintProgress) { | 1044 if (shouldPrintProgress) { |
| 1116 // TODO(ahe): Add structured diagnostics to the compiler API and | 1045 // TODO(ahe): Add structured diagnostics to the compiler API and |
| 1117 // use it to separate this from the --verbose option. | 1046 // use it to separate this from the --verbose option. |
| 1118 if (phase == PHASE_RESOLVING) { | 1047 if (phase == PHASE_RESOLVING) { |
| 1119 reporter.log( | 1048 reporter.log('Resolved ${enqueuer.resolution.processedElements.length} ' |
| 1120 'Resolved ${enqueuer.resolution.processedElements.length} ' | |
| 1121 'elements.'); | 1049 'elements.'); |
| 1122 progress.reset(); | 1050 progress.reset(); |
| 1123 } | 1051 } |
| 1124 } | 1052 } |
| 1125 AstElement element = work.element; | 1053 AstElement element = work.element; |
| 1126 if (world.hasBeenProcessed(element)) { | 1054 if (world.hasBeenProcessed(element)) { |
| 1127 return const WorldImpact(); | 1055 return const WorldImpact(); |
| 1128 } | 1056 } |
| 1129 WorldImpact worldImpact = analyzeElement(element); | 1057 WorldImpact worldImpact = analyzeElement(element); |
| 1130 backend.onElementResolved(element, element.resolvedAst.elements); | 1058 backend.onElementResolved(element, element.resolvedAst.elements); |
| 1131 world.registerProcessedElement(element); | 1059 world.registerProcessedElement(element); |
| 1132 return worldImpact; | 1060 return worldImpact; |
| 1133 } | 1061 } |
| 1134 | 1062 |
| 1135 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { | 1063 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { |
| 1136 assert(invariant(work.element, identical(world, enqueuer.codegen))); | 1064 assert(invariant(work.element, identical(world, enqueuer.codegen))); |
| 1137 if (shouldPrintProgress) { | 1065 if (shouldPrintProgress) { |
| 1138 // TODO(ahe): Add structured diagnostics to the compiler API and | 1066 // TODO(ahe): Add structured diagnostics to the compiler API and |
| 1139 // use it to separate this from the --verbose option. | 1067 // use it to separate this from the --verbose option. |
| 1140 reporter.log( | 1068 reporter |
| 1141 'Compiled ${enqueuer.codegen.generatedCode.length} methods.'); | 1069 .log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); |
| 1142 progress.reset(); | 1070 progress.reset(); |
| 1143 } | 1071 } |
| 1144 return backend.codegen(work); | 1072 return backend.codegen(work); |
| 1145 } | 1073 } |
| 1146 | 1074 |
| 1147 void reportDiagnostic(DiagnosticMessage message, | 1075 void reportDiagnostic(DiagnosticMessage message, |
| 1148 List<DiagnosticMessage> infos, | 1076 List<DiagnosticMessage> infos, api.Diagnostic kind); |
| 1149 api.Diagnostic kind); | |
| 1150 | 1077 |
| 1151 void reportCrashInUserCode(String message, exception, stackTrace) { | 1078 void reportCrashInUserCode(String message, exception, stackTrace) { |
| 1152 _reporter.onCrashInUserCode(message, exception, stackTrace); | 1079 _reporter.onCrashInUserCode(message, exception, stackTrace); |
| 1153 } | 1080 } |
| 1154 | 1081 |
| 1155 /// Messages for which compile-time errors are reported but compilation | 1082 /// Messages for which compile-time errors are reported but compilation |
| 1156 /// continues regardless. | 1083 /// continues regardless. |
| 1157 static const List<MessageKind> BENIGN_ERRORS = const <MessageKind>[ | 1084 static const List<MessageKind> BENIGN_ERRORS = const <MessageKind>[ |
| 1158 MessageKind.INVALID_METADATA, | 1085 MessageKind.INVALID_METADATA, |
| 1159 MessageKind.INVALID_METADATA_GENERIC, | 1086 MessageKind.INVALID_METADATA_GENERIC, |
| 1160 ]; | 1087 ]; |
| 1161 | 1088 |
| 1162 bool markCompilationAsFailed(DiagnosticMessage message, api.Diagnostic kind) { | 1089 bool markCompilationAsFailed(DiagnosticMessage message, api.Diagnostic kind) { |
| 1163 if (options.testMode) { | 1090 if (options.testMode) { |
| 1164 // When in test mode, i.e. on the build-bot, we always stop compilation. | 1091 // When in test mode, i.e. on the build-bot, we always stop compilation. |
| 1165 return true; | 1092 return true; |
| 1166 } | 1093 } |
| 1167 if (reporter.options.fatalWarnings) { | 1094 if (reporter.options.fatalWarnings) { |
| 1168 return true; | 1095 return true; |
| 1169 } | 1096 } |
| 1170 return !BENIGN_ERRORS.contains(message.message.kind); | 1097 return !BENIGN_ERRORS.contains(message.message.kind); |
| 1171 } | 1098 } |
| 1172 | 1099 |
| 1173 void fatalDiagnosticReported(DiagnosticMessage message, | 1100 void fatalDiagnosticReported(DiagnosticMessage message, |
| 1174 List<DiagnosticMessage> infos, | 1101 List<DiagnosticMessage> infos, api.Diagnostic kind) { |
| 1175 api.Diagnostic kind) { | |
| 1176 if (markCompilationAsFailed(message, kind)) { | 1102 if (markCompilationAsFailed(message, kind)) { |
| 1177 compilationFailed = true; | 1103 compilationFailed = true; |
| 1178 } | 1104 } |
| 1179 } | 1105 } |
| 1180 | 1106 |
| 1181 // TODO(sigmund): move this dart doc somewhere else too. | 1107 // TODO(sigmund): move this dart doc somewhere else too. |
| 1182 /** | 1108 /** |
| 1183 * Translates the [resolvedUri] into a readable URI. | 1109 * Translates the [resolvedUri] into a readable URI. |
| 1184 * | 1110 * |
| 1185 * The [importingLibrary] holds the library importing [resolvedUri] or | 1111 * The [importingLibrary] holds the library importing [resolvedUri] or |
| 1186 * [:null:] if [resolvedUri] is loaded as the main library. The | 1112 * [:null:] if [resolvedUri] is loaded as the main library. The |
| 1187 * [importingLibrary] is used to grant access to internal libraries from | 1113 * [importingLibrary] is used to grant access to internal libraries from |
| 1188 * platform libraries and patch libraries. | 1114 * platform libraries and patch libraries. |
| 1189 * | 1115 * |
| 1190 * If the [resolvedUri] is not accessible from [importingLibrary], this method | 1116 * If the [resolvedUri] is not accessible from [importingLibrary], this method |
| 1191 * is responsible for reporting errors. | 1117 * is responsible for reporting errors. |
| 1192 * | 1118 * |
| 1193 * See [LibraryLoader] for terminology on URIs. | 1119 * See [LibraryLoader] for terminology on URIs. |
| 1194 */ | 1120 */ |
| 1195 Uri translateResolvedUri(LibraryElement importingLibrary, | 1121 Uri translateResolvedUri( |
| 1196 Uri resolvedUri, Spannable spannable) { | 1122 LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable) { |
| 1197 unimplemented(importingLibrary, 'Compiler.translateResolvedUri'); | 1123 unimplemented(importingLibrary, 'Compiler.translateResolvedUri'); |
| 1198 return null; | 1124 return null; |
| 1199 } | 1125 } |
| 1200 | 1126 |
| 1201 /** | 1127 /** |
| 1202 * Reads the script specified by the [readableUri]. | 1128 * Reads the script specified by the [readableUri]. |
| 1203 * | 1129 * |
| 1204 * See [LibraryLoader] for terminology on URIs. | 1130 * See [LibraryLoader] for terminology on URIs. |
| 1205 */ | 1131 */ |
| 1206 Future<Script> readScript(Uri readableUri, [Spannable node]) { | 1132 Future<Script> readScript(Uri readableUri, [Spannable node]) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1307 (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri)); | 1233 (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri)); |
| 1308 } | 1234 } |
| 1309 | 1235 |
| 1310 Iterable<CodeLocation> computeUserCodeLocations( | 1236 Iterable<CodeLocation> computeUserCodeLocations( |
| 1311 {bool assumeInUserCode: false}) { | 1237 {bool assumeInUserCode: false}) { |
| 1312 List<CodeLocation> userCodeLocations = <CodeLocation>[]; | 1238 List<CodeLocation> userCodeLocations = <CodeLocation>[]; |
| 1313 if (mainApp != null) { | 1239 if (mainApp != null) { |
| 1314 userCodeLocations.add(new CodeLocation(mainApp.canonicalUri)); | 1240 userCodeLocations.add(new CodeLocation(mainApp.canonicalUri)); |
| 1315 } | 1241 } |
| 1316 if (librariesToAnalyzeWhenRun != null) { | 1242 if (librariesToAnalyzeWhenRun != null) { |
| 1317 userCodeLocations.addAll(librariesToAnalyzeWhenRun.map( | 1243 userCodeLocations.addAll( |
| 1318 (Uri uri) => new CodeLocation(uri))); | 1244 librariesToAnalyzeWhenRun.map((Uri uri) => new CodeLocation(uri))); |
| 1319 } | 1245 } |
| 1320 if (userCodeLocations.isEmpty && assumeInUserCode) { | 1246 if (userCodeLocations.isEmpty && assumeInUserCode) { |
| 1321 // Assume in user code since [mainApp] has not been set yet. | 1247 // Assume in user code since [mainApp] has not been set yet. |
| 1322 userCodeLocations.add(const AnyLocation()); | 1248 userCodeLocations.add(const AnyLocation()); |
| 1323 } | 1249 } |
| 1324 return userCodeLocations; | 1250 return userCodeLocations; |
| 1325 } | 1251 } |
| 1326 | 1252 |
| 1327 /// Return a canonical URI for the source of [element]. | 1253 /// Return a canonical URI for the source of [element]. |
| 1328 /// | 1254 /// |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 InterfaceType listType([DartType elementType]) { | 1365 InterfaceType listType([DartType elementType]) { |
| 1440 listClass.ensureResolved(resolution); | 1366 listClass.ensureResolved(resolution); |
| 1441 InterfaceType type = listClass.rawType; | 1367 InterfaceType type = listClass.rawType; |
| 1442 if (elementType == null) { | 1368 if (elementType == null) { |
| 1443 return type; | 1369 return type; |
| 1444 } | 1370 } |
| 1445 return type.createInstantiation([elementType]); | 1371 return type.createInstantiation([elementType]); |
| 1446 } | 1372 } |
| 1447 | 1373 |
| 1448 @override | 1374 @override |
| 1449 InterfaceType mapType([DartType keyType, | 1375 InterfaceType mapType([DartType keyType, DartType valueType]) { |
| 1450 DartType valueType]) { | |
| 1451 mapClass.ensureResolved(resolution); | 1376 mapClass.ensureResolved(resolution); |
| 1452 InterfaceType type = mapClass.rawType; | 1377 InterfaceType type = mapClass.rawType; |
| 1453 if (keyType == null && valueType == null) { | 1378 if (keyType == null && valueType == null) { |
| 1454 return type; | 1379 return type; |
| 1455 } else if (keyType == null) { | 1380 } else if (keyType == null) { |
| 1456 keyType = const DynamicType(); | 1381 keyType = const DynamicType(); |
| 1457 } else if (valueType == null) { | 1382 } else if (valueType == null) { |
| 1458 valueType = const DynamicType(); | 1383 valueType = const DynamicType(); |
| 1459 } | 1384 } |
| 1460 return type.createInstantiation([keyType, valueType]); | 1385 return type.createInstantiation([keyType, valueType]); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 bool lastDiagnosticWasFiltered = false; | 1464 bool lastDiagnosticWasFiltered = false; |
| 1540 | 1465 |
| 1541 /// Map containing information about the warnings and hints that have been | 1466 /// Map containing information about the warnings and hints that have been |
| 1542 /// suppressed for each library. | 1467 /// suppressed for each library. |
| 1543 Map<Uri, SuppressionInfo> suppressedWarnings = <Uri, SuppressionInfo>{}; | 1468 Map<Uri, SuppressionInfo> suppressedWarnings = <Uri, SuppressionInfo>{}; |
| 1544 | 1469 |
| 1545 _CompilerDiagnosticReporter(this.compiler, this.options); | 1470 _CompilerDiagnosticReporter(this.compiler, this.options); |
| 1546 | 1471 |
| 1547 Element get currentElement => _currentElement; | 1472 Element get currentElement => _currentElement; |
| 1548 | 1473 |
| 1549 DiagnosticMessage createMessage( | 1474 DiagnosticMessage createMessage(Spannable spannable, MessageKind messageKind, |
| 1550 Spannable spannable, | |
| 1551 MessageKind messageKind, | |
| 1552 [Map arguments = const {}]) { | 1475 [Map arguments = const {}]) { |
| 1553 SourceSpan span = spanFromSpannable(spannable); | 1476 SourceSpan span = spanFromSpannable(spannable); |
| 1554 MessageTemplate template = MessageTemplate.TEMPLATES[messageKind]; | 1477 MessageTemplate template = MessageTemplate.TEMPLATES[messageKind]; |
| 1555 Message message = template.message(arguments, options.terseDiagnostics); | 1478 Message message = template.message(arguments, options.terseDiagnostics); |
| 1556 return new DiagnosticMessage(span, spannable, message); | 1479 return new DiagnosticMessage(span, spannable, message); |
| 1557 } | 1480 } |
| 1558 | 1481 |
| 1559 void reportError( | 1482 void reportError(DiagnosticMessage message, |
| 1560 DiagnosticMessage message, | |
| 1561 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) { | 1483 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) { |
| 1562 reportDiagnosticInternal(message, infos, api.Diagnostic.ERROR); | 1484 reportDiagnosticInternal(message, infos, api.Diagnostic.ERROR); |
| 1563 } | 1485 } |
| 1564 | 1486 |
| 1565 void reportWarning( | 1487 void reportWarning(DiagnosticMessage message, |
| 1566 DiagnosticMessage message, | |
| 1567 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) { | 1488 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) { |
| 1568 reportDiagnosticInternal(message, infos, api.Diagnostic.WARNING); | 1489 reportDiagnosticInternal(message, infos, api.Diagnostic.WARNING); |
| 1569 } | 1490 } |
| 1570 | 1491 |
| 1571 void reportHint( | 1492 void reportHint(DiagnosticMessage message, |
| 1572 DiagnosticMessage message, | |
| 1573 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) { | 1493 [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) { |
| 1574 reportDiagnosticInternal(message, infos, api.Diagnostic.HINT); | 1494 reportDiagnosticInternal(message, infos, api.Diagnostic.HINT); |
| 1575 } | 1495 } |
| 1576 | 1496 |
| 1577 @deprecated | 1497 @deprecated |
| 1578 void reportInfo(Spannable node, MessageKind messageKind, | 1498 void reportInfo(Spannable node, MessageKind messageKind, |
| 1579 [Map arguments = const {}]) { | 1499 [Map arguments = const {}]) { |
| 1580 reportDiagnosticInternal( | 1500 reportDiagnosticInternal(createMessage(node, messageKind, arguments), |
| 1581 createMessage(node, messageKind, arguments), | 1501 const <DiagnosticMessage>[], api.Diagnostic.INFO); |
| 1582 const <DiagnosticMessage>[], | |
| 1583 api.Diagnostic.INFO); | |
| 1584 } | 1502 } |
| 1585 | 1503 |
| 1586 void reportDiagnosticInternal(DiagnosticMessage message, | 1504 void reportDiagnosticInternal(DiagnosticMessage message, |
| 1587 List<DiagnosticMessage> infos, | 1505 List<DiagnosticMessage> infos, api.Diagnostic kind) { |
| 1588 api.Diagnostic kind) { | |
| 1589 if (!options.showAllPackageWarnings && | 1506 if (!options.showAllPackageWarnings && |
| 1590 message.spannable != NO_LOCATION_SPANNABLE) { | 1507 message.spannable != NO_LOCATION_SPANNABLE) { |
| 1591 switch (kind) { | 1508 switch (kind) { |
| 1592 case api.Diagnostic.WARNING: | 1509 case api.Diagnostic.WARNING: |
| 1593 case api.Diagnostic.HINT: | 1510 case api.Diagnostic.HINT: |
| 1594 Element element = elementFromSpannable(message.spannable); | 1511 Element element = elementFromSpannable(message.spannable); |
| 1595 if (!compiler.inUserCode(element, assumeInUserCode: true)) { | 1512 if (!compiler.inUserCode(element, assumeInUserCode: true)) { |
| 1596 Uri uri = compiler.getCanonicalUri(element); | 1513 Uri uri = compiler.getCanonicalUri(element); |
| 1597 if (options.showPackageWarningsFor(uri)) { | 1514 if (options.showPackageWarningsFor(uri)) { |
| 1598 reportDiagnostic(message, infos, kind); | 1515 reportDiagnostic(message, infos, kind); |
| 1516 return; |
| 1517 } |
| 1518 SuppressionInfo info = suppressedWarnings.putIfAbsent( |
| 1519 uri, () => new SuppressionInfo()); |
| 1520 if (kind == api.Diagnostic.WARNING) { |
| 1521 info.warnings++; |
| 1522 } else { |
| 1523 info.hints++; |
| 1524 } |
| 1525 lastDiagnosticWasFiltered = true; |
| 1599 return; | 1526 return; |
| 1600 } | 1527 } |
| 1601 SuppressionInfo info = | 1528 break; |
| 1602 suppressedWarnings.putIfAbsent(uri, () => new SuppressionInfo()); | 1529 case api.Diagnostic.INFO: |
| 1603 if (kind == api.Diagnostic.WARNING) { | 1530 if (lastDiagnosticWasFiltered) { |
| 1604 info.warnings++; | 1531 return; |
| 1605 } else { | |
| 1606 info.hints++; | |
| 1607 } | 1532 } |
| 1608 lastDiagnosticWasFiltered = true; | 1533 break; |
| 1609 return; | |
| 1610 } | |
| 1611 break; | |
| 1612 case api.Diagnostic.INFO: | |
| 1613 if (lastDiagnosticWasFiltered) { | |
| 1614 return; | |
| 1615 } | |
| 1616 break; | |
| 1617 } | 1534 } |
| 1618 } | 1535 } |
| 1619 lastDiagnosticWasFiltered = false; | 1536 lastDiagnosticWasFiltered = false; |
| 1620 reportDiagnostic(message, infos, kind); | 1537 reportDiagnostic(message, infos, kind); |
| 1621 } | 1538 } |
| 1622 | 1539 |
| 1623 void reportDiagnostic(DiagnosticMessage message, | 1540 void reportDiagnostic(DiagnosticMessage message, |
| 1624 List<DiagnosticMessage> infos, | 1541 List<DiagnosticMessage> infos, api.Diagnostic kind) { |
| 1625 api.Diagnostic kind) { | |
| 1626 compiler.reportDiagnostic(message, infos, kind); | 1542 compiler.reportDiagnostic(message, infos, kind); |
| 1627 if (kind == api.Diagnostic.ERROR || | 1543 if (kind == api.Diagnostic.ERROR || |
| 1628 kind == api.Diagnostic.CRASH || | 1544 kind == api.Diagnostic.CRASH || |
| 1629 (options.fatalWarnings && | 1545 (options.fatalWarnings && kind == api.Diagnostic.WARNING)) { |
| 1630 kind == api.Diagnostic.WARNING)) { | |
| 1631 compiler.fatalDiagnosticReported(message, infos, kind); | 1546 compiler.fatalDiagnosticReported(message, infos, kind); |
| 1632 } | 1547 } |
| 1633 } | 1548 } |
| 1634 | 1549 |
| 1635 /** | 1550 /** |
| 1636 * Perform an operation, [f], returning the return value from [f]. If an | 1551 * Perform an operation, [f], returning the return value from [f]. If an |
| 1637 * error occurs then report it as having occurred during compilation of | 1552 * error occurs then report it as having occurred during compilation of |
| 1638 * [element]. Can be nested. | 1553 * [element]. Can be nested. |
| 1639 */ | 1554 */ |
| 1640 withCurrentElement(Element element, f()) { | 1555 withCurrentElement(Element element, f()) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1660 } catch (doubleFault) { | 1575 } catch (doubleFault) { |
| 1661 // Ignoring exceptions in exception handling. | 1576 // Ignoring exceptions in exception handling. |
| 1662 } | 1577 } |
| 1663 rethrow; | 1578 rethrow; |
| 1664 } finally { | 1579 } finally { |
| 1665 _currentElement = old; | 1580 _currentElement = old; |
| 1666 } | 1581 } |
| 1667 } | 1582 } |
| 1668 | 1583 |
| 1669 void reportAssertionFailure(SpannableAssertionFailure ex) { | 1584 void reportAssertionFailure(SpannableAssertionFailure ex) { |
| 1670 String message = (ex.message != null) ? tryToString(ex.message) | 1585 String message = |
| 1671 : tryToString(ex); | 1586 (ex.message != null) ? tryToString(ex.message) : tryToString(ex); |
| 1672 reportDiagnosticInternal( | 1587 reportDiagnosticInternal( |
| 1673 createMessage(ex.node, MessageKind.GENERIC, {'text': message}), | 1588 createMessage(ex.node, MessageKind.GENERIC, {'text': message}), |
| 1674 const <DiagnosticMessage>[], | 1589 const <DiagnosticMessage>[], |
| 1675 api.Diagnostic.CRASH); | 1590 api.Diagnostic.CRASH); |
| 1676 } | 1591 } |
| 1677 | 1592 |
| 1678 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { | 1593 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { |
| 1679 if (begin == null || end == null) { | 1594 if (begin == null || end == null) { |
| 1680 // TODO(ahe): We can almost always do better. Often it is only | 1595 // TODO(ahe): We can almost always do better. Often it is only |
| 1681 // end that is null. Otherwise, we probably know the current | 1596 // end that is null. Otherwise, we probably know the current |
| 1682 // URI. | 1597 // URI. |
| 1683 throw 'Cannot find tokens to produce error message.'; | 1598 throw 'Cannot find tokens to produce error message.'; |
| 1684 } | 1599 } |
| 1685 if (uri == null && currentElement != null) { | 1600 if (uri == null && currentElement != null) { |
| 1686 uri = currentElement.compilationUnit.script.resourceUri; | 1601 uri = currentElement.compilationUnit.script.resourceUri; |
| 1687 assert(invariant(currentElement, () { | 1602 assert(invariant(currentElement, () { |
| 1688 | |
| 1689 bool sameToken(Token token, Token sought) { | 1603 bool sameToken(Token token, Token sought) { |
| 1690 if (token == sought) return true; | 1604 if (token == sought) return true; |
| 1691 if (token.stringValue == '>>') { | 1605 if (token.stringValue == '>>') { |
| 1692 // `>>` is converted to `>` in the parser when needed. | 1606 // `>>` is converted to `>` in the parser when needed. |
| 1693 return sought.stringValue == '>' && | 1607 return sought.stringValue == '>' && |
| 1694 token.charOffset <= sought.charOffset && | 1608 token.charOffset <= sought.charOffset && |
| 1695 sought.charOffset < token.charEnd; | 1609 sought.charOffset < token.charEnd; |
| 1696 } | 1610 } |
| 1697 return false; | 1611 return false; |
| 1698 } | 1612 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1835 } else if (node is Local) { | 1749 } else if (node is Local) { |
| 1836 Local local = node; | 1750 Local local = node; |
| 1837 return spanFromElement(local.executableContext); | 1751 return spanFromElement(local.executableContext); |
| 1838 } else { | 1752 } else { |
| 1839 throw 'No error location.'; | 1753 throw 'No error location.'; |
| 1840 } | 1754 } |
| 1841 } | 1755 } |
| 1842 | 1756 |
| 1843 Element _elementFromHInstruction(HInstruction instruction) { | 1757 Element _elementFromHInstruction(HInstruction instruction) { |
| 1844 return instruction.sourceElement is Element | 1758 return instruction.sourceElement is Element |
| 1845 ? instruction.sourceElement : null; | 1759 ? instruction.sourceElement |
| 1760 : null; |
| 1846 } | 1761 } |
| 1847 | 1762 |
| 1848 internalError(Spannable node, reason) { | 1763 internalError(Spannable node, reason) { |
| 1849 String message = tryToString(reason); | 1764 String message = tryToString(reason); |
| 1850 reportDiagnosticInternal( | 1765 reportDiagnosticInternal( |
| 1851 createMessage(node, MessageKind.GENERIC, {'text': message}), | 1766 createMessage(node, MessageKind.GENERIC, {'text': message}), |
| 1852 const <DiagnosticMessage>[], | 1767 const <DiagnosticMessage>[], |
| 1853 api.Diagnostic.CRASH); | 1768 api.Diagnostic.CRASH); |
| 1854 throw 'Internal Error: $message'; | 1769 throw 'Internal Error: $message'; |
| 1855 } | 1770 } |
| 1856 | 1771 |
| 1857 void unhandledExceptionOnElement(Element element) { | 1772 void unhandledExceptionOnElement(Element element) { |
| 1858 if (hasCrashed) return; | 1773 if (hasCrashed) return; |
| 1859 hasCrashed = true; | 1774 hasCrashed = true; |
| 1860 reportDiagnostic( | 1775 reportDiagnostic(createMessage(element, MessageKind.COMPILER_CRASHED), |
| 1861 createMessage(element, MessageKind.COMPILER_CRASHED), | 1776 const <DiagnosticMessage>[], api.Diagnostic.CRASH); |
| 1862 const <DiagnosticMessage>[], | |
| 1863 api.Diagnostic.CRASH); | |
| 1864 pleaseReportCrash(); | 1777 pleaseReportCrash(); |
| 1865 } | 1778 } |
| 1866 | 1779 |
| 1867 void pleaseReportCrash() { | 1780 void pleaseReportCrash() { |
| 1868 print( | 1781 print(MessageTemplate.TEMPLATES[MessageKind.PLEASE_REPORT_THE_CRASH] |
| 1869 MessageTemplate.TEMPLATES[MessageKind.PLEASE_REPORT_THE_CRASH] | 1782 .message({'buildId': compiler.options.buildId})); |
| 1870 .message({'buildId': compiler.options.buildId})); | |
| 1871 } | 1783 } |
| 1872 | 1784 |
| 1873 /// Finds the approximate [Element] for [node]. [currentElement] is used as | 1785 /// Finds the approximate [Element] for [node]. [currentElement] is used as |
| 1874 /// the default value. | 1786 /// the default value. |
| 1875 Element elementFromSpannable(Spannable node) { | 1787 Element elementFromSpannable(Spannable node) { |
| 1876 Element element; | 1788 Element element; |
| 1877 if (node is Element) { | 1789 if (node is Element) { |
| 1878 element = node; | 1790 element = node; |
| 1879 } else if (node is HInstruction) { | 1791 } else if (node is HInstruction) { |
| 1880 element = _elementFromHInstruction(node); | 1792 element = _elementFromHInstruction(node); |
| 1881 } else if (node is MetadataAnnotation) { | 1793 } else if (node is MetadataAnnotation) { |
| 1882 element = node.annotatedElement; | 1794 element = node.annotatedElement; |
| 1883 } | 1795 } |
| 1884 return element != null ? element : currentElement; | 1796 return element != null ? element : currentElement; |
| 1885 } | 1797 } |
| 1886 | 1798 |
| 1887 void log(message) { | 1799 void log(message) { |
| 1888 Message msg = MessageTemplate.TEMPLATES[MessageKind.GENERIC] | 1800 Message msg = MessageTemplate.TEMPLATES[MessageKind.GENERIC] |
| 1889 .message({'text': '$message'}); | 1801 .message({'text': '$message'}); |
| 1890 reportDiagnostic( | 1802 reportDiagnostic(new DiagnosticMessage(null, null, msg), |
| 1891 new DiagnosticMessage(null, null, msg), | 1803 const <DiagnosticMessage>[], api.Diagnostic.VERBOSE_INFO); |
| 1892 const <DiagnosticMessage>[], | |
| 1893 api.Diagnostic.VERBOSE_INFO); | |
| 1894 } | 1804 } |
| 1895 | 1805 |
| 1896 String tryToString(object) { | 1806 String tryToString(object) { |
| 1897 try { | 1807 try { |
| 1898 return object.toString(); | 1808 return object.toString(); |
| 1899 } catch (_) { | 1809 } catch (_) { |
| 1900 return '<exception in toString()>'; | 1810 return '<exception in toString()>'; |
| 1901 } | 1811 } |
| 1902 } | 1812 } |
| 1903 | 1813 |
| 1904 onError(Uri uri, error) { | 1814 onError(Uri uri, error) { |
| 1905 try { | 1815 try { |
| 1906 if (!hasCrashed) { | 1816 if (!hasCrashed) { |
| 1907 hasCrashed = true; | 1817 hasCrashed = true; |
| 1908 if (error is SpannableAssertionFailure) { | 1818 if (error is SpannableAssertionFailure) { |
| 1909 reportAssertionFailure(error); | 1819 reportAssertionFailure(error); |
| 1910 } else { | 1820 } else { |
| 1911 reportDiagnostic( | 1821 reportDiagnostic( |
| 1912 createMessage( | 1822 createMessage( |
| 1913 new SourceSpan(uri, 0, 0), | 1823 new SourceSpan(uri, 0, 0), MessageKind.COMPILER_CRASHED), |
| 1914 MessageKind.COMPILER_CRASHED), | |
| 1915 const <DiagnosticMessage>[], | 1824 const <DiagnosticMessage>[], |
| 1916 api.Diagnostic.CRASH); | 1825 api.Diagnostic.CRASH); |
| 1917 } | 1826 } |
| 1918 pleaseReportCrash(); | 1827 pleaseReportCrash(); |
| 1919 } | 1828 } |
| 1920 } catch (doubleFault) { | 1829 } catch (doubleFault) { |
| 1921 // Ignoring exceptions in exception handling. | 1830 // Ignoring exceptions in exception handling. |
| 1922 } | 1831 } |
| 1923 throw error; | 1832 throw error; |
| 1924 } | 1833 } |
| 1925 | 1834 |
| 1926 void onCrashInUserCode(String message, exception, stackTrace) { | 1835 void onCrashInUserCode(String message, exception, stackTrace) { |
| 1927 hasCrashed = true; | 1836 hasCrashed = true; |
| 1928 print('$message: ${tryToString(exception)}'); | 1837 print('$message: ${tryToString(exception)}'); |
| 1929 print(tryToString(stackTrace)); | 1838 print(tryToString(stackTrace)); |
| 1930 } | 1839 } |
| 1931 | 1840 |
| 1932 void reportSuppressedMessagesSummary() { | 1841 void reportSuppressedMessagesSummary() { |
| 1933 if (!options.showAllPackageWarnings && !options.suppressWarnings) { | 1842 if (!options.showAllPackageWarnings && !options.suppressWarnings) { |
| 1934 suppressedWarnings.forEach((Uri uri, SuppressionInfo info) { | 1843 suppressedWarnings.forEach((Uri uri, SuppressionInfo info) { |
| 1935 MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS; | 1844 MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS; |
| 1936 if (info.warnings == 0) { | 1845 if (info.warnings == 0) { |
| 1937 kind = MessageKind.HIDDEN_HINTS; | 1846 kind = MessageKind.HIDDEN_HINTS; |
| 1938 } else if (info.hints == 0) { | 1847 } else if (info.hints == 0) { |
| 1939 kind = MessageKind.HIDDEN_WARNINGS; | 1848 kind = MessageKind.HIDDEN_WARNINGS; |
| 1940 } | 1849 } |
| 1941 MessageTemplate template = MessageTemplate.TEMPLATES[kind]; | 1850 MessageTemplate template = MessageTemplate.TEMPLATES[kind]; |
| 1942 Message message = template.message( | 1851 Message message = template.message( |
| 1943 {'warnings': info.warnings, | 1852 {'warnings': info.warnings, 'hints': info.hints, 'uri': uri}, |
| 1944 'hints': info.hints, | 1853 options.terseDiagnostics); |
| 1945 'uri': uri}, | 1854 reportDiagnostic(new DiagnosticMessage(null, null, message), |
| 1946 options.terseDiagnostics); | 1855 const <DiagnosticMessage>[], api.Diagnostic.HINT); |
| 1947 reportDiagnostic( | |
| 1948 new DiagnosticMessage(null, null, message), | |
| 1949 const <DiagnosticMessage>[], | |
| 1950 api.Diagnostic.HINT); | |
| 1951 }); | 1856 }); |
| 1952 } | 1857 } |
| 1953 } | 1858 } |
| 1954 } | 1859 } |
| 1955 | 1860 |
| 1956 // TODO(johnniwinther): Move [ResolverTask] here. | 1861 // TODO(johnniwinther): Move [ResolverTask] here. |
| 1957 class _CompilerResolution implements Resolution { | 1862 class _CompilerResolution implements Resolution { |
| 1958 final Compiler compiler; | 1863 final Compiler compiler; |
| 1959 final Map<Element, ResolutionImpact> _resolutionImpactCache = | 1864 final Map<Element, ResolutionImpact> _resolutionImpactCache = |
| 1960 <Element, ResolutionImpact>{}; | 1865 <Element, ResolutionImpact>{}; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 message: "WorldImpact not computed for $element.")); | 1927 message: "WorldImpact not computed for $element.")); |
| 2023 return worldImpact; | 1928 return worldImpact; |
| 2024 } | 1929 } |
| 2025 | 1930 |
| 2026 @override | 1931 @override |
| 2027 WorldImpact computeWorldImpact(Element element) { | 1932 WorldImpact computeWorldImpact(Element element) { |
| 2028 return _worldImpactCache.putIfAbsent(element, () { | 1933 return _worldImpactCache.putIfAbsent(element, () { |
| 2029 assert(compiler.parser != null); | 1934 assert(compiler.parser != null); |
| 2030 Node tree = compiler.parser.parse(element); | 1935 Node tree = compiler.parser.parse(element); |
| 2031 assert(invariant(element, !element.isSynthesized || tree == null)); | 1936 assert(invariant(element, !element.isSynthesized || tree == null)); |
| 2032 ResolutionImpact resolutionImpact = | 1937 ResolutionImpact resolutionImpact = compiler.resolver.resolve(element); |
| 2033 compiler.resolver.resolve(element); | 1938 if (compiler.serialization.supportSerialization || |
| 2034 if (compiler.serialization.supportSerialization || retainCachesForTesting)
{ | 1939 retainCachesForTesting) { |
| 2035 // [ResolutionImpact] is currently only used by serialization. The | 1940 // [ResolutionImpact] is currently only used by serialization. The |
| 2036 // enqueuer uses the [WorldImpact] which is always cached. | 1941 // enqueuer uses the [WorldImpact] which is always cached. |
| 2037 // TODO(johnniwinther): Align these use cases better; maybe only | 1942 // TODO(johnniwinther): Align these use cases better; maybe only |
| 2038 // cache [ResolutionImpact] and let the enqueuer transform it into | 1943 // cache [ResolutionImpact] and let the enqueuer transform it into |
| 2039 // a [WorldImpact]. | 1944 // a [WorldImpact]. |
| 2040 _resolutionImpactCache[element] = resolutionImpact; | 1945 _resolutionImpactCache[element] = resolutionImpact; |
| 2041 } | 1946 } |
| 2042 if (tree != null && !compiler.options.analyzeSignaturesOnly) { | 1947 if (tree != null && !compiler.options.analyzeSignaturesOnly) { |
| 2043 // TODO(het): don't do this if suppressWarnings is on, currently we have | 1948 // TODO(het): don't do this if suppressWarnings is on, currently we have |
| 2044 // to do it because the typechecker also sets types | 1949 // to do it because the typechecker also sets types |
| 2045 // Only analyze nodes with a corresponding [TreeElements]. | 1950 // Only analyze nodes with a corresponding [TreeElements]. |
| 2046 compiler.checker.check(element); | 1951 compiler.checker.check(element); |
| 2047 } | 1952 } |
| 2048 WorldImpact worldImpact = | 1953 WorldImpact worldImpact = compiler.backend.impactTransformer |
| 2049 compiler.backend.impactTransformer.transformResolutionImpact( | 1954 .transformResolutionImpact(resolutionImpact); |
| 2050 resolutionImpact); | |
| 2051 return worldImpact; | 1955 return worldImpact; |
| 2052 }); | 1956 }); |
| 2053 } | 1957 } |
| 2054 | 1958 |
| 2055 @override | 1959 @override |
| 2056 void uncacheWorldImpact(Element element) { | 1960 void uncacheWorldImpact(Element element) { |
| 2057 if (retainCachesForTesting) return; | 1961 if (retainCachesForTesting) return; |
| 2058 if (compiler.serialization.isDeserialized(element)) return; | 1962 if (compiler.serialization.isDeserialized(element)) return; |
| 2059 assert(invariant(element, _worldImpactCache[element] != null, | 1963 assert(invariant(element, _worldImpactCache[element] != null, |
| 2060 message: "WorldImpact not computed for $element.")); | 1964 message: "WorldImpact not computed for $element.")); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2073 | 1977 |
| 2074 @override | 1978 @override |
| 2075 bool hasBeenResolved(Element element) { | 1979 bool hasBeenResolved(Element element) { |
| 2076 return _worldImpactCache.containsKey(element); | 1980 return _worldImpactCache.containsKey(element); |
| 2077 } | 1981 } |
| 2078 | 1982 |
| 2079 @override | 1983 @override |
| 2080 ResolutionWorkItem createWorkItem( | 1984 ResolutionWorkItem createWorkItem( |
| 2081 Element element, ItemCompilationContext compilationContext) { | 1985 Element element, ItemCompilationContext compilationContext) { |
| 2082 if (compiler.serialization.isDeserialized(element)) { | 1986 if (compiler.serialization.isDeserialized(element)) { |
| 2083 return compiler.serialization.createResolutionWorkItem( | 1987 return compiler.serialization |
| 2084 element, compilationContext); | 1988 .createResolutionWorkItem(element, compilationContext); |
| 2085 } else { | 1989 } else { |
| 2086 return new ResolutionWorkItem(element, compilationContext); | 1990 return new ResolutionWorkItem(element, compilationContext); |
| 2087 } | 1991 } |
| 2088 } | 1992 } |
| 2089 } | 1993 } |
| 2090 | 1994 |
| 2091 // TODO(johnniwinther): Move [ParserTask], [PatchParserTask], [DietParserTask] | 1995 // TODO(johnniwinther): Move [ParserTask], [PatchParserTask], [DietParserTask] |
| 2092 // and [ScannerTask] here. | 1996 // and [ScannerTask] here. |
| 2093 class _CompilerParsing implements Parsing { | 1997 class _CompilerParsing implements Parsing { |
| 2094 final Compiler compiler; | 1998 final Compiler compiler; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2140 } | 2044 } |
| 2141 } | 2045 } |
| 2142 | 2046 |
| 2143 // TODO(sigmund): in the future, each of these classes should be self contained | 2047 // TODO(sigmund): in the future, each of these classes should be self contained |
| 2144 // and not use references to `compiler`. | 2048 // and not use references to `compiler`. |
| 2145 class _ResolvedUriTranslator implements ResolvedUriTranslator { | 2049 class _ResolvedUriTranslator implements ResolvedUriTranslator { |
| 2146 Compiler compiler; | 2050 Compiler compiler; |
| 2147 _ResolvedUriTranslator(this.compiler); | 2051 _ResolvedUriTranslator(this.compiler); |
| 2148 | 2052 |
| 2149 Uri translate(LibraryElement importingLibrary, Uri resolvedUri, | 2053 Uri translate(LibraryElement importingLibrary, Uri resolvedUri, |
| 2150 [Spannable spannable]) => | 2054 [Spannable spannable]) => |
| 2151 compiler.translateResolvedUri(importingLibrary, resolvedUri, spannable); | 2055 compiler.translateResolvedUri(importingLibrary, resolvedUri, spannable); |
| 2152 } | 2056 } |
| 2153 | 2057 |
| 2154 class _ScriptLoader implements ScriptLoader { | 2058 class _ScriptLoader implements ScriptLoader { |
| 2155 Compiler compiler; | 2059 Compiler compiler; |
| 2156 _ScriptLoader(this.compiler); | 2060 _ScriptLoader(this.compiler); |
| 2157 | 2061 |
| 2158 Future<Script> readScript(Uri uri, [Spannable spannable]) => | 2062 Future<Script> readScript(Uri uri, [Spannable spannable]) => |
| 2159 compiler.readScript(uri, spannable); | 2063 compiler.readScript(uri, spannable); |
| 2160 } | 2064 } |
| 2161 | 2065 |
| 2162 class _ElementScanner implements ElementScanner { | 2066 class _ElementScanner implements ElementScanner { |
| 2163 ScannerTask scanner; | 2067 ScannerTask scanner; |
| 2164 _ElementScanner(this.scanner); | 2068 _ElementScanner(this.scanner); |
| 2165 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); | 2069 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); |
| 2166 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); | 2070 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); |
| 2167 } | 2071 } |
| 2168 | 2072 |
| 2169 class _EmptyEnvironment implements Environment { | 2073 class _EmptyEnvironment implements Environment { |
| 2170 const _EmptyEnvironment(); | 2074 const _EmptyEnvironment(); |
| 2171 | 2075 |
| 2172 String valueOf(String key) => null; | 2076 String valueOf(String key) => null; |
| 2173 } | 2077 } |
| OLD | NEW |