test/langtools/tools/sjavac/ApiExtraction.java
changeset 47216 71c04702a3d5
parent 40308 274367a99f98
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/sjavac/ApiExtraction.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8054717
+ * @summary Make sure extraction of non-private APIs work as expected.
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.sjavac
+ *          jdk.compiler/com.sun.tools.sjavac.options
+ *          jdk.compiler/com.sun.tools.sjavac.pubapi
+ * @build Wrapper toolbox.ToolBox toolbox.JavacTask
+ * @run main Wrapper ApiExtraction
+ */
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PROTECTED;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.lang.model.type.TypeKind;
+
+import com.sun.tools.sjavac.PubApiExtractor;
+import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PrimitiveTypeDesc;
+import com.sun.tools.sjavac.pubapi.PubApi;
+import com.sun.tools.sjavac.pubapi.PubMethod;
+import com.sun.tools.sjavac.pubapi.PubType;
+import com.sun.tools.sjavac.pubapi.PubVar;
+import com.sun.tools.sjavac.pubapi.ReferenceTypeDesc;
+
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+public class ApiExtraction {
+    public static void main(String[] args) throws IOException {
+
+        String testSrc = String.join("\n",
+                "import java.util.*;",
+                "public final class TestClass extends Thread {",
+
+                // Fields with various combination of modifiers
+                "    private String s1 = \"str 1\";",
+                "    public String s2 = \"str 2\";",
+                "    protected final String s3 = \"str 3\";",
+                "    static String s4 = \"str 4\";",
+
+                // Methods with various combinations of types and modifiers
+                "    protected void m1() {}",
+                "    public static Map<Integer, List<String>> m2() {",
+                "        return null;",
+                "    }",
+                "    final void m3(Set<Map<Integer, Map<String, String>>> s) {}",
+
+                // Some inner classes
+                "    static class DummyInner1 implements Runnable {",
+                "        protected int field;",
+                "        public void run() {}",
+                "    }",
+                "    final class DummyInner2 { }",
+                "}");
+
+        // Create class file to extract API from
+        new JavacTask(new ToolBox()).sources(testSrc).run();
+
+        // Extract PubApi
+        Options options = Options.parseArgs("-d", "bin", "--state-dir=bin", "-cp", ".");
+        PubApiExtractor pubApiExtr = new PubApiExtractor(options);
+        PubApi actualApi = pubApiExtr.getPubApi("TestClass");
+        pubApiExtr.close();
+
+        // Validate result
+        PubApi expectedApi = getExpectedPubApi();
+        if (!expectedApi.equals(actualApi)) {
+            List<String> diffs = expectedApi.diff(actualApi);
+            System.out.println(diffs.size() + " differences found.");
+            for (String diff : diffs) {
+                System.out.println(diff);
+            }
+            throw new AssertionError("Actual API differs from expected API.");
+        }
+    }
+
+    private static PubApi getExpectedPubApi() {
+
+        ReferenceTypeDesc string = new ReferenceTypeDesc("java.lang.String");
+
+        // Fields
+        // (s1 is private and therefore not included)
+        PubVar s2 = new PubVar(setOf(PUBLIC), string, "s2", null);
+        PubVar s4 = new PubVar(setOf(STATIC), string, "s4", null);
+        PubVar s3 = new PubVar(setOf(PROTECTED, FINAL), string, "s3",
+                                   "\"\\u0073\\u0074\\u0072\\u0020\\u0033\"");
+
+        // Methods
+        PubMethod init = new PubMethod(setOf(PUBLIC),
+                                       emptyList(),
+                                       new PrimitiveTypeDesc(TypeKind.VOID),
+                                       "<init>",
+                                       emptyList(),
+                                       emptyList());
+
+        PubMethod clinit = new PubMethod(setOf(STATIC),
+                                         emptyList(),
+                                         new PrimitiveTypeDesc(TypeKind.VOID),
+                                         "<clinit>",
+                                         emptyList(),
+                                         emptyList());
+
+        PubMethod m1 = new PubMethod(setOf(PROTECTED),
+                                     emptyList(),
+                                     new PrimitiveTypeDesc(TypeKind.VOID),
+                                     "m1",
+                                     emptyList(),
+                                     emptyList());
+
+        PubMethod m2 = new PubMethod(setOf(PUBLIC, STATIC),
+                                     emptyList(),
+                                     new ReferenceTypeDesc("java.util.Map"),
+                                     "m2",
+                                     emptyList(),
+                                     emptyList());
+
+        PubMethod m3 = new PubMethod(setOf(FINAL),
+                                     emptyList(),
+                                     new PrimitiveTypeDesc(TypeKind.VOID),
+                                     "m3",
+                                     asList(new ReferenceTypeDesc("java.util.Set")),
+                                     emptyList());
+
+        // Complete class
+        PubType testClass = new PubType(setOf(PUBLIC, FINAL),
+                                        "TestClass",
+                                        new PubApi(asList(getDummyInner1(), getDummyInner2()),
+                                                   asList(s2, s3, s4),
+                                                   asList(init, clinit, m1, m2, m3)));
+
+        // Wrap in "package level" PubApi
+        return new PubApi(asList(testClass), emptyList(), emptyList());
+    }
+
+    private static PubType getDummyInner1() {
+        PubMethod init = new PubMethod(setOf(),
+                                       emptyList(),
+                                       new PrimitiveTypeDesc(TypeKind.VOID),
+                                       "<init>",
+                                       emptyList(),
+                                       emptyList());
+
+        PubMethod run = new PubMethod(setOf(PUBLIC),
+                                      emptyList(),
+                                      new PrimitiveTypeDesc(TypeKind.VOID),
+                                      "run",
+                                      emptyList(),
+                                      emptyList());
+
+        PubVar field = new PubVar(setOf(PROTECTED),
+                                  new PrimitiveTypeDesc(TypeKind.INT),
+                                  "field",
+                                  null);
+
+        return new PubType(setOf(STATIC),
+                           "TestClass$DummyInner1",
+                           new PubApi(emptyList(),
+                                      asList(field),
+                                      asList(init, run)));
+    }
+
+    private static PubType getDummyInner2() {
+        PubMethod init = new PubMethod(setOf(),
+                                       emptyList(),
+                                       new PrimitiveTypeDesc(TypeKind.VOID),
+                                       "<init>",
+                                       emptyList(),
+                                       emptyList());
+
+        return new PubType(setOf(FINAL),
+                           "TestClass$DummyInner2",
+                           new PubApi(emptyList(),
+                                      emptyList(),
+                                      asList(init)));
+    }
+
+    @SafeVarargs
+    private static <T> Set<T> setOf(T... elements) {
+        return new HashSet<>(asList(elements));
+    }
+}