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

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

Powered by Google App Engine
This is Rietveld 408576698