Index: sdk/lib/_internal/compiler/implementation/js_backend/custom_elements_analysis.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/custom_elements_analysis.dart b/sdk/lib/_internal/compiler/implementation/js_backend/custom_elements_analysis.dart |
deleted file mode 100644 |
index 9a5c8e987940a9ec62bb27bc9291ab808012f7ee..0000000000000000000000000000000000000000 |
--- a/sdk/lib/_internal/compiler/implementation/js_backend/custom_elements_analysis.dart |
+++ /dev/null |
@@ -1,207 +0,0 @@ |
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
-// 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 js_backend; |
- |
-/** |
- * Support for Custom Elements. |
- * |
- * The support for custom elements the compiler builds a table that maps the |
- * custom element class's [Type] to the interceptor for the class and the |
- * constructor(s) for the class. |
- * |
- * We want the table to contain only the custom element classes used, and we |
- * want to avoid resolving and compiling constructors that are not used since |
- * that may bring in unused code. This class controls the resolution and code |
- * generation to restrict the impact. |
- * |
- * The following line of code requires the generation of the generative |
- * constructor factory function(s) for FancyButton, and their insertion into the |
- * table: |
- * |
- * document.register(FancyButton, 'x-fancy-button'); |
- * |
- * We detect this by 'joining' the classes that are referenced as type literals |
- * with the classes that are custom elements, enabled by detecting the presence |
- * of the table access code used by document.register. |
- * |
- * We have to be more conservative when the type is unknown, e.g. |
- * |
- * document.register(classMirror.reflectedType, tagFromMetadata); |
- * |
- * and |
- * |
- * class Component<T> { |
- * final tag; |
- * Component(this.tag); |
- * void register() => document.register(T, tag); |
- * } |
- * const Component<FancyButton>('x-fancy-button').register(); |
- * |
- * In these cases we conservatively generate all viable entries in the table. |
- */ |
-class CustomElementsAnalysis { |
- final JavaScriptBackend backend; |
- final Compiler compiler; |
- final CustomElementsAnalysisJoin resolutionJoin; |
- final CustomElementsAnalysisJoin codegenJoin; |
- bool fetchedTableAccessorMethod = false; |
- Element tableAccessorMethod; |
- |
- CustomElementsAnalysis(JavaScriptBackend backend) |
- : this.backend = backend, |
- this.compiler = backend.compiler, |
- resolutionJoin = new CustomElementsAnalysisJoin(backend), |
- codegenJoin = new CustomElementsAnalysisJoin(backend) { |
- // TODO(sra): Remove this work-around. We should mark allClassesSelected in |
- // both joins only when we see a construct generating an unknown [Type] but |
- // we can't currently recognize all cases. In particular, the work-around |
- // for the unimplemented `ClassMirror.reflectedType` is not recognizable. |
- // TODO(12607): Match on [ClassMirror.reflectedType] |
- resolutionJoin.allClassesSelected = true; |
- codegenJoin.allClassesSelected = true; |
- } |
- |
- CustomElementsAnalysisJoin joinFor(Enqueuer enqueuer) => |
- enqueuer.isResolutionQueue ? resolutionJoin : codegenJoin; |
- |
- void registerInstantiatedClass(ClassElement classElement, Enqueuer enqueuer) { |
- classElement.ensureResolved(compiler); |
- if (!Elements.isNativeOrExtendsNative(classElement)) return; |
- if (classElement.isMixinApplication) return; |
- if (classElement.isAbstract) return; |
- joinFor(enqueuer).instantiatedClasses.add(classElement); |
- } |
- |
- void registerTypeLiteral(DartType type, Registry registry) { |
- assert(registry.isForResolution); |
- // In codegen we see the TypeConstants instead. |
- if (!registry.isForResolution) return; |
- |
- if (type.isInterfaceType) { |
- // TODO(sra): If we had a flow query from the type literal expression to |
- // the Type argument of the metadata lookup, we could tell if this type |
- // literal is really a demand for the metadata. |
- resolutionJoin.selectedClasses.add(type.element); |
- } else if (type.isTypeVariable) { |
- // This is a type parameter of a parameterized class. |
- // TODO(sra): Is there a way to determine which types are bound to the |
- // parameter? |
- resolutionJoin.allClassesSelected = true; |
- } |
- } |
- |
- void registerTypeConstant(Element element, Enqueuer enqueuer) { |
- assert(element.isClass); |
- assert(!enqueuer.isResolutionQueue); |
- codegenJoin.selectedClasses.add(element); |
- } |
- |
- void registerStaticUse(Element element, Enqueuer enqueuer) { |
- assert(element != null); |
- if (!fetchedTableAccessorMethod) { |
- fetchedTableAccessorMethod = true; |
- tableAccessorMethod = backend.findInterceptor( |
- 'findIndexForNativeSubclassType'); |
- } |
- if (element == tableAccessorMethod) { |
- joinFor(enqueuer).demanded = true; |
- } |
- } |
- |
- void onQueueEmpty(Enqueuer enqueuer) { |
- joinFor(enqueuer).flush(enqueuer); |
- } |
- |
- bool get needsTable => codegenJoin.demanded; |
- |
- bool needsClass(ClassElement classElement) => |
- codegenJoin.activeClasses.contains(classElement); |
- |
- List<Element> constructors(ClassElement classElement) => |
- codegenJoin.computeEscapingConstructors(classElement); |
-} |
- |
- |
-class CustomElementsAnalysisJoin { |
- final JavaScriptBackend backend; |
- Compiler get compiler => backend.compiler; |
- |
- // Classes that are candidates for needing constructors. Classes are moved to |
- // [activeClasses] when we know they need constructors. |
- final instantiatedClasses = new Set<ClassElement>(); |
- |
- // Classes explicitly named. |
- final selectedClasses = new Set<ClassElement>(); |
- |
- // True if we must conservatively include all extension classes. |
- bool allClassesSelected = false; |
- |
- // Did we see a demand for the data? |
- bool demanded = false; |
- |
- // ClassesOutput: classes requiring metadata. |
- final activeClasses = new Set<ClassElement>(); |
- |
- CustomElementsAnalysisJoin(this.backend); |
- |
- void flush(Enqueuer enqueuer) { |
- if (!demanded) return; |
- var newActiveClasses = new Set<ClassElement>(); |
- for (ClassElement classElement in instantiatedClasses) { |
- bool isNative = classElement.isNative; |
- bool isExtension = |
- !isNative && Elements.isNativeOrExtendsNative(classElement); |
- // Generate table entries for native classes that are explicitly named and |
- // extensions that fix our criteria. |
- if ((isNative && selectedClasses.contains(classElement)) || |
- (isExtension && |
- (allClassesSelected || selectedClasses.contains(classElement)))) { |
- newActiveClasses.add(classElement); |
- Iterable<Element> escapingConstructors = |
- computeEscapingConstructors(classElement); |
- escapingConstructors.forEach(enqueuer.registerStaticUse); |
- escapingConstructors |
- .forEach(compiler.globalDependencies.registerDependency); |
- // Force the generaton of the type constant that is the key to an entry |
- // in the generated table. |
- ConstantValue constant = makeTypeConstant(classElement); |
- backend.registerCompileTimeConstant( |
- constant, compiler.globalDependencies); |
- backend.constants.addCompileTimeConstantForEmission(constant); |
- } |
- } |
- activeClasses.addAll(newActiveClasses); |
- instantiatedClasses.removeAll(newActiveClasses); |
- } |
- |
- TypeConstantValue makeTypeConstant(ClassElement element) { |
- DartType elementType = element.rawType; |
- DartType constantType = backend.typeImplementation.rawType; |
- return new TypeConstantValue(elementType, constantType); |
- } |
- |
- List<Element> computeEscapingConstructors(ClassElement classElement) { |
- List<Element> result = <Element>[]; |
- // Only classes that extend native classes have constructors in the table. |
- // We could refine this to classes that extend Element, but that would break |
- // the tests and there is no sane reason to subclass other native classes. |
- if (classElement.isNative) return result; |
- |
- selectGenerativeConstructors(ClassElement enclosing, Element member) { |
- if (member.isGenerativeConstructor) { |
- // Ignore constructors that cannot be called with zero arguments. |
- FunctionElement constructor = member; |
- FunctionSignature parameters = constructor.functionSignature; |
- if (parameters.requiredParameterCount == 0) { |
- result.add(member); |
- } |
- } |
- } |
- classElement.forEachMember(selectGenerativeConstructors, |
- includeBackendMembers: false, |
- includeSuperAndInjectedMembers: false); |
- return result; |
- } |
-} |