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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/model.dart

Issue 1198293002: dart2js: Use an abstract Name class for names in the generated JavaScript ast. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix tests Created 5 years, 5 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart2js.new_js_emitter.model; 5 library dart2js.new_js_emitter.model;
6 6
7 import '../js/js.dart' as js show Expression, Statement; 7 import '../js/js.dart' as js show Expression, Statement, Name, Literal;
8 import '../constants/values.dart' show ConstantValue; 8 import '../constants/values.dart' show ConstantValue;
9 9
10 import '../deferred_load.dart' show OutputUnit; 10 import '../deferred_load.dart' show OutputUnit;
11 11
12 import 'js_emitter.dart' show MetadataCollector, TokenFinalizer; 12 import 'js_emitter.dart' show MetadataCollector, TokenFinalizer;
13 13
14 import '../common.dart'; 14 import '../common.dart';
15 15
16 class Program { 16 class Program {
17 final List<Fragment> fragments; 17 final List<Fragment> fragments;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 outputFileName, 158 outputFileName,
159 libraries, 159 libraries,
160 staticNonFinalFields, 160 staticNonFinalFields,
161 staticLazilyInitializedFields, 161 staticLazilyInitializedFields,
162 constants); 162 constants);
163 163
164 bool get isMainFragment => false; 164 bool get isMainFragment => false;
165 } 165 }
166 166
167 class Constant { 167 class Constant {
168 final String name; 168 final js.Name name;
169 final Holder holder; 169 final Holder holder;
170 final ConstantValue value; 170 final ConstantValue value;
171 171
172 Constant(this.name, this.holder, this.value); 172 Constant(this.name, this.holder, this.value);
173 } 173 }
174 174
175 abstract class FieldContainer { 175 abstract class FieldContainer {
176 List<Field> get staticFieldsForReflection; 176 List<Field> get staticFieldsForReflection;
177 } 177 }
178 178
(...skipping 10 matching lines...) Expand all
189 189
190 Library(this.element, this.uri, this.statics, this.classes, 190 Library(this.element, this.uri, this.statics, this.classes,
191 this.staticFieldsForReflection); 191 this.staticFieldsForReflection);
192 } 192 }
193 193
194 class StaticField { 194 class StaticField {
195 /// The element should only be used during the transition to the new model. 195 /// The element should only be used during the transition to the new model.
196 /// Uses indicate missing information in the model. 196 /// Uses indicate missing information in the model.
197 final Element element; 197 final Element element;
198 198
199 final String name; 199 js.Name name;
200 // TODO(floitsch): the holder for static fields is the isolate object. We 200 // TODO(floitsch): the holder for static fields is the isolate object. We
201 // could remove this field and use the isolate object directly. 201 // could remove this field and use the isolate object directly.
202 final Holder holder; 202 final Holder holder;
203 final js.Expression code; 203 final js.Expression code;
204 final bool isFinal; 204 final bool isFinal;
205 final bool isLazy; 205 final bool isLazy;
206 206
207 StaticField(this.element, 207 StaticField(this.element,
208 this.name, this.holder, this.code, 208 this.name, this.holder, this.code,
209 this.isFinal, this.isLazy); 209 this.isFinal, this.isLazy);
210 } 210 }
211 211
212 class Class implements FieldContainer { 212 class Class implements FieldContainer {
213 /// The element should only be used during the transition to the new model. 213 /// The element should only be used during the transition to the new model.
214 /// Uses indicate missing information in the model. 214 /// Uses indicate missing information in the model.
215 final Element element; 215 final Element element;
216 216
217 final String name; 217 final js.Name name;
218 final Holder holder; 218 final Holder holder;
219 Class _superclass; 219 Class _superclass;
220 final List<Method> methods; 220 final List<Method> methods;
221 final List<Field> fields; 221 final List<Field> fields;
222 final List<StubMethod> isChecks; 222 final List<StubMethod> isChecks;
223 223
224 /// Stub methods for this class that are call stubs for getters. 224 /// Stub methods for this class that are call stubs for getters.
225 final List<StubMethod> callStubs; 225 final List<StubMethod> callStubs;
226 226
227 /// Stub methods for this class handling reads to type variables. 227 /// Stub methods for this class handling reads to type variables.
228 final List<StubMethod> typeVariableReaderStubs; 228 final List<StubMethod> typeVariableReaderStubs;
229 229
230 /// noSuchMethod stubs in the special case that the class is Object. 230 /// noSuchMethod stubs in the special case that the class is Object.
231 final List<StubMethod> noSuchMethodStubs; 231 final List<StubMethod> noSuchMethodStubs;
232 final List<Field> staticFieldsForReflection; 232 final List<Field> staticFieldsForReflection;
233 final bool onlyForRti; 233 final bool onlyForRti;
234 final bool isDirectlyInstantiated; 234 final bool isDirectlyInstantiated;
235 final bool isNative; 235 final bool isNative;
236 236
237 // If the class implements a function type, and the type is encoded in the 237 // If the class implements a function type, and the type is encoded in the
238 // metatada table, then this field contains the index into that field. 238 // metatada table, then this field contains the index into that field.
239 final js.Expression functionTypeIndex; 239 final js.Expression functionTypeIndex;
240 240
241 /// Whether the class must be evaluated eagerly. 241 /// Whether the class must be evaluated eagerly.
242 bool isEager = false; 242 bool isEager = false;
243 243
244 /// Data that must be emitted with the class for native interop. 244 /// Data that must be emitted with the class for native interop.
245 String nativeInfo; 245 js.Literal nativeInfo;
246 246
247 Class(this.element, this.name, this.holder, 247 Class(this.element, this.name, this.holder,
248 this.methods, 248 this.methods,
249 this.fields, 249 this.fields,
250 this.staticFieldsForReflection, 250 this.staticFieldsForReflection,
251 this.callStubs, 251 this.callStubs,
252 this.typeVariableReaderStubs, 252 this.typeVariableReaderStubs,
253 this.noSuchMethodStubs, 253 this.noSuchMethodStubs,
254 this.isChecks, 254 this.isChecks,
255 this.functionTypeIndex, 255 this.functionTypeIndex,
256 {this.onlyForRti, 256 {this.onlyForRti,
257 this.isDirectlyInstantiated, 257 this.isDirectlyInstantiated,
258 this.isNative}) { 258 this.isNative}) {
259 assert(onlyForRti != null); 259 assert(onlyForRti != null);
260 assert(isDirectlyInstantiated != null); 260 assert(isDirectlyInstantiated != null);
261 assert(isNative != null); 261 assert(isNative != null);
262 } 262 }
263 263
264 bool get isMixinApplication => false; 264 bool get isMixinApplication => false;
265 Class get superclass => _superclass; 265 Class get superclass => _superclass;
266 266
267 void setSuperclass(Class superclass) { 267 void setSuperclass(Class superclass) {
268 _superclass = superclass; 268 _superclass = superclass;
269 } 269 }
270 270
271 String get superclassName 271 js.Name get superclassName
272 => (superclass == null) ? "" : superclass.name; 272 => superclass == null ? null : superclass.name;
273
273 int get superclassHolderIndex 274 int get superclassHolderIndex
274 => (superclass == null) ? 0 : superclass.holder.index; 275 => (superclass == null) ? 0 : superclass.holder.index;
275 } 276 }
276 277
277 class MixinApplication extends Class { 278 class MixinApplication extends Class {
278 Class _mixinClass; 279 Class _mixinClass;
279 280
280 MixinApplication(Element element, String name, Holder holder, 281 MixinApplication(Element element, js.Name name, Holder holder,
281 List<Field> instanceFields, 282 List<Field> instanceFields,
282 List<Field> staticFieldsForReflection, 283 List<Field> staticFieldsForReflection,
283 List<StubMethod> callStubs, 284 List<StubMethod> callStubs,
284 List<StubMethod> typeVariableReaderStubs, 285 List<StubMethod> typeVariableReaderStubs,
285 List<StubMethod> isChecks, 286 List<StubMethod> isChecks,
286 js.Expression functionTypeIndex, 287 js.Expression functionTypeIndex,
287 {bool onlyForRti, 288 {bool onlyForRti,
288 bool isDirectlyInstantiated}) 289 bool isDirectlyInstantiated})
289 : super(element, 290 : super(element,
290 name, holder, 291 name, holder,
(...skipping 18 matching lines...) Expand all
309 310
310 /// A field. 311 /// A field.
311 /// 312 ///
312 /// In general represents an instance field, but for reflection may also 313 /// In general represents an instance field, but for reflection may also
313 /// represent static fields. 314 /// represent static fields.
314 class Field { 315 class Field {
315 /// The element should only be used during the transition to the new model. 316 /// The element should only be used during the transition to the new model.
316 /// Uses indicate missing information in the model. 317 /// Uses indicate missing information in the model.
317 final Element element; 318 final Element element;
318 319
319 final String name; 320 final js.Name name;
320 final String accessorName; 321 final js.Name accessorName;
321 322
322 /// 00: Does not need any getter. 323 /// 00: Does not need any getter.
323 /// 01: function() { return this.field; } 324 /// 01: function() { return this.field; }
324 /// 10: function(receiver) { return receiver.field; } 325 /// 10: function(receiver) { return receiver.field; }
325 /// 11: function(receiver) { return this.field; } 326 /// 11: function(receiver) { return this.field; }
326 final int getterFlags; 327 final int getterFlags;
327 328
328 /// 00: Does not need any setter. 329 /// 00: Does not need any setter.
329 /// 01: function(value) { this.field = value; } 330 /// 01: function(value) { this.field = value; }
330 /// 10: function(receiver, value) { receiver.field = value; } 331 /// 10: function(receiver, value) { receiver.field = value; }
(...skipping 11 matching lines...) Expand all
342 bool get needsUncheckedSetter => setterFlags != 0; 343 bool get needsUncheckedSetter => setterFlags != 0;
343 344
344 bool get needsInterceptedGetter => getterFlags > 1; 345 bool get needsInterceptedGetter => getterFlags > 1;
345 bool get needsInterceptedSetter => setterFlags > 1; 346 bool get needsInterceptedSetter => setterFlags > 1;
346 } 347 }
347 348
348 abstract class Method { 349 abstract class Method {
349 /// The element should only be used during the transition to the new model. 350 /// The element should only be used during the transition to the new model.
350 /// Uses indicate missing information in the model. 351 /// Uses indicate missing information in the model.
351 final Element element; 352 final Element element;
352 final String name; 353 final js.Name name;
353 final js.Expression code; 354 final js.Expression code;
354 355
355 Method(this.element, this.name, this.code); 356 Method(this.element, this.name, this.code);
356 } 357 }
357 358
358 /// A method that corresponds to a method in the original Dart program. 359 /// A method that corresponds to a method in the original Dart program.
359 class DartMethod extends Method { 360 class DartMethod extends Method {
360 final bool needsTearOff; 361 final bool needsTearOff;
361 final String tearOffName; 362 final js.Name tearOffName;
362 final List<ParameterStubMethod> parameterStubs; 363 final List<ParameterStubMethod> parameterStubs;
363 final bool canBeApplied; 364 final bool canBeApplied;
364 final bool canBeReflected; 365 final bool canBeReflected;
365 366
366 // Is non-null if [needsTearOff] or [canBeReflected]. 367 // Is non-null if [needsTearOff] or [canBeReflected].
367 // 368 //
368 // If the type is encoded in the metadata table this field contains an index 369 // If the type is encoded in the metadata table this field contains an index
369 // into the table. Otherwise the type contains type variables in which case 370 // into the table. Otherwise the type contains type variables in which case
370 // this field holds a function computing the function signature. 371 // this field holds a function computing the function signature.
371 final js.Expression functionType; 372 final js.Expression functionType;
372 373
373 // Signature information for this method. This is only required and stored 374 // Signature information for this method. This is only required and stored
374 // here if the method [canBeApplied] or [canBeReflected] 375 // here if the method [canBeApplied] or [canBeReflected]
375 final int requiredParameterCount; 376 final int requiredParameterCount;
376 final /* Map | List */ optionalParameterDefaultValues; 377 final /* Map | List */ optionalParameterDefaultValues;
377 378
378 // If this method can be torn off, contains the name of the corresponding 379 // If this method can be torn off, contains the name of the corresponding
379 // call method. For example, for the member `foo$1$name` it would be 380 // call method. For example, for the member `foo$1$name` it would be
380 // `call$1$name` (in unminified mode). 381 // `call$1$name` (in unminified mode).
381 final String callName; 382 final js.Name callName;
382 383
383 DartMethod(Element element, String name, js.Expression code, 384 DartMethod(Element element, js.Name name, js.Expression code,
384 this.parameterStubs, this.callName, 385 this.parameterStubs, this.callName,
385 {this.needsTearOff, this.tearOffName, this.canBeApplied, 386 {this.needsTearOff, this.tearOffName, this.canBeApplied,
386 this.canBeReflected, this.requiredParameterCount, 387 this.canBeReflected, this.requiredParameterCount,
387 this.optionalParameterDefaultValues, this.functionType}) 388 this.optionalParameterDefaultValues, this.functionType})
388 : super(element, name, code) { 389 : super(element, name, code) {
389 assert(needsTearOff != null); 390 assert(needsTearOff != null);
390 assert(!needsTearOff || tearOffName != null); 391 assert(!needsTearOff || tearOffName != null);
391 assert(canBeApplied != null); 392 assert(canBeApplied != null);
392 assert(canBeReflected != null); 393 assert(canBeReflected != null);
393 assert((!canBeReflected && !canBeApplied) || 394 assert((!canBeReflected && !canBeApplied) ||
394 (requiredParameterCount != null && 395 (requiredParameterCount != null &&
395 optionalParameterDefaultValues != null)); 396 optionalParameterDefaultValues != null));
396 } 397 }
397 } 398 }
398 399
399 class InstanceMethod extends DartMethod { 400 class InstanceMethod extends DartMethod {
400 /// An alternative name for this method. This is used to model calls to 401 /// An alternative name for this method. This is used to model calls to
401 /// a method via `super`. If [aliasName] is non-null, the emitter has to 402 /// a method via `super`. If [aliasName] is non-null, the emitter has to
402 /// ensure that this method is registered on the prototype under both [name] 403 /// ensure that this method is registered on the prototype under both [name]
403 /// and [aliasName]. 404 /// and [aliasName].
404 final String aliasName; 405 final js.Name aliasName;
405 final bool isClosure; 406 final bool isClosure;
406 407
407 408
408 InstanceMethod(Element element, String name, js.Expression code, 409 InstanceMethod(Element element, js.Name name, js.Expression code,
409 List<ParameterStubMethod> parameterStubs, 410 List<ParameterStubMethod> parameterStubs,
410 String callName, 411 js.Name callName,
411 {bool needsTearOff, 412 {bool needsTearOff,
412 String tearOffName, 413 js.Name tearOffName,
413 this.aliasName, 414 this.aliasName,
414 bool canBeApplied, 415 bool canBeApplied,
415 bool canBeReflected, 416 bool canBeReflected,
416 int requiredParameterCount, 417 int requiredParameterCount,
417 /* List | Map */ optionalParameterDefaultValues, 418 /* List | Map */ optionalParameterDefaultValues,
418 this.isClosure, 419 this.isClosure,
419 js.Expression functionType}) 420 js.Expression functionType})
420 : super(element, name, code, parameterStubs, callName, 421 : super(element, name, code, parameterStubs, callName,
421 needsTearOff: needsTearOff, 422 needsTearOff: needsTearOff,
422 tearOffName: tearOffName, 423 tearOffName: tearOffName,
423 canBeApplied: canBeApplied, 424 canBeApplied: canBeApplied,
424 canBeReflected: canBeReflected, 425 canBeReflected: canBeReflected,
425 requiredParameterCount: requiredParameterCount, 426 requiredParameterCount: requiredParameterCount,
426 optionalParameterDefaultValues: optionalParameterDefaultValues, 427 optionalParameterDefaultValues: optionalParameterDefaultValues,
427 functionType: functionType) { 428 functionType: functionType) {
428 assert(isClosure != null); 429 assert(isClosure != null);
429 } 430 }
430 } 431 }
431 432
432 /// A method that is generated by the backend and has not direct correspondence 433 /// A method that is generated by the backend and has not direct correspondence
433 /// to a method in the original Dart program. Examples are getter and setter 434 /// to a method in the original Dart program. Examples are getter and setter
434 /// stubs and stubs to dispatch calls to methods with optional parameters. 435 /// stubs and stubs to dispatch calls to methods with optional parameters.
435 class StubMethod extends Method { 436 class StubMethod extends Method {
436 StubMethod(String name, js.Expression code, 437 StubMethod(js.Name name, js.Expression code,
437 {Element element}) 438 {Element element})
438 : super(element, name, code); 439 : super(element, name, code);
439 } 440 }
440 441
441 /// A stub that adapts and redirects to the main method (the one containing) 442 /// A stub that adapts and redirects to the main method (the one containing)
442 /// the actual code. 443 /// the actual code.
443 /// 444 ///
444 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter 445 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter
445 /// stub-method could be `foo$1(x) => foo$2(x, 499)`. 446 /// stub-method could be `foo$1(x) => foo$2(x, 499)`.
446 /// 447 ///
447 /// ParameterStubMethods are always attached to (static or instance) methods. 448 /// ParameterStubMethods are always attached to (static or instance) methods.
448 class ParameterStubMethod extends StubMethod { 449 class ParameterStubMethod extends StubMethod {
449 /// The `call` name of this stub. 450 /// The `call` name of this stub.
450 /// 451 ///
451 /// When an instance method is torn off, it is invoked as a `call` member and 452 /// When an instance method is torn off, it is invoked as a `call` member and
452 /// not it's original name anymore. The [callName] provides the stub's 453 /// not it's original name anymore. The [callName] provides the stub's
453 /// name when it is used this way. 454 /// name when it is used this way.
454 /// 455 ///
455 /// If a stub's member can not be torn off, the [callName] is `null`. 456 /// If a stub's member can not be torn off, the [callName] is `null`.
456 String callName; 457 js.Name callName;
457 458
458 ParameterStubMethod(String name, this.callName, js.Expression code) 459 ParameterStubMethod(js.Name name, this.callName, js.Expression code)
459 : super(name, code); 460 : super(name, code);
460 } 461 }
461 462
462 abstract class StaticMethod implements Method { 463 abstract class StaticMethod implements Method {
463 Holder get holder; 464 Holder get holder;
464 } 465 }
465 466
466 class StaticDartMethod extends DartMethod implements StaticMethod { 467 class StaticDartMethod extends DartMethod implements StaticMethod {
467 final Holder holder; 468 final Holder holder;
468 469
469 StaticDartMethod(Element element, String name, this.holder, 470 StaticDartMethod(Element element, js.Name name, this.holder,
470 js.Expression code, List<ParameterStubMethod> parameterStubs, 471 js.Expression code, List<ParameterStubMethod> parameterStubs,
471 String callName, 472 js.Name callName,
472 {bool needsTearOff, String tearOffName, bool canBeApplied, 473 {bool needsTearOff, js.Name tearOffName,
473 bool canBeReflected, int requiredParameterCount, 474 bool canBeApplied, bool canBeReflected,
475 int requiredParameterCount,
474 /* List | Map */ optionalParameterDefaultValues, 476 /* List | Map */ optionalParameterDefaultValues,
475 js.Expression functionType}) 477 js.Expression functionType})
476 : super(element, name, code, parameterStubs, callName, 478 : super(element, name, code, parameterStubs, callName,
477 needsTearOff: needsTearOff, 479 needsTearOff: needsTearOff,
478 tearOffName : tearOffName, 480 tearOffName : tearOffName,
479 canBeApplied : canBeApplied, 481 canBeApplied : canBeApplied,
480 canBeReflected : canBeReflected, 482 canBeReflected : canBeReflected,
481 requiredParameterCount: requiredParameterCount, 483 requiredParameterCount: requiredParameterCount,
482 optionalParameterDefaultValues: optionalParameterDefaultValues, 484 optionalParameterDefaultValues: optionalParameterDefaultValues,
483 functionType: functionType); 485 functionType: functionType);
484 } 486 }
485 487
486 class StaticStubMethod extends StubMethod implements StaticMethod { 488 class StaticStubMethod extends StubMethod implements StaticMethod {
487 Holder holder; 489 Holder holder;
488 StaticStubMethod(String name, this.holder, js.Expression code) 490 StaticStubMethod(js.Name name, this.holder, js.Expression code)
489 : super(name, code); 491 : super(name, code);
490 } 492 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698