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

Side by Side Diff: pkg/compiler/lib/src/js_backend/constant_emitter.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
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 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant); 7 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
8 8
9 typedef jsAst.Expression _ConstantListGenerator(jsAst.Expression array); 9 typedef jsAst.Expression _ConstantListGenerator(jsAst.Expression array);
10 10
11 /** 11 /**
12 * Generates the JavaScript expressions for constants. 12 * Generates the JavaScript expressions for constants.
13 * 13 *
14 * It uses a given [constantReferenceGenerator] to reference nested constants 14 * It uses a given [constantReferenceGenerator] to reference nested constants
15 * (if there are some). It is hence up to that function to decide which 15 * (if there are some). It is hence up to that function to decide which
16 * constants should be inlined or not. 16 * constants should be inlined or not.
17 */ 17 */
18 class ConstantEmitter 18 class ConstantEmitter implements ConstantValueVisitor<jsAst.Expression, Null> {
19 implements ConstantValueVisitor<jsAst.Expression, Null> {
20
21 // Matches blank lines, comment lines and trailing comments that can't be part 19 // Matches blank lines, comment lines and trailing comments that can't be part
22 // of a string. 20 // of a string.
23 static final RegExp COMMENT_RE = 21 static final RegExp COMMENT_RE =
24 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true); 22 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''', multiLine: true);
25 23
26 final Compiler compiler; 24 final Compiler compiler;
27 final Namer namer; 25 final Namer namer;
28 final _ConstantReferenceGenerator constantReferenceGenerator; 26 final _ConstantReferenceGenerator constantReferenceGenerator;
29 final _ConstantListGenerator makeConstantList; 27 final _ConstantListGenerator makeConstantList;
30 28
31 /** 29 /**
32 * The given [constantReferenceGenerator] function must, when invoked with a 30 * The given [constantReferenceGenerator] function must, when invoked with a
33 * constant, either return a reference or return its literal expression if it 31 * constant, either return a reference or return its literal expression if it
34 * can be inlined. 32 * can be inlined.
(...skipping 24 matching lines...) Expand all
59 reporter.internalError(NO_LOCATION_SPANNABLE, 57 reporter.internalError(NO_LOCATION_SPANNABLE,
60 "The function constant does not need specific JS code."); 58 "The function constant does not need specific JS code.");
61 return null; 59 return null;
62 } 60 }
63 61
64 @override 62 @override
65 jsAst.Expression visitNull(NullConstantValue constant, [_]) { 63 jsAst.Expression visitNull(NullConstantValue constant, [_]) {
66 return new jsAst.LiteralNull(); 64 return new jsAst.LiteralNull();
67 } 65 }
68 66
69 static final _exponentialRE = new RegExp( 67 static final _exponentialRE = new RegExp('^'
70 '^' 68 '\([-+]?\)' // 1: sign
71 '\([-+]?\)' // 1: sign 69 '\([0-9]+\)' // 2: leading digit(s)
72 '\([0-9]+\)' // 2: leading digit(s)
73 '\(\.\([0-9]*\)\)?' // 4: fraction digits 70 '\(\.\([0-9]*\)\)?' // 4: fraction digits
74 'e\([-+]?[0-9]+\)' // 5: exponent with sign 71 'e\([-+]?[0-9]+\)' // 5: exponent with sign
75 r'$'); 72 r'$');
76 73
77 /// Reduces the size of exponential representations when minification is 74 /// Reduces the size of exponential representations when minification is
78 /// enabled. 75 /// enabled.
79 /// 76 ///
80 /// Removes the "+" after the exponential sign, and removes the "." before the 77 /// Removes the "+" after the exponential sign, and removes the "." before the
81 /// "e". For example `1.23e+5` is changed to `123e3`. 78 /// "e". For example `1.23e+5` is changed to `123e3`.
82 String _shortenExponentialRepresentation(String numberString) { 79 String _shortenExponentialRepresentation(String numberString) {
83 Match match = _exponentialRE.firstMatch(numberString); 80 Match match = _exponentialRE.firstMatch(numberString);
84 if (match == null) return numberString; 81 if (match == null) return numberString;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 } 144 }
148 145
149 /** 146 /**
150 * Write the contents of the quoted string to a [CodeBuffer] in 147 * Write the contents of the quoted string to a [CodeBuffer] in
151 * a form that is valid as JavaScript string literal content. 148 * a form that is valid as JavaScript string literal content.
152 * The string is assumed quoted by double quote characters. 149 * The string is assumed quoted by double quote characters.
153 */ 150 */
154 @override 151 @override
155 jsAst.Expression visitString(StringConstantValue constant, [_]) { 152 jsAst.Expression visitString(StringConstantValue constant, [_]) {
156 return js.escapedString(constant.primitiveValue.slowToString(), 153 return js.escapedString(constant.primitiveValue.slowToString(),
157 ascii: true); 154 ascii: true);
158 } 155 }
159 156
160 @override 157 @override
161 jsAst.Expression visitList(ListConstantValue constant, [_]) { 158 jsAst.Expression visitList(ListConstantValue constant, [_]) {
162 List<jsAst.Expression> elements = constant.entries 159 List<jsAst.Expression> elements = constant.entries
163 .map(constantReferenceGenerator) 160 .map(constantReferenceGenerator)
164 .toList(growable: false); 161 .toList(growable: false);
165 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements); 162 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements);
166 jsAst.Expression value = makeConstantList(array); 163 jsAst.Expression value = makeConstantList(array);
167 return maybeAddTypeArguments(constant.type, value); 164 return maybeAddTypeArguments(constant.type, value);
(...skipping 14 matching lines...) Expand all
182 jsAst.Expression valueExpression = 179 jsAst.Expression valueExpression =
183 constantReferenceGenerator(constant.values[i]); 180 constantReferenceGenerator(constant.values[i]);
184 properties.add(new jsAst.Property(keyExpression, valueExpression)); 181 properties.add(new jsAst.Property(keyExpression, valueExpression));
185 } 182 }
186 return new jsAst.ObjectInitializer(properties); 183 return new jsAst.ObjectInitializer(properties);
187 } 184 }
188 185
189 jsAst.Expression jsGeneralMap() { 186 jsAst.Expression jsGeneralMap() {
190 List<jsAst.Expression> data = <jsAst.Expression>[]; 187 List<jsAst.Expression> data = <jsAst.Expression>[];
191 for (int i = 0; i < constant.keys.length; i++) { 188 for (int i = 0; i < constant.keys.length; i++) {
192 jsAst.Expression keyExpression = constantReferenceGenerator(constant.key s[i]); 189 jsAst.Expression keyExpression =
190 constantReferenceGenerator(constant.keys[i]);
193 jsAst.Expression valueExpression = 191 jsAst.Expression valueExpression =
194 constantReferenceGenerator(constant.values[i]); 192 constantReferenceGenerator(constant.values[i]);
195 data.add(keyExpression); 193 data.add(keyExpression);
196 data.add(valueExpression); 194 data.add(valueExpression);
197 } 195 }
198 return new jsAst.ArrayInitializer(data); 196 return new jsAst.ArrayInitializer(data);
199 } 197 }
200 198
201 ClassElement classElement = constant.type.element; 199 ClassElement classElement = constant.type.element;
202 String className = classElement.name; 200 String className = classElement.name;
203 201
204 List<jsAst.Expression> arguments = <jsAst.Expression>[]; 202 List<jsAst.Expression> arguments = <jsAst.Expression>[];
205 203
206 // The arguments of the JavaScript constructor for any given Dart class 204 // The arguments of the JavaScript constructor for any given Dart class
207 // are in the same order as the members of the class element. 205 // are in the same order as the members of the class element.
208 int emittedArgumentCount = 0; 206 int emittedArgumentCount = 0;
209 classElement.implementation.forEachInstanceField( 207 classElement.implementation.forEachInstanceField(
210 (ClassElement enclosing, Element field) { 208 (ClassElement enclosing, Element field) {
211 if (field.name == JavaScriptMapConstant.LENGTH_NAME) { 209 if (field.name == JavaScriptMapConstant.LENGTH_NAME) {
212 arguments.add( 210 arguments
213 new jsAst.LiteralNumber('${constant.keyList.entries.length}')); 211 .add(new jsAst.LiteralNumber('${constant.keyList.entries.length}'));
214 } else if (field.name == JavaScriptMapConstant.JS_OBJECT_NAME) { 212 } else if (field.name == JavaScriptMapConstant.JS_OBJECT_NAME) {
215 arguments.add(jsMap()); 213 arguments.add(jsMap());
216 } else if (field.name == JavaScriptMapConstant.KEYS_NAME) { 214 } else if (field.name == JavaScriptMapConstant.KEYS_NAME) {
217 arguments.add(constantReferenceGenerator(constant.keyList)); 215 arguments.add(constantReferenceGenerator(constant.keyList));
218 } else if (field.name == JavaScriptMapConstant.PROTO_VALUE) { 216 } else if (field.name == JavaScriptMapConstant.PROTO_VALUE) {
219 assert(constant.protoValue != null); 217 assert(constant.protoValue != null);
220 arguments.add(constantReferenceGenerator(constant.protoValue)); 218 arguments.add(constantReferenceGenerator(constant.protoValue));
221 } else if (field.name == JavaScriptMapConstant.JS_DATA_NAME) { 219 } else if (field.name == JavaScriptMapConstant.JS_DATA_NAME) {
222 arguments.add(jsGeneralMap()); 220 arguments.add(jsGeneralMap());
223 } else { 221 } else {
224 reporter.internalError(field, 222 reporter.internalError(
225 "Compiler has unexpected field ${field.name} for " 223 field,
226 "${className}."); 224 "Compiler has unexpected field ${field.name} for "
227 } 225 "${className}.");
228 emittedArgumentCount++; 226 }
229 }, 227 emittedArgumentCount++;
230 includeSuperAndInjectedMembers: true); 228 }, includeSuperAndInjectedMembers: true);
231 if ((className == JavaScriptMapConstant.DART_STRING_CLASS && 229 if ((className == JavaScriptMapConstant.DART_STRING_CLASS &&
232 emittedArgumentCount != 3) || 230 emittedArgumentCount != 3) ||
233 (className == JavaScriptMapConstant.DART_PROTO_CLASS && 231 (className == JavaScriptMapConstant.DART_PROTO_CLASS &&
234 emittedArgumentCount != 4) || 232 emittedArgumentCount != 4) ||
235 (className == JavaScriptMapConstant.DART_GENERAL_CLASS && 233 (className == JavaScriptMapConstant.DART_GENERAL_CLASS &&
236 emittedArgumentCount != 1)) { 234 emittedArgumentCount != 1)) {
237 reporter.internalError(classElement, 235 reporter.internalError(classElement,
238 "Compiler and ${className} disagree on number of fields."); 236 "Compiler and ${className} disagree on number of fields.");
239 } 237 }
240 238
241 jsAst.Expression constructor = 239 jsAst.Expression constructor =
242 backend.emitter.constructorAccess(classElement); 240 backend.emitter.constructorAccess(classElement);
243 jsAst.Expression value = new jsAst.New(constructor, arguments); 241 jsAst.Expression value = new jsAst.New(constructor, arguments);
244 return maybeAddTypeArguments(constant.type, value); 242 return maybeAddTypeArguments(constant.type, value);
245 } 243 }
246 244
247 JavaScriptBackend get backend => compiler.backend; 245 JavaScriptBackend get backend => compiler.backend;
248 246
249 jsAst.PropertyAccess getHelperProperty(Element helper) { 247 jsAst.PropertyAccess getHelperProperty(Element helper) {
250 return backend.emitter.staticFunctionAccess(helper); 248 return backend.emitter.staticFunctionAccess(helper);
251 } 249 }
252 250
253 @override 251 @override
254 jsAst.Expression visitType(TypeConstantValue constant, [_]) { 252 jsAst.Expression visitType(TypeConstantValue constant, [_]) {
255 DartType type = constant.representedType; 253 DartType type = constant.representedType;
256 jsAst.Name typeName = namer.runtimeTypeName(type.element); 254 jsAst.Name typeName = namer.runtimeTypeName(type.element);
257 return new jsAst.Call(getHelperProperty(backend.helpers.createRuntimeType), 255 return new jsAst.Call(getHelperProperty(backend.helpers.createRuntimeType),
258 [js.quoteName(typeName)]); 256 [js.quoteName(typeName)]);
259 } 257 }
260 258
261 @override 259 @override
262 jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) { 260 jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) {
263 ClassElement interceptorClass = constant.dispatchedType.element; 261 ClassElement interceptorClass = constant.dispatchedType.element;
264 return backend.emitter.interceptorPrototypeAccess(interceptorClass); 262 return backend.emitter.interceptorPrototypeAccess(interceptorClass);
265 } 263 }
266 264
267 @override 265 @override
268 jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) { 266 jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) {
269 switch (constant.kind) { 267 switch (constant.kind) {
270 case SyntheticConstantKind.DUMMY_INTERCEPTOR: 268 case SyntheticConstantKind.DUMMY_INTERCEPTOR:
271 case SyntheticConstantKind.EMPTY_VALUE: 269 case SyntheticConstantKind.EMPTY_VALUE:
272 return new jsAst.LiteralNumber('0'); 270 return new jsAst.LiteralNumber('0');
273 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: 271 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
274 case SyntheticConstantKind.NAME: 272 case SyntheticConstantKind.NAME:
275 return constant.payload; 273 return constant.payload;
276 default: 274 default:
277 reporter.internalError(NO_LOCATION_SPANNABLE, 275 reporter.internalError(NO_LOCATION_SPANNABLE,
278 "Unexpected DummyConstantKind ${constant.kind}"); 276 "Unexpected DummyConstantKind ${constant.kind}");
279 return null; 277 return null;
280 } 278 }
281 } 279 }
282 280
283 @override 281 @override
284 jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) { 282 jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) {
285 Element element = constant.type.element; 283 Element element = constant.type.element;
286 if (backend.isForeign(element) 284 if (backend.isForeign(element) && element.name == 'JS_CONST') {
287 && element.name == 'JS_CONST') {
288 StringConstantValue str = constant.fields.values.single; 285 StringConstantValue str = constant.fields.values.single;
289 String value = str.primitiveValue.slowToString(); 286 String value = str.primitiveValue.slowToString();
290 return new jsAst.LiteralExpression(stripComments(value)); 287 return new jsAst.LiteralExpression(stripComments(value));
291 } 288 }
292 jsAst.Expression constructor = 289 jsAst.Expression constructor =
293 backend.emitter.constructorAccess(constant.type.element); 290 backend.emitter.constructorAccess(constant.type.element);
294 List<jsAst.Expression> fields = 291 List<jsAst.Expression> fields = constant.fields.values
295 constant.fields.values.map(constantReferenceGenerator) 292 .map(constantReferenceGenerator)
296 .toList(growable: false); 293 .toList(growable: false);
297 jsAst.New instantiation = new jsAst.New(constructor, fields); 294 jsAst.New instantiation = new jsAst.New(constructor, fields);
298 return maybeAddTypeArguments(constant.type, instantiation); 295 return maybeAddTypeArguments(constant.type, instantiation);
299 } 296 }
300 297
301 String stripComments(String rawJavaScript) { 298 String stripComments(String rawJavaScript) {
302 return rawJavaScript.replaceAll(COMMENT_RE, ''); 299 return rawJavaScript.replaceAll(COMMENT_RE, '');
303 } 300 }
304 301
305 jsAst.Expression maybeAddTypeArguments(InterfaceType type, 302 jsAst.Expression maybeAddTypeArguments(
306 jsAst.Expression value) { 303 InterfaceType type, jsAst.Expression value) {
307 if (type is InterfaceType && 304 if (type is InterfaceType &&
308 !type.treatAsRaw && 305 !type.treatAsRaw &&
309 backend.classNeedsRti(type.element)) { 306 backend.classNeedsRti(type.element)) {
310 InterfaceType interface = type; 307 InterfaceType interface = type;
311 RuntimeTypesEncoder rtiEncoder = backend.rtiEncoder; 308 RuntimeTypesEncoder rtiEncoder = backend.rtiEncoder;
312 Iterable<jsAst.Expression> arguments = interface.typeArguments 309 Iterable<jsAst.Expression> arguments = interface.typeArguments.map(
313 .map((DartType type) => 310 (DartType type) =>
314 rtiEncoder.getTypeRepresentationWithPlaceholders(type, (_){})); 311 rtiEncoder.getTypeRepresentationWithPlaceholders(type, (_) {}));
315 jsAst.Expression argumentList = 312 jsAst.Expression argumentList =
316 new jsAst.ArrayInitializer(arguments.toList()); 313 new jsAst.ArrayInitializer(arguments.toList());
317 return new jsAst.Call( 314 return new jsAst.Call(
318 getHelperProperty(backend.helpers.setRuntimeTypeInfo), 315 getHelperProperty(backend.helpers.setRuntimeTypeInfo),
319 [value, argumentList]); 316 [value, argumentList]);
320 } 317 }
321 return value; 318 return value;
322 } 319 }
323 320
324 @override 321 @override
325 jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) { 322 jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) {
326 return constantReferenceGenerator(constant.referenced); 323 return constantReferenceGenerator(constant.referenced);
327 } 324 }
328 } 325 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/unsugar.dart ('k') | pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698