Revision: 7045
Author: [email protected]
Date: Thu Nov 19 14:34:20 2009
Log: trunk c7033-c7039 were merged into this branch
   Fixes an NPE in JsniChecker; improves test coverage on JsniCollector and  
JsniChecker.
   JsniChecker should support the "::new" syntax.
   In JsniChecker, suppressed warnings should cascade down to nested members.
   JUnit's -noserver option was not actually doing anything useful.
   GWTShell must not link public and autogenerated artifacts into the shell  
generated resource directory.
   Fix up native lines + mime type svn props.
     svn merge --ignore-ancestry -r7032:7039  
https://google-web-toolkit.googlecode.com/svn/trunk/ .


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

Added:
  /releases/2.0/dev/core/test/com/google/gwt/dev/javac/JsniCollectorTest.java
Modified:
  /releases/2.0/branch-info.txt
  /releases/2.0/dev/core/src/com/google/gwt/dev/DevMode.java
  /releases/2.0/dev/core/src/com/google/gwt/dev/DevModeBase.java
  /releases/2.0/dev/core/src/com/google/gwt/dev/GWTShell.java
  /releases/2.0/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java
   
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
   
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java
  /releases/2.0/dev/core/test/com/google/gwt/dev/javac/JsniCheckerTest.java
   
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/impl/StaticJavaResource.java
  /releases/2.0/user/src/com/google/gwt/junit/JUnitShell.java
   
/releases/2.0/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java

=======================================
--- /dev/null
+++  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/JsniCollectorTest.java     
 
