Reorder outer 'this' constructor arguments to come before user arguments.
The main purpose of this change is to remove the impedance mismatch between our constructor argument order, and the argument order for JSNI ::new() invocations. Our constructors put the synthetic this args after user args, JSNI ::new() puts the args before user args.
Once this impedance mismatch is cleared up, in a follow up change I plan to remove the static synthetic 'new' methods in favor of targeting the constructors directly.
http://gwt-code-reviews.appspot.com/675801/show
Review by: tobyr
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8365 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
index 44414f4..f81072f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -77,7 +77,6 @@
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -177,19 +176,11 @@
program.getTypePrimitiveInt(), true, false, newCtor);
}
- // user args
- mapParameters(newCtor, ctorDecl);
- addThrownExceptions(ctorDecl.binding, newCtor);
- // original params are now frozen
-
- info.addCorrelation(program.getCorrelator().by(newCtor));
-
- int syntheticParamCount = 0;
ReferenceBinding declaringClass = b.declaringClass;
+ Set<String> alreadyNamedVariables = new HashSet<String>();
if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
- // add synthetic args for outer this and locals
+ // add synthetic args for outer this
NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
- Set<String> alreadyNamedVariables = new HashSet<String>();
if (nestedBinding.enclosingInstances != null) {
for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
@@ -198,11 +189,22 @@
argName += "_" + i;
}
createParameter(arg, argName, newCtor);
- ++syntheticParamCount;
alreadyNamedVariables.add(argName);
}
}
+ }
+ // user args
+ mapParameters(newCtor, ctorDecl);
+ // original params are now frozen
+
+ addThrownExceptions(ctorDecl.binding, newCtor);
+
+ info.addCorrelation(program.getCorrelator().by(newCtor));
+
+ if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
+ // add synthetic args for locals
+ NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
if (nestedBinding.outerLocalVariables != null) {
for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
@@ -211,7 +213,6 @@
argName += "_" + i;
}
createParameter(arg, argName, newCtor);
- ++syntheticParamCount;
alreadyNamedVariables.add(argName);
}
}
@@ -222,11 +223,7 @@
// Now let's implicitly create a static function called 'new' that will
// allow construction from JSNI methods
if (!enclosingType.isAbstract()) {
- ReferenceBinding enclosingBinding = ctorDecl.binding.declaringClass.enclosingType();
- JReferenceType outerType = enclosingBinding == null ? null
- : (JReferenceType) typeMap.get(enclosingBinding);
- createSyntheticConstructor(newCtor,
- ctorDecl.binding.declaringClass.isStatic(), outerType);
+ createSyntheticConstructor(newCtor);
}
return true;
@@ -402,8 +399,7 @@
* constructed. This may be <code>null</code> if the class is a
* top-level type.
*/
- private JMethod createSyntheticConstructor(JConstructor constructor,
- boolean staticClass, JReferenceType enclosingType) {
+ private JMethod createSyntheticConstructor(JConstructor constructor) {
JClassType type = constructor.getEnclosingType();
// Define the method
@@ -420,41 +416,17 @@
"new instance"), constructor, type);
/*
- * If the type isn't static, make the first parameter a reference to the
- * instance of the enclosing class. It's the first instance to allow the
- * JSNI qualifier to be moved without affecting evaluation order.
- */
- JParameter enclosingInstance = null;
- if (!staticClass) {
- enclosingInstance = JProgram.createParameter(
- synthetic.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
- "outer instance"), "this$outer", enclosingType, false, false,
- synthetic);
- }
-
- /*
* In one pass, add the parameters to the synthetic constructor and
* arguments to the method call.
*/
- for (Iterator<JParameter> i = constructor.getParams().iterator(); i.hasNext();) {
- JParameter param = i.next();
- /*
- * This supports x.new Inner() by passing the enclosing instance
- * implicitly as the last argument to the constructor.
- */
- if (enclosingInstance != null && !i.hasNext()) {
- newInstance.addArg(new JParameterRef(
- synthetic.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
- "enclosing instance"), enclosingInstance));
- } else {
- JParameter syntheticParam = JProgram.createParameter(
- synthetic.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
- "Argument " + param.getName()), param.getName(),
- param.getType(), true, false, synthetic);
- newInstance.addArg(new JParameterRef(
- syntheticParam.getSourceInfo().makeChild(
- BuildDeclMapVisitor.class, "reference"), syntheticParam));
- }
+ for (JParameter param : constructor.getParams()) {
+ JParameter syntheticParam = JProgram.createParameter(
+ synthetic.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
+ "Argument " + param.getName()), param.getName(),
+ param.getType(), true, false, synthetic);
+ newInstance.addArg(new JParameterRef(
+ syntheticParam.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
+ "reference"), syntheticParam));
}
// Lock the method.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
index f5b512d..1075083 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -683,11 +683,10 @@
if (!hasExplicitThis) {
ReferenceBinding declaringClass = x.binding.declaringClass;
if (declaringClass instanceof NestedTypeBinding) {
- Iterator<JParameter> paramIt = getSyntheticsIterator();
+ Iterator<JParameter> paramIt = currentMethod.getParams().iterator();
NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
if (nestedBinding.enclosingInstances != null) {
- for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
- SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
+ for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
JParameter param = paramIt.next();
if (arg.matchingField != null) {
JField field = (JField) typeMap.get(arg);
@@ -698,9 +697,9 @@
}
}
+ paramIt = getSyntheticLocalsIterator();
if (nestedBinding.outerLocalVariables != null) {
- for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
- SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
+ for (SyntheticArgumentBinding arg : nestedBinding.outerLocalVariables) {
JParameter param = paramIt.next();
JField field = (JField) typeMap.get(arg);
block.addStmt(JProgram.createAssignmentStmt(info,
@@ -804,25 +803,28 @@
program.getLiteralInt(x.enumConstant.binding.original().id));
}
- // Plain old regular user arguments
- addCallArgs(x.arguments, call, b);
-
// Synthetic args for inner classes
ReferenceBinding targetBinding = b.declaringClass;
if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
// Synthetic this args for inner classes
if (nestedBinding.enclosingInstances != null) {
- for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
- SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
+ for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
JClassType syntheticThisType = (JClassType) typeMap.get(arg.type);
call.addArg(createThisRef(info, syntheticThisType));
}
}
+ }
+
+ // Plain old regular user arguments
+ addCallArgs(x.arguments, call, b);
+
+ // Synthetic args for inner classes
+ if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
+ NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
// Synthetic locals for local classes
if (nestedBinding.outerLocalVariables != null) {
- for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
- SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
+ for (SyntheticArgumentBinding arg : nestedBinding.outerLocalVariables) {
JVariable variable = (JVariable) typeMap.get(arg.actualOuterLocalVariable);
call.addArg(createVariableRef(info, variable,
arg.actualOuterLocalVariable));
@@ -1233,25 +1235,26 @@
qualList.add(implicitOuter);
}
- // Plain old regular arguments
- addCallArgs(x.arguments, newInstance, b);
-
- // Synthetic args for inner classes
+ // Synthetic this args for inner classes
ReferenceBinding targetBinding = b.declaringClass;
if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
- // Synthetic this args for inner classes
if (nestedBinding.enclosingInstances != null) {
- for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
- SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
+ for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
JClassType syntheticThisType = (JClassType) typeMap.get(arg.type);
newInstance.addArg(createThisRef(syntheticThisType, qualList));
}
}
- // Synthetic locals for local classes
+ }
+
+ // Plain old regular arguments
+ addCallArgs(x.arguments, newInstance, b);
+
+ // Synthetic locals for local classes
+ if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
+ NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
if (nestedBinding.outerLocalVariables != null) {
- for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
- SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
+ for (SyntheticArgumentBinding arg : nestedBinding.outerLocalVariables) {
JVariable variable = (JVariable) typeMap.get(arg.actualOuterLocalVariable);
newInstance.addArg(createVariableRef(info, variable,
arg.actualOuterLocalVariable));
@@ -1852,8 +1855,6 @@
JExpression trueQualifier = createThisRef(info, currentClass);
JMethodCall call = new JMethodCall(info, trueQualifier, ctor);
- addCallArgs(x.arguments, call, x.binding);
-
// We have to find and pass through any synthetics our supertype needs
ReferenceBinding superClass = x.binding.declaringClass;
if (superClass.isNestedType() && !superClass.isStatic()) {
@@ -1875,7 +1876,7 @@
* check each one to see if any will make a suitable this ref.
*/
List<JExpression> workList = new ArrayList<JExpression>();
- Iterator<JParameter> paramIt = getSyntheticsIterator();
+ Iterator<JParameter> paramIt = currentMethod.getParams().iterator();
for (ReferenceBinding b : myBinding.syntheticEnclosingInstanceTypes()) {
workList.add(createVariableRef(info, paramIt.next()));
}
@@ -1885,6 +1886,13 @@
}
}
}
+ }
+
+ addCallArgs(x.arguments, call, x.binding);
+
+ // We have to find and pass through any synthetics our supertype needs
+ if (superClass.isNestedType() && !superClass.isStatic()) {
+ ReferenceBinding superBinding = superClass;
// outer locals
if (superBinding.syntheticOuterLocalVariables() != null) {
@@ -1893,8 +1901,7 @@
JType varType = (JType) typeMap.get(arg.type);
String varName = String.valueOf(arg.name);
JParameter param = null;
- for (int i = 0; i < currentMethod.getParams().size(); ++i) {
- JParameter paramIt = currentMethod.getParams().get(i);
+ for (JParameter paramIt : currentMethod.getParams()) {
if (varType == paramIt.getType()
&& varName.equals(paramIt.getName())) {
param = paramIt;
@@ -1920,18 +1927,24 @@
assert (x.qualification == null);
- addCallArgs(x.arguments, call, x.binding);
-
- // All synthetics must be passed through to the target ctor
+ // All synthetic this args must be passed through to the target ctor
ReferenceBinding declaringClass = x.binding.declaringClass;
if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
- Iterator<JParameter> paramIt = getSyntheticsIterator();
+ Iterator<JParameter> paramIt = currentMethod.getParams().iterator();
NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(declaringClass);
if (nestedBinding.enclosingInstances != null) {
- for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
+ for (SyntheticArgumentBinding unused : nestedBinding.enclosingInstances) {
call.addArg(createVariableRef(info, paramIt.next()));
}
}
+ }
+
+ addCallArgs(x.arguments, call, x.binding);
+
+ // All synthetic locals must be passed through to the target ctor
+ if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
+ Iterator<JParameter> paramIt = getSyntheticLocalsIterator();
+ NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(declaringClass);
if (nestedBinding.outerLocalVariables != null) {
for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
call.addArg(createVariableRef(info, paramIt.next()));
@@ -2302,14 +2315,11 @@
/**
* Gets a JParameter iterator for a constructor method over its synthetic
- * parameters.
+ * local parameters.
*/
- private Iterator<JParameter> getSyntheticsIterator() {
- Iterator<JParameter> it = currentMethod.getParams().iterator();
- for (int i = 0, c = currentMethod.getOriginalParamTypes().size(); i < c; ++i) {
- it.next();
- }
- return it;
+ private Iterator<JParameter> getSyntheticLocalsIterator() {
+ return currentMethod.getParams().listIterator(
+ currentMethod.getOriginalParamTypes().size());
}
private void implementMethod(JMethod method, JExpression returnValue) {