Revision: 8522
Author: sco...@google.com
Date: Wed Aug 11 13:59:10 2010
Log: For synthetic this refs, use params rather than fields while in constructors

http://gwt-code-reviews.appspot.com/752801
Review by: tobyr

http://code.google.com/p/google-web-toolkit/source/detail?r=8522

Modified:
 /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java Mon Feb 8 08:29:30 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java Wed Aug 11 13:59:10 2010
@@ -25,10 +25,14 @@
    * Determines whether the variable is final, volatile, or neither.
    */
   public static enum Disposition {
-    COMPILE_TIME_CONSTANT, FINAL, NONE, VOLATILE;
+    COMPILE_TIME_CONSTANT, FINAL, NONE, THIS_REF, VOLATILE;

     public boolean isFinal() {
-      return this == COMPILE_TIME_CONSTANT || this == FINAL;
+ return this == COMPILE_TIME_CONSTANT || this == FINAL || this == THIS_REF;
+    }
+
+    public boolean isThisRef() {
+      return this == THIS_REF;
     }

     private boolean isCompileTimeConstant() {
@@ -43,6 +47,7 @@
   private final JDeclaredType enclosingType;
   private final boolean isCompileTimeConstant;
   private final boolean isStatic;
+  private boolean isThisRef;
   private boolean isVolatile;

JField(SourceInfo info, String name, JDeclaredType enclosingType, JType type,
@@ -52,6 +57,7 @@
     this.isStatic = isStatic;
     this.isCompileTimeConstant = disposition.isCompileTimeConstant();
     this.isVolatile = disposition.isVolatile();
+    this.isThisRef = disposition.isThisRef();
     // Disposition is not cached because we can be set final later.
   }

@@ -74,6 +80,10 @@
   public boolean isStatic() {
     return isStatic;
   }
+
+  public boolean isThisRef() {
+    return isThisRef;
+  }

   public boolean isVolatile() {
     return isVolatile;
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java Fri Aug 6 12:01:02 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java Wed Aug 11 13:59:10 2010
@@ -620,12 +620,12 @@
   }

   private JField createField(SyntheticArgumentBinding binding,
-      JDeclaredType enclosingType) {
+      JDeclaredType enclosingType, Disposition disposition) {
     JType type = getType(binding.type);
     SourceInfo info = enclosingType.getSourceInfo().makeChild(
BuildDeclMapVisitor.class, "Field " + String.valueOf(binding.name));
     JField field = program.createField(info, String.valueOf(binding.name),
-        enclosingType, type, false, Disposition.FINAL);
+        enclosingType, type, false, disposition);
     info.addCorrelation(program.getCorrelator().by(field));
     if (binding.matchingField != null) {
       typeMap.put(binding.matchingField, field);
@@ -841,7 +841,7 @@
for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) { SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
             if (arg.matchingField != null) {
-              createField(arg, type);
+              createField(arg, type, Disposition.THIS_REF);
             }
           }
         }
@@ -849,7 +849,7 @@
         if (nestedBinding.outerLocalVariables != null) {
for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) { SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
-            createField(arg, type);
+            createField(arg, type, Disposition.FINAL);
           }
         }
       }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java Fri Aug 6 12:01:02 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java Wed Aug 11 13:59:10 2010
@@ -103,6 +103,7 @@
 import com.google.gwt.dev.js.ast.JsProgram;
 import com.google.gwt.dev.util.JsniRef;
 import com.google.gwt.dev.util.collect.Lists;
+import com.google.gwt.dev.util.collect.Maps;
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
@@ -272,6 +273,8 @@

     private MethodScope currentMethodScope;

+    private Map<JField, JParameter> currentOuterThisRefParams;
+
     private int[] currentSeparatorPositions;

     private final boolean disableClassMetadata;
@@ -671,13 +674,6 @@
         currentMethod = ctor;
         currentMethodBody = ctor.getBody();
         currentMethodScope = x.scope;
-
-        JMethodCall superOrThisCall = null;
-        ExplicitConstructorCall ctorCall = x.constructorCall;
-        if (ctorCall != null) {
-          superOrThisCall = (JMethodCall) dispatch("processExpression",
-              ctorCall);
-        }

         /*
          * Determine if we have an explicit this call. The presence of an
@@ -686,11 +682,12 @@
          * steps are 1) assigning synthetic args to fields and 2) running
          * initializers.
          */
