mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
dart2js: Construct the entire output as a single AST before printing.
BUG= R=floitsch@google.com, sra@google.com Review URL: https://codereview.chromium.org//1140703006
This commit is contained in:
parent
6f6521ccb8
commit
03917ffe4d
9 changed files with 469 additions and 458 deletions
|
@ -296,11 +296,11 @@ class ConstantEmitter
|
|||
backend.classNeedsRti(type.element)) {
|
||||
InterfaceType interface = type;
|
||||
RuntimeTypes rti = backend.rti;
|
||||
Iterable<String> arguments = interface.typeArguments
|
||||
Iterable<jsAst.Expression> arguments = interface.typeArguments
|
||||
.map((DartType type) =>
|
||||
rti.getTypeRepresentationWithHashes(type, (_){}));
|
||||
rti.getTypeRepresentationWithPlaceholders(type, (_){}));
|
||||
jsAst.Expression argumentList =
|
||||
new jsAst.LiteralString('[${arguments.join(', ')}]');
|
||||
new jsAst.ArrayInitializer(arguments.toList());
|
||||
return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()),
|
||||
[value, argumentList]);
|
||||
}
|
||||
|
|
|
@ -550,15 +550,16 @@ class RuntimeTypes {
|
|||
}
|
||||
}
|
||||
|
||||
String getTypeRepresentationWithHashes(DartType type,
|
||||
OnVariableCallback onVariable) {
|
||||
jsAst.Expression getTypeRepresentationWithPlaceholders(DartType type,
|
||||
OnVariableCallback onVariable) {
|
||||
// Create a type representation. For type variables call the original
|
||||
// callback for side effects and return a template placeholder.
|
||||
int positions = 0;
|
||||
jsAst.Expression representation = getTypeRepresentation(type, (variable) {
|
||||
onVariable(variable);
|
||||
return new jsAst.LiteralString('#');
|
||||
return new jsAst.InterpolatedExpression(positions++);
|
||||
});
|
||||
return jsAst.prettyPrint(representation, compiler).buffer.toString();
|
||||
return representation;
|
||||
}
|
||||
|
||||
jsAst.Expression getTypeRepresentation(
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,35 +13,40 @@ class InterceptorEmitter extends CodeEmitterHelper {
|
|||
}
|
||||
}
|
||||
|
||||
void emitGetInterceptorMethod(CodeOutput output,
|
||||
String key,
|
||||
Set<ClassElement> classes) {
|
||||
jsAst.Expression buildGetInterceptorMethod(String key,
|
||||
Set<ClassElement> classes) {
|
||||
InterceptorStubGenerator stubGenerator =
|
||||
new InterceptorStubGenerator(compiler, namer, backend);
|
||||
jsAst.Expression function =
|
||||
stubGenerator.generateGetInterceptorMethod(classes);
|
||||
|
||||
output.addBuffer(jsAst.prettyPrint(
|
||||
js('${namer.globalObjectFor(backend.interceptorsLibrary)}.# = #',
|
||||
[key, function]),
|
||||
compiler));
|
||||
output.add(N);
|
||||
return function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit all versions of the [:getInterceptor:] method.
|
||||
*/
|
||||
void emitGetInterceptorMethods(CodeOutput output) {
|
||||
emitter.addComment('getInterceptor methods', output);
|
||||
jsAst.Statement buildGetInterceptorMethods() {
|
||||
List<jsAst.Statement> parts = <jsAst.Statement>[];
|
||||
|
||||
parts.add(js.comment('getInterceptor methods'));
|
||||
|
||||
Map<String, Set<ClassElement>> specializedGetInterceptors =
|
||||
backend.specializedGetInterceptors;
|
||||
for (String name in specializedGetInterceptors.keys.toList()..sort()) {
|
||||
Set<ClassElement> classes = specializedGetInterceptors[name];
|
||||
emitGetInterceptorMethod(output, name, classes);
|
||||
parts.add(
|
||||
js.statement('#.# = #',
|
||||
[namer.globalObjectFor(backend.interceptorsLibrary),
|
||||
name,
|
||||
buildGetInterceptorMethod(name, classes)]));
|
||||
}
|
||||
|
||||
return new jsAst.Block(parts);
|
||||
}
|
||||
|
||||
void emitOneShotInterceptors(CodeOutput output) {
|
||||
jsAst.Statement buildOneShotInterceptors() {
|
||||
List<jsAst.Statement> parts = <jsAst.Statement>[];
|
||||
List<String> names = backend.oneShotInterceptors.keys.toList();
|
||||
names.sort();
|
||||
|
||||
|
@ -51,12 +56,10 @@ class InterceptorEmitter extends CodeEmitterHelper {
|
|||
for (String name in names) {
|
||||
jsAst.Expression function =
|
||||
stubGenerator.generateOneShotInterceptor(name);
|
||||
jsAst.Expression assignment =
|
||||
js('${globalObject}.# = #', [name, function]);
|
||||
|
||||
output.addBuffer(jsAst.prettyPrint(assignment, compiler));
|
||||
output.add(N);
|
||||
parts.add(js.statement('${globalObject}.# = #', [name, function]));
|
||||
}
|
||||
|
||||
return new jsAst.Block(parts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,15 +90,12 @@ class InterceptorEmitter extends CodeEmitterHelper {
|
|||
* `findInterceptorForType`. See declaration of `typeToInterceptor` in
|
||||
* `interceptors.dart`.
|
||||
*/
|
||||
void emitTypeToInterceptorMap(Program program, CodeOutput output) {
|
||||
jsAst.Statement buildTypeToInterceptorMap(Program program) {
|
||||
jsAst.Expression array = program.typeToInterceptorMap;
|
||||
if (array == null) return;
|
||||
if (array == null) return js.comment("Empty type-to-interceptor map.");
|
||||
|
||||
jsAst.Expression typeToInterceptorMap = emitter
|
||||
.generateEmbeddedGlobalAccess(embeddedNames.TYPE_TO_INTERCEPTOR_MAP);
|
||||
jsAst.Expression assignment = js('# = #', [typeToInterceptorMap, array]);
|
||||
|
||||
output.addBuffer(jsAst.prettyPrint(assignment, compiler));
|
||||
output.add(N);
|
||||
return js.statement('# = #', [typeToInterceptorMap, array]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3559,17 +3559,17 @@ class SsaBuilder extends NewResolvedVisitor {
|
|||
InterfaceType interface = type;
|
||||
List<HInstruction> inputs = <HInstruction>[];
|
||||
bool first = true;
|
||||
List<String> templates = <String>[];
|
||||
List<js.Expression> templates = <js.Expression>[];
|
||||
for (DartType argument in interface.typeArguments) {
|
||||
templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) {
|
||||
templates.add(rti.getTypeRepresentationWithPlaceholders(argument, (variable) {
|
||||
HInstruction runtimeType = addTypeVariableReference(variable);
|
||||
inputs.add(runtimeType);
|
||||
}));
|
||||
}
|
||||
String template = '[${templates.join(', ')}]';
|
||||
// TODO(sra): This is a fresh template each time. We can't let the
|
||||
// template manager build them.
|
||||
js.Template code = js.js.uncachedExpressionTemplate(template);
|
||||
js.Template code = new js.Template(null,
|
||||
new js.ArrayInitializer(templates));
|
||||
HInstruction representation =
|
||||
new HForeignCode(code, backend.readableArrayType, inputs,
|
||||
nativeBehavior: native.NativeBehavior.PURE_ALLOCATION);
|
||||
|
@ -4618,11 +4618,12 @@ class SsaBuilder extends NewResolvedVisitor {
|
|||
|
||||
List<HInstruction> inputs = <HInstruction>[];
|
||||
|
||||
String template = rti.getTypeRepresentationWithHashes(argument, (variable) {
|
||||
inputs.add(addTypeVariableReference(variable));
|
||||
});
|
||||
js.Expression template =
|
||||
rti.getTypeRepresentationWithPlaceholders(argument, (variable) {
|
||||
inputs.add(addTypeVariableReference(variable));
|
||||
});
|
||||
|
||||
js.Template code = js.js.uncachedExpressionTemplate(template);
|
||||
js.Template code = new js.Template(null, template);
|
||||
HInstruction result = new HForeignCode(code, backend.stringType, inputs,
|
||||
nativeBehavior: native.NativeBehavior.PURE);
|
||||
add(result);
|
||||
|
|
|
@ -130,7 +130,6 @@ Future<Compiler> reuseCompiler(
|
|||
|
||||
backend.emitter.oldEmitter
|
||||
..outputBuffers.clear()
|
||||
..isolateProperties = null
|
||||
..classesCollector = null
|
||||
..mangledFieldNames.clear()
|
||||
..mangledGlobalFieldNames.clear()
|
||||
|
|
|
@ -329,8 +329,6 @@ class JsBuilder {
|
|||
/// [escapedString].
|
||||
LiteralString string(String value) => new LiteralString('"$value"');
|
||||
|
||||
LiteralString name(String name) => new LiteralString(name);
|
||||
|
||||
LiteralNumber number(num value) => new LiteralNumber('$value');
|
||||
|
||||
LiteralBool boolean(bool value) => new LiteralBool(value);
|
||||
|
|
|
@ -1156,9 +1156,13 @@ class OrderedSet<T> {
|
|||
// separate pass because JS vars are lifted to the top of the function.
|
||||
class VarCollector extends BaseVisitor {
|
||||
bool nested;
|
||||
bool enableRenaming = true;
|
||||
final OrderedSet<String> vars;
|
||||
final OrderedSet<String> params;
|
||||
|
||||
static final String disableVariableMinificationPattern = "::norenaming::";
|
||||
static final String enableVariableMinificationPattern = "::dorenaming::";
|
||||
|
||||
VarCollector() : nested = false,
|
||||
vars = new OrderedSet<String>(),
|
||||
params = new OrderedSet<String>();
|
||||
|
@ -1195,8 +1199,16 @@ class VarCollector extends BaseVisitor {
|
|||
|
||||
void visitThis(This node) {}
|
||||
|
||||
void visitComment(Comment node) {
|
||||
if (node.comment.contains(disableVariableMinificationPattern)) {
|
||||
enableRenaming = false;
|
||||
} else if (node.comment.contains(enableVariableMinificationPattern)) {
|
||||
enableRenaming = true;
|
||||
}
|
||||
}
|
||||
|
||||
void visitVariableDeclaration(VariableDeclaration decl) {
|
||||
if (decl.allowRename) vars.add(decl.name);
|
||||
if (enableRenaming && decl.allowRename) vars.add(decl.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ class Template {
|
|||
|
||||
Template(this.source, this.ast,
|
||||
{this.isExpression: true, this.forceCopy: false}) {
|
||||
assert(this.isExpression ? ast is Expression : ast is Statement);
|
||||
_compile();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue