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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart

Issue 246633006: Revert "JS templates" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index 41c78cd73255abd7f36481bddab5b857adaebfd9..c5dd94aaae0da35570c35080e1f94d7b88a4d23b 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -148,65 +148,74 @@ class CodeEmitterTask extends CompilerTask {
String valueParamName = compiler.enableMinification ? "v" : "value";
String reflectableField = namer.reflectableField;
- return js.statement('''
- function generateAccessor(fieldDescriptor, accessors, cls) {
- var fieldInformation = fieldDescriptor.split("-");
- var field = fieldInformation[0];
- var len = field.length;
- var code = field.charCodeAt(len - 1);
- var reflectable;
- if (fieldInformation.length > 1) reflectable = true;
- else reflectable = false;
- code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))
- ? code - $RANGE1_ADJUST
- : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))
- ? code - $RANGE2_ADJUST
- : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))
- ? code - $RANGE3_ADJUST
- : $NO_FIELD_CODE;
-
- if (code) { // needsAccessor
- var getterCode = code & 3;
- var setterCode = code >> 2;
- var accessorName = field = field.substring(0, len - 1);
-
- var divider = field.indexOf(":");
- if (divider > 0) { // Colon never in first position.
- accessorName = field.substring(0, divider);
- field = field.substring(divider + 1);
- }
-
- if (getterCode) { // needsGetter
- var args = (getterCode & 2) ? "$receiverParamName" : "";
- var receiver = (getterCode & 1) ? "this" : "$receiverParamName";
- var body = "return " + receiver + "." + field;
- var property =
- cls + ".prototype.${namer.getterPrefix}" + accessorName + "=";
- var fn = "function(" + args + "){" + body + "}";
- if (reflectable)
- accessors.push(property + "\$reflectable(" + fn + ");\\n");
- else
- accessors.push(property + fn + ";\\n");
- }
-
- if (setterCode) { // needsSetter
- var args = (setterCode & 2)
- ? "$receiverParamName,${_}$valueParamName"
- : "$valueParamName";
- var receiver = (setterCode & 1) ? "this" : "$receiverParamName";
- var body = receiver + "." + field + "$_=$_$valueParamName";
- var property =
- cls + ".prototype.${namer.setterPrefix}" + accessorName + "=";
- var fn = "function(" + args + "){" + body + "}";
- if (reflectable)
- accessors.push(property + "\$reflectable(" + fn + ");\\n");
- else
- accessors.push(property + fn + ";\\n");
- }
- }
+ // function generateAccessor(field, prototype, cls) {
+ jsAst.Fun fun = js.fun(['fieldDescriptor', 'accessors', 'cls'], [
+ js('var fieldInformation = fieldDescriptor.split("-")'),
+ js('var field = fieldInformation[0]'),
+ js('var len = field.length'),
+ js('var code = field.charCodeAt(len - 1)'),
+ js('var reflectable'),
+ js.if_('fieldInformation.length > 1', js('reflectable = true'),
+ js('reflectable = false')),
+ js('code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))'
+ ' ? code - $RANGE1_ADJUST'
+ ' : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))'
+ ' ? code - $RANGE2_ADJUST'
+ ' : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))'
+ ' ? code - $RANGE3_ADJUST'
+ ' : $NO_FIELD_CODE'),
+
+ // if (needsAccessor) {
+ js.if_('code', [
+ js('var getterCode = code & 3'),
+ js('var setterCode = code >> 2'),
+ js('var accessorName = field = field.substring(0, len - 1)'),
+
+ js('var divider = field.indexOf(":")'),
+ js.if_('divider > 0', [ // Colon never in first position.
+ js('accessorName = field.substring(0, divider)'),
+ js('field = field.substring(divider + 1)')
+ ]),
+
+ // if (needsGetter) {
+ js.if_('getterCode', [
+ js('var args = (getterCode & 2) ? "$receiverParamName" : ""'),
+ js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'),
+ js('var body = "return " + receiver + "." + field'),
+ js('var property ='
+ ' cls + ".prototype.${namer.getterPrefix}" + accessorName + "="'),
+ js('var fn = "function(" + args + "){" + body + "}"'),
+ js.if_(
+ 'reflectable',
+ js('accessors.push(property + "\$reflectable(" + fn + ");\\n")'),
+ js('accessors.push(property + fn + ";\\n")')),
+ ]),
+
+ // if (needsSetter) {
+ js.if_('setterCode', [
+ js('var args = (setterCode & 2)'
+ ' ? "$receiverParamName,${_}$valueParamName"'
+ ' : "$valueParamName"'),
+ js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'),
+ js('var body = receiver + "." + field + "$_=$_$valueParamName"'),
+ js('var property ='
+ ' cls + ".prototype.${namer.setterPrefix}" + accessorName + "="'),
+ js('var fn = "function(" + args + "){" + body + "}"'),
+ js.if_(
+ 'reflectable',
+ js('accessors.push(property + "\$reflectable(" + fn + ");\\n")'),
+ js('accessors.push(property + fn + ";\\n")')),
+ ]),
+
+ ]),
+
+ // return field;
+ js.return_('field')
+ ]);
- return field;
- }''');
+ return new jsAst.FunctionDeclaration(
+ new jsAst.VariableDeclaration('generateAccessor'),
+ fun);
}
List get defineClassFunction {
@@ -295,134 +304,130 @@ class CodeEmitterTask extends CompilerTask {
// object and copy over the members.
String reflectableField = namer.reflectableField;
+ List<jsAst.Node> statements = [
+ js('var pendingClasses = {}'),
+ js.if_('!init.allClasses', js('init.allClasses = {}')),
+ js('var allClasses = init.allClasses'),
+
+ optional(
+ DEBUG_FAST_OBJECTS,
+ js('print("Number of classes: "'
+ r' + Object.getOwnPropertyNames($$).length)')),
+
+ js('var hasOwnProperty = Object.prototype.hasOwnProperty'),
+
+ js.if_('typeof dart_precompiled == "function"',
+ [js('var constructors = dart_precompiled(collectedClasses)')],
+
+ [js('var combinedConstructorFunction = "function \$reflectable(fn){'
+ 'fn.$reflectableField=1;return fn};\\n"+ "var \$desc;\\n"'),
+ js('var constructorsList = []')]),
+ js.forIn('cls', 'collectedClasses', [
+ js.if_('hasOwnProperty.call(collectedClasses, cls)', [
+ js('var desc = collectedClasses[cls]'),
+ js.if_('desc instanceof Array', js('desc = desc[1]')),
+
+ /* The 'fields' are either a constructor function or a
+ * string encoding fields, constructor and superclass. Get
+ * the superclass and the fields in the format
+ * '[name/]Super;field1,field2'
+ * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
+ * The 'name/' is optional and contains the name that should be used
+ * when printing the runtime type string. It is used, for example, to
+ * print the runtime type JSInt as 'int'.
+ */
+ js('var classData = desc["${namer.classDescriptorProperty}"], '
+ 'supr, name = cls, fields = classData'),
+ optional(
+ backend.hasRetainedMetadata,
+ js.if_('typeof classData == "object" && '
+ 'classData instanceof Array',
+ [js('classData = fields = classData[0]')])),
+
+ js.if_('typeof classData == "string"', [
+ js('var split = classData.split("/")'),
+ js.if_('split.length == 2', [
+ js('name = split[0]'),
+ js('fields = split[1]')
+ ])
+ ]),
+
+ js('var s = fields.split(";")'),
+ js('fields = s[1] == "" ? [] : s[1].split(",")'),
+ js('supr = s[0]'),
+ js('split = supr.split(":")'),
+ js.if_('split.length == 2', [
+ js('supr = split[0]'),
+ js('var functionSignature = split[1]'),
+ js.if_('functionSignature',
+ js('desc.\$signature = #',
+ js.fun('s',
+ js.return_(js.fun([], js.return_('init.metadata[s]'))))(
+ js('functionSignature'))))
+ ]),
+
+ optional(needsMixinSupport, js.if_('supr && supr.indexOf("+") > 0', [
+ js('s = supr.split("+")'),
+ js('supr = s[0]'),
+ js('var mixin = collectedClasses[s[1]]'),
+ js.if_('mixin instanceof Array', js('mixin = mixin[1]')),
+ js.forIn('d', 'mixin', [
+ js.if_('hasOwnProperty.call(mixin, d)'
+ '&& !hasOwnProperty.call(desc, d)',
+ js('desc[d] = mixin[d]'))
+ ]),
+ ])),
+
+ js.if_('typeof dart_precompiled != "function"',
+ [js('combinedConstructorFunction +='
+ ' defineClass(name, cls, fields)'),
+ js('constructorsList.push(cls)')]),
+ js.if_('supr', js('pendingClasses[cls] = supr'))
+ ])
+ ]),
+ js.statement('''
+ if (typeof dart_precompiled != "function") {
+ combinedConstructorFunction +=
+ "return [\\n " + constructorsList.join(",\\n ") + "\\n]";
+ var constructors =
+ new Function("\$collectedClasses", combinedConstructorFunction)
+ (collectedClasses);
+ combinedConstructorFunction = null;
+ }'''),
+ js.for_('var i = 0', 'i < constructors.length', 'i++', [
+ js('var constructor = constructors[i]'),
+ js('var cls = constructor.name'),
+ js('var desc = collectedClasses[cls]'),
+ js('var globalObject = isolateProperties'),
+ js.if_('desc instanceof Array', [
+ js('globalObject = desc[0] || isolateProperties'),
+ js('desc = desc[1]')
+ ]),
+ optional(backend.isTreeShakingDisabled,
+ js('constructor["${namer.metadataField}"] = desc')),
+ js('allClasses[cls] = constructor'),
+ js('globalObject[cls] = constructor'),
+ ]),
+ js('constructors = null'),
+
+ js('var finishedClasses = {}'),
+ js('init.interceptorsByTag = Object.create(null)'),
+ js('init.leafTags = {}'),
+
+ buildFinishClass(),
+ ];
- return js('''
- function(collectedClasses, isolateProperties, existingIsolateProperties) {
- var pendingClasses = {};
- if (!init.allClasses) init.allClasses = {};
- var allClasses = init.allClasses;
-
- if (#) // DEBUG_FAST_OBJECTS
- print("Number of classes: " +
- Object.getOwnPropertyNames(\$\$).length);
-
- var hasOwnProperty = Object.prototype.hasOwnProperty;
-
- if (typeof dart_precompiled == "function") {
- var constructors = dart_precompiled(collectedClasses);
- } else {
- var combinedConstructorFunction =
- "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+
- "var \$desc;\\n";
- var constructorsList = [];
- }
-
- for (var cls in collectedClasses) {
- if (hasOwnProperty.call(collectedClasses, cls)) {
- var desc = collectedClasses[cls];
- if (desc instanceof Array) desc = desc[1];
-
- /* The 'fields' are either a constructor function or a
- * string encoding fields, constructor and superclass. Get
- * the superclass and the fields in the format
- * '[name/]Super;field1,field2'
- * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
- * The 'name/' is optional and contains the name that should be used
- * when printing the runtime type string. It is used, for example,
- * to print the runtime type JSInt as 'int'.
- */
- var classData = desc["${namer.classDescriptorProperty}"],
- supr, name = cls, fields = classData;
- if (#) // backend.hasRetainedMetadata
- if (typeof classData == "object" &&
- classData instanceof Array) {
- classData = fields = classData[0];
- }
- if (typeof classData == "string") {
- var split = classData.split("/");
- if (split.length == 2) {
- name = split[0];
- fields = split[1];
- }
- }
-
- var s = fields.split(";");
- fields = s[1] == "" ? [] : s[1].split(",");
- supr = s[0];
- split = supr.split(":");
- if (split.length == 2) {
- supr = split[0];
- var functionSignature = split[1];
- if (functionSignature)
- desc.\$signature = (function(s) {
- return function(){ return init.metadata[s]; };
- })(functionSignature);
- }
-
- if (#) // needsMixinSupport
- if (supr && supr.indexOf("+") > 0) {
- s = supr.split("+");
- supr = s[0];
- var mixin = collectedClasses[s[1]];
- if (mixin instanceof Array) mixin = mixin[1];
- for(var d in mixin) {
- if (hasOwnProperty.call(mixin, d) &&
- !hasOwnProperty.call(desc, d))
- desc[d] = mixin[d];
- }
- }
-
- if (typeof dart_precompiled != "function") {
- combinedConstructorFunction += defineClass(name, cls, fields);
- constructorsList.push(cls);
- }
- if (supr) pendingClasses[cls] = supr;
- }
- }
-
- if (typeof dart_precompiled != "function") {
- combinedConstructorFunction +=
- "return [\\n " + constructorsList.join(",\\n ") + "\\n]";
- var constructors =
- new Function("\$collectedClasses", combinedConstructorFunction)
- (collectedClasses);
- combinedConstructorFunction = null;
- }
-
- for (var i = 0; i < constructors.length; i++) {
- var constructor = constructors[i];
- var cls = constructor.name;
- var desc = collectedClasses[cls];
- var globalObject = isolateProperties;
- if (desc instanceof Array) {
- globalObject = desc[0] || isolateProperties;
- desc = desc[1];
- }
- if (#) //backend.isTreeShakingDisabled,
- constructor["${namer.metadataField}"] = desc;
- allClasses[cls] = constructor;
- globalObject[cls] = constructor;
- }
-
- constructors = null;
-
- var finishedClasses = {};
- init.interceptorsByTag = Object.create(null);
- init.leafTags = {};
-
- #; // buildFinishClass(),
+ nsmEmitter.addTrivialNsmHandlers(statements);
- #; // buildTrivialNsmHandlers()
+ statements.add(
+ js.statement('for (var cls in pendingClasses) finishClass(cls);')
+ );
- for (var cls in pendingClasses) finishClass(cls);
- }''', [
- DEBUG_FAST_OBJECTS,
- backend.hasRetainedMetadata,
- needsMixinSupport,
- backend.isTreeShakingDisabled,
- buildFinishClass(),
- nsmEmitter.buildTrivialNsmHandlers()]);
-
+ // function(collectedClasses,
+ // isolateProperties,
+ // existingIsolateProperties)
+ return js.fun(['collectedClasses', 'isolateProperties',
+ 'existingIsolateProperties'], statements);
}
jsAst.Node optional(bool condition, jsAst.Node node) {
@@ -432,35 +437,38 @@ class CodeEmitterTask extends CompilerTask {
jsAst.FunctionDeclaration buildFinishClass() {
String specProperty = '"${namer.nativeSpecProperty}"'; // "%"
- return js.statement('''
- function finishClass(cls) {
+ // function finishClass(cls) {
+ jsAst.Fun fun = js.fun(['cls'], [
- // TODO(8540): Remove this work around.
- // Opera does not support 'getOwnPropertyNames'. Therefore we use
- // hasOwnProperty instead.
- var hasOwnProperty = Object.prototype.hasOwnProperty;
+ // TODO(8540): Remove this work around.
+ /* Opera does not support 'getOwnPropertyNames'. Therefore we use
+ hasOwnProperty instead. */
+ js('var hasOwnProperty = Object.prototype.hasOwnProperty'),
- if (hasOwnProperty.call(finishedClasses, cls)) return;
+ // if (hasOwnProperty.call(finishedClasses, cls)) return;
+ js.if_('hasOwnProperty.call(finishedClasses, cls)',
+ js.return_()),
- finishedClasses[cls] = true;
+ js('finishedClasses[cls] = true'),
- var superclass = pendingClasses[cls];
+ js('var superclass = pendingClasses[cls]'),
- // The superclass is only false (empty string) for the Dart Object
- // class. The minifier together with noSuchMethod can put methods on
- // the Object.prototype object, and they show through here, so we check
- // that we have a string.
- if (!superclass || typeof superclass != "string") return;
- finishClass(superclass);
- var constructor = allClasses[cls];
- var superConstructor = allClasses[superclass];
+ // The superclass is only false (empty string) for Dart's Object class.
+ // The minifier together with noSuchMethod can put methods on the
+ // Object.prototype object, and they show through here, so we check that
+ // we have a string.
+ js.if_('!superclass || typeof superclass != "string"', js.return_()),
+ js('finishClass(superclass)'),
+ js('var constructor = allClasses[cls]'),
+ js('var superConstructor = allClasses[superclass]'),
- if (!superConstructor)
- superConstructor = existingIsolateProperties[superclass];
+ js.if_(js('!superConstructor'),
+ js('superConstructor ='
+ 'existingIsolateProperties[superclass]')),
- var prototype = inheritFrom(constructor, superConstructor);
+ js('var prototype = inheritFrom(constructor, superConstructor)'),
- if (#) { // !nativeClasses.isEmpty,
+ optional(!nativeClasses.isEmpty,
// The property looks like this:
//
// HtmlElement: {
@@ -482,34 +490,30 @@ class CodeEmitterTask extends CompilerTask {
//
// The information is used to build tables referenced by
// getNativeInterceptor and custom element support.
- if (hasOwnProperty.call(prototype, $specProperty)) {
- var nativeSpec = prototype[$specProperty].split(";");
- if (nativeSpec[0]) {
- var tags = nativeSpec[0].split("|");
- for (var i = 0; i < tags.length; i++) {
- init.interceptorsByTag[tags[i]] = constructor;
- init.leafTags[tags[i]] = true;
- }
- }
- if (nativeSpec[1]) {
- tags = nativeSpec[1].split("|");
- if (#) { // User subclassing of native classes?
- if (nativeSpec[2]) {
- var subclasses = nativeSpec[2].split("|");
- for (var i = 0; i < subclasses.length; i++) {
- var subclass = allClasses[subclasses[i]];
- subclass.\$nativeSuperclassTag = tags[0];
- }
- }
- for (i = 0; i < tags.length; i++) {
- init.interceptorsByTag[tags[i]] = constructor;
- init.leafTags[tags[i]] = false;
- }
- }
- }
- }
- }
- }''', [!nativeClasses.isEmpty, true]);
+ js.if_('hasOwnProperty.call(prototype, $specProperty)', [
+ js('var nativeSpec = prototype[$specProperty].split(";")'),
+ js.if_('nativeSpec[0]', [
+ js('var tags = nativeSpec[0].split("|")'),
+ js.for_('var i = 0', 'i < tags.length', 'i++', [
+ js('init.interceptorsByTag[tags[i]] = constructor'),
+ js('init.leafTags[tags[i]] = true')])]),
+ js.if_('nativeSpec[1]', [
+ js('tags = nativeSpec[1].split("|")'),
+ optional(true, // User subclassing of native classes?
+ js.if_('nativeSpec[2]', [
+ js('var subclasses = nativeSpec[2].split("|")'),
+ js.for_('var i = 0', 'i < subclasses.length', 'i++', [
+ js('var subclass = allClasses[subclasses[i]]'),
+ js('subclass.\$nativeSuperclassTag = '
+ 'tags[0]')])])),
+ js.for_('i = 0', 'i < tags.length', 'i++', [
+ js('init.interceptorsByTag[tags[i]] = constructor'),
+ js('init.leafTags[tags[i]] = false')])])]))
+ ]);
+
+ return new jsAst.FunctionDeclaration(
+ new jsAst.VariableDeclaration('finishClass'),
+ fun);
}
jsAst.Fun get finishIsolateConstructorFunction {
@@ -536,57 +540,80 @@ class CodeEmitterTask extends CompilerTask {
Isolate.prototype = oldIsolate.prototype;
Isolate.prototype.constructor = Isolate;
Isolate.${namer.isolatePropertiesName} = isolateProperties;
- if (#)
- Isolate.$finishClassesProperty = oldIsolate.$finishClassesProperty;
- if (#)
- Isolate.makeConstantList = oldIsolate.makeConstantList;
+ #
+ #
return Isolate;
}''',
- [ needsDefineClass, hasMakeConstantList ]);
+ [ optional(needsDefineClass,
+ js('Isolate.$finishClassesProperty ='
+ ' oldIsolate.$finishClassesProperty')),
+ optional(hasMakeConstantList,
+ js('Isolate.makeConstantList = oldIsolate.makeConstantList'))
+ ]);
}
jsAst.Fun get lazyInitializerFunction {
+ // function(prototype, staticName, fieldName, getterName, lazyValue) {
+ var parameters = <String>['prototype', 'staticName', 'fieldName',
+ 'getterName', 'lazyValue'];
+ return js.fun(parameters, addLazyInitializerLogic());
+ }
+
+ List addLazyInitializerLogic() {
String isolate = namer.currentIsolate;
String cyclicThrow = namer.isolateAccess(backend.getCyclicThrowHelper());
+ var lazies = [];
+ if (backend.rememberLazies) {
+ lazies = [
+ js.if_('!init.lazies', js('init.lazies = {}')),
+ js('init.lazies[fieldName] = getterName')];
+ }
- return js('''
- function (prototype, staticName, fieldName, getterName, lazyValue) {
- if (#) {
- if (!init.lazies) init.lazies = {};
- init.lazies[fieldName] = getterName;
- }
-
- var sentinelUndefined = {};
- var sentinelInProgress = {};
- prototype[fieldName] = sentinelUndefined;
-
- prototype[getterName] = function () {
- var result = $isolate[fieldName];
- try {
- if (result === sentinelUndefined) {
- $isolate[fieldName] = sentinelInProgress;
-
- try {
- result = $isolate[fieldName] = lazyValue();
- } finally {
- // Use try-finally, not try-catch/throw as it destroys the
- // stack trace.
- if (result === sentinelUndefined)
- if ($isolate[fieldName] === sentinelInProgress)
- $isolate[fieldName] = null;
- }
- } else {
- if (result === sentinelInProgress)
- $cyclicThrow(staticName);
- }
-
- return result;
- } finally {
- $isolate[getterName] = function() { return this[fieldName]; };
- }
- }
- }
- ''', [backend.rememberLazies]);
+ return lazies..addAll([
+ js('var sentinelUndefined = {}'),
+ js('var sentinelInProgress = {}'),
+ js('prototype[fieldName] = sentinelUndefined'),
+
+ // prototype[getterName] = function()
+ js('prototype[getterName] = #', js.fun([], [
+ js('var result = $isolate[fieldName]'),
+
+ // try
+ js.try_([
+ js.if_('result === sentinelUndefined', [
+ js('$isolate[fieldName] = sentinelInProgress'),
+
+ // try
+ js.try_([
+ js('result = $isolate[fieldName] = lazyValue()'),
+
+ ], finallyPart: [
+ // Use try-finally, not try-catch/throw as it destroys the
+ // stack trace.
+
+ // if (result === sentinelUndefined)
+ js.if_('result === sentinelUndefined', [
+ // if ($isolate[fieldName] === sentinelInProgress)
+ js.if_('$isolate[fieldName] === sentinelInProgress', [
+ js('$isolate[fieldName] = null'),
+ ])
+ ])
+ ])
+ ], /* else */ [
+ js.if_('result === sentinelInProgress',
+ js('$cyclicThrow(staticName)')
+ )
+ ]),
+
+ // return result;
+ js.return_('result')
+
+ ], finallyPart: [
+ js('$isolate[getterName] = #',
+ js.fun([], [js.return_('this[fieldName]')]))
+ ])
+ ]))
+ ]);
}
List buildDefineClassAndFinishClassFunctionsIfNecessary() {
@@ -601,7 +628,7 @@ class CodeEmitterTask extends CompilerTask {
List buildLazyInitializerFunctionIfNecessary() {
if (!needsLazyInitializer) return [];
- return [js('# = #', [js(lazyInitializerName), lazyInitializerFunction])];
+ return [js('$lazyInitializerName = #', lazyInitializerFunction)];
}
List buildFinishIsolateConstructor() {
@@ -732,14 +759,15 @@ class CodeEmitterTask extends CompilerTask {
jsAst.FunctionDeclaration buildPrecompiledFunction() {
// TODO(ahe): Compute a hash code.
- return js.statement('''
- function dart_precompiled(\$collectedClasses) {
- var \$desc;
- #;
- return #;
- }''', [
- precompiledFunction,
- new jsAst.ArrayInitializer.from(precompiledConstructorNames)]);
+ String name = 'dart_precompiled';
+
+ precompiledFunction.add(
+ js.return_(
+ new jsAst.ArrayInitializer.from(precompiledConstructorNames)));
+ precompiledFunction.insert(0, js(r'var $desc'));
+ return new jsAst.FunctionDeclaration(
+ new jsAst.VariableDeclaration(name),
+ js.fun([r'$collectedClasses'], precompiledFunction));
}
void generateClass(ClassElement classElement, ClassBuilder properties) {
@@ -830,9 +858,8 @@ class CodeEmitterTask extends CompilerTask {
compiler.withCurrentElement(element, () {
Constant initialValue = handler.getInitialValueFor(element);
jsAst.Expression init =
- js('$isolateProperties.# = #',
- [namer.getNameOfGlobalField(element),
- constantEmitter.referenceInInitializationContext(initialValue)]);
+ js('$isolateProperties.${namer.getNameOfGlobalField(element)} = #',
+ constantEmitter.referenceInInitializationContext(initialValue));
buffer.write(jsAst.prettyPrint(init, compiler));
buffer.write('$N');
});
@@ -856,15 +883,17 @@ class CodeEmitterTask extends CompilerTask {
// lazyInitializer(prototype, 'name', fieldName, getterName, initial);
// The name is used for error reporting. The 'initial' must be a
// closure that constructs the initial value.
+ List<jsAst.Expression> arguments = <jsAst.Expression>[];
+ arguments.add(js(isolateProperties));
+ arguments.add(js.string(element.name));
+ arguments.add(js.string(namer.getNameX(element)));
+ arguments.add(js.string(namer.getLazyInitializerName(element)));
+ arguments.add(code);
jsAst.Expression getter = buildLazyInitializedGetter(element);
- jsAst.Expression init = js('#(#,#,#,#,#,#)',
- [js(lazyInitializerName),
- js(isolateProperties),
- js.string(element.name),
- js.string(namer.getNameX(element)),
- js.string(namer.getLazyInitializerName(element)),
- code,
- getter == null ? [] : [getter]]);
+ if (getter != null) {
+ arguments.add(getter);
+ }
+ jsAst.Expression init = js(lazyInitializerName)(arguments);
buffer.write(jsAst.prettyPrint(init, compiler));
buffer.write("$N");
}
@@ -899,9 +928,9 @@ class CodeEmitterTask extends CompilerTask {
String name = namer.constantName(constant);
if (constant.isList) emitMakeConstantListIfNotEmitted(buffer);
- jsAst.Expression init = js('#.# = #',
- [namer.globalObjectForConstant(constant), name,
- constantInitializerExpression(constant)]);
+ jsAst.Expression init = js(
+ '${namer.globalObjectForConstant(constant)}.$name = #',
+ constantInitializerExpression(constant));
buffer.write(jsAst.prettyPrint(init, compiler));
buffer.write('$N');
}
@@ -1165,15 +1194,15 @@ class CodeEmitterTask extends CompilerTask {
}
void emitInitFunction(CodeBuffer buffer) {
- jsAst.FunctionDeclaration decl = js.statement('''
- function init() {
- $isolateProperties = {};
- #; #; #;
- }''', [
- buildDefineClassAndFinishClassFunctionsIfNecessary(),
- buildLazyInitializerFunctionIfNecessary(),
- buildFinishIsolateConstructor()]);
-
+ jsAst.Fun fun = js.fun([], [
+ js('$isolateProperties = {}'),
+ ]
+ ..addAll(buildDefineClassAndFinishClassFunctionsIfNecessary())
+ ..addAll(buildLazyInitializerFunctionIfNecessary())
+ ..addAll(buildFinishIsolateConstructor())
+ );
+ jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration(
+ new jsAst.VariableDeclaration('init'), fun);
buffer.write(jsAst.prettyPrint(decl, compiler).getText());
if (compiler.enableMinification) buffer.write('\n');
}
@@ -1360,7 +1389,7 @@ mainBuffer.add(r'''
var map = new jsAst.ObjectInitializer(properties);
mainBuffer.write(
jsAst.prettyPrint(
- js.statement('init.mangledNames = #', map), compiler));
+ js('init.mangledNames = #', map).toStatement(), compiler));
if (compiler.enableMinification) {
mainBuffer.write(';');
}
@@ -1376,7 +1405,7 @@ mainBuffer.add(r'''
var map = new jsAst.ObjectInitializer(properties);
mainBuffer.write(
jsAst.prettyPrint(
- js.statement('init.mangledGlobalNames = #', map),
+ js('init.mangledGlobalNames = #', map).toStatement(),
compiler));
if (compiler.enableMinification) {
mainBuffer.write(';');

Powered by Google App Engine
This is Rietveld 408576698