-        boolean hasExplicitThis = (ctorCall != null)
-            && !ctorCall.isSuperAccess();
+        boolean hasExplicitThis = (x.constructorCall != null)
+            && !x.constructorCall.isSuperAccess();

         JClassType enclosingType = ctor.getEnclosingType();
         JBlock block = currentMethodBody.getBlock();
+        currentOuterThisRefParams = Maps.create();

         /*
* All synthetic fields must be assigned, unless we have an explicit
@@ -710,6 +707,8 @@
                   block.addStmt(JProgram.createAssignmentStmt(info,
createVariableRef(info, field), createVariableRef(info,
                           param)));
+                  currentOuterThisRefParams = Maps.put(
+                      currentOuterThisRefParams, field, param);
                 }
               }
             }
@@ -726,20 +725,21 @@
             }
           }
         }
-
- // Enums: wire up synthetic name/ordinal params to the super method.
-        if (enclosingType.isEnumOrSubclass() != null) {
-          assert (superOrThisCall != null);
-          JVariableRef enumNameRef = createVariableRef(
-              superOrThisCall.getSourceInfo(), ctor.getParams().get(0));
-          superOrThisCall.addArg(0, enumNameRef);
-          JVariableRef enumOrdinalRef = createVariableRef(
-              superOrThisCall.getSourceInfo(), ctor.getParams().get(1));
-          superOrThisCall.addArg(1, enumOrdinalRef);
-        }

         // optional this or super constructor call
-        if (superOrThisCall != null) {
+        if (x.constructorCall != null) {
+          JMethodCall superOrThisCall = (JMethodCall) dispatch(
+              "processExpression", x.constructorCall);
+ // Enums: wire up synthetic name/ordinal params to the super method.
+          if (enclosingType.isEnumOrSubclass() != null) {
+            JVariableRef enumNameRef = createVariableRef(
+                superOrThisCall.getSourceInfo(), ctor.getParams().get(0));
+            superOrThisCall.addArg(0, enumNameRef);
+            JVariableRef enumOrdinalRef = createVariableRef(
+                superOrThisCall.getSourceInfo(), ctor.getParams().get(1));
+            superOrThisCall.addArg(1, enumOrdinalRef);
+          }
+
           superOrThisCall.setStaticDispatchOnly();
           block.addStmt(superOrThisCall.makeStatement());
         }
@@ -760,6 +760,7 @@
         // user code (finally!)
         block.addStmts(processStatements(x.statements));

+        currentOuterThisRefParams = null;
         currentMethodScope = null;
         currentMethod = null;
       } catch (Throwable e) {
@@ -1969,18 +1970,21 @@
       return call;
     }

-    private void addAllOuterThisRefs(List<? super JFieldRef> list,
+    private void addAllOuterThisRefs(List<? super JVariableRef> list,
         JExpression expr, JClassType classType) {
-      if (classType.getFields().size() > 0) {
-        JField field = classType.getFields().get(0);
-        /*
- * In some circumstances, the outer this ref can be captured as a local
-         * value (val$this), in other cases, as a this ref (this$).
-         *
- * TODO: investigate using more JDT node information as an alternative
-         */
-        if (field.getName().startsWith("this$")
-            || field.getName().startsWith("val$this$")) {
+      for (JField field : classType.getFields()) {
+        // This fields are always first.
+        if (!field.isThisRef()) {
+          break;
+        }
+        // In a constructor, use the local param instead of the field.
+        JParameter param = null;
+ if (currentOuterThisRefParams != null && expr instanceof JThisRef) {
+          param = currentOuterThisRefParams.get(field);
+        }
+        if (param != null) {
+          list.add(new JParameterRef(expr.getSourceInfo(), param));
+        } else {
           list.add(new JFieldRef(expr.getSourceInfo(), expr, field,
               currentClass));
         }
@@ -1988,7 +1992,8 @@
     }

     private void addAllOuterThisRefsPlusSuperChain(
- List<? super JFieldRef> workList, JExpression expr, JClassType classType) {
+        List<? super JVariableRef> workList, JExpression expr,
+        JClassType classType) {
       for (; classType != null; classType = classType.getSuperClass()) {
         addAllOuterThisRefs(workList, expr, classType);
       }

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to