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

Unified Diff: dart/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart

Issue 12208067: Build finishClasses from JS AST nodes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased Created 7 years, 10 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 | « dart/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/dart/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index 0343457b8aec8189c1000763d94f0e92de2705da..9c96a802db7d2750ecf599ba3a9645cdbb4f5e69 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -138,11 +138,11 @@ function(cls, desc) {
if (builder.properties.isEmpty) return;
String nativeTag = toNativeTag(classElement);
- js.Expression definition =
- js.call(js.use(defineNativeClassName),
- [js.string(nativeTag), builder.toObjectInitializer()]);
+ jsAst.Expression definition =
+ js[defineNativeClassName](
+ [js.string(nativeTag), builder.toObjectInitializer()]);
- nativeBuffer.add(js.prettyPrint(definition, compiler));
+ nativeBuffer.add(jsAst.prettyPrint(definition, compiler));
nativeBuffer.add('$N$n');
classesWithDynamicDispatch.add(classElement);
@@ -153,9 +153,10 @@ function(cls, desc) {
return result == null ? const<ClassElement>[] : result;
}
- void potentiallyConvertDartClosuresToJs(List<js.Statement> statements,
- FunctionElement member,
- List<js.Parameter> stubParameters) {
+ void potentiallyConvertDartClosuresToJs(
+ List<jsAst.Statement> statements,
+ FunctionElement member,
+ List<jsAst.Parameter> stubParameters) {
FunctionSignature parameters = member.computeSignature(compiler);
Element converter =
compiler.findHelper(const SourceString('convertDartClosureToJS'));
@@ -166,7 +167,7 @@ function(cls, desc) {
String name = parameter.name.slowToString();
// If [name] is not in [stubParameters], then the parameter is an optional
// parameter that was not provided for this stub.
- for (js.Parameter stubParameter in stubParameters) {
+ for (jsAst.Parameter stubParameter in stubParameters) {
if (stubParameter.name == name) {
DartType type = parameter.computeType(compiler).unalias(compiler);
if (type is FunctionType) {
@@ -175,11 +176,12 @@ function(cls, desc) {
int arity = type.computeArity();
statements.add(
- new js.ExpressionStatement(
+ new jsAst.ExpressionStatement(
js.assign(
- js.use(name),
- js.use(closureConverter).callWith(
- [js.use(name), new js.LiteralNumber('$arity')]))));
+ js[name],
+ js[closureConverter](
+ [js[name],
+ new jsAst.LiteralNumber('$arity')]))));
break;
}
}
@@ -187,11 +189,11 @@ function(cls, desc) {
});
}
- List<js.Statement> generateParameterStubStatements(
+ List<jsAst.Statement> generateParameterStubStatements(
Element member,
String invocationName,
- List<js.Parameter> stubParameters,
- List<js.Expression> argumentsBuffer,
+ List<jsAst.Parameter> stubParameters,
+ List<jsAst.Expression> argumentsBuffer,
int indexOfLastOptionalArgumentInParameters) {
// The target JS function may check arguments.length so we need to
// make sure not to pass any unspecified optional arguments to it.
@@ -205,11 +207,11 @@ function(cls, desc) {
ClassElement classElement = member.enclosingElement;
String nativeTagInfo = classElement.nativeTagInfo.slowToString();
- List<js.Statement> statements = <js.Statement>[];
+ List<jsAst.Statement> statements = <jsAst.Statement>[];
potentiallyConvertDartClosuresToJs(statements, member, stubParameters);
String target;
- List<js.Expression> arguments;
+ List<jsAst.Expression> arguments;
if (!nativeMethods.contains(member)) {
// When calling a method that has a native body, we call it with our
@@ -224,16 +226,16 @@ function(cls, desc) {
0, indexOfLastOptionalArgumentInParameters + 1);
}
statements.add(
- new js.Return(
- new js.VariableUse('this').dot(target).callWith(arguments)));
+ new jsAst.Return(
+ new jsAst.VariableUse('this')[target](arguments)));
if (!overriddenMethods.contains(member)) {
// Call the method directly.
return statements;
} else {
- return <js.Statement>[
+ return <jsAst.Statement>[
generateMethodBodyWithPrototypeCheck(
- invocationName, new js.Block(statements), stubParameters)];
+ invocationName, new jsAst.Block(statements), stubParameters)];
}
}
@@ -242,26 +244,24 @@ function(cls, desc) {
// super class. If the method is not available, we make a direct call to
// Object.prototype.$methodName. This method will patch the prototype of
// 'this' to the real method.
- js.Statement generateMethodBodyWithPrototypeCheck(
+ jsAst.Statement generateMethodBodyWithPrototypeCheck(
String methodName,
- js.Statement body,
- List<js.Parameter> parameters) {
+ jsAst.Statement body,
+ List<jsAst.Parameter> parameters) {
return js.if_(
- js.use('Object').dot('getPrototypeOf')
- .callWith([js.use('this')])
- .dot('hasOwnProperty').callWith([js.string(methodName)]),
+ js['Object']['getPrototypeOf']('this')['hasOwnProperty'](
+ js.string(methodName)),
body,
js.return_(
- js.use('Object').dot('prototype').dot(methodName).dot('call')
- .callWith(
- <js.Expression>[js.use('this')]..addAll(
- parameters.map((param) => js.use(param.name))))));
+ js['Object']['prototype'][methodName]['call'](
+ <jsAst.Expression>[js['this']]..addAll(
+ parameters.map((param) => js[param.name])))));
}
- js.Block generateMethodBodyWithPrototypeCheckForElement(
+ jsAst.Block generateMethodBodyWithPrototypeCheckForElement(
FunctionElement element,
- js.Block body,
- List<js.Parameter> parameters) {
+ jsAst.Block body,
+ List<jsAst.Parameter> parameters) {
ElementKind kind = element.kind;
if (kind != ElementKind.FUNCTION &&
kind != ElementKind.GETTER &&
@@ -270,7 +270,7 @@ function(cls, desc) {
}
String methodName = backend.namer.getName(element);
- return new js.Block(
+ return new jsAst.Block(
[generateMethodBodyWithPrototypeCheck(methodName, body, parameters)]);
}
@@ -322,23 +322,23 @@ function(cls, desc) {
// Temporary variables for common substrings.
List<String> varNames = <String>[];
// Values of temporary variables.
- Map<String, js.Expression> varDefns = new Map<String, js.Expression>();
+ Map<String, jsAst.Expression> varDefns = new Map<String, jsAst.Expression>();
// Expression to compute tags string for a class. The expression will
// initially be a string or expression building a string, but may be
// replaced with a variable reference to the common substring.
- Map<ClassElement, js.Expression> tagDefns =
- new Map<ClassElement, js.Expression>();
+ Map<ClassElement, jsAst.Expression> tagDefns =
+ new Map<ClassElement, jsAst.Expression>();
- js.Expression makeExpression(ClassElement classElement) {
+ jsAst.Expression makeExpression(ClassElement classElement) {
// Expression fragments for this set of cls keys.
- List<js.Expression> expressions = <js.Expression>[];
+ List<jsAst.Expression> expressions = <jsAst.Expression>[];
// TODO: Remove if cls is abstract.
List<String> subtags = [toNativeTag(classElement)];
void walk(ClassElement cls) {
for (final ClassElement subclass in getDirectSubclasses(cls)) {
ClassElement tag = subclass;
- js.Expression existing = tagDefns[tag];
+ jsAst.Expression existing = tagDefns[tag];
if (existing == null) {
// [subclass] is still within the subtree between dispatch classes.
subtags.add(toNativeTag(tag));
@@ -346,19 +346,19 @@ function(cls, desc) {
} else {
// [subclass] is one of the preorderDispatchClasses, so CSE this
// reference with the previous reference.
- js.VariableUse use = existing.asVariableUse();
+ jsAst.VariableUse use = existing.asVariableUse();
if (use != null && varDefns.containsKey(use.name)) {
// We end up here if the subclasses have a DAG structure. We
// don't have DAGs yet, but if the dispatch is used for mixins
// that will be a possibility.
// Re-use the previously created temporary variable.
- expressions.add(new js.VariableUse(use.name));
+ expressions.add(new jsAst.VariableUse(use.name));
} else {
String varName = 'v${varNames.length}_${tag.name.slowToString()}';
varNames.add(varName);
varDefns[varName] = existing;
- tagDefns[tag] = new js.VariableUse(varName);
- expressions.add(new js.VariableUse(varName));
+ tagDefns[tag] = new jsAst.VariableUse(varName);
+ expressions.add(new jsAst.VariableUse(varName));
}
}
}
@@ -368,12 +368,12 @@ function(cls, desc) {
if (!subtags.isEmpty) {
expressions.add(js.string(subtags.join('|')));
}
- js.Expression expression;
+ jsAst.Expression expression;
if (expressions.length == 1) {
expression = expressions[0];
} else {
- js.Expression array = new js.ArrayInitializer.from(expressions);
- expression = js.call(array.dot('join'), [js.string('|')]);
+ jsAst.Expression array = new jsAst.ArrayInitializer.from(expressions);
+ expression = array['join']([js.string('|')]);
}
return expression;
}
@@ -384,46 +384,47 @@ function(cls, desc) {
// Write out a thunk that builds the metadata.
if (!tagDefns.isEmpty) {
- List<js.Statement> statements = <js.Statement>[];
+ List<jsAst.Statement> statements = <jsAst.Statement>[];
- List<js.VariableInitialization> initializations =
- <js.VariableInitialization>[];
+ List<jsAst.VariableInitialization> initializations =
+ <jsAst.VariableInitialization>[];
for (final String varName in varNames) {
initializations.add(
- new js.VariableInitialization(
- new js.VariableDeclaration(varName),
+ new jsAst.VariableInitialization(
+ new jsAst.VariableDeclaration(varName),
varDefns[varName]));
}
if (!initializations.isEmpty) {
statements.add(
- new js.ExpressionStatement(
- new js.VariableDeclarationList(initializations)));
+ new jsAst.ExpressionStatement(
+ new jsAst.VariableDeclarationList(initializations)));
}
// [table] is a list of lists, each inner list of the form:
// [dynamic-dispatch-tag, tags-of-classes-implementing-dispatch-tag]
// E.g.
// [['Node', 'Text|HTMLElement|HTMLDivElement|...'], ...]
- js.Expression table =
- new js.ArrayInitializer.from(
+ jsAst.Expression table =
+ new jsAst.ArrayInitializer.from(
preorderDispatchClasses.map((cls) =>
- new js.ArrayInitializer.from([
+ new jsAst.ArrayInitializer.from([
js.string(toNativeTag(cls)),
tagDefns[cls]])));
// $.dynamicSetMetadata(table);
statements.add(
- new js.ExpressionStatement(
- new js.Call(
- new js.VariableUse(dynamicSetMetadataName),
+ new jsAst.ExpressionStatement(
+ new jsAst.Call(
+ new jsAst.VariableUse(dynamicSetMetadataName),
[table])));
// (function(){statements})();
if (emitter.compiler.enableMinification) nativeBuffer.add(';');
nativeBuffer.add(
- js.prettyPrint(
- new js.ExpressionStatement(
- new js.Call(new js.Fun([], new js.Block(statements)), [])),
+ jsAst.prettyPrint(
+ new jsAst.ExpressionStatement(
+ new jsAst.Call(new jsAst.Fun([], new jsAst.Block(statements)),
+ [])),
compiler));
}
}
@@ -460,10 +461,10 @@ function(cls, desc) {
targetBuffer.add('$defineNativeClassName = '
'$defineNativeClassFunction$N$n');
- List<js.Property> objectProperties = <js.Property>[];
+ List<jsAst.Property> objectProperties = <jsAst.Property>[];
- void addProperty(String name, js.Expression value) {
- objectProperties.add(new js.Property(js.string(name), value));
+ void addProperty(String name, jsAst.Expression value) {
+ objectProperties.add(new jsAst.Property(js.string(name), value));
}
// Because of native classes, we have to generate some is checks
@@ -478,16 +479,14 @@ function(cls, desc) {
if (element.isObject(compiler)) continue;
String name = backend.namer.operatorIs(element);
addProperty(name,
- js.fun([], js.block1(js.return_(new js.LiteralBool(false)))));
+ js.fun([], js.return_(new jsAst.LiteralBool(false))));
}
}
emitIsChecks();
- js.Expression makeCallOnThis(String functionName) =>
- js.fun([],
- js.block1(
- js.return_(
- js.call(js.use(functionName), [js.use('this')]))));
+ jsAst.Expression makeCallOnThis(String functionName) {
+ return js.fun([], js.return_(js[functionName]('this')));
+ }
// In order to have the toString method on every native class,
// we must patch the JS Object prototype with a helper method.
@@ -503,8 +502,8 @@ function(cls, desc) {
// Same as above, but for operator==.
String equalsName = backend.namer.publicInstanceMethodNameByArity(
const SourceString('=='), 1);
- addProperty(equalsName, js.fun(['a'], js.block1(
- js.return_(js.strictEquals(new js.This(), js.use('a'))))));
+ addProperty(equalsName, js.fun(['a'],
+ js.return_(js.strictEquals(new jsAst.This(), js['a']))));
// If the native emitter has been asked to take care of the
// noSuchMethod handlers, we do that now.
@@ -515,28 +514,25 @@ function(cls, desc) {
// If we have any properties to add to Object.prototype, we run
// through them and add them using defineProperty.
if (!objectProperties.isEmpty) {
- js.Expression init =
- js.call(
- js.fun(['table'],
- js.block1(
- new js.ForIn(
- new js.VariableDeclarationList(
- [new js.VariableInitialization(
- new js.VariableDeclaration('key'),
- null)]),
- js.use('table'),
- new js.ExpressionStatement(
- js.call(
- js.use(defPropName),
- [js.use('Object').dot('prototype'),
- js.use('key'),
- new js.PropertyAccess(js.use('table'),
- js.use('key'))]))))),
- [new js.ObjectInitializer(objectProperties)]);
+ jsAst.Expression init =
+ js.fun(['table'],
+ new jsAst.ForIn(
+ new jsAst.VariableDeclarationList(
+ [new jsAst.VariableInitialization(
+ new jsAst.VariableDeclaration('key'),
+ null)]),
+ js['table'],
+ new jsAst.ExpressionStatement(
+ js[defPropName](
+ [js['Object']['prototype'],
+ js['key'],
+ new jsAst.PropertyAccess(js['table'],
+ js['key'])]))))(
+ new jsAst.ObjectInitializer(objectProperties));
if (emitter.compiler.enableMinification) targetBuffer.add(';');
- targetBuffer.add(js.prettyPrint(
- new js.ExpressionStatement(init), compiler));
+ targetBuffer.add(jsAst.prettyPrint(
+ new jsAst.ExpressionStatement(init), compiler));
targetBuffer.add('\n');
}
« no previous file with comments | « dart/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698