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

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

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
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.
4
5 part of js_backend;
6
7 /**
8 * Handles construction of TypeVariable constants needed at runtime.
9 */
10 class TypeVariableHandler {
11 JavaScriptBackend backend;
12 FunctionElement typeVariableConstructor;
13 CompileTimeConstantEvaluator evaluator;
14
15 /**
16 * Contains all instantiated classes that have type variables and are needed
17 * for reflection.
18 */
19 List<ClassElement> typeVariableClasses = new List<ClassElement>();
20
21 /**
22 * Maps a class element to a list with indices that point to type variables
23 * constants for each of the class' type variables.
24 */
25 Map<ClassElement, List<int>> typeVariables =
26 new Map<ClassElement, List<int>>();
27
28 /**
29 * Maps a TypeVariableType to the index pointing to the constant representing
30 * the corresponding type variable at runtime.
31 */
32 Map<TypeVariableElement, int> typeVariableConstants =
33 new Map<TypeVariableElement, int>();
34
35 TypeVariableHandler(this.backend);
36
37 ClassElement get typeVariableClass => backend.typeVariableClass;
38 CodeEmitterTask get task => backend.emitter;
39 MetadataEmitter get emitter => task.oldEmitter.metadataEmitter;
40 Compiler get compiler => backend.compiler;
41
42 void registerClassWithTypeVariables(ClassElement cls) {
43 if (typeVariableClasses != null) {
44 typeVariableClasses.add(cls);
45 }
46 }
47
48 void processTypeVariablesOf(ClassElement cls) {
49 //TODO(zarah): Running through all the members is suboptimal. Change this
50 // as part of marking elements for reflection.
51 bool hasMemberNeededForReflection(ClassElement cls) {
52 bool result = false;
53 cls.implementation.forEachMember((ClassElement cls, Element member) {
54 result = result || backend.referencedFromMirrorSystem(member);
55 });
56 return result;
57 }
58
59 if (!backend.referencedFromMirrorSystem(cls) &&
60 !hasMemberNeededForReflection(cls)) {
61 return;
62 }
63
64 InterfaceType typeVariableType = typeVariableClass.thisType;
65 List<int> constants = <int>[];
66
67 for (TypeVariableType currentTypeVariable in cls.typeVariables) {
68 TypeVariableElement typeVariableElement = currentTypeVariable.element;
69
70 AstConstant wrapConstant(ConstantExpression constant) {
71 return new AstConstant(typeVariableElement,
72 typeVariableElement.node,
73 constant);
74 }
75
76 ConstantExpression name = new PrimitiveConstantExpression(
77 backend.constantSystem.createString(
78 new DartString.literal(currentTypeVariable.name)));
79 ConstantExpression bound = new PrimitiveConstantExpression(
80 backend.constantSystem.createInt(
81 emitter.reifyType(typeVariableElement.bound)));
82 ConstantExpression type = backend.constants.createTypeConstant(cls);
83 List<AstConstant> arguments =
84 [wrapConstant(type), wrapConstant(name), wrapConstant(bound)];
85
86 // TODO(johnniwinther): Support a less front-end specific creation of
87 // constructed constants.
88 AstConstant constant =
89 CompileTimeConstantEvaluator.makeConstructedConstant(
90 compiler,
91 backend.constants,
92 typeVariableElement,
93 typeVariableElement.node,
94 typeVariableType,
95 typeVariableConstructor,
96 new Selector.callConstructor('', null, 3),
97 arguments,
98 arguments);
99 ConstantValue value = constant.value;
100 backend.registerCompileTimeConstant(value, compiler.globalDependencies);
101 backend.constants.addCompileTimeConstantForEmission(value);
102 constants.add(
103 reifyTypeVariableConstant(value, currentTypeVariable.element));
104 }
105 typeVariables[cls] = constants;
106 }
107
108 void onTreeShakingDisabled(Enqueuer enqueuer) {
109 if (enqueuer.isResolutionQueue) {
110 backend.enqueueClass(
111 enqueuer, typeVariableClass, compiler.globalDependencies);
112 typeVariableClass.ensureResolved(compiler);
113 Link constructors = typeVariableClass.constructors;
114 if (constructors.isEmpty && constructors.tail.isEmpty) {
115 compiler.internalError(typeVariableClass,
116 "Class '$typeVariableClass' should only have one constructor");
117 }
118 typeVariableConstructor = typeVariableClass.constructors.head;
119 backend.enqueueInResolution(typeVariableConstructor,
120 compiler.globalDependencies);
121 enqueuer.registerInstantiatedType(typeVariableClass.rawType,
122 compiler.globalDependencies);
123 enqueuer.registerStaticUse(backend.getCreateRuntimeType());
124 } else if (typeVariableClasses != null) {
125 List<ClassElement> worklist = typeVariableClasses;
126 typeVariableClasses = null;
127 worklist.forEach((cls) => processTypeVariablesOf(cls));
128 }
129 }
130
131 /**
132 * Adds [c] to [emitter.globalMetadata] and returns the index pointing to
133 * the entry.
134 *
135 * If the corresponding type variable has already been encountered an
136 * entry in the list has already been reserved and the constant is added
137 * there, otherwise a new entry for [c] is created.
138 */
139 int reifyTypeVariableConstant(ConstantValue c, TypeVariableElement variable) {
140 String name = jsAst.prettyPrint(task.constantReference(c),
141 compiler).getText();
142 int index;
143 if (typeVariableConstants.containsKey(variable)) {
144 index = typeVariableConstants[variable];
145 emitter.globalMetadata[index] = name;
146 } else {
147 index = emitter.addGlobalMetadata(name);
148 typeVariableConstants[variable] = index;
149 }
150 return index;
151 }
152
153 /**
154 * Returns the index pointing to the constant in [emitter.globalMetadata]
155 * representing this type variable.
156 *
157 * If the constant has not yet been constructed, an entry is allocated in
158 * the global metadata list and the index pointing to this entry is returned.
159 * When the corresponding constant is constructed later,
160 * [reifyTypeVariableConstant] will be called and the constant will be added
161 * on the allocated entry.
162 */
163 int reifyTypeVariable(TypeVariableElement variable) {
164 if (typeVariableConstants.containsKey(variable)) {
165 return typeVariableConstants[variable];
166 }
167
168 // TODO(15613): Remove quotes.
169 emitter.globalMetadata.add('"Placeholder for ${variable}"');
170 return typeVariableConstants[variable] = emitter.globalMetadata.length - 1;
171 }
172
173 List<int> typeVariablesOf(ClassElement classElement) {
174 List<int> result = typeVariables[classElement];
175 if (result == null) {
176 result = const <int>[];
177 }
178 return result;
179 }
180 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698