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 |