| OLD | NEW |
| 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_emitter; | 5 library dart2js.new_js_emitter.model_emitter; |
| 6 | 6 |
| 7 import '../../dart2jslib.dart' show Compiler; | 7 import '../../dart2jslib.dart' show Compiler; |
| 8 import '../../js/js.dart' as js; | 8 import '../../js/js.dart' as js; |
| 9 import '../../js_backend/js_backend.dart' show | 9 import '../../js_backend/js_backend.dart' show |
| 10 JavaScriptBackend, | 10 JavaScriptBackend, |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 278 |
| 279 js.Expression staticArray = | 279 js.Expression staticArray = |
| 280 new js.ArrayInitializer(staticDescriptors.toList(growable: false)); | 280 new js.ArrayInitializer(staticDescriptors.toList(growable: false)); |
| 281 js.Expression classArray = | 281 js.Expression classArray = |
| 282 new js.ArrayInitializer(classDescriptors.toList(growable: false)); | 282 new js.ArrayInitializer(classDescriptors.toList(growable: false)); |
| 283 | 283 |
| 284 return new js.ArrayInitializer([staticArray, classArray]); | 284 return new js.ArrayInitializer([staticArray, classArray]); |
| 285 } | 285 } |
| 286 | 286 |
| 287 js.Expression _generateConstructor(Class cls) { | 287 js.Expression _generateConstructor(Class cls) { |
| 288 List<String> allFieldNames = <String>[]; | 288 List<String> fieldNames = <String>[]; |
| 289 | 289 |
| 290 // If the class is not directly instantiated we only need it for inheritance | 290 // If the class is not directly instantiated we only need it for inheritance |
| 291 // or RTI. In either case we don't need its fields. | 291 // or RTI. In either case we don't need its fields. |
| 292 if (cls.isDirectlyInstantiated) { | 292 if (cls.isDirectlyInstantiated && !cls.isNative) { |
| 293 Class currentClass = cls; | 293 fieldNames = cls.fields.map((Field field) => field.name).toList(); |
| 294 while (currentClass != null) { | |
| 295 // Mixins are not allowed to inject fields. | |
| 296 assert(!currentClass.isMixinApplication || | |
| 297 (currentClass as MixinApplication).mixinClass.fields.isEmpty); | |
| 298 | |
| 299 allFieldNames.addAll( | |
| 300 currentClass.fields.map((InstanceField field) => field.name)); | |
| 301 currentClass = currentClass.superclass; | |
| 302 } | |
| 303 } | 294 } |
| 304 String name = cls.name; | 295 String name = cls.name; |
| 305 String parameters = allFieldNames.join(', '); | 296 String parameters = fieldNames.join(', '); |
| 306 String assignments = allFieldNames | 297 String assignments = fieldNames |
| 307 .map((String field) => "this.$field = $field;\n") | 298 .map((String field) => "this.$field = $field;\n") |
| 308 .join(); | 299 .join(); |
| 309 String code = 'function $name($parameters) { $assignments }'; | 300 String code = 'function $name($parameters) { $assignments }'; |
| 310 js.Template template = js.js.uncachedExpressionTemplate(code); | 301 js.Template template = js.js.uncachedExpressionTemplate(code); |
| 311 return template.instantiate(const []); | 302 return template.instantiate(const []); |
| 312 } | 303 } |
| 313 | 304 |
| 314 Method _generateGetter(InstanceField field) { | 305 Method _generateGetter(Field field) { |
| 315 String getterTemplateFor(int flags) { | 306 String getterTemplateFor(int flags) { |
| 316 switch (flags) { | 307 switch (flags) { |
| 317 case 1: return "function() { return this[#]; }"; | 308 case 1: return "function() { return this[#]; }"; |
| 318 case 2: return "function(receiver) { return receiver[#]; }"; | 309 case 2: return "function(receiver) { return receiver[#]; }"; |
| 319 case 3: return "function(receiver) { return this[#]; }"; | 310 case 3: return "function(receiver) { return this[#]; }"; |
| 320 } | 311 } |
| 321 return null; | 312 return null; |
| 322 } | 313 } |
| 323 | 314 |
| 324 js.Expression fieldName = js.string(field.name); | 315 js.Expression fieldName = js.string(field.name); |
| 325 js.Expression code = js.js(getterTemplateFor(field.getterFlags), fieldName); | 316 js.Expression code = js.js(getterTemplateFor(field.getterFlags), fieldName); |
| 326 String getterName = "${namer.getterPrefix}${field.name}"; | 317 String getterName = "${namer.getterPrefix}${field.name}"; |
| 327 return new StubMethod(getterName, code, needsTearOff: false); | 318 return new StubMethod(getterName, code, needsTearOff: false); |
| 328 } | 319 } |
| 329 | 320 |
| 330 Method _generateSetter(InstanceField field) { | 321 Method _generateSetter(Field field) { |
| 331 String setterTemplateFor(int flags) { | 322 String setterTemplateFor(int flags) { |
| 332 switch (flags) { | 323 switch (flags) { |
| 333 case 1: return "function(val) { return this[#] = val; }"; | 324 case 1: return "function(val) { return this[#] = val; }"; |
| 334 case 2: return "function(receiver, val) { return receiver[#] = val; }"; | 325 case 2: return "function(receiver, val) { return receiver[#] = val; }"; |
| 335 case 3: return "function(receiver, val) { return this[#] = val; }"; | 326 case 3: return "function(receiver, val) { return this[#] = val; }"; |
| 336 } | 327 } |
| 337 return null; | 328 return null; |
| 338 } | 329 } |
| 339 js.Expression fieldName = js.string(field.name); | 330 js.Expression fieldName = js.string(field.name); |
| 340 js.Expression code = js.js(setterTemplateFor(field.setterFlags), fieldName); | 331 js.Expression code = js.js(setterTemplateFor(field.setterFlags), fieldName); |
| 341 String setterName = "${namer.setterPrefix}${field.name}"; | 332 String setterName = "${namer.setterPrefix}${field.name}"; |
| 342 return new StubMethod(setterName, code, needsTearOff: false); | 333 return new StubMethod(setterName, code, needsTearOff: false); |
| 343 } | 334 } |
| 344 | 335 |
| 345 Iterable<Method> _generateGettersSetters(Class cls) { | 336 Iterable<Method> _generateGettersSetters(Class cls) { |
| 346 Iterable<Method> getters = cls.fields | 337 Iterable<Method> getters = cls.fields |
| 347 .where((InstanceField field) => field.needsGetter) | 338 .where((Field field) => field.needsGetter) |
| 348 .map(_generateGetter); | 339 .map(_generateGetter); |
| 349 | 340 |
| 350 Iterable<Method> setters = cls.fields | 341 Iterable<Method> setters = cls.fields |
| 351 .where((InstanceField field) => field.needsSetter) | 342 .where((Field field) => field.needsUncheckedSetter) |
| 352 .map(_generateSetter); | 343 .map(_generateSetter); |
| 353 | 344 |
| 354 return [getters, setters].expand((x) => x); | 345 return [getters, setters].expand((x) => x); |
| 355 } | 346 } |
| 356 | 347 |
| 357 // This string should be referenced wherever JavaScript code makes assumptions | 348 // This string should be referenced wherever JavaScript code makes assumptions |
| 358 // on the mixin format. | 349 // on the mixin format. |
| 359 static final String mixinFormatDescription = | 350 static final String mixinFormatDescription = |
| 360 "Mixins have no constructor, but a reference to their mixin class."; | 351 "Mixins have no constructor, but a reference to their mixin class."; |
| 361 | 352 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 | 565 |
| 575 var end = Date.now(); | 566 var end = Date.now(); |
| 576 print('Setup: ' + (end - start) + ' ms.'); | 567 print('Setup: ' + (end - start) + ' ms.'); |
| 577 | 568 |
| 578 #main(); // Start main. | 569 #main(); // Start main. |
| 579 | 570 |
| 580 }(Date.now(), #code) | 571 }(Date.now(), #code) |
| 581 }"""; | 572 }"""; |
| 582 | 573 |
| 583 } | 574 } |
| OLD | NEW |