Index: pkg/compiler/lib/src/compiler.dart |
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart |
index f6353790b591b93f3bebbb4a9327f03e6910937b..2fdbf2e2a2b263f6474708211e510247da748787 100644 |
--- a/pkg/compiler/lib/src/compiler.dart |
+++ b/pkg/compiler/lib/src/compiler.dart |
@@ -2,666 +2,130 @@ |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
-part of dart2js; |
- |
-/** |
- * If true, print a warning for each method that was resolved, but not |
- * compiled. |
- */ |
-const bool REPORT_EXCESS_RESOLUTION = false; |
- |
-/** |
- * Contains backend-specific data that is used throughout the compilation of |
- * one work item. |
- */ |
-class ItemCompilationContext { |
-} |
- |
-abstract class WorkItem { |
- final ItemCompilationContext compilationContext; |
- /** |
- * Documentation wanted -- johnniwinther |
- * |
- * Invariant: [element] must be a declaration element. |
- */ |
- final AstElement element; |
- |
- WorkItem(this.element, this.compilationContext) { |
- assert(invariant(element, element.isDeclaration)); |
- } |
- |
- WorldImpact run(Compiler compiler, Enqueuer world); |
-} |
- |
-/// [WorkItem] used exclusively by the [ResolutionEnqueuer]. |
-class ResolutionWorkItem extends WorkItem { |
- bool _isAnalyzed = false; |
- |
- ResolutionWorkItem(AstElement element, |
- ItemCompilationContext compilationContext) |
- : super(element, compilationContext); |
- |
- WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { |
- WorldImpact impact = compiler.analyze(this, world); |
- _isAnalyzed = true; |
- return impact; |
- } |
- |
- bool get isAnalyzed => _isAnalyzed; |
-} |
- |
-// TODO(johnniwinther): Split this class into interface and implementation. |
-// TODO(johnniwinther): Move this implementation to the JS backend. |
-class CodegenRegistry extends Registry { |
- final Compiler compiler; |
- final TreeElements treeElements; |
- |
- CodegenRegistry(this.compiler, this.treeElements); |
- |
- bool get isForResolution => false; |
- |
- Element get currentElement => treeElements.analyzedElement; |
- |
- // TODO(johnniwinther): Remove this getter when [Registry] creates a |
- // dependency node. |
- Setlet<Element> get otherDependencies => treeElements.otherDependencies; |
- |
- CodegenEnqueuer get world => compiler.enqueuer.codegen; |
- js_backend.JavaScriptBackend get backend => compiler.backend; |
- |
- void registerDependency(Element element) { |
- treeElements.registerDependency(element); |
- } |
- |
- void registerInlining(Element inlinedElement, Element context) { |
- if (compiler.dumpInfo) { |
- compiler.dumpInfoTask.registerInlined(inlinedElement, context); |
- } |
- } |
- |
- void registerInstantiatedClass(ClassElement element) { |
- world.registerInstantiatedType(element.rawType, this); |
- } |
- |
- void registerInstantiatedType(InterfaceType type) { |
- world.registerInstantiatedType(type, this); |
- } |
- |
- void registerStaticUse(Element element) { |
- world.registerStaticUse(element); |
- } |
- |
- void registerDynamicInvocation(UniverseSelector selector) { |
- world.registerDynamicInvocation(selector); |
- compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
- } |
- |
- void registerDynamicSetter(UniverseSelector selector) { |
- world.registerDynamicSetter(selector); |
- compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
- } |
- |
- void registerDynamicGetter(UniverseSelector selector) { |
- world.registerDynamicGetter(selector); |
- compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
- } |
- |
- void registerGetterForSuperMethod(Element element) { |
- world.registerGetterForSuperMethod(element); |
- } |
- |
- void registerFieldGetter(Element element) { |
- world.registerFieldGetter(element); |
- } |
- |
- void registerFieldSetter(Element element) { |
- world.registerFieldSetter(element); |
- } |
- |
- void registerIsCheck(DartType type) { |
- world.registerIsCheck(type); |
- backend.registerIsCheckForCodegen(type, world, this); |
- } |
- |
- void registerCompileTimeConstant(ConstantValue constant) { |
- backend.registerCompileTimeConstant(constant, this); |
- backend.constants.addCompileTimeConstantForEmission(constant); |
- } |
- |
- void registerTypeVariableBoundsSubtypeCheck(DartType subtype, |
- DartType supertype) { |
- backend.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
- } |
- |
- void registerInstantiatedClosure(LocalFunctionElement element) { |
- backend.registerInstantiatedClosure(element, this); |
- } |
- |
- void registerGetOfStaticFunction(FunctionElement element) { |
- world.registerGetOfStaticFunction(element); |
- } |
- |
- void registerSelectorUse(Selector selector) { |
- world.registerSelectorUse(new UniverseSelector(selector, null)); |
- } |
- |
- void registerConstSymbol(String name) { |
- backend.registerConstSymbol(name, this); |
- } |
- |
- void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
- backend.registerSpecializedGetInterceptor(classes); |
- } |
- |
- void registerUseInterceptor() { |
- backend.registerUseInterceptor(world); |
- } |
- |
- void registerTypeConstant(ClassElement element) { |
- backend.customElementsAnalysis.registerTypeConstant(element, world); |
- } |
- |
- void registerStaticInvocation(Element element) { |
- world.registerStaticUse(element); |
- } |
- |
- void registerSuperInvocation(Element element) { |
- world.registerStaticUse(element); |
- } |
- |
- void registerDirectInvocation(Element element) { |
- world.registerStaticUse(element); |
- } |
- |
- void registerInstantiation(InterfaceType type) { |
- world.registerInstantiatedType(type, this); |
- } |
- |
- void registerAsyncMarker(FunctionElement element) { |
- backend.registerAsyncMarker(element, world, this); |
- } |
- |
-} |
- |
-/// [WorkItem] used exclusively by the [CodegenEnqueuer]. |
-class CodegenWorkItem extends WorkItem { |
- CodegenRegistry registry; |
- |
- factory CodegenWorkItem( |
- Compiler compiler, |
- AstElement element, |
- ItemCompilationContext compilationContext) { |
- // If this assertion fails, the resolution callbacks of the backend may be |
- // missing call of form registry.registerXXX. Alternatively, the code |
- // generation could spuriously be adding dependencies on things we know we |
- // don't need. |
- assert(invariant(element, |
- compiler.enqueuer.resolution.hasBeenResolved(element), |
- message: "$element has not been resolved.")); |
- assert(invariant(element, element.resolvedAst.elements != null, |
- message: 'Resolution tree is null for $element in codegen work item')); |
- return new CodegenWorkItem.internal(element, compilationContext); |
- } |
- |
- CodegenWorkItem.internal( |
- AstElement element, |
- ItemCompilationContext compilationContext) |
- : super(element, compilationContext); |
- |
- TreeElements get resolutionTree => element.resolvedAst.elements; |
- |
- WorldImpact run(Compiler compiler, CodegenEnqueuer world) { |
- if (world.isProcessed(element)) return const WorldImpact(); |
- |
- registry = new CodegenRegistry(compiler, resolutionTree); |
- return compiler.codegen(this, world); |
- } |
-} |
- |
-typedef void DeferredAction(); |
- |
-class DeferredTask { |
- final Element element; |
- final DeferredAction action; |
- |
- DeferredTask(this.element, this.action); |
-} |
- |
-/// Interface for registration of element dependencies. |
-abstract class Registry { |
- // TODO(johnniwinther): Remove this getter when [Registry] creates a |
- // dependency node. |
- Iterable<Element> get otherDependencies; |
- |
- void registerDependency(Element element); |
- |
- bool get isForResolution; |
- |
- void registerDynamicInvocation(UniverseSelector selector); |
- |
- void registerDynamicGetter(UniverseSelector selector); |
- |
- void registerDynamicSetter(UniverseSelector selector); |
- |
- void registerStaticInvocation(Element element); |
- |
- void registerInstantiation(InterfaceType type); |
- |
- void registerGetOfStaticFunction(FunctionElement element); |
-} |
- |
-abstract class Backend { |
- final Compiler compiler; |
- |
- Backend(this.compiler); |
- |
- /// Returns true if the backend supports reflection. |
- bool get supportsReflection; |
- |
- /// The [ConstantSystem] used to interpret compile-time constants for this |
- /// backend. |
- ConstantSystem get constantSystem; |
- |
- /// The constant environment for the backend interpretation of compile-time |
- /// constants. |
- BackendConstantEnvironment get constants; |
- |
- /// The compiler task responsible for the compilation of constants for both |
- /// the frontend and the backend. |
- ConstantCompilerTask get constantCompilerTask; |
- |
- /// Backend callback methods for the resolution phase. |
- ResolutionCallbacks get resolutionCallbacks; |
- |
- /// The strategy used for collecting and emitting source information. |
- SourceInformationStrategy get sourceInformationStrategy { |
- return const SourceInformationStrategy(); |
- } |
- |
- // TODO(johnniwinther): Move this to the JavaScriptBackend. |
- String get patchVersion => null; |
- |
- /// Set of classes that need to be considered for reflection although not |
- /// otherwise visible during resolution. |
- Iterable<ClassElement> classesRequiredForReflection = const []; |
- |
- // Given a [FunctionElement], return a buffer with the code generated for it |
- // or null if no code was generated. |
- CodeBuffer codeOf(Element element) => null; |
- |
- void initializeHelperClasses() {} |
- |
- void enqueueHelpers(ResolutionEnqueuer world, Registry registry); |
- WorldImpact codegen(CodegenWorkItem work); |
- |
- // The backend determines the native resolution enqueuer, with a no-op |
- // default, so tools like dart2dart can ignore the native classes. |
- native.NativeEnqueuer nativeResolutionEnqueuer(world) { |
- return new native.NativeEnqueuer(); |
- } |
- native.NativeEnqueuer nativeCodegenEnqueuer(world) { |
- return new native.NativeEnqueuer(); |
- } |
- |
- /// Generates the output and returns the total size of the generated code. |
- int assembleProgram(); |
- |
- List<CompilerTask> get tasks; |
- |
- void onResolutionComplete() {} |
- void onTypeInferenceComplete() {} |
- |
- ItemCompilationContext createItemCompilationContext() { |
- return new ItemCompilationContext(); |
- } |
- |
- bool classNeedsRti(ClassElement cls); |
- bool methodNeedsRti(FunctionElement function); |
- |
- /// Enable compilation of code with compile time errors. Returns `true` if |
- /// supported by the backend. |
- bool enableCodegenWithErrorsIfSupported(Spannable node); |
- |
- /// Enable deferred loading. Returns `true` if the backend supports deferred |
- /// loading. |
- bool enableDeferredLoadingIfSupported(Spannable node, Registry registry); |
- |
- /// Called during codegen when [constant] has been used. |
- void registerCompileTimeConstant(ConstantValue constant, Registry registry) {} |
- |
- /// Called during resolution when a constant value for [metadata] on |
- /// [annotatedElement] has been evaluated. |
- void registerMetadataConstant(MetadataAnnotation metadata, |
- Element annotatedElement, |
- Registry registry) {} |
- |
- /// Called to notify to the backend that a class is being instantiated. |
- // TODO(johnniwinther): Remove this. It's only called once for each [cls] and |
- // only with [Compiler.globalDependencies] as [registry]. |
- void registerInstantiatedClass(ClassElement cls, |
- Enqueuer enqueuer, |
- Registry registry) {} |
- |
- /// Called to notify to the backend that an interface type has been |
- /// instantiated. |
- void registerInstantiatedType(InterfaceType type, Registry registry) {} |
- |
- /// Register an is check to the backend. |
- void registerIsCheckForCodegen(DartType type, |
- Enqueuer enqueuer, |
- Registry registry) {} |
- |
- /// Register a runtime type variable bound tests between [typeArgument] and |
- /// [bound]. |
- void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, |
- DartType bound) {} |
- |
- /// Returns `true` if [element] represent the assert function. |
- bool isAssertMethod(Element element) => false; |
- |
- /** |
- * Call this to register that an instantiated generic class has a call |
- * method. |
- */ |
- void registerCallMethodWithFreeTypeVariables( |
- Element callMethod, |
- Enqueuer enqueuer, |
- Registry registry) {} |
- |
- /** |
- * Call this to register that a getter exists for a function on an |
- * instantiated generic class. |
- */ |
- void registerClosureWithFreeTypeVariables( |
- Element closure, |
- Enqueuer enqueuer, |
- Registry registry) {} |
- |
- /// Call this to register that a member has been closurized. |
- void registerBoundClosure(Enqueuer enqueuer) {} |
- |
- /// Call this to register that a static function has been closurized. |
- void registerGetOfStaticFunction(Enqueuer enqueuer) {} |
- |
- /** |
- * Call this to register that the [:runtimeType:] property has been accessed. |
- */ |
- void registerRuntimeType(Enqueuer enqueuer, Registry registry) {} |
- |
- /// Call this to register a `noSuchMethod` implementation. |
- void registerNoSuchMethod(FunctionElement noSuchMethodElement) {} |
- |
- /// Call this method to enable support for `noSuchMethod`. |
- void enableNoSuchMethod(Enqueuer enqueuer) {} |
- |
- /// Returns whether or not `noSuchMethod` support has been enabled. |
- bool get enabledNoSuchMethod => false; |
- |
- /// Call this method to enable support for isolates. |
- void enableIsolateSupport(Enqueuer enqueuer) {} |
- |
- void registerRequiredType(DartType type, Element enclosingElement) {} |
- void registerClassUsingVariableExpression(ClassElement cls) {} |
- |
- void registerConstSymbol(String name, Registry registry) {} |
- void registerNewSymbol(Registry registry) {} |
- |
- bool isNullImplementation(ClassElement cls) { |
- return cls == compiler.nullClass; |
- } |
- |
- ClassElement get intImplementation => compiler.intClass; |
- ClassElement get doubleImplementation => compiler.doubleClass; |
- ClassElement get numImplementation => compiler.numClass; |
- ClassElement get stringImplementation => compiler.stringClass; |
- ClassElement get listImplementation => compiler.listClass; |
- ClassElement get growableListImplementation => compiler.listClass; |
- ClassElement get fixedListImplementation => compiler.listClass; |
- ClassElement get constListImplementation => compiler.listClass; |
- ClassElement get mapImplementation => compiler.mapClass; |
- ClassElement get constMapImplementation => compiler.mapClass; |
- ClassElement get functionImplementation => compiler.functionClass; |
- ClassElement get typeImplementation => compiler.typeClass; |
- ClassElement get boolImplementation => compiler.boolClass; |
- ClassElement get nullImplementation => compiler.nullClass; |
- ClassElement get uint32Implementation => compiler.intClass; |
- ClassElement get uint31Implementation => compiler.intClass; |
- ClassElement get positiveIntImplementation => compiler.intClass; |
- |
- ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass; |
- |
- bool isInterceptorClass(ClassElement element) => false; |
- |
- /// Returns `true` if [element] is a foreign element, that is, that the |
- /// backend has specialized handling for the element. |
- bool isForeign(Element element) => false; |
- |
- /// Processes [element] for resolution and returns the [FunctionElement] that |
- /// defines the implementation of [element]. |
- FunctionElement resolveExternalFunction(FunctionElement element) => element; |
- |
- /// Returns `true` if [library] is a backend specific library whose members |
- /// have special treatment, such as being allowed to extends blacklisted |
- /// classes or member being eagerly resolved. |
- bool isBackendLibrary(LibraryElement library) { |
- // TODO(johnniwinther): Remove this when patching is only done by the |
- // JavaScript backend. |
- Uri canonicalUri = library.canonicalUri; |
- if (canonicalUri == js_backend.JavaScriptBackend.DART_JS_HELPER || |
- canonicalUri == js_backend.JavaScriptBackend.DART_INTERCEPTORS) { |
- return true; |
- } |
- return false; |
- } |
- |
- void registerStaticUse(Element element, Enqueuer enqueuer) {} |
- |
- /// This method is called immediately after the [LibraryElement] [library] has |
- /// been created. |
- void onLibraryCreated(LibraryElement library) {} |
- |
- /// This method is called immediately after the [library] and its parts have |
- /// been scanned. |
- Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
- if (library.canUseNative) { |
- library.forEachLocalMember((Element element) { |
- if (element.isClass) { |
- checkNativeAnnotation(compiler, element); |
- } |
- }); |
- } |
- return new Future.value(); |
- } |
- |
- /// This method is called when all new libraries loaded through |
- /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports |
- /// have been computed. |
- Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
- return new Future.value(); |
- } |
- |
- /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed |
- /// annotations. The arguments corresponds to the unions of the corresponding |
- /// fields of the annotations. |
- void registerMirrorUsage(Set<String> symbols, |
- Set<Element> targets, |
- Set<Element> metaTargets) {} |
- |
- /// Returns true if this element needs reflection information at runtime. |
- bool isAccessibleByReflection(Element element) => true; |
- |
- /// Returns true if this element is covered by a mirrorsUsed annotation. |
- /// |
- /// Note that it might still be ok to tree shake the element away if no |
- /// reflection is used in the program (and thus [isTreeShakingDisabled] is |
- /// still false). Therefore _do not_ use this predicate to decide inclusion |
- /// in the tree, use [requiredByMirrorSystem] instead. |
- bool referencedFromMirrorSystem(Element element, [recursive]) => false; |
- |
- /// Returns true if this element has to be enqueued due to |
- /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if |
- /// normal tree shaking is still active ([isTreeShakingDisabled] is false). |
- bool requiredByMirrorSystem(Element element) => false; |
- |
- /// Returns true if global optimizations such as type inferencing |
- /// can apply to this element. One category of elements that do not |
- /// apply is runtime helpers that the backend calls, but the |
- /// optimizations don't see those calls. |
- bool canBeUsedForGlobalOptimizations(Element element) => true; |
- |
- /// Called when [enqueuer]'s queue is empty, but before it is closed. |
- /// This is used, for example, by the JS backend to enqueue additional |
- /// elements needed for reflection. [recentClasses] is a collection of |
- /// all classes seen for the first time by the [enqueuer] since the last call |
- /// to [onQueueEmpty]. |
- /// |
- /// A return value of [:true:] indicates that [recentClasses] has been |
- /// processed and its elements do not need to be seen in the next round. When |
- /// [:false:] is returned, [onQueueEmpty] will be called again once the |
- /// resolution queue has drained and [recentClasses] will be a superset of the |
- /// current value. |
- /// |
- /// There is no guarantee that a class is only present once in |
- /// [recentClasses], but every class seen by the [enqueuer] will be present in |
- /// [recentClasses] at least once. |
- bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
- return true; |
- } |
- |
- /// Called after [element] has been resolved. |
- // TODO(johnniwinther): Change [TreeElements] to [Registry] or a dependency |
- // node. [elements] is currently unused by the implementation. |
- void onElementResolved(Element element, TreeElements elements) {} |
- |
- // Does this element belong in the output |
- bool shouldOutput(Element element) => true; |
- |
- FunctionElement helperForBadMain() => null; |
- |
- FunctionElement helperForMissingMain() => null; |
- |
- FunctionElement helperForMainArity() => null; |
- |
- void forgetElement(Element element) {} |
- |
- void registerMainHasArguments(Enqueuer enqueuer) {} |
- |
- void registerAsyncMarker(FunctionElement element, |
- Enqueuer enqueuer, |
- Registry registry) {} |
-} |
- |
-/// Backend callbacks function specific to the resolution phase. |
-class ResolutionCallbacks { |
- /// Register that [node] is a call to `assert`. |
- void onAssert(Send node, Registry registry) {} |
- |
- /// Register that an 'await for' has been seen. |
- void onAsyncForIn(AsyncForIn node, Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program uses string interpolation. |
- void onStringInterpolation(Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program has a catch statement. |
- void onCatchStatement(Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program explicitly throws an exception. |
- void onThrowExpression(Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program has a global variable with a lazy initializer. |
- void onLazyField(Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program uses a type variable as an expression. |
- void onTypeVariableExpression(Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program uses a type literal. |
- void onTypeLiteral(DartType type, Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program has a catch statement with a stack trace. |
- void onStackTraceInCatch(Registry registry) {} |
- |
- /// Register an is check to the backend. |
- void onIsCheck(DartType type, Registry registry) {} |
- |
- /// Called during resolution to notify to the backend that the |
- /// program has a for-in loop. |
- void onSyncForIn(Registry registry) {} |
- |
- /// Register an as check to the backend. |
- void onAsCheck(DartType type, Registry registry) {} |
- |
- /// Registers that a type variable bounds check might occur at runtime. |
- void onTypeVariableBoundCheck(Registry registry) {} |
- |
- /// Register that the application may throw a [NoSuchMethodError]. |
- void onThrowNoSuchMethod(Registry registry) {} |
- |
- /// Register that the application may throw a [RuntimeError]. |
- void onThrowRuntimeError(Registry registry) {} |
- |
- /// Register that the application may throw an |
- /// [AbstractClassInstantiationError]. |
- void onAbstractClassInstantiation(Registry registry) {} |
- |
- /// Register that the application may throw a [FallThroughError]. |
- void onFallThroughError(Registry registry) {} |
- |
- /// Register that a super call will end up calling |
- /// [: super.noSuchMethod :]. |
- void onSuperNoSuchMethod(Registry registry) {} |
- |
- /// Register that the application creates a constant map. |
- void onMapLiteral(Registry registry, DartType type, bool isConstant) {} |
- |
- /// Called when resolving the `Symbol` constructor. |
- void onSymbolConstructor(Registry registry) {} |
-} |
- |
-/** |
- * Key class used in [TokenMap] in which the hash code for a token is based |
- * on the [charOffset]. |
- */ |
-class TokenKey { |
- final Token token; |
- TokenKey(this.token); |
- int get hashCode => token.charOffset; |
- operator==(other) => other is TokenKey && token == other.token; |
-} |
- |
-/// Map of tokens and the first associated comment. |
-/* |
- * This implementation was chosen among several candidates for its space/time |
- * efficiency by empirical tests of running dartdoc on dartdoc itself. Time |
- * measurements for the use of [Compiler.commentMap]: |
- * |
- * 1) Using [TokenKey] as key (this class): ~80 msec |
- * 2) Using [TokenKey] as key + storing a separate map in each script: ~120 msec |
- * 3) Using [Token] as key in a [Map]: ~38000 msec |
- * 4) Storing comments is new field in [Token]: ~20 msec |
- * (Abandoned due to the increased memory usage) |
- * 5) Storing comments in an [Expando]: ~14000 msec |
- * 6) Storing token/comments pairs in a linked list: ~5400 msec |
- */ |
-class TokenMap { |
- Map<TokenKey,Token> comments = new Map<TokenKey,Token>(); |
- |
- Token operator[] (Token key) { |
- if (key == null) return null; |
- return comments[new TokenKey(key)]; |
- } |
- |
- void operator[]= (Token key, Token value) { |
- if (key == null) return; |
- comments[new TokenKey(key)] = value; |
- } |
-} |
+library dart2js.compiler_base; |
+ |
+import 'dart:async' show |
+ EventSink, |
+ Future; |
+ |
+import '../compiler_new.dart' as api; |
+import 'cache_strategy.dart' show |
+ CacheStrategy; |
+import 'closure.dart' as closureMapping show |
+ ClosureTask; |
+import 'common/backend_api.dart' show |
+ Backend; |
+import 'common/codegen.dart' show |
+ CodegenRegistry, |
+ CodegenWorkItem; |
+import 'common/registry.dart' show |
+ Registry; |
+import 'common/resolution.dart' show |
+ ResolutionWorkItem; |
+import 'common/tasks.dart' show |
+ CompilerTask, |
+ GenericTask; |
+import 'common/work.dart' show |
+ WorkItem; |
+import 'compile_time_constants.dart'; |
+import 'constants/values.dart'; |
+import 'core_types.dart' show |
+ CoreTypes; |
+import 'cps_ir/cps_ir_builder_task.dart' show |
+ IrBuilderTask; |
+import 'dart_backend/dart_backend.dart' as dart_backend; |
+import 'dart_types.dart' show |
+ DartType, |
+ DynamicType, |
+ InterfaceType, |
+ Types; |
+import 'deferred_load.dart' show DeferredLoadTask, OutputUnit; |
+import 'diagnostic_listener.dart'; |
+import 'diagnostics/code_location.dart'; |
+import 'diagnostics/invariant.dart' show |
+ invariant, |
+ REPORT_EXCESS_RESOLUTION; |
+import 'diagnostics/source_span.dart' show |
+ SourceSpan; |
+import 'diagnostics/spannable.dart' show |
+ CURRENT_ELEMENT_SPANNABLE, |
+ NO_LOCATION_SPANNABLE, |
+ Spannable, |
+ SpannableAssertionFailure; |
+import 'dump_info.dart' show |
+ DumpInfoTask; |
+import 'elements/elements.dart'; |
+import 'elements/modelx.dart' show |
+ ErroneousElementX, |
+ ClassElementX, |
+ CompilationUnitElementX, |
+ DeferredLoaderGetterElementX, |
+ MethodElementX, |
+ LibraryElementX, |
+ PrefixElementX, |
+ VoidElementX; |
+import 'enqueue.dart' show |
+ CodegenEnqueuer, |
+ Enqueuer, |
+ EnqueueTask, |
+ ResolutionEnqueuer, |
+ QueueFilter, |
+ WorldImpact; |
+import 'io/source_information.dart' show |
+ SourceInformation; |
+import 'js_backend/js_backend.dart' as js_backend show |
+ JavaScriptBackend; |
+import 'library_loader.dart' show |
+ LibraryLoader, |
+ LibraryLoaderTask, |
+ LoadedLibraries; |
+import 'messages.dart' show |
+ Message, |
+ MessageKind, |
+ MessageTemplate; |
+import 'mirrors_used.dart' show |
+ MirrorUsageAnalyzerTask; |
+import 'null_compiler_output.dart' show |
+ NullCompilerOutput, |
+ NullSink; |
+import 'patch_parser.dart' show |
+ PatchParserTask; |
+import 'resolution/resolution.dart' show |
+ ResolutionRegistry, |
+ ResolverTask, |
+ TreeElementMapping; |
+import 'scanner/token_map.dart' show |
+ TokenMap; |
+import 'scanner/scannerlib.dart' show |
+ COMMENT_TOKEN, |
+ DietParserTask, |
+ EOF_TOKEN, |
+ ParserTask, |
+ ScannerTask, |
+ StringToken, |
+ Token, |
+ TokenPair; |
+import 'serialization/task.dart' show |
+ SerializationTask; |
+import 'script.dart' show |
+ Script; |
+import 'ssa/ssa.dart' show |
+ HInstruction; |
+import 'tracer.dart' show |
+ Tracer; |
+import 'tree/tree.dart' show |
+ Node; |
+import 'typechecker.dart' show |
+ TypeCheckerTask; |
+import 'types/types.dart' as ti; |
+import 'universe/universe.dart' show |
+ Selector, |
+ Universe; |
+import 'util/characters.dart' show $_; |
+import 'util/util.dart' show |
+ Link; |
+import 'world.dart' show |
+ World; |
abstract class Compiler implements DiagnosticListener { |
static final Uri DART_CORE = new Uri(scheme: 'dart', path: 'core'); |
@@ -2189,130 +1653,6 @@ abstract class Compiler implements DiagnosticListener { |
} |
} |
-class CompilerTask { |
- final Compiler compiler; |
- final Stopwatch watch; |
- UserTag profilerTag; |
- |
- CompilerTask(Compiler compiler) |
- : this.compiler = compiler, |
- watch = (compiler.verbose) ? new Stopwatch() : null; |
- |
- String get name => "Unknown task '${this.runtimeType}'"; |
- int get timing => (watch != null) ? watch.elapsedMilliseconds : 0; |
- |
- int get timingMicroseconds => (watch != null) ? watch.elapsedMicroseconds : 0; |
- |
- UserTag getProfilerTag() { |
- if (profilerTag == null) profilerTag = new UserTag(name); |
- return profilerTag; |
- } |
- |
- measure(action()) { |
- // In verbose mode when watch != null. |
- if (watch == null) return action(); |
- CompilerTask previous = compiler.measuredTask; |
- if (identical(this, previous)) return action(); |
- compiler.measuredTask = this; |
- if (previous != null) previous.watch.stop(); |
- watch.start(); |
- UserTag oldTag = getProfilerTag().makeCurrent(); |
- try { |
- return action(); |
- } finally { |
- watch.stop(); |
- oldTag.makeCurrent(); |
- if (previous != null) previous.watch.start(); |
- compiler.measuredTask = previous; |
- } |
- } |
- |
- measureElement(Element element, action()) { |
- compiler.withCurrentElement(element, () => measure(action)); |
- } |
-} |
- |
-class SourceSpan implements Spannable { |
- final Uri uri; |
- final int begin; |
- final int end; |
- |
- const SourceSpan(this.uri, this.begin, this.end); |
- |
- static withCharacterOffsets(Token begin, Token end, |
- f(int beginOffset, int endOffset)) { |
- final beginOffset = begin.charOffset; |
- final endOffset = end.charOffset + end.charCount; |
- |
- // [begin] and [end] might be the same for the same empty token. This |
- // happens for instance when scanning '$$'. |
- assert(endOffset >= beginOffset); |
- return f(beginOffset, endOffset); |
- } |
- |
- int get hashCode { |
- return 13 * uri.hashCode + |
- 17 * begin.hashCode + |
- 19 * end.hashCode; |
- } |
- |
- bool operator ==(other) { |
- if (identical(this, other)) return true; |
- if (other is! SourceSpan) return false; |
- return uri == other.uri && |
- begin == other.begin && |
- end == other.end; |
- } |
- |
- String toString() => 'SourceSpan($uri, $begin, $end)'; |
-} |
- |
-/// Flag that can be used in assertions to assert that a code path is only |
-/// executed as part of development. |
-/// |
-/// This flag is automatically set to true if helper methods like, [debugPrint], |
-/// [debugWrapPrint], [trace], and [reportHere] are called. |
-bool DEBUG_MODE = false; |
- |
-/// Assert that [DEBUG_MODE] is `true` and provide [message] as part of the |
-/// error message. |
-assertDebugMode(String message) { |
- assert(invariant(NO_LOCATION_SPANNABLE, DEBUG_MODE, |
- message: 'Debug mode is not enabled: $message')); |
-} |
- |
-/** |
- * Throws a [SpannableAssertionFailure] if [condition] is |
- * [:false:]. [condition] must be either a [:bool:] or a no-arg |
- * function returning a [:bool:]. |
- * |
- * Use this method to provide better information for assertion by calling |
- * [invariant] as the argument to an [:assert:] statement: |
- * |
- * assert(invariant(position, isValid)); |
- * |
- * [spannable] must be non-null and will be used to provide positional |
- * information in the generated error message. |
- */ |
-bool invariant(Spannable spannable, var condition, {var message: null}) { |
- // TODO(johnniwinther): Use [spannable] and [message] to provide better |
- // information on assertion errors. |
- if (spannable == null) { |
- throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE, |
- "Spannable was null for invariant. Use CURRENT_ELEMENT_SPANNABLE."); |
- } |
- if (condition is Function){ |
- condition = condition(); |
- } |
- if (!condition) { |
- if (message is Function) { |
- message = message(); |
- } |
- throw new SpannableAssertionFailure(spannable, message); |
- } |
- return true; |
-} |
- |
/// Returns `true` when [s] is private if used as an identifier. |
bool isPrivateName(String s) => !s.isEmpty && s.codeUnitAt(0) == $_; |
@@ -2325,96 +1665,6 @@ class SuppressionInfo { |
int hints = 0; |
} |
-class GenericTask extends CompilerTask { |
- final String name; |
- |
- GenericTask(this.name, Compiler compiler) |
- : super(compiler); |
-} |
- |
-/// [CodeLocation] divides uris into different classes. |
-/// |
-/// These are used to group uris from user code, platform libraries and |
-/// packages. |
-abstract class CodeLocation { |
- /// Returns `true` if [uri] is in this code location. |
- bool inSameLocation(Uri uri); |
- |
- /// Returns the uri of this location relative to [baseUri]. |
- String relativize(Uri baseUri); |
- |
- factory CodeLocation(Uri uri) { |
- if (uri.scheme == 'package') { |
- int slashPos = uri.path.indexOf('/'); |
- if (slashPos != -1) { |
- String packageName = uri.path.substring(0, slashPos); |
- return new PackageLocation(packageName); |
- } else { |
- return new UriLocation(uri); |
- } |
- } else { |
- return new SchemeLocation(uri); |
- } |
- } |
-} |
- |
-/// A code location defined by the scheme of the uri. |
-/// |
-/// Used for non-package uris, such as 'dart', 'file', and 'http'. |
-class SchemeLocation implements CodeLocation { |
- final Uri uri; |
- |
- SchemeLocation(this.uri); |
- |
- bool inSameLocation(Uri uri) { |
- return this.uri.scheme == uri.scheme; |
- } |
- |
- String relativize(Uri baseUri) { |
- return uri_extras.relativize(baseUri, uri, false); |
- } |
-} |
- |
-/// A code location defined by the package name. |
-/// |
-/// Used for package uris, separated by their `package names`, that is, the |
-/// 'foo' of 'package:foo/bar.dart'. |
-class PackageLocation implements CodeLocation { |
- final String packageName; |
- |
- PackageLocation(this.packageName); |
- |
- bool inSameLocation(Uri uri) { |
- return uri.scheme == 'package' && uri.path.startsWith('$packageName/'); |
- } |
- |
- String relativize(Uri baseUri) => 'package:$packageName'; |
-} |
- |
-/// A code location defined by the whole uri. |
-/// |
-/// Used for package uris with no package name. For instance 'package:foo.dart'. |
-class UriLocation implements CodeLocation { |
- final Uri uri; |
- |
- UriLocation(this.uri); |
- |
- bool inSameLocation(Uri uri) => this.uri == uri; |
- |
- String relativize(Uri baseUri) { |
- return uri_extras.relativize(baseUri, uri, false); |
- } |
-} |
- |
-/// A code location that contains any uri. |
-class AnyLocation implements CodeLocation { |
- const AnyLocation(); |
- |
- bool inSameLocation(Uri uri) => true; |
- |
- String relativize(Uri baseUri) => '$baseUri'; |
-} |
- |
class _CompilerCoreTypes implements CoreTypes { |
final Compiler compiler; |
@@ -2517,5 +1767,3 @@ class _CompilerCoreTypes implements CoreTypes { |
return type.createInstantiation([elementType]); |
} |
} |
- |
-typedef void InternalErrorFunction(Spannable location, String message); |