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

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

Issue 22909056: Support general expressions as keys in literal maps. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 7 years, 3 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 ConstantInitializerEmitter _initializerEmitter;
10 10
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 return maybeAddTypeArguments(constant.type, value); 208 return maybeAddTypeArguments(constant.type, value);
209 } 209 }
210 210
211 String getJsConstructor(ClassElement element) { 211 String getJsConstructor(ClassElement element) {
212 return namer.isolateAccess(element); 212 return namer.isolateAccess(element);
213 } 213 }
214 214
215 jsAst.Expression visitMap(MapConstant constant) { 215 jsAst.Expression visitMap(MapConstant constant) {
216 jsAst.Expression jsMap() { 216 jsAst.Expression jsMap() {
217 List<jsAst.Property> properties = <jsAst.Property>[]; 217 List<jsAst.Property> properties = <jsAst.Property>[];
218 int valueIndex = 0;
219 for (int i = 0; i < constant.keys.entries.length; i++) { 218 for (int i = 0; i < constant.keys.entries.length; i++) {
220 StringConstant key = constant.keys.entries[i]; 219 StringConstant key = constant.keys.entries[i];
221 if (key.value == MapConstant.PROTO_PROPERTY) continue; 220 if (key.value == MapConstant.PROTO_PROPERTY) continue;
222 221
223 // Keys in literal maps must be emitted in place. 222 // Keys in literal maps must be emitted in place.
224 jsAst.Literal keyExpression = _visit(key); 223 jsAst.Literal keyExpression = _visit(key);
225 jsAst.Expression valueExpression = 224 jsAst.Expression valueExpression =
226 _reference(constant.values[valueIndex++]); 225 _reference(constant.values[i]);
227 properties.add(new jsAst.Property(keyExpression, valueExpression)); 226 properties.add(new jsAst.Property(keyExpression, valueExpression));
228 } 227 }
229 if (valueIndex != constant.values.length) {
230 compiler.internalError("Bad value count.");
231 }
232 return new jsAst.ObjectInitializer(properties); 228 return new jsAst.ObjectInitializer(properties);
233 } 229 }
234 230
235 void badFieldCountError() { 231 jsAst.Expression jsGeneralMap() {
236 compiler.internalError( 232 List<jsAst.Expression> data = <jsAst.Expression>[];
237 "Compiler and ConstantMap disagree on number of fields."); 233 for (int i = 0; i < constant.keys.entries.length; i++) {
234 jsAst.Expression keyExpression =
235 _reference(constant.keys.entries[i]);
236 jsAst.Expression valueExpression =
237 _reference(constant.values[i]);
238 data.add(keyExpression);
239 data.add(valueExpression);
240 }
241 return new jsAst.ArrayInitializer.from(data);
238 } 242 }
239 243
240 ClassElement classElement = constant.type.element; 244 ClassElement classElement = constant.type.element;
245 SourceString className = classElement.name;
241 246
242 List<jsAst.Expression> arguments = <jsAst.Expression>[]; 247 List<jsAst.Expression> arguments = <jsAst.Expression>[];
243 248
244 // The arguments of the JavaScript constructor for any given Dart class 249 // The arguments of the JavaScript constructor for any given Dart class
245 // are in the same order as the members of the class element. 250 // are in the same order as the members of the class element.
246 int emittedArgumentCount = 0; 251 int emittedArgumentCount = 0;
247 classElement.implementation.forEachInstanceField( 252 classElement.implementation.forEachInstanceField(
248 (ClassElement enclosing, Element field) { 253 (ClassElement enclosing, Element field) {
249 if (field.name == MapConstant.LENGTH_NAME) { 254 if (field.name == MapConstant.LENGTH_NAME) {
250 arguments.add( 255 arguments.add(
251 new jsAst.LiteralNumber('${constant.keys.entries.length}')); 256 new jsAst.LiteralNumber('${constant.keys.entries.length}'));
252 } else if (field.name == MapConstant.JS_OBJECT_NAME) { 257 } else if (field.name == MapConstant.JS_OBJECT_NAME) {
253 arguments.add(jsMap()); 258 arguments.add(jsMap());
254 } else if (field.name == MapConstant.KEYS_NAME) { 259 } else if (field.name == MapConstant.KEYS_NAME) {
255 arguments.add(_reference(constant.keys)); 260 arguments.add(_reference(constant.keys));
256 } else if (field.name == MapConstant.PROTO_VALUE) { 261 } else if (field.name == MapConstant.PROTO_VALUE) {
257 assert(constant.protoValue != null); 262 assert(constant.protoValue != null);
258 arguments.add(_reference(constant.protoValue)); 263 arguments.add(_reference(constant.protoValue));
264 } else if (field.name == MapConstant.JS_DATA_NAME) {
265 arguments.add(jsGeneralMap());
259 } else { 266 } else {
260 badFieldCountError(); 267 compiler.internalError(
268 "Compiler has unexpected field ${field.name} for "
269 "${className}.");
261 } 270 }
262 emittedArgumentCount++; 271 emittedArgumentCount++;
263 }, 272 },
264 includeSuperAndInjectedMembers: true); 273 includeSuperAndInjectedMembers: true);
265 274 if ((className == MapConstant.DART_STRING_CLASS &&
266 if ((constant.protoValue == null && emittedArgumentCount != 3) || 275 emittedArgumentCount != 3) ||
267 (constant.protoValue != null && emittedArgumentCount != 4)) { 276 (className == MapConstant.DART_PROTO_CLASS &&
268 badFieldCountError(); 277 emittedArgumentCount != 4) ||
278 (className == MapConstant.DART_GENERAL_CLASS &&
279 emittedArgumentCount != 1)) {
280 compiler.internalError(
281 "Compiler and ${className} disagree on number of fields.");
269 } 282 }
270 283
271 jsAst.Expression value = new jsAst.New( 284 jsAst.Expression value = new jsAst.New(
272 new jsAst.VariableUse(getJsConstructor(classElement)), 285 new jsAst.VariableUse(getJsConstructor(classElement)),
273 arguments); 286 arguments);
274 return maybeAddTypeArguments(constant.type, value); 287 return maybeAddTypeArguments(constant.type, value);
275 } 288 }
276 289
277 JavaScriptBackend get backend => compiler.backend; 290 JavaScriptBackend get backend => compiler.backend;
278 291
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 .toList(growable: false) 343 .toList(growable: false)
331 .map((DartType type) => rti.getTypeRepresentation(type, (_){})); 344 .map((DartType type) => rti.getTypeRepresentation(type, (_){}));
332 jsAst.Expression argumentList = 345 jsAst.Expression argumentList =
333 new jsAst.LiteralString('[${arguments.join(', ')}]'); 346 new jsAst.LiteralString('[${arguments.join(', ')}]');
334 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()), 347 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()),
335 [value, argumentList]); 348 [value, argumentList]);
336 } 349 }
337 return value; 350 return value;
338 } 351 }
339 } 352 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698