#253185: Emit a warning when there is a mishmash in actual and args parameter names
authorJaroslav Tulach <jtulach@netbeans.org>
Tue, 25 Aug 2015 22:32:18 +0200
changeset 959f14d2132cd52
parent 958 17a8ef18dbc7
child 960 3b8546edbf03
#253185: Emit a warning when there is a mishmash in actual and args parameter names
boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java
boot/src/test/java/org/netbeans/html/boot/impl/Compile.java
boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptProcesorTest.java
     1.1 --- a/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java	Tue Aug 25 22:18:29 2015 +0200
     1.2 +++ b/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java	Tue Aug 25 22:32:18 2015 +0200
     1.3 @@ -47,6 +47,7 @@
     1.4  import java.io.OutputStreamWriter;
     1.5  import java.io.PrintWriter;
     1.6  import java.io.Writer;
     1.7 +import java.util.Arrays;
     1.8  import java.util.Collections;
     1.9  import java.util.HashMap;
    1.10  import java.util.HashSet;
    1.11 @@ -88,11 +89,11 @@
    1.12   */
    1.13  @ServiceProvider(service = Processor.class)
    1.14  public final class JavaScriptProcesor extends AbstractProcessor {
    1.15 -    private final Map<String,Map<String,ExecutableElement>> javacalls = 
    1.16 +    private final Map<String,Map<String,ExecutableElement>> javacalls =
    1.17          new HashMap<String,Map<String,ExecutableElement>>();
    1.18 -    private final Map<String,Set<TypeElement>> bodies = 
    1.19 +    private final Map<String,Set<TypeElement>> bodies =
    1.20          new HashMap<String, Set<TypeElement>>();
    1.21 -    
    1.22 +
    1.23      @Override
    1.24      public Set<String> getSupportedAnnotationTypes() {
    1.25          Set<String> set = new HashSet<String>();
    1.26 @@ -100,7 +101,7 @@
    1.27          set.add(JavaScriptResource.class.getName());
    1.28          return set;
    1.29      }
    1.30 -    
    1.31 +
    1.32      @Override
    1.33      public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    1.34          final Messager msg = processingEnv.getMessager();
    1.35 @@ -110,7 +111,7 @@
    1.36              }
    1.37              ExecutableElement ee = (ExecutableElement)e;
    1.38              List<? extends VariableElement> params = ee.getParameters();
    1.39 -            
    1.40 +
    1.41              JavaScriptBody jsb = e.getAnnotation(JavaScriptBody.class);
    1.42              if (jsb == null) {
    1.43                  continue;
    1.44 @@ -130,6 +131,11 @@
    1.45              if (params.size() != arr.length) {
    1.46                  msg.printMessage(Diagnostic.Kind.ERROR, "Number of args arguments does not match real arguments!", e);
    1.47              }
    1.48 +            for (int i = 0; i < arr.length; i++) {
    1.49 +                if (!params.get(i).getSimpleName().toString().equals(arr[i])) {
    1.50 +                    msg.printMessage(Diagnostic.Kind.WARNING, "Actual method parameter names and args ones " + Arrays.toString(arr) + " differ", e);
    1.51 +                }
    1.52 +            }
    1.53              if (!jsb.wait4js() && ee.getReturnType().getKind() != TypeKind.VOID) {
    1.54                  msg.printMessage(Diagnostic.Kind.ERROR, "Methods that don't wait for JavaScript to finish must return void!", e);
    1.55              }
    1.56 @@ -156,7 +162,7 @@
    1.57              } else {
    1.58                  res = findPkg(e).replace('.', '/') + "/" + r.value();
    1.59              }
    1.60 -            
    1.61 +
    1.62              try {
    1.63                  FileObject os = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "", res);
    1.64                  os.openInputStream().close();
    1.65 @@ -173,7 +179,7 @@
    1.66                      }
    1.67                  }
    1.68              }
    1.69 -            
    1.70 +
    1.71              boolean found = false;
    1.72              for (Element mthod : e.getEnclosedElements()) {
    1.73                  if (mthod.getKind() != ElementKind.METHOD) {
    1.74 @@ -200,7 +206,7 @@
    1.75      }
    1.76  
    1.77      @Override
    1.78 -    public Iterable<? extends Completion> getCompletions(Element e, 
    1.79 +    public Iterable<? extends Completion> getCompletions(Element e,
    1.80          AnnotationMirror annotation, ExecutableElement member, String userText
    1.81      ) {
    1.82          StringBuilder sb = new StringBuilder();
    1.83 @@ -229,7 +235,7 @@
    1.84          protected CharSequence callMethod(String ident, String fqn, String method, String params) {
    1.85              final TypeElement type = processingEnv.getElementUtils().getTypeElement(fqn);
    1.86              if (type == null) {
    1.87 -                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 
    1.88 +                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
    1.89                      "Callback to non-existing class " + fqn, e
    1.90                  );
    1.91                  return "";
    1.92 @@ -251,12 +257,12 @@
    1.93              }
    1.94              if (found == null) {
    1.95                  if (foundParams.length() == 0) {
    1.96 -                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 
    1.97 +                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
    1.98                          "Callback to class " + fqn + " with unknown method " + method, e
    1.99                      );
   1.100                  } else {
   1.101 -                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 
   1.102 -                        "Callback to " + fqn + "." + method + " with wrong parameters: " + 
   1.103 +                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
   1.104 +                        "Callback to " + fqn + "." + method + " with wrong parameters: " +
   1.105                          params + ". Only known parameters are " + foundParams, e
   1.106                      );
   1.107                  }
   1.108 @@ -304,7 +310,7 @@
   1.109              return sb.toString();
   1.110          }
   1.111      }
   1.112 -    
   1.113 +
   1.114      private static void dumpElems(StringBuilder sb, Element e, char after) {
   1.115          if (e == null) {
   1.116              return;
   1.117 @@ -319,14 +325,14 @@
   1.118          sb.append(e.getSimpleName());
   1.119          sb.append(after);
   1.120      }
   1.121 -    
   1.122 +
   1.123      private void generateJavaScriptBodyList(Map<String,Set<TypeElement>> bodies) {
   1.124          if (bodies.isEmpty()) {
   1.125              return;
   1.126          }
   1.127          try {
   1.128              FileObject all = processingEnv.getFiler().createResource(
   1.129 -                StandardLocation.CLASS_OUTPUT, "", "META-INF/net.java.html.js.classes"                
   1.130 +                StandardLocation.CLASS_OUTPUT, "", "META-INF/net.java.html.js.classes"
   1.131              );
   1.132              PrintWriter wAll = new PrintWriter(new OutputStreamWriter(
   1.133                  all.openOutputStream(), "UTF-8"
   1.134 @@ -360,7 +366,7 @@
   1.135              processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Failed to write to " + "META-INF/net.java.html.js.classes: " + x.toString());
   1.136          }
   1.137      }
   1.138 -    
   1.139 +
   1.140      private void generateCallbackClass(Map<String,Map<String, ExecutableElement>> process) {
   1.141          for (Map.Entry<String, Map<String, ExecutableElement>> pkgEn : process.entrySet()) {
   1.142              String pkgName = pkgEn.getKey();
   1.143 @@ -408,12 +414,12 @@
   1.144              return;
   1.145          }
   1.146          final TypeElement selfType = (TypeElement)m.getEnclosingElement();
   1.147 -        
   1.148 -        
   1.149 +
   1.150 +
   1.151          source.append("\n  public java.lang.Object ")
   1.152                  .append(mangled)
   1.153                  .append("(");
   1.154 -        
   1.155 +
   1.156          String sep = "";
   1.157          StringBuilder convert = new StringBuilder();
   1.158          if (!isStatic) {
   1.159 @@ -430,7 +436,7 @@
   1.160              }
   1.161              sep = ", ";
   1.162          }
   1.163 -        
   1.164 +
   1.165          int cnt = 0;
   1.166          for (VariableElement ve : m.getParameters()) {
   1.167              source.append(sep);
   1.168 @@ -494,7 +500,7 @@
   1.169          if (useTryResources()) {
   1.170              source.append("    }\n");
   1.171          } else {
   1.172 -            
   1.173 +
   1.174              source.append("    } finally {\n");
   1.175              source.append("      a.close();\n");
   1.176              source.append("    }\n");
   1.177 @@ -510,12 +516,12 @@
   1.178              return false;
   1.179          }
   1.180      }
   1.181 -    
   1.182 +
   1.183      private static String findPkg(Element e) {
   1.184          while (e.getKind() != ElementKind.PACKAGE) {
   1.185              e = e.getEnclosingElement();
   1.186          }
   1.187          return ((PackageElement)e).getQualifiedName().toString();
   1.188      }
   1.189 -    
   1.190 +
   1.191  }
     2.1 --- a/boot/src/test/java/org/netbeans/html/boot/impl/Compile.java	Tue Aug 25 22:18:29 2015 +0200
     2.2 +++ b/boot/src/test/java/org/netbeans/html/boot/impl/Compile.java	Tue Aug 25 22:32:18 2015 +0200
     2.3 @@ -110,10 +110,13 @@
     2.4      /** Obtains errors created during compilation.
     2.5       */
     2.6      public List<Diagnostic<? extends JavaFileObject>> getErrors() {
     2.7 +        return getDiagnostics(Diagnostic.Kind.ERROR);
     2.8 +    }
     2.9 +    public List<Diagnostic<? extends JavaFileObject>> getDiagnostics(Diagnostic.Kind kind) {
    2.10          List<Diagnostic<? extends JavaFileObject>> err;
    2.11          err = new ArrayList<Diagnostic<? extends JavaFileObject>>();
    2.12          for (Diagnostic<? extends JavaFileObject> diagnostic : errors) {
    2.13 -            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
    2.14 +            if (diagnostic.getKind() == kind) {
    2.15                  err.add(diagnostic);
    2.16              }
    2.17          }
     3.1 --- a/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptProcesorTest.java	Tue Aug 25 22:18:29 2015 +0200
     3.2 +++ b/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptProcesorTest.java	Tue Aug 25 22:32:18 2015 +0200
     3.3 @@ -45,8 +45,13 @@
     3.4  import java.io.IOException;
     3.5  import java.lang.reflect.Field;
     3.6  import java.lang.reflect.Method;
     3.7 +import java.util.List;
     3.8 +import java.util.Locale;
     3.9 +import javax.tools.Diagnostic;
    3.10 +import javax.tools.JavaFileObject;
    3.11  import static org.testng.Assert.assertEquals;
    3.12  import static org.testng.Assert.assertTrue;
    3.13 +import static org.testng.Assert.fail;
    3.14  import org.testng.annotations.Test;
    3.15  
    3.16  /**
    3.17 @@ -113,6 +118,26 @@
    3.18          Compile c = Compile.create("", code);
    3.19          c.assertNoErrors();
    3.20      }
    3.21 +    
    3.22 +    @Test public void misorderNotified() throws IOException {
    3.23 +        String code = "package x.y.z;\n"
    3.24 +            + "import net.java.html.js.JavaScriptBody;\n"
    3.25 +            + "class X {\n"
    3.26 +            + "  @JavaScriptBody(args={\"r\", \"a\", \"b\"}, body =\"\"\n"
    3.27 +            + "  )\n"
    3.28 +            + "  private static native void testEqual(Object p, String q, int r);\n"
    3.29 +            + "}\n";
    3.30 +        
    3.31 +        Compile c = Compile.create("", code);
    3.32 +        List<Diagnostic<? extends JavaFileObject>> warnings = c.getDiagnostics(Diagnostic.Kind.WARNING);
    3.33 +        assertTrue(warnings.size() >= 1, "There are warnings: " + warnings);
    3.34 +        for (Diagnostic<? extends JavaFileObject> w : warnings) {
    3.35 +            if (w.getMessage(Locale.US).contains("Actual method parameter names and args")) {
    3.36 +                return;
    3.37 +            }
    3.38 +        }
    3.39 +        fail("Expecting order warning: " + warnings);
    3.40 +    }
    3.41  
    3.42      @Test public void needJavaScriptBodyToUseResource() throws IOException {
    3.43          String code = "package x.y.z;\n"