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

Unified Diff: lib/compiler/implementation/emitter.dart

Issue 10344021: Create the JavaScript constructor dynamically. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Test. Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « frog/tests/leg/class_codegen_test.dart ('k') | tests/language/class_codegen_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/emitter.dart
diff --git a/lib/compiler/implementation/emitter.dart b/lib/compiler/implementation/emitter.dart
index 68a3d1a3a0077c8102d6fa94373805a8dedeaa9d..4505d6134df0e685e2ef7c44e6700cca8d7e52af 100644
--- a/lib/compiler/implementation/emitter.dart
+++ b/lib/compiler/implementation/emitter.dart
@@ -53,11 +53,12 @@ class CodeEmitterTask extends CompilerTask {
=> '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}';
String get defineClassFunction() {
+ // First the class name, then the super class name, followed by the fields
+ // (in an array) and the members (inside an Object literal).
+ // The caller can also pass in the constructor as a function if needed.
ngeoffray 2012/05/07 09:42:30 Who needs that?
floitsch 2012/05/07 12:42:08 This is in preparation for a future CL. The idea i
+ //
// Example:
- // defineClass("A", "B",
- // function(x) { /* The JavaScript constructor. */
- // this.x = x;
- // }, { /* The members inside an Object literal. */
+ // defineClass("A", "B", ["x", "y"], {
// foo$1: function(y) {
// print(this.x + y);
// },
@@ -66,7 +67,21 @@ class CodeEmitterTask extends CompilerTask {
// },
// });
return """
-function(cls, superclass, constructor, prototype) {
+function(cls, superclass, fields, prototype) {
+ var constructor;
+ if (typeof fields == 'function') {
ngeoffray 2012/05/07 09:42:30 Since we control the emission, why do we need to s
floitsch 2012/05/07 12:42:08 If you prefer I can remove the code for now. (it's
ngeoffray 2012/05/07 12:54:25 It's fine if you keep it but make sure you'll use
+ constructor = fields;
+ } else {
+ var str = "(function " + cls + "(";
+ var body = "";
+ for (var i = 0; i < fields.length; i++) {
+ if (i != 0) str += ", ";
+ str += fields[i];
+ body += "this." + fields[i] + " = " + fields[i] + ";\\n";
+ }
+ str += ") {" + body + "})";
+ constructor = eval(str);
+ }
$isolatePropertiesName[cls] = constructor;
constructor.prototype = prototype;
if (superclass !== "") {
@@ -357,30 +372,16 @@ function() {
emitExtraAccessors(member, defineInstanceMember);
}
- bool generateFieldInits(ClassElement classElement,
- StringBuffer argumentsBuffer,
- StringBuffer bodyBuffer) {
- bool isFirst = true;
- void generateFieldInit(ClassElement enclosingClass, Element member) {
- // TODO(floitsch): make sure there are no name clashes.
- String className = namer.getName(enclosingClass);
- if (!isFirst) argumentsBuffer.add(', ');
- isFirst = false;
- String memberName = namer.instanceFieldName(member.getLibrary(),
- member.name);
- String parameter;
- if (classElement === enclosingClass) {
- parameter = memberName;
- } else {
- parameter = '${className}_$memberName';
- }
- argumentsBuffer.add(parameter);
- bodyBuffer.add(' this.$memberName = $parameter;\n');
+ List<String> generateFieldList(ClassElement classElement) {
+ List<String> result = <String>[];
+ void addField(ClassElement enclosingClass, Element member) {
+ result.add(namer.instanceFieldName(member.getLibrary(), member.name));
}
- classElement.forEachInstanceField(generateFieldInit,
+ classElement.forEachInstanceField(addField,
includeBackendMembers: true,
includeSuperMembers: true);
+ return result;
}
void generateClass(ClassElement classElement, StringBuffer buffer) {
@@ -404,18 +405,20 @@ function() {
}
String constructorName = namer.safeName(classElement.name.slowToString());
buffer.add('$defineClassName("$className", "$superName", ');
- buffer.add('function $constructorName(');
- StringBuffer bodyBuffer = new StringBuffer();
// If the class is never instantiated we still need to set it up for
- // inheritance purposes, but we can leave its JavaScript constructor empty.
- if (compiler.universe.instantiatedClasses.contains(classElement)) {
- generateFieldInits(classElement, buffer, bodyBuffer);
+ // inheritance purposes, but we can simplify its JavaScript constructor.
+ if (!compiler.universe.instantiatedClasses.contains(classElement)) {
+ buffer.add("[]");
+ } else {
+ List<String> fields = generateFieldList(classElement);
+ buffer.add('[');
+ for (int i = 0; i < fields.length; i++) {
+ if (i != 0) buffer.add(", ");
+ buffer.add('"${fields[i]}"');
+ }
+ buffer.add(']');
}
- buffer.add(') {\n');
- buffer.add(bodyBuffer);
- buffer.add(' }, ');
-
- buffer.add('{\n');
+ buffer.add(', {\n');
void defineInstanceMember(String name, String value) {
buffer.add(' $name: $value,\n');
« no previous file with comments | « frog/tests/leg/class_codegen_test.dart ('k') | tests/language/class_codegen_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698