| 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 js_backend.backend; | 5 library js_backend.backend; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| 10 | 10 |
| 11 import '../closure.dart'; | 11 import '../closure.dart'; |
| 12 import '../common.dart'; | 12 import '../common.dart'; |
| 13 import '../common/backend_api.dart' | 13 import '../common/backend_api.dart' |
| 14 show | 14 show BackendClasses, ImpactTransformer, ForeignResolver, NativeRegistry; |
| 15 Backend, | |
| 16 BackendClasses, | |
| 17 ImpactTransformer, | |
| 18 ForeignResolver, | |
| 19 NativeRegistry; | |
| 20 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; | 15 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
| 21 import '../common/names.dart' show Identifiers, Uris; | 16 import '../common/names.dart' show Identifiers, Uris; |
| 22 import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact; | 17 import '../common/resolution.dart' |
| 18 show Frontend, Resolution, ResolutionImpact, Target; |
| 23 import '../common/tasks.dart' show CompilerTask; | 19 import '../common/tasks.dart' show CompilerTask; |
| 24 import '../compiler.dart' show Compiler; | 20 import '../compiler.dart' show Compiler; |
| 25 import '../constants/constant_system.dart'; | 21 import '../constants/constant_system.dart'; |
| 26 import '../constants/expressions.dart'; | 22 import '../constants/expressions.dart'; |
| 27 import '../constants/values.dart'; | 23 import '../constants/values.dart'; |
| 28 import '../core_types.dart' show CommonElements; | 24 import '../core_types.dart' show CommonElements; |
| 29 import '../deferred_load.dart' show DeferredLoadTask; | 25 import '../deferred_load.dart' show DeferredLoadTask; |
| 30 import '../dump_info.dart' show DumpInfoTask; | 26 import '../dump_info.dart' show DumpInfoTask; |
| 31 import '../elements/elements.dart'; | 27 import '../elements/elements.dart'; |
| 32 import '../elements/entities.dart'; | 28 import '../elements/entities.dart'; |
| 33 import '../elements/resolution_types.dart'; | 29 import '../elements/resolution_types.dart'; |
| 34 import '../elements/types.dart'; | 30 import '../elements/types.dart'; |
| 35 import '../enqueue.dart' | 31 import '../enqueue.dart' |
| 36 show Enqueuer, ResolutionEnqueuer, TreeShakingEnqueuerStrategy; | 32 show Enqueuer, EnqueueTask, ResolutionEnqueuer, TreeShakingEnqueuerStrategy; |
| 37 import '../io/position_information.dart' show PositionSourceInformationStrategy; | 33 import '../io/position_information.dart' show PositionSourceInformationStrategy; |
| 38 import '../io/source_information.dart' show SourceInformationStrategy; | 34 import '../io/source_information.dart' show SourceInformationStrategy; |
| 39 import '../io/start_end_information.dart' | 35 import '../io/start_end_information.dart' |
| 40 show StartEndSourceInformationStrategy; | 36 show StartEndSourceInformationStrategy; |
| 41 import '../js/js.dart' as jsAst; | 37 import '../js/js.dart' as jsAst; |
| 42 import '../js/js.dart' show js; | 38 import '../js/js.dart' show js; |
| 43 import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy; | 39 import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy; |
| 44 import '../js/rewrite_async.dart'; | 40 import '../js/rewrite_async.dart'; |
| 45 import '../js_emitter/js_emitter.dart' show CodeEmitterTask; | 41 import '../js_emitter/js_emitter.dart' show CodeEmitterTask; |
| 46 import '../library_loader.dart' show LibraryLoader, LoadedLibraries; | 42 import '../library_loader.dart' show LibraryLoader, LoadedLibraries; |
| 47 import '../native/native.dart' as native; | 43 import '../native/native.dart' as native; |
| 44 import '../patch_parser.dart' |
| 45 show checkNativeAnnotation, checkJsInteropAnnotation; |
| 48 import '../ssa/ssa.dart' show SsaFunctionCompiler; | 46 import '../ssa/ssa.dart' show SsaFunctionCompiler; |
| 49 import '../tracer.dart'; | 47 import '../tracer.dart'; |
| 50 import '../tree/tree.dart'; | 48 import '../tree/tree.dart'; |
| 51 import '../types/types.dart'; | 49 import '../types/types.dart'; |
| 52 import '../universe/call_structure.dart' show CallStructure; | 50 import '../universe/call_structure.dart' show CallStructure; |
| 53 import '../universe/feature.dart'; | 51 import '../universe/feature.dart'; |
| 54 import '../universe/selector.dart' show Selector; | 52 import '../universe/selector.dart' show Selector; |
| 55 import '../universe/world_builder.dart'; | 53 import '../universe/world_builder.dart'; |
| 56 import '../universe/use.dart' | 54 import '../universe/use.dart' |
| 57 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; | 55 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 } | 295 } |
| 298 } | 296 } |
| 299 | 297 |
| 300 enum SyntheticConstantKind { | 298 enum SyntheticConstantKind { |
| 301 DUMMY_INTERCEPTOR, | 299 DUMMY_INTERCEPTOR, |
| 302 EMPTY_VALUE, | 300 EMPTY_VALUE, |
| 303 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. | 301 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. |
| 304 NAME | 302 NAME |
| 305 } | 303 } |
| 306 | 304 |
| 307 class JavaScriptBackend extends Backend { | 305 class JavaScriptBackend extends Target { |
| 306 final Compiler compiler; |
| 307 |
| 308 String get patchVersion => emitter.patchVersion; | 308 String get patchVersion => emitter.patchVersion; |
| 309 | 309 |
| 310 /// Returns true if the backend supports reflection. |
| 310 bool get supportsReflection => emitter.supportsReflection; | 311 bool get supportsReflection => emitter.supportsReflection; |
| 311 | 312 |
| 312 final Annotations annotations; | 313 final Annotations annotations; |
| 313 | 314 |
| 314 /// Set of classes that need to be considered for reflection although not | 315 /// Set of classes that need to be considered for reflection although not |
| 315 /// otherwise visible during resolution. | 316 /// otherwise visible during resolution. |
| 316 Iterable<ClassElement> get classesRequiredForReflection { | 317 Iterable<ClassElement> get classesRequiredForReflection { |
| 317 // TODO(herhut): Clean this up when classes needed for rti are tracked. | 318 // TODO(herhut): Clean this up when classes needed for rti are tracked. |
| 318 return [helpers.closureClass, helpers.jsIndexableClass]; | 319 return [helpers.closureClass, helpers.jsIndexableClass]; |
| 319 } | 320 } |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 | 524 |
| 524 /// Support for classifying `noSuchMethod` implementations. | 525 /// Support for classifying `noSuchMethod` implementations. |
| 525 NoSuchMethodRegistry noSuchMethodRegistry; | 526 NoSuchMethodRegistry noSuchMethodRegistry; |
| 526 | 527 |
| 527 /// Resolution and codegen support for computing reflectable elements. | 528 /// Resolution and codegen support for computing reflectable elements. |
| 528 MirrorsAnalysis mirrorsAnalysis; | 529 MirrorsAnalysis mirrorsAnalysis; |
| 529 | 530 |
| 530 /// Builds kernel representation for the program. | 531 /// Builds kernel representation for the program. |
| 531 KernelTask kernelTask; | 532 KernelTask kernelTask; |
| 532 | 533 |
| 534 /// The compiler task responsible for the compilation of constants for both |
| 535 /// the frontend and the backend. |
| 533 JavaScriptConstantTask constantCompilerTask; | 536 JavaScriptConstantTask constantCompilerTask; |
| 534 | 537 |
| 538 /// Backend transformation methods for the world impacts. |
| 535 JavaScriptImpactTransformer impactTransformer; | 539 JavaScriptImpactTransformer impactTransformer; |
| 536 | 540 |
| 537 PatchResolverTask patchResolverTask; | 541 PatchResolverTask patchResolverTask; |
| 538 | 542 |
| 543 /// Whether or not `noSuchMethod` support has been enabled. |
| 539 bool enabledNoSuchMethod = false; | 544 bool enabledNoSuchMethod = false; |
| 540 bool _noSuchMethodEnabledForCodegen = false; | 545 bool _noSuchMethodEnabledForCodegen = false; |
| 541 | 546 |
| 547 /// The strategy used for collecting and emitting source information. |
| 542 SourceInformationStrategy sourceInformationStrategy; | 548 SourceInformationStrategy sourceInformationStrategy; |
| 543 | 549 |
| 550 /// Interface for serialization of backend specific data. |
| 544 JavaScriptBackendSerialization serialization; | 551 JavaScriptBackendSerialization serialization; |
| 545 | 552 |
| 546 StagedWorldImpactBuilder constantImpactsForResolution = | 553 StagedWorldImpactBuilder constantImpactsForResolution = |
| 547 new StagedWorldImpactBuilder(); | 554 new StagedWorldImpactBuilder(); |
| 548 | 555 |
| 549 StagedWorldImpactBuilder constantImpactsForCodegen = | 556 StagedWorldImpactBuilder constantImpactsForCodegen = |
| 550 new StagedWorldImpactBuilder(); | 557 new StagedWorldImpactBuilder(); |
| 551 | 558 |
| 552 final NativeData nativeData = new NativeData(); | 559 final NativeData nativeData = new NativeData(); |
| 553 | 560 |
| 554 BackendHelpers helpers; | 561 BackendHelpers helpers; |
| 555 final BackendImpacts impacts; | 562 final BackendImpacts impacts; |
| 563 |
| 564 /// Common classes used by the backend. |
| 556 BackendClasses backendClasses; | 565 BackendClasses backendClasses; |
| 557 | 566 |
| 567 /// Backend access to the front-end. |
| 558 final JSFrontendAccess frontend; | 568 final JSFrontendAccess frontend; |
| 559 | 569 |
| 560 Tracer tracer; | 570 Tracer tracer; |
| 561 | 571 |
| 562 JavaScriptBackend(Compiler compiler, | 572 JavaScriptBackend(Compiler compiler, |
| 563 {bool generateSourceMap: true, | 573 {bool generateSourceMap: true, |
| 564 bool useStartupEmitter: false, | 574 bool useStartupEmitter: false, |
| 565 bool useNewSourceInfo: false, | 575 bool useNewSourceInfo: false, |
| 566 bool useKernel: false}) | 576 bool useKernel: false}) |
| 567 : oneShotInterceptors = new Map<jsAst.Name, Selector>(), | 577 : oneShotInterceptors = new Map<jsAst.Name, Selector>(), |
| 568 interceptedElements = new Map<String, Set<Element>>(), | 578 interceptedElements = new Map<String, Set<Element>>(), |
| 569 rti = new _RuntimeTypes(compiler), | 579 rti = new _RuntimeTypes(compiler), |
| 570 rtiEncoder = new _RuntimeTypesEncoder(compiler), | 580 rtiEncoder = new _RuntimeTypesEncoder(compiler), |
| 571 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), | 581 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), |
| 572 annotations = new Annotations(compiler), | 582 annotations = new Annotations(compiler), |
| 573 this.sourceInformationStrategy = generateSourceMap | 583 this.sourceInformationStrategy = generateSourceMap |
| 574 ? (useNewSourceInfo | 584 ? (useNewSourceInfo |
| 575 ? new PositionSourceInformationStrategy() | 585 ? new PositionSourceInformationStrategy() |
| 576 : const StartEndSourceInformationStrategy()) | 586 : const StartEndSourceInformationStrategy()) |
| 577 : const JavaScriptSourceInformationStrategy(), | 587 : const JavaScriptSourceInformationStrategy(), |
| 578 impacts = new BackendImpacts(compiler), | 588 impacts = new BackendImpacts(compiler), |
| 579 frontend = new JSFrontendAccess(compiler), | 589 frontend = new JSFrontendAccess(compiler), |
| 580 super(compiler) { | 590 this.compiler = compiler { |
| 581 helpers = | 591 helpers = |
| 582 new BackendHelpers(compiler.elementEnvironment, this, commonElements); | 592 new BackendHelpers(compiler.elementEnvironment, this, commonElements); |
| 583 emitter = | 593 emitter = |
| 584 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); | 594 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); |
| 585 typeVariableHandler = new TypeVariableHandler(compiler); | 595 typeVariableHandler = new TypeVariableHandler(compiler); |
| 586 customElementsAnalysis = new CustomElementsAnalysis(this); | 596 customElementsAnalysis = new CustomElementsAnalysis(this); |
| 587 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); | 597 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); |
| 588 jsInteropAnalysis = new JsInteropAnalysis(this); | 598 jsInteropAnalysis = new JsInteropAnalysis(this); |
| 589 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); | 599 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); |
| 590 | 600 |
| 591 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 601 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
| 592 kernelTask = new KernelTask(compiler); | 602 kernelTask = new KernelTask(compiler); |
| 593 constantCompilerTask = new JavaScriptConstantTask(compiler); | 603 constantCompilerTask = new JavaScriptConstantTask(compiler); |
| 594 impactTransformer = new JavaScriptImpactTransformer(this); | 604 impactTransformer = new JavaScriptImpactTransformer(this); |
| 595 patchResolverTask = new PatchResolverTask(compiler); | 605 patchResolverTask = new PatchResolverTask(compiler); |
| 596 functionCompiler = | 606 functionCompiler = |
| 597 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); | 607 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); |
| 598 serialization = new JavaScriptBackendSerialization(this); | 608 serialization = new JavaScriptBackendSerialization(this); |
| 599 backendClasses = new JavaScriptBackendClasses(helpers); | 609 backendClasses = new JavaScriptBackendClasses(helpers); |
| 600 } | 610 } |
| 601 | 611 |
| 612 /// The [ConstantSystem] used to interpret compile-time constants for this |
| 613 /// backend. |
| 602 ConstantSystem get constantSystem => constants.constantSystem; | 614 ConstantSystem get constantSystem => constants.constantSystem; |
| 603 | 615 |
| 604 DiagnosticReporter get reporter => compiler.reporter; | 616 DiagnosticReporter get reporter => compiler.reporter; |
| 605 | 617 |
| 606 CommonElements get commonElements => compiler.commonElements; | 618 CommonElements get commonElements => compiler.commonElements; |
| 607 | 619 |
| 608 Resolution get resolution => compiler.resolution; | 620 Resolution get resolution => compiler.resolution; |
| 609 | 621 |
| 610 /// Returns constant environment for the JavaScript interpretation of the | 622 /// Returns constant environment for the JavaScript interpretation of the |
| 611 /// constants. | 623 /// constants. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 // add both to the list of helpers. | 680 // add both to the list of helpers. |
| 669 helpersUsed.add(element.implementation); | 681 helpersUsed.add(element.implementation); |
| 670 } | 682 } |
| 671 return element; | 683 return element; |
| 672 } | 684 } |
| 673 | 685 |
| 674 bool _isValidBackendUse(Element element) { | 686 bool _isValidBackendUse(Element element) { |
| 675 assert(invariant(element, element.isDeclaration, message: "")); | 687 assert(invariant(element, element.isDeclaration, message: "")); |
| 676 if (element is ConstructorElement && | 688 if (element is ConstructorElement && |
| 677 (element == helpers.streamIteratorConstructor || | 689 (element == helpers.streamIteratorConstructor || |
| 678 compiler.commonElements.isSymbolConstructor(element) || | 690 compiler.commonElements.isSymbolConstructor(element) || |
| 679 helpers.isSymbolValidatedConstructor(element) || | 691 helpers.isSymbolValidatedConstructor(element) || |
| 680 element == helpers.syncCompleterConstructor)) { | 692 element == helpers.syncCompleterConstructor)) { |
| 681 // TODO(johnniwinther): These are valid but we could be more precise. | 693 // TODO(johnniwinther): These are valid but we could be more precise. |
| 682 return true; | 694 return true; |
| 683 } else if (element == commonElements.symbolClass || | 695 } else if (element == commonElements.symbolClass || |
| 684 element == helpers.objectNoSuchMethod) { | 696 element == helpers.objectNoSuchMethod) { |
| 685 // TODO(johnniwinther): These are valid but we could be more precise. | 697 // TODO(johnniwinther): These are valid but we could be more precise. |
| 686 return true; | 698 return true; |
| 687 } else if (element.implementationLibrary.isPatch || | 699 } else if (element.implementationLibrary.isPatch || |
| 688 // Needed to detect deserialized injected elements, that is | 700 // Needed to detect deserialized injected elements, that is |
| 689 // element declared in patch files. | 701 // element declared in patch files. |
| 690 (element.library.isPlatformLibrary && | 702 (element.library.isPlatformLibrary && |
| 691 element.sourcePosition.uri.path | 703 element.sourcePosition.uri.path |
| 692 .contains('_internal/js_runtime/lib/')) || | 704 .contains('_internal/js_runtime/lib/')) || |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 if (element.isField) { | 739 if (element.isField) { |
| 728 if (Elements.isStaticOrTopLevel(element) && | 740 if (Elements.isStaticOrTopLevel(element) && |
| 729 (element.isFinal || element.isConst)) { | 741 (element.isFinal || element.isConst)) { |
| 730 return false; | 742 return false; |
| 731 } | 743 } |
| 732 } | 744 } |
| 733 | 745 |
| 734 return isAccessibleByReflection(element.declaration); | 746 return isAccessibleByReflection(element.declaration); |
| 735 } | 747 } |
| 736 | 748 |
| 749 /// Returns true if global optimizations such as type inferencing |
| 750 /// can apply to this element. One category of elements that do not |
| 751 /// apply is runtime helpers that the backend calls, but the |
| 752 /// optimizations don't see those calls. |
| 737 bool canBeUsedForGlobalOptimizations(Element element) { | 753 bool canBeUsedForGlobalOptimizations(Element element) { |
| 738 return !usedByBackend(element) && !invokedReflectively(element); | 754 return !usedByBackend(element) && !invokedReflectively(element); |
| 739 } | 755 } |
| 740 | 756 |
| 741 bool isInterceptorClass(ClassElement element) { | 757 bool isInterceptorClass(ClassElement element) { |
| 742 if (element == null) return false; | 758 if (element == null) return false; |
| 743 if (isNativeOrExtendsNative(element)) return true; | 759 if (isNativeOrExtendsNative(element)) return true; |
| 744 if (interceptedClasses.contains(element)) return true; | 760 if (interceptedClasses.contains(element)) return true; |
| 745 if (classesMixedIntoInterceptedClasses.contains(element)) return true; | 761 if (classesMixedIntoInterceptedClasses.contains(element)) return true; |
| 746 return false; | 762 return false; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 774 return !selector.isGetter; | 790 return !selector.isGetter; |
| 775 } | 791 } |
| 776 | 792 |
| 777 /** | 793 /** |
| 778 * Returns `true` if [member] is called from a subclass via `super`. | 794 * Returns `true` if [member] is called from a subclass via `super`. |
| 779 */ | 795 */ |
| 780 bool isAliasedSuperMember(FunctionElement member) { | 796 bool isAliasedSuperMember(FunctionElement member) { |
| 781 return aliasedSuperMembers.contains(member); | 797 return aliasedSuperMembers.contains(member); |
| 782 } | 798 } |
| 783 | 799 |
| 784 /// Returns `true` if [element] is part of JsInterop. | 800 /// Returns `true` if [element] is implemented via typed JavaScript interop. |
| 785 @override | 801 @override |
| 786 bool isJsInterop(Element element) => nativeData.isJsInterop(element); | 802 bool isJsInterop(Element element) => nativeData.isJsInterop(element); |
| 787 | 803 |
| 788 /// Returns `true` if [element] is a JsInterop class. | 804 /// Returns `true` if [element] is a JsInterop class. |
| 789 bool isJsInteropClass(ClassElement element) => isJsInterop(element); | 805 bool isJsInteropClass(ClassElement element) => isJsInterop(element); |
| 790 | 806 |
| 791 /// Returns `true` if [element] is a JsInterop method. | 807 /// Returns `true` if [element] is a JsInterop method. |
| 792 bool isJsInteropMethod(MethodElement element) => isJsInterop(element); | 808 bool isJsInteropMethod(MethodElement element) => isJsInterop(element); |
| 793 | 809 |
| 794 /// Whether [element] corresponds to a native JavaScript construct either | 810 /// Whether [element] corresponds to a native JavaScript construct either |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 jsAst.Name name = namer.nameForGetInterceptor(classes); | 1065 jsAst.Name name = namer.nameForGetInterceptor(classes); |
| 1050 if (classes.contains(helpers.jsInterceptorClass)) { | 1066 if (classes.contains(helpers.jsInterceptorClass)) { |
| 1051 // We can't use a specialized [getInterceptorMethod], so we make | 1067 // We can't use a specialized [getInterceptorMethod], so we make |
| 1052 // sure we emit the one with all checks. | 1068 // sure we emit the one with all checks. |
| 1053 specializedGetInterceptors[name] = interceptedClasses; | 1069 specializedGetInterceptors[name] = interceptedClasses; |
| 1054 } else { | 1070 } else { |
| 1055 specializedGetInterceptors[name] = classes; | 1071 specializedGetInterceptors[name] = classes; |
| 1056 } | 1072 } |
| 1057 } | 1073 } |
| 1058 | 1074 |
| 1075 /// Called during codegen when [constant] has been used. |
| 1059 void computeImpactForCompileTimeConstant(ConstantValue constant, | 1076 void computeImpactForCompileTimeConstant(ConstantValue constant, |
| 1060 WorldImpactBuilder impactBuilder, bool isForResolution) { | 1077 WorldImpactBuilder impactBuilder, bool isForResolution) { |
| 1061 computeImpactForCompileTimeConstantInternal( | 1078 computeImpactForCompileTimeConstantInternal( |
| 1062 constant, impactBuilder, isForResolution); | 1079 constant, impactBuilder, isForResolution); |
| 1063 | 1080 |
| 1064 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { | 1081 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { |
| 1065 // Note: internally, this registration will temporarily remove the | 1082 // Note: internally, this registration will temporarily remove the |
| 1066 // constant dependencies and add them later on-demand. | 1083 // constant dependencies and add them later on-demand. |
| 1067 lookupMapAnalysis.registerLookupMapReference(constant); | 1084 lookupMapAnalysis.registerLookupMapReference(constant); |
| 1068 } | 1085 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 // constant emitter will generate a call to the createRuntimeType | 1138 // constant emitter will generate a call to the createRuntimeType |
| 1122 // helper so we register a use of that. | 1139 // helper so we register a use of that. |
| 1123 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 1140 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 1124 // TODO(johnniwinther): Find the right [CallStructure]. | 1141 // TODO(johnniwinther): Find the right [CallStructure]. |
| 1125 helpers.createRuntimeType, | 1142 helpers.createRuntimeType, |
| 1126 null)); | 1143 null)); |
| 1127 } | 1144 } |
| 1128 } | 1145 } |
| 1129 } | 1146 } |
| 1130 | 1147 |
| 1148 /// Called to notify to the backend that a class is being instantiated. Any |
| 1149 /// backend specific [WorldImpact] of this is returned. |
| 1131 WorldImpact registerInstantiatedClass(ClassElement cls, | 1150 WorldImpact registerInstantiatedClass(ClassElement cls, |
| 1132 {bool forResolution}) { | 1151 {bool forResolution}) { |
| 1133 return _processClass(cls, forResolution: forResolution); | 1152 return _processClass(cls, forResolution: forResolution); |
| 1134 } | 1153 } |
| 1135 | 1154 |
| 1155 /// Called to notify to the backend that a class is implemented by an |
| 1156 /// instantiated class. Any backend specific [WorldImpact] of this is |
| 1157 /// returned. |
| 1136 WorldImpact registerImplementedClass(ClassElement cls, {bool forResolution}) { | 1158 WorldImpact registerImplementedClass(ClassElement cls, {bool forResolution}) { |
| 1137 return _processClass(cls, forResolution: forResolution); | 1159 return _processClass(cls, forResolution: forResolution); |
| 1138 } | 1160 } |
| 1139 | 1161 |
| 1140 WorldImpact _processClass(ClassElement cls, {bool forResolution}) { | 1162 WorldImpact _processClass(ClassElement cls, {bool forResolution}) { |
| 1141 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | 1163 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 1142 if (!cls.typeVariables.isEmpty) { | 1164 if (!cls.typeVariables.isEmpty) { |
| 1143 typeVariableHandler.registerClassWithTypeVariables(cls, | 1165 typeVariableHandler.registerClassWithTypeVariables(cls, |
| 1144 forResolution: forResolution); | 1166 forResolution: forResolution); |
| 1145 } | 1167 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 | 1280 |
| 1259 customElementsAnalysis.registerInstantiatedClass(cls, | 1281 customElementsAnalysis.registerInstantiatedClass(cls, |
| 1260 forResolution: forResolution); | 1282 forResolution: forResolution); |
| 1261 if (!forResolution) { | 1283 if (!forResolution) { |
| 1262 lookupMapAnalysis.registerInstantiatedClass(cls); | 1284 lookupMapAnalysis.registerInstantiatedClass(cls); |
| 1263 } | 1285 } |
| 1264 | 1286 |
| 1265 return impactBuilder; | 1287 return impactBuilder; |
| 1266 } | 1288 } |
| 1267 | 1289 |
| 1290 /// Called to instruct to the backend register [type] as instantiated on |
| 1291 /// [enqueuer]. |
| 1268 void registerInstantiatedType(ResolutionInterfaceType type) { | 1292 void registerInstantiatedType(ResolutionInterfaceType type) { |
| 1269 lookupMapAnalysis.registerInstantiatedType(type); | 1293 lookupMapAnalysis.registerInstantiatedType(type); |
| 1270 } | 1294 } |
| 1271 | 1295 |
| 1272 @override | 1296 /// Compute the [WorldImpact] for backend helper methods. |
| 1273 WorldImpact computeHelpersImpact() { | 1297 WorldImpact computeHelpersImpact() { |
| 1274 assert(helpers.interceptorsLibrary != null); | 1298 assert(helpers.interceptorsLibrary != null); |
| 1275 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | 1299 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 1276 // TODO(ngeoffray): Not enqueuing those two classes currently make | 1300 // TODO(ngeoffray): Not enqueuing those two classes currently make |
| 1277 // the compiler potentially crash. However, any reasonable program | 1301 // the compiler potentially crash. However, any reasonable program |
| 1278 // will instantiate those two classes. | 1302 // will instantiate those two classes. |
| 1279 addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true); | 1303 addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true); |
| 1280 addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true); | 1304 addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true); |
| 1281 if (compiler.options.enableTypeAssertions) { | 1305 if (compiler.options.enableTypeAssertions) { |
| 1282 impactTransformer.registerBackendImpact( | 1306 impactTransformer.registerBackendImpact( |
| 1283 impactBuilder, impacts.enableTypeAssertions); | 1307 impactBuilder, impacts.enableTypeAssertions); |
| 1284 } | 1308 } |
| 1285 | 1309 |
| 1286 if (TRACE_CALLS) { | 1310 if (TRACE_CALLS) { |
| 1287 impactTransformer.registerBackendImpact( | 1311 impactTransformer.registerBackendImpact( |
| 1288 impactBuilder, impacts.traceHelper); | 1312 impactBuilder, impacts.traceHelper); |
| 1289 } | 1313 } |
| 1290 impactTransformer.registerBackendImpact( | 1314 impactTransformer.registerBackendImpact( |
| 1291 impactBuilder, impacts.assertUnreachable); | 1315 impactBuilder, impacts.assertUnreachable); |
| 1292 _registerCheckedModeHelpers(impactBuilder); | 1316 _registerCheckedModeHelpers(impactBuilder); |
| 1293 return impactBuilder; | 1317 return impactBuilder; |
| 1294 } | 1318 } |
| 1295 | 1319 |
| 1296 onResolutionComplete( | 1320 void onResolutionComplete( |
| 1297 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { | 1321 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { |
| 1298 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { | 1322 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { |
| 1299 processAnnotations(entity, closedWorldRefiner); | 1323 processAnnotations(entity, closedWorldRefiner); |
| 1300 } | 1324 } |
| 1301 computeMembersNeededForReflection(closedWorld); | 1325 computeMembersNeededForReflection(closedWorld); |
| 1302 rti.computeClassesNeedingRti( | 1326 rti.computeClassesNeedingRti( |
| 1303 compiler.enqueuer.resolution.worldBuilder, closedWorld); | 1327 compiler.enqueuer.resolution.worldBuilder, closedWorld); |
| 1304 _registeredMetadata.clear(); | 1328 _registeredMetadata.clear(); |
| 1305 } | 1329 } |
| 1306 | 1330 |
| 1307 onTypeInferenceComplete() { | 1331 void onTypeInferenceComplete() { |
| 1308 super.onTypeInferenceComplete(); | |
| 1309 noSuchMethodRegistry.onTypeInferenceComplete(); | 1332 noSuchMethodRegistry.onTypeInferenceComplete(); |
| 1310 } | 1333 } |
| 1311 | 1334 |
| 1312 /// Called to register that an instantiated generic class has a call method. | 1335 /// Called to register that an instantiated generic class has a call method. |
| 1313 /// Any backend specific [WorldImpact] of this is returned. | 1336 /// Any backend specific [WorldImpact] of this is returned. |
| 1314 /// | 1337 /// |
| 1315 /// Note: The [callMethod] is registered even thought it doesn't reference | 1338 /// Note: The [callMethod] is registered even thought it doesn't reference |
| 1316 /// the type variables. | 1339 /// the type variables. |
| 1317 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, | 1340 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, |
| 1318 {bool forResolution}) { | 1341 {bool forResolution}) { |
| 1319 if (forResolution || methodNeedsRti(callMethod)) { | 1342 if (forResolution || methodNeedsRti(callMethod)) { |
| 1320 return _registerComputeSignature(); | 1343 return _registerComputeSignature(); |
| 1321 } | 1344 } |
| 1322 return const WorldImpact(); | 1345 return const WorldImpact(); |
| 1323 } | 1346 } |
| 1324 | 1347 |
| 1348 /// Called to instruct the backend to register that a closure exists for a |
| 1349 /// function on an instantiated generic class. Any backend specific |
| 1350 /// [WorldImpact] of this is returned. |
| 1325 WorldImpact registerClosureWithFreeTypeVariables(Element closure, | 1351 WorldImpact registerClosureWithFreeTypeVariables(Element closure, |
| 1326 {bool forResolution}) { | 1352 {bool forResolution}) { |
| 1327 if (forResolution || methodNeedsRti(closure)) { | 1353 if (forResolution || methodNeedsRti(closure)) { |
| 1328 return _registerComputeSignature(); | 1354 return _registerComputeSignature(); |
| 1329 } | 1355 } |
| 1330 return const WorldImpact(); | 1356 return const WorldImpact(); |
| 1331 } | 1357 } |
| 1332 | 1358 |
| 1359 /// Called to register that a member has been closurized. Any backend specific |
| 1360 /// [WorldImpact] of this is returned. |
| 1333 WorldImpact registerBoundClosure() { | 1361 WorldImpact registerBoundClosure() { |
| 1334 return impactTransformer.createImpactFor(impacts.memberClosure); | 1362 return impactTransformer.createImpactFor(impacts.memberClosure); |
| 1335 } | 1363 } |
| 1336 | 1364 |
| 1365 /// Called to register that a static function has been closurized. Any backend |
| 1366 /// specific [WorldImpact] of this is returned. |
| 1337 WorldImpact registerGetOfStaticFunction() { | 1367 WorldImpact registerGetOfStaticFunction() { |
| 1338 return impactTransformer.createImpactFor(impacts.staticClosure); | 1368 return impactTransformer.createImpactFor(impacts.staticClosure); |
| 1339 } | 1369 } |
| 1340 | 1370 |
| 1341 WorldImpact _registerComputeSignature() { | 1371 WorldImpact _registerComputeSignature() { |
| 1342 return impactTransformer.createImpactFor(impacts.computeSignature); | 1372 return impactTransformer.createImpactFor(impacts.computeSignature); |
| 1343 } | 1373 } |
| 1344 | 1374 |
| 1345 /// Called to register that the `runtimeType` property has been accessed. Any | 1375 /// Called to register that the `runtimeType` property has been accessed. Any |
| 1346 /// backend specific [WorldImpact] of this is returned. | 1376 /// backend specific [WorldImpact] of this is returned. |
| 1347 WorldImpact registerRuntimeType() { | 1377 WorldImpact registerRuntimeType() { |
| 1348 return impactTransformer.createImpactFor(impacts.runtimeTypeSupport); | 1378 return impactTransformer.createImpactFor(impacts.runtimeTypeSupport); |
| 1349 } | 1379 } |
| 1350 | 1380 |
| 1381 /// Register a runtime type variable bound tests between [typeArgument] and |
| 1382 /// [bound]. |
| 1351 void registerTypeVariableBoundsSubtypeCheck( | 1383 void registerTypeVariableBoundsSubtypeCheck( |
| 1352 ResolutionDartType typeArgument, ResolutionDartType bound) { | 1384 ResolutionDartType typeArgument, ResolutionDartType bound) { |
| 1353 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); | 1385 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); |
| 1354 } | 1386 } |
| 1355 | 1387 |
| 1388 /// Returns the [WorldImpact] of enabling deferred loading. |
| 1356 WorldImpact computeDeferredLoadingImpact() { | 1389 WorldImpact computeDeferredLoadingImpact() { |
| 1357 return impactTransformer.createImpactFor(impacts.deferredLoading); | 1390 return impactTransformer.createImpactFor(impacts.deferredLoading); |
| 1358 } | 1391 } |
| 1359 | 1392 |
| 1360 /// Called to register a `noSuchMethod` implementation. | 1393 /// Called to register a `noSuchMethod` implementation. |
| 1361 void registerNoSuchMethod(MethodElement noSuchMethod) { | 1394 void registerNoSuchMethod(MethodElement noSuchMethod) { |
| 1362 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); | 1395 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); |
| 1363 } | 1396 } |
| 1364 | 1397 |
| 1365 /// Called when resolving a call to a foreign function. | 1398 /// Called when resolving a call to a foreign function. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1393 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 1426 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
| 1394 } | 1427 } |
| 1395 // No native behavior for this call. | 1428 // No native behavior for this call. |
| 1396 return null; | 1429 return null; |
| 1397 } | 1430 } |
| 1398 | 1431 |
| 1399 WorldImpact computeNoSuchMethodImpact() { | 1432 WorldImpact computeNoSuchMethodImpact() { |
| 1400 return impactTransformer.createImpactFor(impacts.noSuchMethodSupport); | 1433 return impactTransformer.createImpactFor(impacts.noSuchMethodSupport); |
| 1401 } | 1434 } |
| 1402 | 1435 |
| 1436 /// Called to enable support for isolates. Any backend specific [WorldImpact] |
| 1437 /// of this is returned. |
| 1403 WorldImpact enableIsolateSupport({bool forResolution}) { | 1438 WorldImpact enableIsolateSupport({bool forResolution}) { |
| 1404 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | 1439 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 1405 // TODO(floitsch): We should also ensure that the class IsolateMessage is | 1440 // TODO(floitsch): We should also ensure that the class IsolateMessage is |
| 1406 // instantiated. Currently, just enabling isolate support works. | 1441 // instantiated. Currently, just enabling isolate support works. |
| 1407 if (compiler.mainFunction != null) { | 1442 if (compiler.mainFunction != null) { |
| 1408 // The JavaScript backend implements [Isolate.spawn] by looking up | 1443 // The JavaScript backend implements [Isolate.spawn] by looking up |
| 1409 // top-level functions by name. So all top-level function tear-off | 1444 // top-level functions by name. So all top-level function tear-off |
| 1410 // closures have a private name field. | 1445 // closures have a private name field. |
| 1411 // | 1446 // |
| 1412 // The JavaScript backend of [Isolate.spawnUri] uses the same internal | 1447 // The JavaScript backend of [Isolate.spawnUri] uses the same internal |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1437 | 1472 |
| 1438 bool isComplexNoSuchMethod(FunctionElement element) => | 1473 bool isComplexNoSuchMethod(FunctionElement element) => |
| 1439 noSuchMethodRegistry.isComplex(element); | 1474 noSuchMethodRegistry.isComplex(element); |
| 1440 | 1475 |
| 1441 bool methodNeedsRti(FunctionElement function) { | 1476 bool methodNeedsRti(FunctionElement function) { |
| 1442 return rti.methodsNeedingRti.contains(function) || hasRuntimeTypeSupport; | 1477 return rti.methodsNeedingRti.contains(function) || hasRuntimeTypeSupport; |
| 1443 } | 1478 } |
| 1444 | 1479 |
| 1445 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; | 1480 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; |
| 1446 | 1481 |
| 1482 /// Creates an [Enqueuer] for code generation specific to this backend. |
| 1447 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) { | 1483 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) { |
| 1448 return new CodegenEnqueuer( | 1484 return new CodegenEnqueuer( |
| 1449 task, this, compiler.options, const TreeShakingEnqueuerStrategy()); | 1485 task, this, compiler.options, const TreeShakingEnqueuerStrategy()); |
| 1450 } | 1486 } |
| 1451 | 1487 |
| 1452 WorldImpact codegen(CodegenWorkItem work) { | 1488 WorldImpact codegen(CodegenWorkItem work) { |
| 1453 Element element = work.element; | 1489 Element element = work.element; |
| 1454 if (compiler.elementHasCompileTimeError(element)) { | 1490 if (compiler.elementHasCompileTimeError(element)) { |
| 1455 DiagnosticMessage message = | 1491 DiagnosticMessage message = |
| 1456 // If there's more than one error, the first is probably most | 1492 // If there's more than one error, the first is probably most |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 /** | 1577 /** |
| 1542 * Unit test hook that returns code of an element as a String. | 1578 * Unit test hook that returns code of an element as a String. |
| 1543 * | 1579 * |
| 1544 * Invariant: [element] must be a declaration element. | 1580 * Invariant: [element] must be a declaration element. |
| 1545 */ | 1581 */ |
| 1546 String getGeneratedCode(Element element) { | 1582 String getGeneratedCode(Element element) { |
| 1547 assert(invariant(element, element.isDeclaration)); | 1583 assert(invariant(element, element.isDeclaration)); |
| 1548 return jsAst.prettyPrint(generatedCode[element], compiler); | 1584 return jsAst.prettyPrint(generatedCode[element], compiler); |
| 1549 } | 1585 } |
| 1550 | 1586 |
| 1587 /// Generates the output and returns the total size of the generated code. |
| 1551 int assembleProgram(ClosedWorld closedWorld) { | 1588 int assembleProgram(ClosedWorld closedWorld) { |
| 1552 int programSize = emitter.assembleProgram(namer, closedWorld); | 1589 int programSize = emitter.assembleProgram(namer, closedWorld); |
| 1553 noSuchMethodRegistry.emitDiagnostic(); | 1590 noSuchMethodRegistry.emitDiagnostic(); |
| 1554 int totalMethodCount = generatedCode.length; | 1591 int totalMethodCount = generatedCode.length; |
| 1555 if (totalMethodCount != preMirrorsMethodCount) { | 1592 if (totalMethodCount != preMirrorsMethodCount) { |
| 1556 int mirrorCount = totalMethodCount - preMirrorsMethodCount; | 1593 int mirrorCount = totalMethodCount - preMirrorsMethodCount; |
| 1557 double percentage = (mirrorCount / totalMethodCount) * 100; | 1594 double percentage = (mirrorCount / totalMethodCount) * 100; |
| 1558 DiagnosticMessage hint = | 1595 DiagnosticMessage hint = |
| 1559 reporter.createMessage(compiler.mainApp, MessageKind.MIRROR_BLOAT, { | 1596 reporter.createMessage(compiler.mainApp, MessageKind.MIRROR_BLOAT, { |
| 1560 'count': mirrorCount, | 1597 'count': mirrorCount, |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 bool mayGenerateInstanceofCheck(ResolutionDartType type) { | 1799 bool mayGenerateInstanceofCheck(ResolutionDartType type) { |
| 1763 // We can use an instanceof check for raw types that have no subclass that | 1800 // We can use an instanceof check for raw types that have no subclass that |
| 1764 // is mixed-in or in an implements clause. | 1801 // is mixed-in or in an implements clause. |
| 1765 | 1802 |
| 1766 if (!type.isRaw) return false; | 1803 if (!type.isRaw) return false; |
| 1767 ClassElement classElement = type.element; | 1804 ClassElement classElement = type.element; |
| 1768 if (isInterceptorClass(classElement)) return false; | 1805 if (isInterceptorClass(classElement)) return false; |
| 1769 return _closedWorld.hasOnlySubclasses(classElement); | 1806 return _closedWorld.hasOnlySubclasses(classElement); |
| 1770 } | 1807 } |
| 1771 | 1808 |
| 1809 /// Called to register that [element] is statically known to be used. Any |
| 1810 /// backend specific [WorldImpact] of this is returned. |
| 1772 WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) { | 1811 WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) { |
| 1773 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl(); | 1812 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl(); |
| 1774 if (element == helpers.disableTreeShakingMarker) { | 1813 if (element == helpers.disableTreeShakingMarker) { |
| 1775 isTreeShakingDisabled = true; | 1814 isTreeShakingDisabled = true; |
| 1776 } else if (element == helpers.preserveNamesMarker) { | 1815 } else if (element == helpers.preserveNamesMarker) { |
| 1777 mustPreserveNames = true; | 1816 mustPreserveNames = true; |
| 1778 } else if (element == helpers.preserveMetadataMarker) { | 1817 } else if (element == helpers.preserveMetadataMarker) { |
| 1779 mustRetainMetadata = true; | 1818 mustRetainMetadata = true; |
| 1780 } else if (element == helpers.preserveUrisMarker) { | 1819 } else if (element == helpers.preserveUrisMarker) { |
| 1781 if (compiler.options.preserveUris) mustPreserveUris = true; | 1820 if (compiler.options.preserveUris) mustPreserveUris = true; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1885 metadata.ensureResolved(resolution); | 1924 metadata.ensureResolved(resolution); |
| 1886 ConstantValue constant = | 1925 ConstantValue constant = |
| 1887 constants.getConstantValueForMetadata(metadata); | 1926 constants.getConstantValueForMetadata(metadata); |
| 1888 constants.addCompileTimeConstantForEmission(constant); | 1927 constants.addCompileTimeConstantForEmission(constant); |
| 1889 } | 1928 } |
| 1890 return true; | 1929 return true; |
| 1891 } | 1930 } |
| 1892 return false; | 1931 return false; |
| 1893 } | 1932 } |
| 1894 | 1933 |
| 1934 /// This method is called immediately after the [library] and its parts have |
| 1935 /// been scanned. |
| 1895 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 1936 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
| 1896 return super.onLibraryScanned(library, loader).then((_) { | 1937 if (!compiler.serialization.isDeserialized(library)) { |
| 1897 if (library.isPlatformLibrary && | 1938 if (canLibraryUseNative(library)) { |
| 1898 // Don't patch library currently disallowed. | 1939 library.forEachLocalMember((Element element) { |
| 1899 !library.isSynthesized && | 1940 if (element.isClass) { |
| 1900 !library.isPatched && | 1941 checkNativeAnnotation(compiler, element); |
| 1901 // Don't patch deserialized libraries. | 1942 } |
| 1902 !compiler.serialization.isDeserialized(library)) { | 1943 }); |
| 1903 // Apply patch, if any. | 1944 } |
| 1904 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); | 1945 checkJsInteropAnnotation(compiler, library); |
| 1905 if (patchUri != null) { | 1946 library.forEachLocalMember((Element element) { |
| 1906 return compiler.patchParser.patchLibrary(loader, patchUri, library); | 1947 checkJsInteropAnnotation(compiler, element); |
| 1948 if (element.isClass && isJsInterop(element)) { |
| 1949 ClassElement classElement = element; |
| 1950 classElement.forEachMember((_, memberElement) { |
| 1951 checkJsInteropAnnotation(compiler, memberElement); |
| 1952 }); |
| 1907 } | 1953 } |
| 1954 }); |
| 1955 } |
| 1956 if (library.isPlatformLibrary && |
| 1957 // Don't patch library currently disallowed. |
| 1958 !library.isSynthesized && |
| 1959 !library.isPatched && |
| 1960 // Don't patch deserialized libraries. |
| 1961 !compiler.serialization.isDeserialized(library)) { |
| 1962 // Apply patch, if any. |
| 1963 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); |
| 1964 if (patchUri != null) { |
| 1965 return compiler.patchParser.patchLibrary(loader, patchUri, library); |
| 1908 } | 1966 } |
| 1909 }).then((_) { | 1967 } |
| 1910 Uri uri = library.canonicalUri; | 1968 Uri uri = library.canonicalUri; |
| 1911 if (uri == Uris.dart_html) { | 1969 if (uri == Uris.dart_html) { |
| 1912 htmlLibraryIsLoaded = true; | 1970 htmlLibraryIsLoaded = true; |
| 1913 } else if (uri == LookupMapAnalysis.PACKAGE_LOOKUP_MAP) { | 1971 } else if (uri == LookupMapAnalysis.PACKAGE_LOOKUP_MAP) { |
| 1914 lookupMapAnalysis.init(library); | 1972 lookupMapAnalysis.init(library); |
| 1915 } | 1973 } |
| 1916 annotations.onLibraryScanned(library); | 1974 annotations.onLibraryScanned(library); |
| 1917 }); | 1975 return new Future.value(); |
| 1918 } | 1976 } |
| 1919 | 1977 |
| 1978 /// This method is called when all new libraries loaded through |
| 1979 /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports |
| 1980 /// have been computed. |
| 1920 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 1981 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
| 1921 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { | 1982 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { |
| 1922 return new Future.value(); | 1983 return new Future.value(); |
| 1923 } | 1984 } |
| 1924 | 1985 |
| 1925 helpers.onLibrariesLoaded(loadedLibraries); | 1986 helpers.onLibrariesLoaded(loadedLibraries); |
| 1926 | 1987 |
| 1927 implementationClasses = <ClassElement, ClassElement>{}; | 1988 implementationClasses = <ClassElement, ClassElement>{}; |
| 1928 implementationClasses[commonElements.intClass] = helpers.jsIntClass; | 1989 implementationClasses[commonElements.intClass] = helpers.jsIntClass; |
| 1929 implementationClasses[commonElements.boolClass] = helpers.jsBoolClass; | 1990 implementationClasses[commonElements.boolClass] = helpers.jsBoolClass; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1942 ..add(helpers.jsInterceptorClass) | 2003 ..add(helpers.jsInterceptorClass) |
| 1943 ..add(helpers.jsNullClass); | 2004 ..add(helpers.jsNullClass); |
| 1944 | 2005 |
| 1945 validateInterceptorImplementsAllObjectMethods(helpers.jsInterceptorClass); | 2006 validateInterceptorImplementsAllObjectMethods(helpers.jsInterceptorClass); |
| 1946 // The null-interceptor must also implement *all* methods. | 2007 // The null-interceptor must also implement *all* methods. |
| 1947 validateInterceptorImplementsAllObjectMethods(helpers.jsNullClass); | 2008 validateInterceptorImplementsAllObjectMethods(helpers.jsNullClass); |
| 1948 | 2009 |
| 1949 return new Future.value(); | 2010 return new Future.value(); |
| 1950 } | 2011 } |
| 1951 | 2012 |
| 2013 /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed |
| 2014 /// annotations. The arguments corresponds to the unions of the corresponding |
| 2015 /// fields of the annotations. |
| 1952 void registerMirrorUsage( | 2016 void registerMirrorUsage( |
| 1953 Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) { | 2017 Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) { |
| 1954 if (symbols == null && targets == null && metaTargets == null) { | 2018 if (symbols == null && targets == null && metaTargets == null) { |
| 1955 // The user didn't specify anything, or there are imports of | 2019 // The user didn't specify anything, or there are imports of |
| 1956 // 'dart:mirrors' without @MirrorsUsed. | 2020 // 'dart:mirrors' without @MirrorsUsed. |
| 1957 hasInsufficientMirrorsUsed = true; | 2021 hasInsufficientMirrorsUsed = true; |
| 1958 return; | 2022 return; |
| 1959 } | 2023 } |
| 1960 if (symbols != null) symbolsUsed.addAll(symbols); | 2024 if (symbols != null) symbolsUsed.addAll(symbols); |
| 1961 if (targets != null) { | 2025 if (targets != null) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1981 * accessed (invoked, get, set) that is not accessible for the reflective | 2045 * accessed (invoked, get, set) that is not accessible for the reflective |
| 1982 * system. | 2046 * system. |
| 1983 */ | 2047 */ |
| 1984 bool isAccessibleByReflection(Element element) { | 2048 bool isAccessibleByReflection(Element element) { |
| 1985 if (element.isClass) { | 2049 if (element.isClass) { |
| 1986 element = getDartClass(element); | 2050 element = getDartClass(element); |
| 1987 } | 2051 } |
| 1988 return membersNeededForReflection.contains(element); | 2052 return membersNeededForReflection.contains(element); |
| 1989 } | 2053 } |
| 1990 | 2054 |
| 2055 /// Returns `true` if this member element needs reflection information at |
| 2056 /// runtime. |
| 1991 bool isMemberAccessibleByReflection(MemberElement element) { | 2057 bool isMemberAccessibleByReflection(MemberElement element) { |
| 1992 return membersNeededForReflection.contains(element); | 2058 return membersNeededForReflection.contains(element); |
| 1993 } | 2059 } |
| 1994 | 2060 |
| 1995 /** | 2061 /// Returns true if this element has to be enqueued due to |
| 1996 * Returns true if the element has to be resolved due to a mirrorsUsed | 2062 /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if |
| 1997 * annotation. If we have insufficient mirrors used annotations, we only | 2063 /// normal tree shaking is still active ([isTreeShakingDisabled] is false). |
| 1998 * keep additional elements if treeshaking has been disabled. | |
| 1999 */ | |
| 2000 bool requiredByMirrorSystem(Element element) { | 2064 bool requiredByMirrorSystem(Element element) { |
| 2001 return hasInsufficientMirrorsUsed && isTreeShakingDisabled || | 2065 return hasInsufficientMirrorsUsed && isTreeShakingDisabled || |
| 2002 matchesMirrorsMetaTarget(element) || | 2066 matchesMirrorsMetaTarget(element) || |
| 2003 targetsUsed.contains(element); | 2067 targetsUsed.contains(element); |
| 2004 } | 2068 } |
| 2005 | 2069 |
| 2006 /** | 2070 /// Returns true if this element is covered by a mirrorsUsed annotation. |
| 2007 * Returns true if the element matches a mirrorsUsed annotation. If | 2071 /// |
| 2008 * we have insufficient mirrorsUsed information, this returns true for | 2072 /// Note that it might still be ok to tree shake the element away if no |
| 2009 * all elements, as they might all be potentially referenced. | 2073 /// reflection is used in the program (and thus [isTreeShakingDisabled] is |
| 2010 */ | 2074 /// still false). Therefore _do not_ use this predicate to decide inclusion |
| 2075 /// in the tree, use [requiredByMirrorSystem] instead. |
| 2011 bool referencedFromMirrorSystem(Element element, [recursive = true]) { | 2076 bool referencedFromMirrorSystem(Element element, [recursive = true]) { |
| 2012 Element enclosing = recursive ? element.enclosingElement : null; | 2077 Element enclosing = recursive ? element.enclosingElement : null; |
| 2013 | 2078 |
| 2014 return hasInsufficientMirrorsUsed || | 2079 return hasInsufficientMirrorsUsed || |
| 2015 matchesMirrorsMetaTarget(element) || | 2080 matchesMirrorsMetaTarget(element) || |
| 2016 targetsUsed.contains(element) || | 2081 targetsUsed.contains(element) || |
| 2017 (enclosing != null && referencedFromMirrorSystem(enclosing)); | 2082 (enclosing != null && referencedFromMirrorSystem(enclosing)); |
| 2018 } | 2083 } |
| 2019 | 2084 |
| 2020 /** | 2085 /** |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2237 if (target == null) continue; | 2302 if (target == null) continue; |
| 2238 if (target.isField) { | 2303 if (target.isField) { |
| 2239 staticFields.add(target); | 2304 staticFields.add(target); |
| 2240 } else if (target.isLibrary || target.isClass) { | 2305 } else if (target.isLibrary || target.isClass) { |
| 2241 addFieldsInContainer(target); | 2306 addFieldsInContainer(target); |
| 2242 } | 2307 } |
| 2243 } | 2308 } |
| 2244 return staticFields; | 2309 return staticFields; |
| 2245 } | 2310 } |
| 2246 | 2311 |
| 2247 /// Called when [enqueuer] is empty, but before it is closed. | 2312 /// Called when [enqueuer]'s queue is empty, but before it is closed. |
| 2313 /// |
| 2314 /// This is used, for example, by the JS backend to enqueue additional |
| 2315 /// elements needed for reflection. [recentClasses] is a collection of |
| 2316 /// all classes seen for the first time by the [enqueuer] since the last call |
| 2317 /// to [onQueueEmpty]. |
| 2318 /// |
| 2319 /// A return value of [:true:] indicates that [recentClasses] has been |
| 2320 /// processed and its elements do not need to be seen in the next round. When |
| 2321 /// [:false:] is returned, [onQueueEmpty] will be called again once the |
| 2322 /// resolution queue has drained and [recentClasses] will be a superset of the |
| 2323 /// current value. |
| 2324 /// |
| 2325 /// There is no guarantee that a class is only present once in |
| 2326 /// [recentClasses], but every class seen by the [enqueuer] will be present in |
| 2327 /// [recentClasses] at least once. |
| 2248 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) { | 2328 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) { |
| 2249 // Add elements used synthetically, that is, through features rather than | 2329 // Add elements used synthetically, that is, through features rather than |
| 2250 // syntax, for instance custom elements. | 2330 // syntax, for instance custom elements. |
| 2251 // | 2331 // |
| 2252 // Return early if any elements are added to avoid counting the elements as | 2332 // Return early if any elements are added to avoid counting the elements as |
| 2253 // due to mirrors. | 2333 // due to mirrors. |
| 2254 enqueuer.applyImpact(customElementsAnalysis.flush( | 2334 enqueuer.applyImpact(customElementsAnalysis.flush( |
| 2255 forResolution: enqueuer.isResolutionQueue)); | 2335 forResolution: enqueuer.isResolutionQueue)); |
| 2256 enqueuer.applyImpact( | 2336 enqueuer.applyImpact( |
| 2257 lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue)); | 2337 lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue)); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2378 } | 2458 } |
| 2379 } else { | 2459 } else { |
| 2380 processLibraryMetadata(element.library); | 2460 processLibraryMetadata(element.library); |
| 2381 } | 2461 } |
| 2382 } | 2462 } |
| 2383 } | 2463 } |
| 2384 | 2464 |
| 2385 entities.forEach(processElementMetadata); | 2465 entities.forEach(processElementMetadata); |
| 2386 } | 2466 } |
| 2387 | 2467 |
| 2468 /// Called after the queue is closed. [onQueueEmpty] may be called multiple |
| 2469 /// times, but [onQueueClosed] is only called once. |
| 2388 void onQueueClosed() { | 2470 void onQueueClosed() { |
| 2389 lookupMapAnalysis.onQueueClosed(); | 2471 lookupMapAnalysis.onQueueClosed(); |
| 2390 jsInteropAnalysis.onQueueClosed(); | 2472 jsInteropAnalysis.onQueueClosed(); |
| 2391 } | 2473 } |
| 2392 | 2474 |
| 2393 // TODO(johnniwinther): Create a CodegenPhase object for the backend to hold | 2475 // TODO(johnniwinther): Create a CodegenPhase object for the backend to hold |
| 2394 // data only available during code generation. | 2476 // data only available during code generation. |
| 2395 ClosedWorld _closedWorldCache; | 2477 ClosedWorld _closedWorldCache; |
| 2396 ClosedWorld get _closedWorld { | 2478 ClosedWorld get _closedWorld { |
| 2397 assert(invariant(NO_LOCATION_SPANNABLE, _closedWorldCache != null, | 2479 assert(invariant(NO_LOCATION_SPANNABLE, _closedWorldCache != null, |
| 2398 message: "ClosedWorld has not be set yet.")); | 2480 message: "ClosedWorld has not be set yet.")); |
| 2399 return _closedWorldCache; | 2481 return _closedWorldCache; |
| 2400 } | 2482 } |
| 2401 | 2483 |
| 2402 void set _closedWorld(ClosedWorld value) { | 2484 void set _closedWorld(ClosedWorld value) { |
| 2403 _closedWorldCache = value; | 2485 _closedWorldCache = value; |
| 2404 } | 2486 } |
| 2405 | 2487 |
| 2488 /// Called when the compiler starts running the codegen enqueuer. The |
| 2489 /// [WorldImpact] of enabled backend features is returned. |
| 2406 WorldImpact onCodegenStart(ClosedWorld closedWorld) { | 2490 WorldImpact onCodegenStart(ClosedWorld closedWorld) { |
| 2407 _closedWorld = closedWorld; | 2491 _closedWorld = closedWorld; |
| 2408 _namer = determineNamer(_closedWorld, compiler.codegenWorldBuilder); | 2492 _namer = determineNamer(_closedWorld, compiler.codegenWorldBuilder); |
| 2409 tracer = new Tracer(_closedWorld, namer, compiler.outputProvider); | 2493 tracer = new Tracer(_closedWorld, namer, compiler.outputProvider); |
| 2410 emitter.createEmitter(_namer, _closedWorld); | 2494 emitter.createEmitter(_namer, _closedWorld); |
| 2411 lookupMapAnalysis.onCodegenStart(); | 2495 lookupMapAnalysis.onCodegenStart(); |
| 2412 if (hasIsolateSupport) { | 2496 if (hasIsolateSupport) { |
| 2413 return enableIsolateSupport(forResolution: false); | 2497 return enableIsolateSupport(forResolution: false); |
| 2414 } | 2498 } |
| 2415 return const WorldImpact(); | 2499 return const WorldImpact(); |
| 2416 } | 2500 } |
| 2417 | 2501 |
| 2502 /// Called when code generation has been completed. |
| 2418 void onCodegenEnd() { | 2503 void onCodegenEnd() { |
| 2419 sourceInformationStrategy.onComplete(); | 2504 sourceInformationStrategy.onComplete(); |
| 2420 tracer.close(); | 2505 tracer.close(); |
| 2421 } | 2506 } |
| 2422 | 2507 |
| 2508 // Does this element belong in the output |
| 2509 bool shouldOutput(Element element) => true; |
| 2510 |
| 2511 /// Returns `true` if the `native` pseudo keyword is supported for [library]. |
| 2512 bool canLibraryUseNative(LibraryElement library) { |
| 2513 return native.maybeEnableNative(compiler, library); |
| 2514 } |
| 2515 |
| 2516 @override |
| 2517 bool isTargetSpecificLibrary(LibraryElement library) { |
| 2518 Uri canonicalUri = library.canonicalUri; |
| 2519 if (canonicalUri == BackendHelpers.DART_JS_HELPER || |
| 2520 canonicalUri == BackendHelpers.DART_INTERCEPTORS) { |
| 2521 return true; |
| 2522 } |
| 2523 return false; |
| 2524 } |
| 2525 |
| 2423 /// Process backend specific annotations. | 2526 /// Process backend specific annotations. |
| 2424 void processAnnotations( | 2527 void processAnnotations( |
| 2425 Element element, ClosedWorldRefiner closedWorldRefiner) { | 2528 Element element, ClosedWorldRefiner closedWorldRefiner) { |
| 2426 if (element.isMalformed) { | 2529 if (element.isMalformed) { |
| 2427 // Elements that are marked as malformed during parsing or resolution | 2530 // Elements that are marked as malformed during parsing or resolution |
| 2428 // might be registered here. These should just be ignored. | 2531 // might be registered here. These should just be ignored. |
| 2429 return; | 2532 return; |
| 2430 } | 2533 } |
| 2431 | 2534 |
| 2432 Element implementation = element.implementation; | 2535 Element implementation = element.implementation; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 "@NoSideEffects() should always be combined with @NoInline."); | 2602 "@NoSideEffects() should always be combined with @NoInline."); |
| 2500 } | 2603 } |
| 2501 } | 2604 } |
| 2502 | 2605 |
| 2503 MethodElement helperForBadMain() => helpers.badMain; | 2606 MethodElement helperForBadMain() => helpers.badMain; |
| 2504 | 2607 |
| 2505 MethodElement helperForMissingMain() => helpers.missingMain; | 2608 MethodElement helperForMissingMain() => helpers.missingMain; |
| 2506 | 2609 |
| 2507 MethodElement helperForMainArity() => helpers.mainHasTooManyParameters; | 2610 MethodElement helperForMainArity() => helpers.mainHasTooManyParameters; |
| 2508 | 2611 |
| 2509 @override | 2612 /// Computes the [WorldImpact] of calling [mainMethod] as the entry point. |
| 2510 WorldImpact computeMainImpact(MethodElement mainMethod, | 2613 WorldImpact computeMainImpact(MethodElement mainMethod, |
| 2511 {bool forResolution}) { | 2614 {bool forResolution}) { |
| 2512 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); | 2615 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); |
| 2513 if (mainMethod.parameters.isNotEmpty) { | 2616 if (mainMethod.parameters.isNotEmpty) { |
| 2514 impactTransformer.registerBackendImpact( | 2617 impactTransformer.registerBackendImpact( |
| 2515 mainImpact, impacts.mainWithArguments); | 2618 mainImpact, impacts.mainWithArguments); |
| 2516 mainImpact.registerStaticUse( | 2619 mainImpact.registerStaticUse( |
| 2517 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); | 2620 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); |
| 2518 // If the main method takes arguments, this compilation could be the | 2621 // If the main method takes arguments, this compilation could be the |
| 2519 // target of Isolate.spawnUri. Strictly speaking, that can happen also if | 2622 // target of Isolate.spawnUri. Strictly speaking, that can happen also if |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2533 String deferredPartFileName(String name, {bool addExtension: true}) { | 2636 String deferredPartFileName(String name, {bool addExtension: true}) { |
| 2534 assert(name != ""); | 2637 assert(name != ""); |
| 2535 String outPath = compiler.options.outputUri != null | 2638 String outPath = compiler.options.outputUri != null |
| 2536 ? compiler.options.outputUri.path | 2639 ? compiler.options.outputUri.path |
| 2537 : "out"; | 2640 : "out"; |
| 2538 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); | 2641 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); |
| 2539 String extension = addExtension ? ".part.js" : ""; | 2642 String extension = addExtension ? ".part.js" : ""; |
| 2540 return "${outName}_$name$extension"; | 2643 return "${outName}_$name$extension"; |
| 2541 } | 2644 } |
| 2542 | 2645 |
| 2543 @override | 2646 /// Enable deferred loading. Returns `true` if the backend supports deferred |
| 2647 /// loading. |
| 2544 bool enableDeferredLoadingIfSupported(Spannable node) => true; | 2648 bool enableDeferredLoadingIfSupported(Spannable node) => true; |
| 2545 | 2649 |
| 2546 @override | 2650 /// Enable compilation of code with compile time errors. Returns `true` if |
| 2651 /// supported by the backend. |
| 2547 bool enableCodegenWithErrorsIfSupported(Spannable node) => true; | 2652 bool enableCodegenWithErrorsIfSupported(Spannable node) => true; |
| 2548 | 2653 |
| 2549 jsAst.Expression rewriteAsync( | 2654 jsAst.Expression rewriteAsync( |
| 2550 FunctionElement element, jsAst.Expression code) { | 2655 FunctionElement element, jsAst.Expression code) { |
| 2551 AsyncRewriterBase rewriter = null; | 2656 AsyncRewriterBase rewriter = null; |
| 2552 jsAst.Name name = namer.methodPropertyName(element); | 2657 jsAst.Name name = namer.methodPropertyName(element); |
| 2553 switch (element.asyncMarker) { | 2658 switch (element.asyncMarker) { |
| 2554 case AsyncMarker.ASYNC: | 2659 case AsyncMarker.ASYNC: |
| 2555 rewriter = new AsyncRewriter(reporter, element, | 2660 rewriter = new AsyncRewriter(reporter, element, |
| 2556 asyncHelper: emitter.staticFunctionAccess(helpers.asyncHelper), | 2661 asyncHelper: emitter.staticFunctionAccess(helpers.asyncHelper), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2603 "core": "_internal/js_runtime/lib/core_patch.dart", | 2708 "core": "_internal/js_runtime/lib/core_patch.dart", |
| 2604 "developer": "_internal/js_runtime/lib/developer_patch.dart", | 2709 "developer": "_internal/js_runtime/lib/developer_patch.dart", |
| 2605 "io": "_internal/js_runtime/lib/io_patch.dart", | 2710 "io": "_internal/js_runtime/lib/io_patch.dart", |
| 2606 "isolate": "_internal/js_runtime/lib/isolate_patch.dart", | 2711 "isolate": "_internal/js_runtime/lib/isolate_patch.dart", |
| 2607 "math": "_internal/js_runtime/lib/math_patch.dart", | 2712 "math": "_internal/js_runtime/lib/math_patch.dart", |
| 2608 "mirrors": "_internal/js_runtime/lib/mirrors_patch.dart", | 2713 "mirrors": "_internal/js_runtime/lib/mirrors_patch.dart", |
| 2609 "typed_data": "_internal/js_runtime/lib/typed_data_patch.dart", | 2714 "typed_data": "_internal/js_runtime/lib/typed_data_patch.dart", |
| 2610 "_internal": "_internal/js_runtime/lib/internal_patch.dart" | 2715 "_internal": "_internal/js_runtime/lib/internal_patch.dart" |
| 2611 }; | 2716 }; |
| 2612 | 2717 |
| 2613 @override | 2718 /// Returns the location of the patch-file associated with [libraryName] |
| 2719 /// resolved from [plaformConfigUri]. |
| 2720 /// |
| 2721 /// Returns null if there is none. |
| 2614 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { | 2722 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { |
| 2615 String patchLocation = _patchLocations[libraryName]; | 2723 String patchLocation = _patchLocations[libraryName]; |
| 2616 if (patchLocation == null) return null; | 2724 if (patchLocation == null) return null; |
| 2617 return platformConfigUri.resolve(patchLocation); | 2725 return platformConfigUri.resolve(patchLocation); |
| 2618 } | 2726 } |
| 2619 | 2727 |
| 2620 @override | 2728 /// Creates an impact strategy to use for compilation. |
| 2621 ImpactStrategy createImpactStrategy( | 2729 ImpactStrategy createImpactStrategy( |
| 2622 {bool supportDeferredLoad: true, | 2730 {bool supportDeferredLoad: true, |
| 2623 bool supportDumpInfo: true, | 2731 bool supportDumpInfo: true, |
| 2624 bool supportSerialization: true}) { | 2732 bool supportSerialization: true}) { |
| 2625 return new JavaScriptImpactStrategy(resolution, compiler.dumpInfoTask, | 2733 return new JavaScriptImpactStrategy(resolution, compiler.dumpInfoTask, |
| 2626 supportDeferredLoad: supportDeferredLoad, | 2734 supportDeferredLoad: supportDeferredLoad, |
| 2627 supportDumpInfo: supportDumpInfo, | 2735 supportDumpInfo: supportDumpInfo, |
| 2628 supportSerialization: supportSerialization); | 2736 supportSerialization: supportSerialization); |
| 2629 } | 2737 } |
| 2738 |
| 2739 EnqueueTask makeEnqueuer() => new EnqueueTask(compiler); |
| 2630 } | 2740 } |
| 2631 | 2741 |
| 2632 class JSFrontendAccess implements Frontend { | 2742 class JSFrontendAccess implements Frontend { |
| 2633 final Compiler compiler; | 2743 final Compiler compiler; |
| 2634 | 2744 |
| 2635 JSFrontendAccess(this.compiler); | 2745 JSFrontendAccess(this.compiler); |
| 2636 | 2746 |
| 2637 Resolution get resolution => compiler.resolution; | 2747 Resolution get resolution => compiler.resolution; |
| 2638 | 2748 |
| 2639 @override | 2749 @override |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3281 @override | 3391 @override |
| 3282 bool isNativeClass(ClassElement element) { | 3392 bool isNativeClass(ClassElement element) { |
| 3283 return helpers.backend.isNative(element); | 3393 return helpers.backend.isNative(element); |
| 3284 } | 3394 } |
| 3285 | 3395 |
| 3286 @override | 3396 @override |
| 3287 bool isNativeMember(MemberElement element) { | 3397 bool isNativeMember(MemberElement element) { |
| 3288 return helpers.backend.isNative(element); | 3398 return helpers.backend.isNative(element); |
| 3289 } | 3399 } |
| 3290 } | 3400 } |
| OLD | NEW |