OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * Handles construction of TypeVariable constants needed at runtime. | 8 * Handles construction of TypeVariable constants needed at runtime. |
9 */ | 9 */ |
10 class TypeVariableHandler { | 10 class TypeVariableHandler { |
(...skipping 20 matching lines...) Expand all Loading... |
31 new Map<TypeVariableElement, jsAst.Expression>(); | 31 new Map<TypeVariableElement, jsAst.Expression>(); |
32 | 32 |
33 TypeVariableHandler(this._compiler); | 33 TypeVariableHandler(this._compiler); |
34 | 34 |
35 ClassElement get _typeVariableClass => _backend.helpers.typeVariableClass; | 35 ClassElement get _typeVariableClass => _backend.helpers.typeVariableClass; |
36 CodeEmitterTask get _task => _backend.emitter; | 36 CodeEmitterTask get _task => _backend.emitter; |
37 MetadataCollector get _metadataCollector => _task.metadataCollector; | 37 MetadataCollector get _metadataCollector => _task.metadataCollector; |
38 JavaScriptBackend get _backend => _compiler.backend; | 38 JavaScriptBackend get _backend => _compiler.backend; |
39 DiagnosticReporter get reporter => _compiler.reporter; | 39 DiagnosticReporter get reporter => _compiler.reporter; |
40 | 40 |
41 void registerClassWithTypeVariables(ClassElement cls, Enqueuer enqueuer, | 41 void registerClassWithTypeVariables( |
42 Registry registry) { | 42 ClassElement cls, Enqueuer enqueuer, Registry registry) { |
43 if (enqueuer.isResolutionQueue) { | 43 if (enqueuer.isResolutionQueue) { |
44 // On first encounter, we have to ensure that the support classes get | 44 // On first encounter, we have to ensure that the support classes get |
45 // resolved. | 45 // resolved. |
46 if (!_seenClassesWithTypeVariables) { | 46 if (!_seenClassesWithTypeVariables) { |
47 _backend.enqueueClass(enqueuer, _typeVariableClass, registry); | 47 _backend.enqueueClass(enqueuer, _typeVariableClass, registry); |
48 _typeVariableClass.ensureResolved(_compiler.resolution); | 48 _typeVariableClass.ensureResolved(_compiler.resolution); |
49 Link constructors = _typeVariableClass.constructors; | 49 Link constructors = _typeVariableClass.constructors; |
50 if (constructors.isEmpty && constructors.tail.isEmpty) { | 50 if (constructors.isEmpty && constructors.tail.isEmpty) { |
51 reporter.internalError(_typeVariableClass, | 51 reporter.internalError(_typeVariableClass, |
52 "Class '$_typeVariableClass' should only have one constructor"); | 52 "Class '$_typeVariableClass' should only have one constructor"); |
53 } | 53 } |
54 _typeVariableConstructor = _typeVariableClass.constructors.head; | 54 _typeVariableConstructor = _typeVariableClass.constructors.head; |
55 _backend.enqueueInResolution(_typeVariableConstructor, registry); | 55 _backend.enqueueInResolution(_typeVariableConstructor, registry); |
56 _backend.registerInstantiatedType( | 56 _backend.registerInstantiatedType( |
57 _typeVariableClass.rawType, enqueuer, registry); | 57 _typeVariableClass.rawType, enqueuer, registry); |
58 enqueuer.registerStaticUse( | 58 enqueuer.registerStaticUse(new StaticUse.staticInvoke( |
59 new StaticUse.staticInvoke( | 59 _backend.registerBackendUse(_backend.helpers.createRuntimeType), |
60 _backend.registerBackendUse(_backend.helpers.createRuntimeType), | 60 CallStructure.ONE_ARG)); |
61 CallStructure.ONE_ARG)); | |
62 _seenClassesWithTypeVariables = true; | 61 _seenClassesWithTypeVariables = true; |
63 } | 62 } |
64 } else { | 63 } else { |
65 if (_backend.isAccessibleByReflection(cls)) { | 64 if (_backend.isAccessibleByReflection(cls)) { |
66 processTypeVariablesOf(cls); | 65 processTypeVariablesOf(cls); |
67 } | 66 } |
68 } | 67 } |
69 } | 68 } |
70 | 69 |
71 void processTypeVariablesOf(ClassElement cls) { | 70 void processTypeVariablesOf(ClassElement cls) { |
72 // Do not process classes twice. | 71 // Do not process classes twice. |
73 if (_typeVariables.containsKey(cls)) return; | 72 if (_typeVariables.containsKey(cls)) return; |
74 | 73 |
75 InterfaceType typeVariableType = _typeVariableClass.thisType; | 74 InterfaceType typeVariableType = _typeVariableClass.thisType; |
76 List<jsAst.Expression> constants = <jsAst.Expression>[]; | 75 List<jsAst.Expression> constants = <jsAst.Expression>[]; |
77 | 76 |
78 for (TypeVariableType currentTypeVariable in cls.typeVariables) { | 77 for (TypeVariableType currentTypeVariable in cls.typeVariables) { |
79 TypeVariableElement typeVariableElement = currentTypeVariable.element; | 78 TypeVariableElement typeVariableElement = currentTypeVariable.element; |
80 | 79 |
81 AstConstant name = new AstConstant( | 80 AstConstant name = new AstConstant( |
82 typeVariableElement, | 81 typeVariableElement, |
83 typeVariableElement.node, | 82 typeVariableElement.node, |
84 new StringConstantExpression(currentTypeVariable.name), | 83 new StringConstantExpression(currentTypeVariable.name), |
85 _backend.constantSystem.createString( | 84 _backend.constantSystem |
86 new DartString.literal(currentTypeVariable.name))); | 85 .createString(new DartString.literal(currentTypeVariable.name))); |
87 jsAst.Expression boundIndex = | 86 jsAst.Expression boundIndex = |
88 _metadataCollector.reifyType(typeVariableElement.bound); | 87 _metadataCollector.reifyType(typeVariableElement.bound); |
89 ConstantValue boundValue = | 88 ConstantValue boundValue = new SyntheticConstantValue( |
90 new SyntheticConstantValue( | 89 SyntheticConstantKind.TYPEVARIABLE_REFERENCE, boundIndex); |
91 SyntheticConstantKind.TYPEVARIABLE_REFERENCE, | |
92 boundIndex); | |
93 ConstantExpression boundExpression = | 90 ConstantExpression boundExpression = |
94 new SyntheticConstantExpression(boundValue); | 91 new SyntheticConstantExpression(boundValue); |
95 AstConstant bound = new AstConstant( | 92 AstConstant bound = new AstConstant(typeVariableElement, |
96 typeVariableElement, | 93 typeVariableElement.node, boundExpression, boundValue); |
97 typeVariableElement.node, | |
98 boundExpression, | |
99 boundValue); | |
100 AstConstant type = new AstConstant( | 94 AstConstant type = new AstConstant( |
101 typeVariableElement, | 95 typeVariableElement, |
102 typeVariableElement.node, | 96 typeVariableElement.node, |
103 new TypeConstantExpression(cls.rawType), | 97 new TypeConstantExpression(cls.rawType), |
104 _backend.constantSystem.createType(_backend.compiler, cls.rawType)); | 98 _backend.constantSystem.createType(_backend.compiler, cls.rawType)); |
105 List<AstConstant> arguments = [type, name, bound]; | 99 List<AstConstant> arguments = [type, name, bound]; |
106 | 100 |
107 // TODO(johnniwinther): Support a less front-end specific creation of | 101 // TODO(johnniwinther): Support a less front-end specific creation of |
108 // constructed constants. | 102 // constructed constants. |
109 AstConstant constant = | 103 AstConstant constant = |
110 CompileTimeConstantEvaluator.makeConstructedConstant( | 104 CompileTimeConstantEvaluator.makeConstructedConstant( |
111 _compiler, | 105 _compiler, |
112 _backend.constants, | 106 _backend.constants, |
113 typeVariableElement, | 107 typeVariableElement, |
114 typeVariableElement.node, | 108 typeVariableElement.node, |
115 typeVariableType, | 109 typeVariableType, |
116 _typeVariableConstructor, | 110 _typeVariableConstructor, |
117 typeVariableType, | 111 typeVariableType, |
118 _typeVariableConstructor, | 112 _typeVariableConstructor, |
119 const CallStructure.unnamed(3), | 113 const CallStructure.unnamed(3), |
120 arguments, | 114 arguments, |
121 arguments); | 115 arguments); |
122 ConstantValue value = constant.value; | 116 ConstantValue value = constant.value; |
123 _backend.registerCompileTimeConstant(value, _compiler.globalDependencies); | 117 _backend.registerCompileTimeConstant(value, _compiler.globalDependencies); |
124 _backend.addCompileTimeConstantForEmission(value); | 118 _backend.addCompileTimeConstantForEmission(value); |
125 _backend.constants.addCompileTimeConstantForEmission(value); | 119 _backend.constants.addCompileTimeConstantForEmission(value); |
126 constants.add( | 120 constants |
127 _reifyTypeVariableConstant(value, currentTypeVariable.element)); | 121 .add(_reifyTypeVariableConstant(value, currentTypeVariable.element)); |
128 } | 122 } |
129 _typeVariables[cls] = constants; | 123 _typeVariables[cls] = constants; |
130 } | 124 } |
131 | 125 |
132 /** | 126 /** |
133 * Adds [c] to [emitter.metadataCollector] and returns the index pointing to | 127 * Adds [c] to [emitter.metadataCollector] and returns the index pointing to |
134 * the entry. | 128 * the entry. |
135 * | 129 * |
136 * If the corresponding type variable has already been encountered an | 130 * If the corresponding type variable has already been encountered an |
137 * entry in the list has already been reserved and the constant is added | 131 * entry in the list has already been reserved and the constant is added |
138 * there, otherwise a new entry for [c] is created. | 132 * there, otherwise a new entry for [c] is created. |
139 */ | 133 */ |
140 jsAst.Expression _reifyTypeVariableConstant(ConstantValue c, | 134 jsAst.Expression _reifyTypeVariableConstant( |
141 TypeVariableElement variable) { | 135 ConstantValue c, TypeVariableElement variable) { |
142 jsAst.Expression name = _task.constantReference(c); | 136 jsAst.Expression name = _task.constantReference(c); |
143 jsAst.Expression result = _metadataCollector.reifyExpression(name); | 137 jsAst.Expression result = _metadataCollector.reifyExpression(name); |
144 if (_typeVariableConstants.containsKey(variable)) { | 138 if (_typeVariableConstants.containsKey(variable)) { |
145 Placeholder placeholder = _typeVariableConstants[variable]; | 139 Placeholder placeholder = _typeVariableConstants[variable]; |
146 placeholder.bind(result); | 140 placeholder.bind(result); |
147 } | 141 } |
148 _typeVariableConstants[variable] = result; | 142 _typeVariableConstants[variable] = result; |
149 return result; | 143 return result; |
150 } | 144 } |
151 | 145 |
(...skipping 18 matching lines...) Expand all Loading... |
170 } | 164 } |
171 | 165 |
172 List<jsAst.Expression> typeVariablesOf(ClassElement classElement) { | 166 List<jsAst.Expression> typeVariablesOf(ClassElement classElement) { |
173 List<jsAst.Expression> result = _typeVariables[classElement]; | 167 List<jsAst.Expression> result = _typeVariables[classElement]; |
174 if (result == null) { | 168 if (result == null) { |
175 result = const <jsAst.Expression>[]; | 169 result = const <jsAst.Expression>[]; |
176 } | 170 } |
177 return result; | 171 return result; |
178 } | 172 } |
179 } | 173 } |
OLD | NEW |