Thu Nov 19 14:34:20 2009
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may  
not
+ * use this file except in compliance with the License. You may obtain a  
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.dev.javac;
+
+import com.google.gwt.dev.javac.impl.StaticJavaResource;
+import com.google.gwt.dev.jjs.SourceInfo;
+import com.google.gwt.dev.js.ast.JsContext;
+import com.google.gwt.dev.js.ast.JsExpression;
+import com.google.gwt.dev.js.ast.JsNameRef;
+import com.google.gwt.dev.js.ast.JsVisitor;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests {...@link JsniCollector}.
+ */
+public class JsniCollectorTest extends CompilationStateTestBase {
+
+  /**
+   * TODO: currently JSNI does not parse character position. Turn this on  
(and
+   * delete it, actually) when it does.
+   */
+  public static final boolean JSNI_PARSES_SOURCE_POSITION = false;
+
+  public void testErrorPosition() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Foo {\n");
+    code.append("  native void m(Object o) /*-{\n");
+    code.append("    o...@foo::m(Ljava/lang/String);\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    String source = code.toString();
+
+    CategorizedProblem[] problems = getProblems("Foo", source);
+    assertEquals(1, problems.length);
+    CategorizedProblem problem = problems[0];
+    if (JSNI_PARSES_SOURCE_POSITION) {
+      assertEquals(source.indexOf('@'), problem.getSourceStart());
+    }
+    assertEquals(3, problem.getSourceLineNumber());
+    assertTrue(problem.isWarning());
+    assertEquals(
+        "Referencing method 'Foo.m(Ljava/lang/String)': unable to resolve  
method, expect subsequent failures",
+        problem.getMessage());
+  }
+
+  public void testMalformedJsniRefPosition() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Foo {\n");
+    code.append("  native void m() /*-{\n");
+    code.append("    @Bar;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    String source = code.toString();
+    CategorizedProblem[] problems = getProblems("Foo", source);
+    assertEquals(1, problems.length);
+    CategorizedProblem problem = problems[0];
+    assertEquals(source.indexOf('@') + "Bar".length(),  
problem.getSourceStart());
+    assertEquals(3, problem.getSourceLineNumber());
+    assertTrue(problem.isError());
+    assertEquals("Expected \":\" in JSNI reference", problem.getMessage());
+  }
+
+  public void testMalformedJsniRefPositionWithExtraLines() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Foo {\n");
+    code.append("  native\nvoid\nm()\n\n\n/*-{\n\n");
+    code.append("    @Bar;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    String source = code.toString();
+    CategorizedProblem[] problems = getProblems("Foo", source);
+    assertEquals(1, problems.length);
+    CategorizedProblem problem = problems[0];
+    assertEquals(source.indexOf('@') + "Bar".length(),  
problem.getSourceStart());
+    assertEquals(9, problem.getSourceLineNumber());
+    assertTrue(problem.isError());
+    assertEquals("Expected \":\" in JSNI reference", problem.getMessage());
+  }
+
+  public void testSourcePosition() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Foo {\n");
+    code.append("  native void m(Object o) /*-{\n");
+    code.append("    o...@foo::m(Ljava/lang/Object);\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    String source = code.toString();
+
+    List<JsNameRef> foundRefs = findJsniRefs("Foo", source);
+    assertEquals(1, foundRefs.size());
+    JsNameRef ref = foundRefs.get(0);
+    SourceInfo info = ref.getSourceInfo();
+    if (JSNI_PARSES_SOURCE_POSITION) {
+      assertEquals(source.indexOf('@'), info.getStartPos());
+    }
+    assertEquals(3, info.getStartLine());
+  }
+
+  private List<JsNameRef> findJsniRefs(String typeName, final String  
source) {
+    addGeneratedUnits(new StaticJavaResource(typeName, source));
+    CompilationUnit unit = state.getCompilationUnitMap().get(typeName);
+    assertNotNull(unit);
+    List<JsniMethod> jsniMethods = unit.getJsniMethods();
+    assertEquals(1, jsniMethods.size());
+    JsniMethod jsniMethod = jsniMethods.get(0);
+    final List<JsNameRef> foundRefs = new ArrayList<JsNameRef>();
+    new JsVisitor() {
+      @Override
+      public void endVisit(JsNameRef x, JsContext<JsExpression> ctx) {
+        if (x.getIdent().startsWith("@")) {
+          foundRefs.add(x);
+        }
+      }
+    }.accept(jsniMethod.function());
+    return foundRefs;
+  }
+
+  private CategorizedProblem[] getProblems(String typeName, String source)  
{
+    addGeneratedUnits(new StaticJavaResource(typeName, source));
+    CompilationUnit unit = state.getCompilationUnitMap().get(typeName);
+    assertNotNull(unit);
+    CategorizedProblem[] problems = unit.getProblems();
+    return problems;
+  }
+}
=======================================
--- /releases/2.0/branch-info.txt       Thu Nov 19 14:17:04 2009
+++ /releases/2.0/branch-info.txt       Thu Nov 19 14:34:20 2009
@@ -837,6 +837,15 @@
      svn merge --ignore-ancestry -c7027 \
        https://google-web-toolkit.googlecode.com/svn/trunk/ .

+trunk c7033-c7039 were merged into this branch
+  Fixes an NPE in JsniChecker; improves test coverage on JsniCollector and  
JsniChecker.
+  JsniChecker should support the "::new" syntax.
+  In JsniChecker, suppressed warnings should cascade down to nested  
members.
+  JUnit's -noserver option was not actually doing anything useful.
+  GWTShell must not link public and autogenerated artifacts into the shell  
generated resource directory.
+  Fix up native lines + mime type svn props.
+    svn merge --ignore-ancestry -r7032:7039  
https://google-web-toolkit.googlecode.com/svn/trunk/ .
+
  tr...@7041 was merged into this branch
    Making CookieTest use client time to set cookie expiration.
    svn merge --ignore-ancestry -c 7041  
https://google-web-toolkit.googlecode.com/svn/trunk .
=======================================
--- /releases/2.0/dev/core/src/com/google/gwt/dev/DevMode.java  Wed Nov 18  
14:09:08 2009
+++ /releases/2.0/dev/core/src/com/google/gwt/dev/DevMode.java  Thu Nov 19  
14:34:20 2009
@@ -376,10 +376,11 @@

    @Override
    protected synchronized void produceOutput(TreeLogger logger,
-      StandardLinkerContext linkerStack, ArtifactSet artifacts, ModuleDef  
module)
-      throws UnableToCompleteException {
+      StandardLinkerContext linkerStack, ArtifactSet artifacts,
+      ModuleDef module, boolean isRelink) throws UnableToCompleteException  
{
      File moduleOutDir = new File(options.getWarDir(), module.getName());
      linkerStack.produceOutputDirectory(logger, artifacts, moduleOutDir);
+
      if (options.getExtraDir() != null) {
        File moduleExtraDir = new File(options.getExtraDir(),  
module.getName());
        linkerStack.produceExtraDirectory(logger, artifacts, moduleExtraDir);
=======================================
--- /releases/2.0/dev/core/src/com/google/gwt/dev/DevModeBase.java      Thu Nov 
 
19 13:50:21 2009
+++ /releases/2.0/dev/core/src/com/google/gwt/dev/DevModeBase.java      Thu Nov 
 
19 14:34:20 2009
@@ -866,7 +866,7 @@
      StandardLinkerContext linkerStack = new  
StandardLinkerContext(linkLogger,
          module, options);
      ArtifactSet artifacts = linkerStack.invokeLink(linkLogger);
-    produceOutput(linkLogger, linkerStack, artifacts, module);
+    produceOutput(linkLogger, linkerStack, artifacts, module, false);
      return linkerStack;
    }

@@ -921,8 +921,8 @@
    }

    protected abstract void produceOutput(TreeLogger logger,
-      StandardLinkerContext linkerStack, ArtifactSet artifacts, ModuleDef  
module)
-      throws UnableToCompleteException;
+      StandardLinkerContext linkerStack, ArtifactSet artifacts,
+      ModuleDef module, boolean isRelink) throws UnableToCompleteException;

    protected final void setDone() {
      blockUntilDone.release();
@@ -1008,6 +1008,6 @@

      ArtifactSet artifacts = linkerContext.invokeRelink(linkLogger,
          newlyGeneratedArtifacts);
-    produceOutput(linkLogger, linkerContext, artifacts, module);
+    produceOutput(linkLogger, linkerContext, artifacts, module, true);
    }
  }
=======================================
--- /releases/2.0/dev/core/src/com/google/gwt/dev/GWTShell.java Mon Nov 16  
19:22:20 2009
+++ /releases/2.0/dev/core/src/com/google/gwt/dev/GWTShell.java Thu Nov 19  
14:34:20 2009
@@ -199,7 +199,7 @@
      TreeLogger logger = ui.getWebServerLogger("Tomcat", null);
      // TODO(bruce): make tomcat work in terms of the modular launcher
      String whyFailed = EmbeddedTomcatServer.start(isHeadless() ?  
getTopLogger()
-        : logger, getPort(), options);
+        : logger, getPort(), options, shouldAutoGenerateResources());

      if (whyFailed != null) {
        getTopLogger().log(TreeLogger.ERROR, "Starting Tomcat: " +  
whyFailed);
@@ -209,9 +209,21 @@
    }

    protected synchronized void produceOutput(TreeLogger logger,
-      StandardLinkerContext linkerStack, ArtifactSet artifacts, ModuleDef  
module)
-      throws UnableToCompleteException {
-    File moduleOutDir = options.getShellPublicGenDir(module);
-    linkerStack.produceOutputDirectory(logger, artifacts, moduleOutDir);
+      StandardLinkerContext linkerStack, ArtifactSet artifacts,
+      ModuleDef module, boolean isRelink) throws UnableToCompleteException  
{
+    /*
+     * Legacy: in GWTShell we only copy generated artifacts into the  
public gen
+     * folder. Public files and "autogen" files have special handling (that
+     * needs to die).
+     */
+    if (isRelink) {
+      File outputDir = options.getShellPublicGenDir(module);
+      outputDir.mkdirs();
+      linkerStack.produceOutputDirectory(logger, artifacts, outputDir);
+    }
+  }
+
+  protected boolean shouldAutoGenerateResources() {
+    return true;
    }
  }
