Basic compiler support for varargs.

Review by: mmendez

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1487 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 de0dd89..a6e4313 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
@@ -711,11 +711,7 @@
       }
 
       // Plain old regular user arguments
-      if (x.arguments != null) {
-        for (int i = 0, n = x.arguments.length; i < n; ++i) {
-          call.getArgs().add(dispProcessExpression(x.arguments[i]));
-        }
-      }
+      addCallArgs(x.arguments, call, b);
 
       // Synthetic args for inner classes
       ReferenceBinding targetBinding = b.declaringClass;
@@ -1030,11 +1026,7 @@
       }
 
       // The arguments come first...
-      if (x.arguments != null) {
-        for (int i = 0, n = x.arguments.length; i < n; ++i) {
-          call.getArgs().add(dispProcessExpression(x.arguments[i]));
-        }
-      }
+      addCallArgs(x.arguments, call, x.binding);
 
       if (type != method.getType()) {
         // Must be a generic; insert a cast operation.
@@ -1136,11 +1128,7 @@
       }
 
       // Plain old regular arguments
-      if (x.arguments != null) {
-        for (int i = 0, n = x.arguments.length; i < n; ++i) {
-          call.getArgs().add(dispProcessExpression(x.arguments[i]));
-        }
-      }
+      addCallArgs(x.arguments, call, b);
 
       // Synthetic args for inner classes
       ReferenceBinding targetBinding = b.declaringClass;
@@ -1780,11 +1768,7 @@
       JExpression trueQualifier = createThisRef(info, currentClass);
       JMethodCall call = new JMethodCall(program, info, trueQualifier, ctor);
 
-      if (x.arguments != null) {
-        for (int i = 0, n = x.arguments.length; i < n; ++i) {
-          call.getArgs().add(dispProcessExpression(x.arguments[i]));
-        }
-      }
+      addCallArgs(x.arguments, call, x.binding);
 
       // We have to find and pass through any synthetics our supertype needs
       ReferenceBinding superClass = x.binding.declaringClass;
@@ -1854,11 +1838,7 @@
 
       assert (x.qualification == null);
 
-      if (x.arguments != null) {
-        for (int i = 0, n = x.arguments.length; i < n; ++i) {
-          call.getArgs().add(dispProcessExpression(x.arguments[i]));
-        }
-      }
+      addCallArgs(x.arguments, call, x.binding);
 
       // All synthetics must be passed through to the target ctor
       ReferenceBinding declaringClass = x.binding.declaringClass;
@@ -1898,6 +1878,50 @@
       }
     }
 
+    private void addCallArgs(Expression[] args, JMethodCall call,
+        MethodBinding binding) {
+      if (args != null) {
+        TypeBinding[] params = binding.parameters;
+        int n = params.length;
+
+        if (binding.isVarargs()) {
+          // Do everything but the last arg.
+          --n;
+        }
+
+        for (int i = 0; i < n; ++i) {
+          call.getArgs().add(dispProcessExpression(args[i]));
+        }
+
+        if (binding.isVarargs()) {
+          // Handle the last arg.
+          JArrayType type = (JArrayType) typeMap.get(params[n]);
+
+          // See if there is only one arg and it's an array of the correct dims.
+          if (args.length == n + 1) {
+            JType lastArgType = (JType) typeMap.get(args[n].resolvedType);
+            if (lastArgType instanceof JArrayType) {
+              JArrayType lastArgArrayType = (JArrayType) lastArgType;
+              if (lastArgArrayType.getDims() == type.getDims()) {
+                // Looks like it's already an array.
+                call.getArgs().add(dispProcessExpression(args[n]));
+                return;
+              }
+            }
+          }
+
+          // Fall through: must synthesize a new array allocation.
+          SourceInfo info = makeSourceInfo(args[n]);
+          JNewArray newArray = new JNewArray(program, info, type);
+          newArray.initializers = new ArrayList<JExpression>();
+          for (int i = n; i < args.length; ++i) {
+            newArray.initializers.add(dispProcessExpression(args[i]));
+          }
+          call.getArgs().add(newArray);
+        }
+      }
+    }
+
     private JExpression box(JExpression toBox, JClassType wrapperType) {
       JPrimitiveType primitiveType = getPrimitiveTypeForWrapperType(wrapperType);
       if (primitiveType == null) {