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

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

Issue 256453004: Avoid inlining constants that are used via a deferred import. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase Created 6 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class ConstantEmitter { 7 class ConstantEmitter {
8 ConstantReferenceEmitter _referenceEmitter; 8 ConstantReferenceEmitter _referenceEmitter;
9 ConstantInitializerEmitter _initializerEmitter; 9 ConstantLiteralEmitter _literalEmitter;
10 10
11 ConstantEmitter(Compiler compiler, Namer namer) { 11 ConstantEmitter(Compiler compiler, Namer namer) {
12 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer); 12 _literalEmitter = new ConstantLiteralEmitter(compiler, namer, this);
13 _initializerEmitter = new ConstantInitializerEmitter( 13 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer, this);
14 compiler, namer, _referenceEmitter);
15 } 14 }
16 15
17 /** 16 /**
18 * Constructs an expression that is a reference to the constant. Uses a 17 * Constructs an expression that is a reference to the constant. Uses a
19 * canonical name unless the constant can be emitted multiple times (as for 18 * canonical name unless the constant can be emitted multiple times (as for
20 * numbers and strings). 19 * numbers and strings).
21 */ 20 */
22 jsAst.Expression reference(Constant constant) { 21 jsAst.Expression reference(Constant constant) {
23 return _referenceEmitter.generate(constant); 22 return _referenceEmitter.generate(constant);
24 } 23 }
25 24
26 /** 25 /**
26 * Constructs a literal expression that evaluates to the constant. Uses a
27 * canonical name unless the constant can be emitted multiple times (as for
28 * numbers and strings).
29 */
30 jsAst.Expression literal(Constant constant) {
31 return _literalEmitter.generate(constant);
32 }
33
34 /**
27 * Constructs an expression like [reference], but the expression is valid 35 * Constructs an expression like [reference], but the expression is valid
28 * during isolate initialization. 36 * during isolate initialization.
29 */ 37 */
30 jsAst.Expression referenceInInitializationContext(Constant constant) { 38 jsAst.Expression referenceInInitializationContext(Constant constant) {
31 return _referenceEmitter.generateInInitializationContext(constant); 39 return _referenceEmitter.generate(constant);
32 } 40 }
33 41
34 /** 42 /**
35 * Constructs an expression used to initialize a canonicalized constant. 43 * Constructs an expression used to initialize a canonicalized constant.
36 */ 44 */
37 jsAst.Expression initializationExpression(Constant constant) { 45 jsAst.Expression initializationExpression(Constant constant) {
38 return _initializerEmitter.generate(constant); 46 return _literalEmitter.generate(constant);
39 } 47 }
40 } 48 }
41 49
42 /** 50 /**
43 * Visitor for generating JavaScript expressions to refer to [Constant]s. 51 * Visitor for generating JavaScript expressions to refer to [Constant]s.
44 * Do not use directly, use methods from [ConstantEmitter]. 52 * Do not use directly, use methods from [ConstantEmitter].
45 */ 53 */
46 class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> { 54 class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> {
47 final Compiler compiler; 55 final Compiler compiler;
48 final Namer namer; 56 final Namer namer;
49 57
50 ConstantReferenceEmitter(this.compiler, this.namer); 58 final ConstantEmitter constantEmitter;
59
60 ConstantReferenceEmitter(this.compiler, this.namer, this.constantEmitter);
51 61
52 jsAst.Expression generate(Constant constant) { 62 jsAst.Expression generate(Constant constant) {
53 return _visit(constant); 63 return _visit(constant);
54 } 64 }
55 65
56 jsAst.Expression generateInInitializationContext(Constant constant) {
57 return _visit(constant);
58 }
59
60 jsAst.Expression _visit(Constant constant) { 66 jsAst.Expression _visit(Constant constant) {
61 return constant.accept(this); 67 return constant.accept(this);
62 } 68 }
63 69
70 jsAst.Expression emitCanonicalVersion(Constant constant) {
71 String name = namer.constantName(constant);
72 return new jsAst.PropertyAccess.field(
73 new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name);
74 }
75
76 jsAst.Expression literal(Constant constant) {
77 return constantEmitter.literal(constant);
78 }
79
64 jsAst.Expression visitFunction(FunctionConstant constant) { 80 jsAst.Expression visitFunction(FunctionConstant constant) {
65 return namer.isolateStaticClosureAccess(constant.element); 81 return namer.isolateStaticClosureAccess(constant.element);
66 } 82 }
67 83
68 jsAst.Expression visitNull(NullConstant constant) { 84 jsAst.Expression visitNull(NullConstant constant) {
69 return new jsAst.LiteralNull(); 85 return literal(constant);
70 } 86 }
71 87
72 jsAst.Expression visitInt(IntConstant constant) { 88 jsAst.Expression visitInt(IntConstant constant) {
73 return new jsAst.LiteralNumber('${constant.value}'); 89 return literal(constant);
74 } 90 }
75 91
76 jsAst.Expression visitDouble(DoubleConstant constant) { 92 jsAst.Expression visitDouble(DoubleConstant constant) {
77 double value = constant.value; 93 return literal(constant);
78 if (value.isNaN) {
79 return js("0/0");
80 } else if (value == double.INFINITY) {
81 return js("1/0");
82 } else if (value == -double.INFINITY) {
83 return js("-1/0");
84 } else {
85 return new jsAst.LiteralNumber("$value");
86 }
87 } 94 }
88 95
89 jsAst.Expression visitTrue(TrueConstant constant) { 96 jsAst.Expression visitTrue(TrueConstant constant) {
90 if (compiler.enableMinification) { 97 return literal(constant);
91 // Use !0 for true.
92 return js("!0");
93 } else {
94 return js('true');
95 }
96 } 98 }
97 99
98 jsAst.Expression visitFalse(FalseConstant constant) { 100 jsAst.Expression visitFalse(FalseConstant constant) {
99 if (compiler.enableMinification) { 101 return literal(constant);
100 // Use !1 for false.
101 return js("!1");
102 } else {
103 return js('false');
104 }
105 } 102 }
106 103
107 /** 104 /**
108 * Write the contents of the quoted string to a [CodeBuffer] in 105 * Write the contents of the quoted string to a [CodeBuffer] in
109 * a form that is valid as JavaScript string literal content. 106 * a form that is valid as JavaScript string literal content.
110 * The string is assumed quoted by double quote characters. 107 * The string is assumed quoted by double quote characters.
111 */ 108 */
112 jsAst.Expression visitString(StringConstant constant) { 109 jsAst.Expression visitString(StringConstant constant) {
113 // TODO(sra): If the string is long *and repeated* (and not on a hot path) 110 // TODO(sra): If the string is long *and repeated* (and not on a hot path)
114 // then it should be assigned to a name. We don't have reference counts (or 111 // then it should be assigned to a name. We don't have reference counts (or
115 // profile information) here, so this is the wrong place. 112 // profile information) here, so this is the wrong place.
116 StringBuffer sb = new StringBuffer(); 113 return literal(constant);
117 writeJsonEscapedCharsOn(constant.value.slowToString(), sb);
118 return new jsAst.LiteralString('"$sb"');
119 }
120
121 jsAst.Expression emitCanonicalVersion(Constant constant) {
122 String name = namer.constantName(constant);
123 return new jsAst.PropertyAccess.field(
124 new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name);
125 } 114 }
126 115
127 jsAst.Expression visitList(ListConstant constant) { 116 jsAst.Expression visitList(ListConstant constant) {
128 return emitCanonicalVersion(constant); 117 return emitCanonicalVersion(constant);
129 } 118 }
130 119
131 jsAst.Expression visitMap(MapConstant constant) { 120 jsAst.Expression visitMap(MapConstant constant) {
132 return emitCanonicalVersion(constant); 121 return emitCanonicalVersion(constant);
133 } 122 }
134 123
135 jsAst.Expression visitType(TypeConstant constant) { 124 jsAst.Expression visitType(TypeConstant constant) {
136 return emitCanonicalVersion(constant); 125 return emitCanonicalVersion(constant);
137 } 126 }
138 127
139 jsAst.Expression visitConstructed(ConstructedConstant constant) { 128 jsAst.Expression visitConstructed(ConstructedConstant constant) {
140 return emitCanonicalVersion(constant); 129 return emitCanonicalVersion(constant);
141 } 130 }
142 131
143 jsAst.Expression visitInterceptor(InterceptorConstant constant) { 132 jsAst.Expression visitInterceptor(InterceptorConstant constant) {
144 return emitCanonicalVersion(constant); 133 return emitCanonicalVersion(constant);
145 } 134 }
146 135
147 jsAst.Expression visitDummy(DummyConstant constant) { 136 jsAst.Expression visitDummy(DummyConstant constant) {
148 return new jsAst.LiteralNumber('0'); 137 return literal(constant);
138 }
139
140 jsAst.Expression visitDeferred(DeferredConstant constant) {
141 return emitCanonicalVersion(constant);
149 } 142 }
150 } 143 }
151 144
152 /** 145 /**
153 * Visitor for generating JavaScript expressions to initialize [Constant]s. 146 * Visitor for generating JavaScript expressions that litterally represent
154 * Do not use directly; use methods from [ConstantEmitter]. 147 * [Constant]s. These can be used for inlining constants or in initializers.
148 * Do not use directly, use methods from [ConstantEmitter].
155 */ 149 */
156 class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> { 150 class ConstantLiteralEmitter implements ConstantVisitor<jsAst.Expression> {
157 final Compiler compiler;
158 final Namer namer;
159 final ConstantReferenceEmitter referenceEmitter;
160 151
161 // Matches blank lines, comment lines and trailing comments that can't be part 152 // Matches blank lines, comment lines and trailing comments that can't be part
162 // of a string. 153 // of a string.
163 static final RegExp COMMENT_RE = 154 static final RegExp COMMENT_RE =
164 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true); 155 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true);
165 156
166 ConstantInitializerEmitter(this.compiler, this.namer, this.referenceEmitter); 157 final Compiler compiler;
158 final Namer namer;
159 final ConstantEmitter constantEmitter;
160
161 ConstantLiteralEmitter(this.compiler, this.namer, this.constantEmitter);
167 162
168 jsAst.Expression generate(Constant constant) { 163 jsAst.Expression generate(Constant constant) {
169 return _visit(constant); 164 return _visit(constant);
170 } 165 }
171 166
172 jsAst.Expression _visit(Constant constant) { 167 jsAst.Expression _visit(Constant constant) {
173 return constant.accept(this); 168 return constant.accept(this);
174 } 169 }
175 170
176 jsAst.Expression _reference(Constant constant) {
177 return referenceEmitter.generateInInitializationContext(constant);
178 }
179
180 jsAst.Expression visitFunction(FunctionConstant constant) { 171 jsAst.Expression visitFunction(FunctionConstant constant) {
181 compiler.internalError(NO_LOCATION_SPANNABLE, 172 compiler.internalError(NO_LOCATION_SPANNABLE,
182 "The function constant does not need specific JS code."); 173 "The function constant does not need specific JS code.");
183 return null; 174 return null;
184 } 175 }
185 176
186 jsAst.Expression visitNull(NullConstant constant) { 177 jsAst.Expression visitNull(NullConstant constant) {
187 return _reference(constant); 178 return new jsAst.LiteralNull();
188 } 179 }
189 180
190 jsAst.Expression visitInt(IntConstant constant) { 181 jsAst.Expression visitInt(IntConstant constant) {
191 return _reference(constant); 182 return new jsAst.LiteralNumber('${constant.value}');
192 } 183 }
193 184
194 jsAst.Expression visitDouble(DoubleConstant constant) { 185 jsAst.Expression visitDouble(DoubleConstant constant) {
195 return _reference(constant); 186 double value = constant.value;
187 if (value.isNaN) {
188 return js("0/0");
189 } else if (value == double.INFINITY) {
190 return js("1/0");
191 } else if (value == -double.INFINITY) {
192 return js("-1/0");
193 } else {
194 return new jsAst.LiteralNumber("$value");
195 }
196 } 196 }
197 197
198 jsAst.Expression visitTrue(TrueConstant constant) { 198 jsAst.Expression visitTrue(TrueConstant constant) {
199 return _reference(constant); 199 if (compiler.enableMinification) {
200 // Use !0 for true.
201 return js("!0");
202 } else {
203 return js('true');
204 }
200 } 205 }
201 206
202 jsAst.Expression visitFalse(FalseConstant constant) { 207 jsAst.Expression visitFalse(FalseConstant constant) {
203 return _reference(constant); 208 if (compiler.enableMinification) {
209 // Use !1 for false.
210 return js("!1");
211 } else {
212 return js('false');
213 }
204 } 214 }
205 215
216 /**
217 * Write the contents of the quoted string to a [CodeBuffer] in
218 * a form that is valid as JavaScript string literal content.
219 * The string is assumed quoted by double quote characters.
220 */
206 jsAst.Expression visitString(StringConstant constant) { 221 jsAst.Expression visitString(StringConstant constant) {
207 // TODO(sra): Some larger strings are worth sharing. 222 StringBuffer sb = new StringBuffer();
208 return _reference(constant); 223 writeJsonEscapedCharsOn(constant.value.slowToString(), sb);
224 return new jsAst.LiteralString('"$sb"');
209 } 225 }
210 226
211 jsAst.Expression visitList(ListConstant constant) { 227 jsAst.Expression visitList(ListConstant constant) {
212 jsAst.Expression value = new jsAst.Call( 228 jsAst.Expression value = new jsAst.Call(
213 new jsAst.PropertyAccess.field( 229 new jsAst.PropertyAccess.field(
214 new jsAst.VariableUse(namer.isolateName), 230 new jsAst.VariableUse(namer.isolateName),
215 'makeConstantList'), 231 'makeConstantList'),
216 [new jsAst.ArrayInitializer.from(_array(constant.entries))]); 232 [new jsAst.ArrayInitializer.from(_array(constant.entries))]);
217 return maybeAddTypeArguments(constant.type, value); 233 return maybeAddTypeArguments(constant.type, value);
218 } 234 }
219 235
220 jsAst.Expression getJsConstructor(ClassElement element) { 236 jsAst.Expression getJsConstructor(ClassElement element) {
221 return namer.elementAccess(element); 237 return namer.elementAccess(element);
222 } 238 }
223 239
224 jsAst.Expression visitMap(MapConstant constant) { 240 jsAst.Expression visitMap(MapConstant constant) {
225 jsAst.Expression jsMap() { 241 jsAst.Expression jsMap() {
226 List<jsAst.Property> properties = <jsAst.Property>[]; 242 List<jsAst.Property> properties = <jsAst.Property>[];
227 for (int i = 0; i < constant.keys.entries.length; i++) { 243 for (int i = 0; i < constant.keys.entries.length; i++) {
228 StringConstant key = constant.keys.entries[i]; 244 StringConstant key = constant.keys.entries[i];
229 if (key.value == MapConstant.PROTO_PROPERTY) continue; 245 if (key.value == MapConstant.PROTO_PROPERTY) continue;
230 246
231 // Keys in literal maps must be emitted in place. 247 // Keys in literal maps must be emitted in place.
232 jsAst.Literal keyExpression = _visit(key); 248 jsAst.Literal keyExpression = _visit(key);
233 jsAst.Expression valueExpression = 249 jsAst.Expression valueExpression =
234 _reference(constant.values[i]); 250 constantEmitter.reference(constant.values[i]);
235 properties.add(new jsAst.Property(keyExpression, valueExpression)); 251 properties.add(new jsAst.Property(keyExpression, valueExpression));
236 } 252 }
237 return new jsAst.ObjectInitializer(properties); 253 return new jsAst.ObjectInitializer(properties);
238 } 254 }
239 255
240 jsAst.Expression jsGeneralMap() { 256 jsAst.Expression jsGeneralMap() {
241 List<jsAst.Expression> data = <jsAst.Expression>[]; 257 List<jsAst.Expression> data = <jsAst.Expression>[];
242 for (int i = 0; i < constant.keys.entries.length; i++) { 258 for (int i = 0; i < constant.keys.entries.length; i++) {
243 jsAst.Expression keyExpression = 259 jsAst.Expression keyExpression =
244 _reference(constant.keys.entries[i]); 260 constantEmitter.reference(constant.keys.entries[i]);
245 jsAst.Expression valueExpression = 261 jsAst.Expression valueExpression =
246 _reference(constant.values[i]); 262 constantEmitter.reference(constant.values[i]);
247 data.add(keyExpression); 263 data.add(keyExpression);
248 data.add(valueExpression); 264 data.add(valueExpression);
249 } 265 }
250 return new jsAst.ArrayInitializer.from(data); 266 return new jsAst.ArrayInitializer.from(data);
251 } 267 }
252 268
253 ClassElement classElement = constant.type.element; 269 ClassElement classElement = constant.type.element;
254 String className = classElement.name; 270 String className = classElement.name;
255 271
256 List<jsAst.Expression> arguments = <jsAst.Expression>[]; 272 List<jsAst.Expression> arguments = <jsAst.Expression>[];
257 273
258 // The arguments of the JavaScript constructor for any given Dart class 274 // The arguments of the JavaScript constructor for any given Dart class
259 // are in the same order as the members of the class element. 275 // are in the same order as the members of the class element.
260 int emittedArgumentCount = 0; 276 int emittedArgumentCount = 0;
261 classElement.implementation.forEachInstanceField( 277 classElement.implementation.forEachInstanceField(
262 (ClassElement enclosing, Element field) { 278 (ClassElement enclosing, Element field) {
263 if (field.name == MapConstant.LENGTH_NAME) { 279 if (field.name == MapConstant.LENGTH_NAME) {
264 arguments.add( 280 arguments.add(
265 new jsAst.LiteralNumber('${constant.keys.entries.length}')); 281 new jsAst.LiteralNumber('${constant.keys.entries.length}'));
266 } else if (field.name == MapConstant.JS_OBJECT_NAME) { 282 } else if (field.name == MapConstant.JS_OBJECT_NAME) {
267 arguments.add(jsMap()); 283 arguments.add(jsMap());
268 } else if (field.name == MapConstant.KEYS_NAME) { 284 } else if (field.name == MapConstant.KEYS_NAME) {
269 arguments.add(_reference(constant.keys)); 285 arguments.add(constantEmitter.reference(constant.keys));
270 } else if (field.name == MapConstant.PROTO_VALUE) { 286 } else if (field.name == MapConstant.PROTO_VALUE) {
271 assert(constant.protoValue != null); 287 assert(constant.protoValue != null);
272 arguments.add(_reference(constant.protoValue)); 288 arguments.add(constantEmitter.reference(constant.protoValue));
273 } else if (field.name == MapConstant.JS_DATA_NAME) { 289 } else if (field.name == MapConstant.JS_DATA_NAME) {
274 arguments.add(jsGeneralMap()); 290 arguments.add(jsGeneralMap());
275 } else { 291 } else {
276 compiler.internalError(field, 292 compiler.internalError(field,
277 "Compiler has unexpected field ${field.name} for " 293 "Compiler has unexpected field ${field.name} for "
278 "${className}."); 294 "${className}.");
279 } 295 }
280 emittedArgumentCount++; 296 emittedArgumentCount++;
281 }, 297 },
282 includeSuperAndInjectedMembers: true); 298 includeSuperAndInjectedMembers: true);
(...skipping 26 matching lines...) Expand all
309 [typeName]); 325 [typeName]);
310 } 326 }
311 327
312 jsAst.Expression visitInterceptor(InterceptorConstant constant) { 328 jsAst.Expression visitInterceptor(InterceptorConstant constant) {
313 return new jsAst.PropertyAccess.field( 329 return new jsAst.PropertyAccess.field(
314 getJsConstructor(constant.dispatchedType.element), 330 getJsConstructor(constant.dispatchedType.element),
315 'prototype'); 331 'prototype');
316 } 332 }
317 333
318 jsAst.Expression visitDummy(DummyConstant constant) { 334 jsAst.Expression visitDummy(DummyConstant constant) {
319 return _reference(constant); 335 return new jsAst.LiteralNumber('0');
320 } 336 }
321 337
322 jsAst.Expression visitConstructed(ConstructedConstant constant) { 338 jsAst.Expression visitConstructed(ConstructedConstant constant) {
323 Element element = constant.type.element; 339 Element element = constant.type.element;
324 if (element.isForeign(compiler) 340 if (element.isForeign(compiler)
325 && element.name == 'JS_CONST') { 341 && element.name == 'JS_CONST') {
326 StringConstant str = constant.fields[0]; 342 StringConstant str = constant.fields[0];
327 String value = str.value.slowToString(); 343 String value = str.value.slowToString();
328 return new jsAst.LiteralExpression(stripComments(value)); 344 return new jsAst.LiteralExpression(stripComments(value));
329 } 345 }
330 jsAst.New instantiation = new jsAst.New( 346 jsAst.New instantiation = new jsAst.New(
331 getJsConstructor(constant.type.element), 347 getJsConstructor(constant.type.element),
332 _array(constant.fields)); 348 _array(constant.fields));
333 return maybeAddTypeArguments(constant.type, instantiation); 349 return maybeAddTypeArguments(constant.type, instantiation);
334 } 350 }
335 351
336 String stripComments(String rawJavaScript) { 352 String stripComments(String rawJavaScript) {
337 return rawJavaScript.replaceAll(COMMENT_RE, ''); 353 return rawJavaScript.replaceAll(COMMENT_RE, '');
338 } 354 }
339 355
340 List<jsAst.Expression> _array(List<Constant> values) { 356 List<jsAst.Expression> _array(List<Constant> values) {
341 List<jsAst.Expression> valueList = <jsAst.Expression>[]; 357 List<jsAst.Expression> valueList = <jsAst.Expression>[];
342 for (int i = 0; i < values.length; i++) { 358 for (int i = 0; i < values.length; i++) {
343 valueList.add(_reference(values[i])); 359 valueList.add(constantEmitter.reference(values[i]));
344 } 360 }
345 return valueList; 361 return valueList;
346 } 362 }
347 363
348 jsAst.Expression maybeAddTypeArguments(InterfaceType type, 364 jsAst.Expression maybeAddTypeArguments(InterfaceType type,
349 jsAst.Expression value) { 365 jsAst.Expression value) {
350 if (type is InterfaceType && 366 if (type is InterfaceType &&
351 !type.treatAsRaw && 367 !type.treatAsRaw &&
352 backend.classNeedsRti(type.element)) { 368 backend.classNeedsRti(type.element)) {
353 InterfaceType interface = type; 369 InterfaceType interface = type;
354 RuntimeTypes rti = backend.rti; 370 RuntimeTypes rti = backend.rti;
355 Iterable<String> arguments = interface.typeArguments 371 Iterable<String> arguments = interface.typeArguments
356 .toList(growable: false) 372 .toList(growable: false)
357 .map((DartType type) => 373 .map((DartType type) =>
358 rti.getTypeRepresentationWithHashes(type, (_){})); 374 rti.getTypeRepresentationWithHashes(type, (_){}));
359 jsAst.Expression argumentList = 375 jsAst.Expression argumentList =
360 new jsAst.LiteralString('[${arguments.join(', ')}]'); 376 new jsAst.LiteralString('[${arguments.join(', ')}]');
361 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()), 377 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()),
362 [value, argumentList]); 378 [value, argumentList]);
363 } 379 }
364 return value; 380 return value;
365 } 381 }
382
383 jsAst.Expression visitDeferred(DeferredConstant constant) {
384 return constantEmitter.reference(constant.referenced);
385 }
366 } 386 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698