=======================================
--- /releases/2.0/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java        
 
Fri Nov 13 08:09:56 2009
+++ /releases/2.0/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java        
 
Thu Nov 19 14:34:20 2009
@@ -39,14 +39,19 @@
  import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
  import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.TypeReference;
  import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
  import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
  import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
  import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
  import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
  import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
  import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
  import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
  import org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding;
@@ -54,6 +59,7 @@
  import java.util.Locale;
  import java.util.Map;
  import java.util.Set;
+import java.util.Stack;

  /**
   * Tests for access to Java from JSNI. Issues a warning for:
@@ -84,8 +90,47 @@
            checkDecl(meth, scope);
          }
          JsniMethod jsniMethod = jsniMethods.get(meth);
-        new JsniRefChecker(meth,  
hasUnsafeLongsAnnotation).check(jsniMethod.function());
-      }
+        if (jsniMethod != null) {
+          new JsniRefChecker(meth,  
hasUnsafeLongsAnnotation).check(jsniMethod.function());
+        }
+      }
+      suppressWarningsStack.pop();
+    }
+
+    public void endVisit(TypeDeclaration typeDeclaration, BlockScope  
scope) {
+      suppressWarningsStack.pop();
+    }
+
+    public void endVisit(TypeDeclaration typeDeclaration, ClassScope  
scope) {
+      suppressWarningsStack.pop();
+    }
+
+    public void endVisit(TypeDeclaration typeDeclaration,
+        CompilationUnitScope scope) {
+      suppressWarningsStack.pop();
+    }
+
+    @Override
+    public boolean visit(MethodDeclaration meth, ClassScope scope) {
+      suppressWarningsStack.push(getSuppressedWarnings(meth.annotations));
+      return true;
+    }
+
+    public boolean visit(TypeDeclaration typeDeclaration, BlockScope  
scope) {
+       
suppressWarningsStack.push(getSuppressedWarnings(typeDeclaration.annotations));
+      return true;
+    }
+
+    @Override
+    public boolean visit(TypeDeclaration typeDeclaration, ClassScope  
scope) {
+       
suppressWarningsStack.push(getSuppressedWarnings(typeDeclaration.annotations));
+      return true;
+    }
+
+    public boolean visit(TypeDeclaration typeDeclaration,
+        CompilationUnitScope scope) {
+       
suppressWarningsStack.push(getSuppressedWarnings(typeDeclaration.annotations));
+      return true;
      }

      private void checkDecl(MethodDeclaration meth, ClassScope scope) {
@@ -121,13 +166,11 @@
      private transient SourceInfo errorInfo;
      private final boolean hasUnsafeLongsAnnotation;
      private final MethodDeclaration method;
-    private final Set<String> suppressWarnings;

      public JsniRefChecker(MethodDeclaration method,
          boolean hasUnsafeLongsAnnotation) {
        this.method = method;
        this.hasUnsafeLongsAnnotation = hasUnsafeLongsAnnotation;
-      this.suppressWarnings = getSuppressedWarnings(method);
      }

      public void check(JsFunction function) {
@@ -156,6 +199,9 @@
        }
        FieldBinding target = getField(clazz, jsniRef);
        if (target == null) {
+        emitWarning("jsni", "Referencing field '" + jsniRef.className()  
+ "."
+            + jsniRef.memberName()
+            + "': unable to resolve field, expect subsequent failures");
          return;
        }
        if (target.isDeprecated()) {
@@ -177,6 +223,9 @@
        assert jsniRef.isMethod();
        MethodBinding target = getMethod(clazz, jsniRef);
        if (target == null) {
+        emitWarning("jsni", "Referencing method '" + jsniRef.className()  
+ "."
+            + jsniRef.memberSignature()
+            + "': unable to resolve method, expect subsequent failures");
          return;
        }
        if (target.isDeprecated()) {
@@ -262,7 +311,7 @@
          }
        } else {
          emitWarning("jsni", "Referencing class '" + className
-            + ": unable to resolve class, expect subsequent failures");
+            + "': unable to resolve class, expect subsequent failures");
        }
      }

@@ -271,9 +320,11 @@
      }

      private void emitWarning(String category, String msg) {
-      if (suppressWarnings.contains(category)
-          || suppressWarnings.contains("all")) {
-        return;
+      for (Set<String> suppressWarnings : suppressWarningsStack) {
+        if (suppressWarnings.contains(category)
+            || suppressWarnings.contains("all")) {
+          return;
+        }
        }
        JsniCollector.reportJsniWarning(errorInfo, method, msg);
      }
@@ -299,46 +350,40 @@

      private MethodBinding getMethod(ReferenceBinding clazz, JsniRef  
jsniRef) {
        assert jsniRef.isMethod();
-      for (MethodBinding findMethod :  
clazz.getMethods(jsniRef.memberName().toCharArray())) {
-        if (paramTypesMatch(findMethod, jsniRef)) {
-          return findMethod;
-        }
-      }
-      return null;
-    }
-
-    private Set<String> getSuppressedWarnings(MethodDeclaration method) {
-      Annotation[] annotations = method.annotations;
-      if (annotations == null) {
-        return Sets.create();
-      }
-
-      for (Annotation a : annotations) {
-        if (SuppressWarnings.class.getName().equals(
-            CharOperation.toString(((ReferenceBinding)  
a.resolvedType).compoundName))) {
-          for (MemberValuePair pair : a.memberValuePairs()) {
-            if (String.valueOf(pair.name).equals("value")) {
-              Expression valueExpr = pair.value;
-              if (valueExpr instanceof StringLiteral) {
-                // @SuppressWarnings("Foo")
-                return Sets.create(((StringLiteral)  
valueExpr).constant.stringValue().toLowerCase(Locale.ENGLISH));
-              } else if (valueExpr instanceof ArrayInitializer) {
-                // @SuppressWarnings({ "Foo", "Bar"})
-                ArrayInitializer ai = (ArrayInitializer) valueExpr;
-                String[] values = new String[ai.expressions.length];
-                for (int i = 0, j = values.length; i < j; i++) {
-                  values[i] = ((StringLiteral)  
ai.expressions[i]).constant.stringValue().toLowerCase(Locale.ENGLISH);
-                }
-                return Sets.create(values);
-              } else {
-                throw new InternalCompilerException(
-                    "Unable to analyze SuppressWarnings annotation");
+      String methodName = jsniRef.memberName();
+      if ("new".equals(methodName)) {
+        for (MethodBinding findMethod : clazz.getMethods(INIT_CTOR_CHARS))  
{
+          StringBuilder methodSig = new StringBuilder();
+          if (clazz instanceof NestedTypeBinding) {
+            // Match synthetic args for enclosing instances.
+            NestedTypeBinding nestedBinding = (NestedTypeBinding) clazz;
+            if (nestedBinding.enclosingInstances != null) {
+              for (int i = 0; i < nestedBinding.enclosingInstances.length;  
++i) {
+                SyntheticArgumentBinding arg =  
nestedBinding.enclosingInstances[i];
+                methodSig.append(arg.type.signature());
                }
              }
            }
+          if (findMethod.parameters != null) {
+            for (TypeBinding binding : findMethod.parameters) {
+              methodSig.append(binding.signature());
+            }
+          }
+          if (methodSig.toString().equals(jsniRef.paramTypesString())) {
+            return findMethod;
+          }
+        }
+      } else {
+        while (clazz != null) {
+          for (MethodBinding findMethod :  
clazz.getMethods(methodName.toCharArray())) {
+            if (paramTypesMatch(findMethod, jsniRef)) {
+              return findMethod;
+            }
+          }
+          clazz = clazz.superclass();
          }
        }
-      return Sets.create();
+      return null;
      }

      private boolean looksLikeAnonymousClass(JsniRef jsniRef) {
@@ -365,6 +410,8 @@
        return String.valueOf(type.shortReadableName());
      }
    }
+
+  private static final char[] INIT_CTOR_CHARS = "<init>".toCharArray();

    private static final char[][] UNSAFE_LONG_ANNOTATION_CHARS =  
CharOperation.splitOn(
        '.', UnsafeNativeLong.class.getName().toCharArray());
@@ -379,9 +426,43 @@
        TypeResolver typeResolver) {
      new JsniChecker(cud, typeResolver, jsniMethods).check();
    }
+
+  static Set<String> getSuppressedWarnings(Annotation[] annotations) {
+    if (annotations != null) {
+      for (Annotation a : annotations) {
+        if (SuppressWarnings.class.getName().equals(
+            CharOperation.toString(((ReferenceBinding)  
a.resolvedType).compoundName))) {
+          for (MemberValuePair pair : a.memberValuePairs()) {
+            if (String.valueOf(pair.name).equals("value")) {
+              Expression valueExpr = pair.value;
+              if (valueExpr instanceof StringLiteral) {
+                // @SuppressWarnings("Foo")
+                return Sets.create(((StringLiteral)  
valueExpr).constant.stringValue().toLowerCase(
+                    Locale.ENGLISH));
+              } else if (valueExpr instanceof ArrayInitializer) {
+                // @SuppressWarnings({ "Foo", "Bar"})
+                ArrayInitializer ai = (ArrayInitializer) valueExpr;
+                String[] values = new String[ai.expressions.length];
+                for (int i = 0, j = values.length; i < j; i++) {
+                  values[i] = ((StringLiteral)  
ai.expressions[i]).constant.stringValue().toLowerCase(
+                      Locale.ENGLISH);
+                }
+                return Sets.create(values);
+              } else {
+                throw new InternalCompilerException(
+                    "Unable to analyze SuppressWarnings annotation");
+              }
+            }
+          }
+        }
+      }
+    }
+    return Sets.create();
+  }

    private final CompilationUnitDeclaration cud;
    private final Map<AbstractMethodDeclaration, JsniMethod> jsniMethods;
+  private final Stack<Set<String>> suppressWarningsStack = new  
Stack<Set<String>>();
    private final TypeResolver typeResolver;

    private JsniChecker(CompilationUnitDeclaration cud,
=======================================
---  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
       
Thu Nov 12 05:54:31 2009
+++  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
       
Thu Nov 19 14:34:20 2009
@@ -17,7 +17,6 @@

  import com.google.gwt.core.ext.TreeLogger;
  import com.google.gwt.dev.javac.impl.JavaResourceBase;
-import com.google.gwt.dev.javac.impl.MockJavaResource;
  import com.google.gwt.dev.javac.impl.MockResource;
  import com.google.gwt.dev.javac.impl.MockResourceOracle;
  import com.google.gwt.dev.resource.Resource;
@@ -48,7 +47,7 @@
      boolean reallyLog = false;
      if (reallyLog) {
        AbstractTreeLogger logger = new PrintWriterTreeLogger();
-      logger.setMaxDetail(TreeLogger.ALL);
+      logger.setMaxDetail(TreeLogger.WARN);
        return logger;
      }
      return TreeLogger.NULL;
@@ -102,7 +101,7 @@
    protected CompilationState state = isolatedBuilder.doBuildFrom(
        createTreeLogger(), oracle.getResources());

-  protected void addGeneratedUnits(MockJavaResource... sourceFiles) {
+  protected void addGeneratedUnits(MockResource... sourceFiles) {
      state.addGeneratedCompilationUnits(createTreeLogger(),
          getGeneratedUnits(sourceFiles));
    }
=======================================
---  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java  
 
Wed Nov 11 11:04:31 2009
+++  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java  
 
Thu Nov 19 14:34:20 2009
@@ -39,6 +39,7 @@
      suite.addTestSuite(JdtCompilerTest.class);
      suite.addTestSuite(JSORestrictionsTest.class);
      suite.addTestSuite(JsniCheckerTest.class);
+    suite.addTestSuite(JsniCollectorTest.class);
      suite.addTestSuite(TypeOracleMediatorTest.class);

      suite.addTestSuite(CollectClassDataTest.class);
=======================================
---  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/JsniCheckerTest.java       
 
Wed Nov 11 11:04:31 2009
+++  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/JsniCheckerTest.java       
 
Thu Nov 19 14:34:20 2009
@@ -61,6 +61,29 @@
      shouldGenerateError(code, 10, "Referencing class \'Buggy$1.A: "
          + "JSNI references to anonymous classes are illegal");
    }
+
+  public void testArrayBadMember() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Buggy[][]::blah;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateError(
+        code,
+        3,
+        "Referencing member 'Buggy[][].blah': 'class' is the only legal  
reference for array types");
+  }
+
+  public void testArrayClass() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Buggy[][]::class;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateNoWarning(code);
+  }

    public void testCyclicReferences() {
      {
@@ -153,7 +176,28 @@
      code.append("    @D::bar;\n");
      code.append("  }-*/;\n");
      code.append("}\n");
