Index: compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java |
=================================================================== |
--- compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java (revision 320) |
+++ compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java (working copy) |
@@ -174,7 +174,8 @@ |
private final DartCompilerContext context; |
private final OptimizationStrategy optStrategy; |
private final DartUnit unit; |
- private CoreTypeProvider typeProvider; |
+ private final CoreTypeProvider typeProvider; |
+ private final boolean generateClosureCompatibleCode; |
/** |
* Generates the Javascript AST using the names created in {@link GenerateNamesAndScopes}. |
@@ -182,6 +183,8 @@ |
static class GenerateJavascriptVisitor |
implements DartPlainVisitor<JsNode>, TraversalContextProvider { |
+ private final boolean generateClosureCompatibleCode; |
+ |
private static boolean isSuperCall(Symbol symbol) { |
return ElementKind.of(symbol).equals(ElementKind.SUPER); |
} |
@@ -252,13 +255,15 @@ |
public GenerateJavascriptVisitor(DartUnit unit, DartCompilerContext context, |
TranslationContext translationContext, |
- OptimizationStrategy optStrategy, CoreTypeProvider typeProvider) { |
+ OptimizationStrategy optStrategy, CoreTypeProvider typeProvider, |
+ boolean generateClosureCompatibleCode) { |
this.context = context; |
this.translationContext = translationContext; |
this.optStrategy = optStrategy; |
this.typeProvider = typeProvider; |
this.typeUtils = Types.getInstance(typeProvider); |
this.unitLibrary = unit.getLibrary().getElement(); |
+ this.generateClosureCompatibleCode = generateClosureCompatibleCode; |
// Cache the mangler in a field since it is used frequently |
mangler = translationContext.getMangler(); |
@@ -384,7 +389,7 @@ |
private void generateIsolateDefaultFactoryMember(MethodElement element, JsName funcName) { |
JsName className = getJsName(element.getEnclosingElement()); |
JsNameRef unmangledName = AstUtil.newNameRef(className.makeRef(), ISOLATE_DEFAULT_FACTORY); |
- JsNameRef factoryName = AstUtil.newNameRef(className.makeRef(), funcName); |
+ JsNameRef factoryName = AstUtil.nameref(null, className.makeRef(), funcName); |
JsBinaryOperation defaultAsg = AstUtil.newAssignment(unmangledName, factoryName); |
defaultAsg.setSourceRef(element.getNode()); |
globalBlock.getStatements().add(defaultAsg.makeStmt()); |
@@ -599,13 +604,13 @@ |
JsExpression methodToCall; |
if (methodElement.getModifiers().isStatic()) { |
// function() { return <class><member>$member; } |
- getterJsNameRef = AstUtil.newNameRef(classJsNameRef, getterJsName); |
+ getterJsNameRef = AstUtil.nameref(null, classJsNameRef, getterJsName); |
methodToCall = AstUtil.newNameRef(classJsNameRef, mangledMethodName); |
func.setBody(AstUtil.newBlock(new JsReturn(methodToCall))); |
} else { |
// function() { return $bind(<class>.prototype.<member>$member, this); } |
JsNameRef prototypeRef = AstUtil.newPrototypeNameRef(classJsNameRef); |
- getterJsNameRef = AstUtil.newNameRef(prototypeRef, getterJsName); |
+ getterJsNameRef = AstUtil.nameref(null, prototypeRef, getterJsName); |
methodToCall = AstUtil.newNameRef(prototypeRef, mangledMethodName); |
JsExpression bindMethodCall = AstUtil.newInvocation( |
new JsNameRef("$bind"), methodToCall, new JsThisRef()); |
@@ -662,7 +667,7 @@ |
FieldElement element, JsExpression prevPart) { |
JsExpression qualifier = getGetterSetterQualifier(element); |
JsName fieldJsName = getJsName(element); |
- JsNameRef ref = AstUtil.newNameRef(qualifier, fieldJsName); |
+ JsNameRef ref = AstUtil.nameref(null, qualifier, fieldJsName); |
// example: prevPart + ":" + $const_id(this.field) |
return add(prevPart, add(string(":"), |
@@ -799,7 +804,7 @@ |
} |
private JsExpression generateInlineFieldInitializer(DartField field) { |
- JsNameRef fieldName = AstUtil.newNameRef(new JsThisRef(), getJsName(field.getSymbol())); |
+ JsNameRef fieldName = AstUtil.nameref(null, new JsThisRef(), getJsName(field.getSymbol())); |
JsExpression initExpr = (JsExpression) generate(field.getValue()); |
return AstUtil.newAssignment(fieldName, initExpr); |
} |
@@ -912,7 +917,7 @@ |
// Call the initializer in the factory. This must be executed |
// before calling the super constructor: <class>.<name>$Initializer.call(this, ...) |
- JsNameRef initRef = AstUtil.newNameRef(curClassJsName.makeRef(), initJsName); |
+ JsNameRef initRef = AstUtil.nameref(null, curClassJsName.makeRef(), initJsName); |
JsNameRef initCallRef = AstUtil.newNameRef(initRef, "call"); |
JsInvocation initCall = AstUtil.newInvocation(initCallRef, tempVar.makeRef()); |
for (DartParameter p : params) { |
@@ -1001,7 +1006,7 @@ |
// necessary to ensure that the created temporary does not conflict with the parameters. |
JsInvocation constructorInvocation = new JsInvocation(); |
JsName constructorJsName = getJsName(element); |
- JsNameRef constructorRef = AstUtil.newNameRef(curClassJsName.makeRef(), constructorJsName); |
+ JsNameRef constructorRef = AstUtil.nameref(null, curClassJsName.makeRef(), constructorJsName); |
constructorInvocation.setQualifier(AstUtil.newNameRef(constructorRef, "call")); |
// Add the arguments to the constructor invocation. Note that the constructor call is still |
@@ -1178,20 +1183,25 @@ |
continue; |
} |
- JsNameRef ifExpr = AstUtil.newNameRef(namedParam.getName().makeRef(), |
- jsParam.getName()); |
+ JsExpression paramName; |
+ paramName = string(jsParam.getName().getShortIdent()); |
+ if (generateClosureCompatibleCode) { |
+ paramName = AstUtil.call(null, |
+ AstUtil.nameref(null, "JSCompiler_renameProperty"), paramName); |
+ } |
+ JsExpression ifExpr; |
+ ifExpr = AstUtil.in(null, paramName, namedParam.getName().makeRef()); |
JsPrefixOperation ppSeen = new JsPrefixOperation(JsUnaryOperator.INC, seen.makeRef()); |
- JsBinaryOperation thenExpr = new JsBinaryOperation(JsBinaryOperator.COMMA, ppSeen, |
- AstUtil.newNameRef(namedParam.getName().makeRef(), jsParam.getName())); |
+ JsBinaryOperation thenExpr = AstUtil.comma(null, ppSeen, |
+ AstUtil.nameref(null, namedParam.getName(), jsParam.getName())); |
JsExpression elseExpr; |
DartExpression defaultValue = param.getDefaultExpr(); |
if (defaultValue != null) { |
JsPrefixOperation ppDef = new JsPrefixOperation(JsUnaryOperator.INC, def.makeRef()); |
- elseExpr = new JsBinaryOperation(JsBinaryOperator.COMMA, ppDef, |
- generateDefaultValue(defaultValue)); |
+ elseExpr = AstUtil.comma( null, ppDef, generateDefaultValue(defaultValue)); |
} else { |
elseExpr = nulle(); |
} |
@@ -1224,7 +1234,7 @@ |
} |
JsInvocation jsInvoke = AstUtil.newInvocation( |
- AstUtil.newNameRef(origJsName.getQualifier(), origJsName.getName())); |
+ AstUtil.nameref(null, origJsName.getQualifier(), origJsName.getName())); |
if (preserveThis) { |
JsNameRef call = AstUtil.newNameRef(jsInvoke.getQualifier(), "call"); |
jsInvoke = AstUtil.newInvocation(call, new JsThisRef()); |
@@ -1294,7 +1304,7 @@ |
qualifier = AstUtil.newPrototypeNameRef(classJsName); |
} |
- JsNameRef prop = AstUtil.newNameRef(qualifier, name); |
+ JsNameRef prop = AstUtil.nameref(null, qualifier, name); |
// TODO(johnlenz): This should be the name node reference |
prop.setSourceRef(element.getNode()); |
return prop; |
@@ -1354,7 +1364,7 @@ |
private void makePropertyGetter(FieldElement element) { |
JsExpression qualifier = getGetterSetterQualifier(element); |
JsName fieldJsName = getJsName(element); |
- JsNameRef ref = AstUtil.newNameRef(qualifier, fieldJsName); |
+ JsNameRef ref = AstUtil.nameref(null, qualifier, fieldJsName); |
makeGetter(element, ref); |
} |
@@ -1452,7 +1462,7 @@ |
JsName t2 = scope.declareTemporary(); |
JsVars initializeT0 = AstUtil.newVar( |
- null, t0, AstUtil.newNameRef(fieldQualifier, fieldJsName)); |
+ null, t0, AstUtil.nameref(null, fieldQualifier, fieldJsName)); |
JsVars initializeT1 = AstUtil.newVar( |
null, t1, new JsNameRef(STATIC_INITIALIZING)); |
JsStatement checkIfCircular = new JsIf( |
@@ -1470,11 +1480,11 @@ |
new JsReturn(t0.makeRef()), |
null); |
JsStatement markField = AstUtil.newAssignment( |
- AstUtil.newNameRef(fieldQualifier, fieldJsName), t1.makeRef()).makeStmt(); |
+ AstUtil.nameref(null, fieldQualifier, fieldJsName), t1.makeRef()).makeStmt(); |
JsStatement initializeT2 = AstUtil.newVar( |
null, t2, initExpression); |
JsStatement initializeField = AstUtil.newAssignment( |
- AstUtil.newNameRef(fieldQualifier, fieldJsName), t2.makeRef()).makeStmt(); |
+ AstUtil.nameref(null, fieldQualifier, fieldJsName), t2.makeRef()).makeStmt(); |
JsStatement returnT2 = new JsReturn(t2.makeRef()); |
// Construct the method from the statements. |
@@ -1508,7 +1518,7 @@ |
JsExpression qualifier = getGetterSetterQualifier(element); |
JsName fieldJsName = getJsName(element); |
- JsNameRef ref = AstUtil.newNameRef(qualifier, fieldJsName); |
+ JsNameRef ref = AstUtil.nameref(null, qualifier, fieldJsName); |
JsBinaryOperation asg = AstUtil.newAssignment(ref, parameter.makeRef()); |
func.setBody(AstUtil.newBlock(new JsExprStmt(asg))); |
@@ -1521,7 +1531,7 @@ |
if (!x.isInvocation()) { |
JsName fieldJsName = getJsName(x.getName().getTargetSymbol()); |
assert fieldJsName != null : "Field name must have been resolved."; |
- JsNameRef field = AstUtil.newNameRef(new JsThisRef(), fieldJsName); |
+ JsNameRef field = AstUtil.nameref(null, new JsThisRef(), fieldJsName); |
e = AstUtil.newAssignment(field, e); |
e.setSourceRef(x); |
} |
@@ -1566,9 +1576,9 @@ |
JsNameRef fieldName; |
if (isDeclaredAsStaticOrImplicitlyStatic(element)) { |
JsExpression qualifier = getGetterSetterQualifier(element); |
- fieldName = AstUtil.newNameRef(qualifier, translationContext.getNames().getName(element)); |
+ fieldName = AstUtil.nameref(null, qualifier, translationContext.getNames().getName(element)); |
} else { |
- fieldName = AstUtil.newNameRef(new JsThisRef(), getJsName(element)); |
+ fieldName = AstUtil.nameref(null, new JsThisRef(), getJsName(element)); |
} |
JsExpression initExpr; |
@@ -3711,18 +3721,20 @@ |
} |
GenerateJavascriptAST(DartUnit unit, CoreTypeProvider typeProvider, DartCompilerContext context, |
- OptimizationStrategy optimizationStrategy) { |
+ OptimizationStrategy optimizationStrategy, |
+ boolean generateClosureCompatibleCode) { |
this.unit = unit; |
this.context = context; |
this.optStrategy = optimizationStrategy; |
this.typeProvider = typeProvider; |
+ this.generateClosureCompatibleCode = generateClosureCompatibleCode; |
} |
public void translateNode(TranslationContext translationContext, DartNode node, |
JsBlock blockStatics) { |
GenerateJavascriptVisitor generator = |
new GenerateJavascriptVisitor(unit, context, translationContext, |
- optStrategy, typeProvider); |
+ optStrategy, typeProvider, generateClosureCompatibleCode); |
// Generate the Javascript AST. |
node.accept(generator); |
// Set aside the static initializations |