| 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
|
|
|