-
+    shouldGenerateNoWarning(code);
+
+    // Check inherited suppress warnings.
+    code = new StringBuffer();
+    code.append("@Deprecated class D {\n");
+    code.append("  int bar;\n");
+    code.append("}\n");
+    code.append("@SuppressWarnings(\"deprecation\")\n");
+    code.append("class Buggy {\n");
+    code.append("  @Deprecated void foo(){}\n");
+    code.append("  @Deprecated int bar;\n");
+    code.append("  native void jsniMethod1() /*-{\n");
+    code.append("    @Buggy::foo();\n");
+    code.append("    @Buggy::bar;\n");
+    code.append("    @D::bar;\n");
+    code.append("  }-*/;\n");
+    code.append("  native void jsniMethod2() /*-{\n");
+    code.append("    @Buggy::foo();\n");
+    code.append("    @Buggy::bar;\n");
+    code.append("    @D::bar;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
      shouldGenerateNoWarning(code);
    }

@@ -212,6 +256,47 @@
      shouldGenerateError(code, 6, "Referencing field 'Buggy$Inner.x': "
          + "type 'long' is not safe to access in JSNI code");
    }
+
+  public void testInnerNew() {
+    StringBuffer code = new StringBuffer();
+    code.append("public class Buggy {\n");
+    code.append("  class Inner {\n");
+    code.append("    long x = 3;\n");
+    code.append("    Inner(boolean b) { };\n");
+    code.append("  }\n");
+    code.append("  native void jsniMeth() /*-{\n");
+    code.append("     
$wnd.alert(@Buggy.Inner::new(Z)(true).toString());\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+
+    // Cannot resolve, missing synthetic enclosing instance.
+    shouldGenerateWarning(code, 7, "Referencing  
method 'Buggy.Inner.new(Z)': "
+        + "unable to resolve method, expect subsequent failures");
+
+    code = new StringBuffer();
+    code.append("public class Buggy {\n");
+    code.append("  static class Inner {\n");
+    code.append("    long x = 3;\n");
+    code.append("    Inner(boolean b) { };\n");
+    code.append("  }\n");
+    code.append("  native void jsniMeth() /*-{\n");
+    code.append("    $wnd.alert(@Buggy.Inner::new(Z)(this,  
true).toString());\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateNoWarning(code);
+
+    code = new StringBuffer();
+    code.append("public class Buggy {\n");
+    code.append("  class Inner {\n");
+    code.append("    long x = 3;\n");
+    code.append("    Inner(boolean b) { };\n");
+    code.append("  }\n");
+    code.append("  native void jsniMeth() /*-{\n");
+    code.append("    $wnd.alert(@Buggy.Inner::new(LBuggy;Z)(this,  
true).toString());\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateNoWarning(code);
+  }

    /**
     * The proper behavior here is a close call. In hosted mode, Java arrays  
are
@@ -248,6 +333,16 @@
      shouldGenerateError(code, 2,
          "Type 'long' may not be returned from a JSNI method");
    }
+
+  public void testMalformedJsniRef() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Buggy;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateError(code, 3, "Expected \":\" in JSNI reference");
+  }

    public void testMethodArgument() {
      StringBuffer code = new StringBuffer();
@@ -275,6 +370,25 @@
          4,
          "Referencing method 'Buggy.m': return type 'long' is not safe to  
access in JSNI code");
    }
+
+  public void testNew() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  static native Object main() /*-{\n");
+    code.append("    return @Buggy::new()();\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateNoWarning(code);
+
+    code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  Buggy(boolean b) { }\n");
+    code.append("  static native Object main() /*-{\n");
+    code.append("    return @Buggy::new(Z)(true);\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateNoWarning(code);
+  }

    public void testNullField() {
      StringBuffer code = new StringBuffer();
@@ -324,6 +438,29 @@
          5,
          "Referencing method 'Buggy.m': return type 'long' is not safe to  
access in JSNI code");
    }
+
+  public void testPrimitiveBadMember() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Z::blah;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateError(
+        code,
+        3,
+        "Referencing member 'Z.blah': 'class' is the only legal reference  
for primitive types");
+  }
+
+  public void testPrimitiveClass() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Z::class;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateNoWarning(code);
+  }

    public void testRefInString() {
      {
@@ -337,6 +474,43 @@
        shouldGenerateNoError(code);
      }
    }
+
+  public void testUnresolvedClass() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Foo::x;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateWarning(code, 3,
+        "Referencing class 'Foo': unable to resolve class, expect  
subsequent failures");
+  }
+
+  public void testUnresolvedField() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Buggy::x;\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateWarning(
+        code,
+        3,
+        "Referencing field 'Buggy.x': unable to resolve field, expect  
subsequent failures");
+  }
+
+  public void testUnresolvedMethod() {
+    StringBuffer code = new StringBuffer();
+    code.append("class Buggy {\n");
+    code.append("  native void jsniMethod() /*-{\n");
+    code.append("    @Buggy::x(Ljava/lang/String);\n");
+    code.append("  }-*/;\n");
+    code.append("}\n");
+    shouldGenerateWarning(
+        code,
+        3,
+        "Referencing method 'Buggy.x(Ljava/lang/String)': unable to  
resolve method, expect subsequent failures");
+  }

    public void testUnsafeAnnotation() {
      {
=======================================
---  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/impl/StaticJavaResource.java
        
Wed Nov 11 11:04:31 2009
+++  
/releases/2.0/dev/core/test/com/google/gwt/dev/javac/impl/StaticJavaResource.java
        
Thu Nov 19 14:34:20 2009
@@ -15,14 +15,12 @@
   */
  package com.google.gwt.dev.javac.impl;

-import com.google.gwt.dev.javac.Shared;
-
-public class StaticJavaResource extends MockResource {
+public class StaticJavaResource extends MockJavaResource {

    private final CharSequence source;

-  public StaticJavaResource(String typeName, CharSequence source) {
-    super(Shared.toPath(typeName));
+  public StaticJavaResource(String qualifiedTypeName, CharSequence source)  
{
+    super(qualifiedTypeName);
      this.source = source;
    }

=======================================
--- /releases/2.0/user/src/com/google/gwt/junit/JUnitShell.java Wed Nov 18  
14:04:15 2009
+++ /releases/2.0/user/src/com/google/gwt/junit/JUnitShell.java Thu Nov 19  
14:34:20 2009
@@ -899,6 +899,7 @@
      return true;
    }

+  @Override
    protected boolean shouldAutoGenerateResources() {
      return shouldAutoGenerateResources;
    }
=======================================
---  
/releases/2.0/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
        
Wed Nov 11 12:06:42 2009
+++  
/releases/2.0/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java
        
Thu Nov 19 14:34:20 2009
@@ -143,7 +143,7 @@

      ClassSourceFileComposerFactory composerFactory = new  
ClassSourceFileComposerFactory(
          packageName, className);
-
+     
composerFactory.addAnnotationDeclaration("@SuppressWarnings(\"deprecation\")");
      return composerFactory.createSourceWriter(ctx, printWriter);
    }

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

Reply via email to