Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1205)

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart

Issue 26900005: Reapply "Add TypeVariable object on runtime to support reflection on type variables." and "Fix type… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix: stop ignoring classes not needed for reflection when processing type variables. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart b/sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart
new file mode 100644
index 0000000000000000000000000000000000000000..8cddea717845ad65bc7dc80957810f5e183315d7
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/type_variable_handler.dart
@@ -0,0 +1,143 @@
+// 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;
+
+/**
+ * Handles construction of TypeVariable constants needed at runtime.
+ */
+class TypeVariableHandler {
+ JavaScriptBackend backend;
+ FunctionElement typeVariableConstructor;
+ CompileTimeConstantEvaluator evaluator;
+
+ /**
+ * Contains all instantiated classes that have type variables and are needed
+ * for reflection.
+ */
+ List<ClassElement> typeVariableClasses = new List<ClassElement>();
+
+ /**
+ * Maps a class element to a list with indices that point to type variables
+ * constants for each of the class' type variables.
+ */
+ Map<ClassElement, List<int>> typeVariables =
+ new Map<ClassElement, List<int>>();
+
+ /**
+ * Maps a TypeVariableType to the index pointing to the constant representing
+ * the corresponding type variable at runtime.
+ */
+ Map<TypeVariableElement, int> typeVariableConstants =
+ new Map<TypeVariableElement, int>();
+
+ TypeVariableHandler(this.backend);
+
+ ClassElement get typeVariableClass => backend.typeVariableClass;
+ CodeEmitterTask get task => backend.emitter;
+ MetadataEmitter get emitter => task.metadataEmitter;
+ Compiler get compiler => backend.compiler;
+
+ void registerClassWithTypeVariables(ClassElement cls) {
+ typeVariableClasses.add(cls);
+ }
+
+ void onResolutionQueueEmpty(Enqueuer enqueuer) {
+ if (typeVariableConstructor == null) {
+ if (!typeVariableClass.constructors.isEmpty &&
+ !typeVariableClass.constructors.tail.isEmpty) {
+ compiler.reportInternalError(
+ typeVariableClass,
+ 'Class $typeVariableClass should only have one constructor');
+ }
+ typeVariableConstructor = typeVariableClass.constructors.head;
+ backend.enqueueClass(
+ enqueuer, typeVariableClass, compiler.globalDependencies);
+ backend.enqueueInResolution(
+ typeVariableConstructor, compiler.globalDependencies);
+ }
+ }
+
+ void onCodegenQueueEmpty() {
+ evaluator = new CompileTimeConstantEvaluator(
+ compiler.constantHandler, compiler.globalDependencies, compiler);
+
+ for (ClassElement cls in typeVariableClasses) {
+ InterfaceType typeVariableType = typeVariableClass.computeType(compiler);
+ List<int> constants = <int>[];
+ for (TypeVariableType currentTypeVariable in cls.typeVariables) {
+ List<Constant> createArguments(FunctionElement constructor) {
+ if (constructor != typeVariableConstructor) {
+ compiler.internalErrorOnElement(
+ currentTypeVariable.element,
+ 'Unexpected constructor $constructor');
+ }
+ Constant name = backend.constantSystem.createString(
+ new DartString.literal(currentTypeVariable.name.slowToString()),
+ null);
+ Constant bound = backend.constantSystem.createInt(
+ emitter.reifyType(currentTypeVariable.element.bound));
+ Constant type = evaluator.makeTypeConstant(cls);
+ return [type, name, bound];
+ }
+
+ Constant c = evaluator.makeConstructedConstant(
+ currentTypeVariable.element, typeVariableType,
+ typeVariableConstructor, createArguments);
+ backend.registerCompileTimeConstant(c, compiler.globalDependencies);
+ compiler.constantHandler.addCompileTimeConstantForEmission(c);
+ constants.add(
+ reifyTypeVariableConstant(c, currentTypeVariable.element));
+ }
+ typeVariables[cls] = constants;
+ }
+ typeVariableClasses.clear();
+ }
+
+ /**
+ * Adds [c] to [emitter.globalMetadata] and returns the index pointing to
+ * the entry.
+ *
+ * If the corresponding type variable has already been encountered an
+ * entry in the list has already been reserved and the constant is added
+ * there, otherwise a new entry for [c] is created.
+ */
+ int reifyTypeVariableConstant(Constant c, TypeVariableElement variable) {
+ String name =
+ jsAst.prettyPrint(task.constantReference(c), compiler).getText();
+ int index;
+ if (typeVariableConstants.containsKey(variable)) {
+ index = typeVariableConstants[variable];
+ emitter.globalMetadata[index] = name;
+ } else {
+ index = emitter.addGlobalMetadata(name);
+ typeVariableConstants[variable] = index;
+ }
+ return index;
+ }
+
+ /**
+ * Returns the index pointing to the constant in [emitter.globalMetadata]
+ * representing this type variable
+ *.
+ *
+ * If the constant has not yet been constructed, an entry is allocated in
+ * the global metadata list and the index pointing to this entry is returned.
+ * When the corresponding constant is constructed later,
+ * [reifyTypeVariableConstant] will be called and the constant will be added
+ * on the allocated entry.
+ */
+ int reifyTypeVariable(TypeVariableElement variable) {
+ if (typeVariableConstants.containsKey(variable)) {
+ return typeVariableConstants[variable];
+ }
+
+ emitter.globalMetadata.add('Placeholder for ${variable}');
+ return typeVariableConstants[variable] = emitter.globalMetadata.length - 1;
+ }
+
+ List<int> typeVariablesOf(ClassElement classElement) {
+ return typeVariables[classElement];
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698