changeset 39283:f696102b95d9

javacomp: Add support for Java 7, 8, 9. * lib/javacomp.c (default_target_version, SOURCE_VERSION_BOUND, source_version_index, get_goodcode_snippet, get_failcode_snippet, corresponding_classfile_version): Accept source_version 1,7, 1.8, 1.9 and target_version 1,7, 1.8, 1.9. * lib/javacomp.h: Update comments accordingly.
author Bruno Haible <bruno@clisp.org>
date Tue, 20 Mar 2018 00:39:01 +0100
parents cff713966bdc
children 74fdb87e099a
files ChangeLog lib/javacomp.c lib/javacomp.h
diffstat 3 files changed, 50 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Mar 20 00:33:19 2018 +0100
+++ b/ChangeLog	Tue Mar 20 00:39:01 2018 +0100
@@ -1,3 +1,12 @@
+2018-03-19  Bruno Haible  <bruno@clisp.org>
+
+	javacomp: Add support for Java 7, 8, 9.
+	* lib/javacomp.c (default_target_version, SOURCE_VERSION_BOUND,
+	source_version_index, get_goodcode_snippet, get_failcode_snippet,
+	corresponding_classfile_version): Accept source_version 1,7, 1.8, 1.9
+	and target_version 1,7, 1.8, 1.9.
+	* lib/javacomp.h: Update comments accordingly.
+
 2018-03-19  Bruno Haible  <bruno@clisp.org>
 
 	javacomp-script: Add support for Java 9.
--- a/lib/javacomp.c	Tue Mar 20 00:33:19 2018 +0100
+++ b/lib/javacomp.c	Tue Mar 20 00:39:01 2018 +0100
@@ -100,7 +100,7 @@
       java_version_cache = javaexec_version ();
       if (java_version_cache == NULL
           || !(java_version_cache[0] == '1' && java_version_cache[1] == '.'
-               && (java_version_cache[2] >= '1' && java_version_cache[2] <= '6')
+               && (java_version_cache[2] >= '1' && java_version_cache[2] <= '9')
                && java_version_cache[3] == '\0'))
         java_version_cache = "1.1";
     }
@@ -110,14 +110,19 @@
 /* ======================= Source version dependent ======================= */
 
 /* Convert a source version to an index.  */
-#define SOURCE_VERSION_BOUND 3 /* exclusive upper bound */
+#define SOURCE_VERSION_BOUND 6 /* exclusive upper bound */
 static unsigned int
 source_version_index (const char *source_version)
 {
-  if (source_version[0] == '1' && source_version[1] == '.'
-      && (source_version[2] >= '3' && source_version[2] <= '5')
-      && source_version[3] == '\0')
-    return source_version[2] - '3';
+  if (source_version[0] == '1' && source_version[1] == '.')
+    {
+      if ((source_version[2] >= '3' && source_version[2] <= '5')
+          && source_version[3] == '\0')
+        return source_version[2] - '3';
+      if ((source_version[2] >= '7' && source_version[2] <= '9')
+          && source_version[3] == '\0')
+        return source_version[2] - '4';
+    }
   error (EXIT_FAILURE, 0, _("invalid source_version argument to compile_java_class"));
   return 0;
 }
@@ -132,6 +137,12 @@
     return "class conftest { static { assert(true); } }\n";
   if (strcmp (source_version, "1.5") == 0)
     return "class conftest<T> { T foo() { return null; } }\n";
+  if (strcmp (source_version, "1.7") == 0)
+    return "class conftest { void foo () { switch (\"A\") {} } }\n";
+  if (strcmp (source_version, "1.8") == 0)
+    return "class conftest { void foo () { Runnable r = () -> {}; } }\n";
+  if (strcmp (source_version, "1.9") == 0)
+    return "interface conftest { private void foo () {} }\n";
   error (EXIT_FAILURE, 0, _("invalid source_version argument to compile_java_class"));
   return NULL;
 }
@@ -147,6 +158,12 @@
   if (strcmp (source_version, "1.4") == 0)
     return "class conftestfail<T> { T foo() { return null; } }\n";
   if (strcmp (source_version, "1.5") == 0)
+    return "class conftestfail { void foo () { switch (\"A\") {} } }\n";
+  if (strcmp (source_version, "1.7") == 0)
+    return "class conftestfail { void foo () { Runnable r = () -> {}; } }\n";
+  if (strcmp (source_version, "1.8") == 0)
+    return "interface conftestfail { private void foo () {} }\n";
+  if (strcmp (source_version, "1.9") == 0)
     return NULL;
   error (EXIT_FAILURE, 0, _("invalid source_version argument to compile_java_class"));
   return NULL;
@@ -184,6 +201,12 @@
     return 49;
   if (strcmp (target_version, "1.6") == 0)
     return 50;
+  if (strcmp (target_version, "1.7") == 0)
+    return 51;
+  if (strcmp (target_version, "1.8") == 0)
+    return 52;
+  if (strcmp (target_version, "1.9") == 0)
+    return 53;
   error (EXIT_FAILURE, 0, _("invalid target_version argument to compile_java_class"));
   return 0;
 }
--- a/lib/javacomp.h	Tue Mar 20 00:33:19 2018 +0100
+++ b/lib/javacomp.h	Tue Mar 20 00:39:01 2018 +0100
@@ -28,7 +28,10 @@
              1.3             inner classes
              1.4             assert keyword
              1.5             generic classes and methods
-             1.6             (not yet supported)
+             1.6             (not supported)
+             1.7             switch(string)
+             1.8             lambdas
+             1.9             private interface methods
    target_version can be:  classfile version:
              1.1                 45.3
              1.2                 46.0
@@ -36,6 +39,9 @@
              1.4                 48.0
              1.5                 49.0
              1.6                 50.0
+             1.7                 51.0
+             1.8                 52.0
+             1.9                 53.0
    target_version can also be given as NULL. In this case, the required
    target_version is determined from the found JVM (see javaversion.h).
    Specifying target_version is useful when building a library (.jar) that is
@@ -44,8 +50,11 @@
    It is unreasonable to ask for:
      - target_version < 1.4 with source_version >= 1.4, or
      - target_version < 1.5 with source_version >= 1.5, or
-     - target_version < 1.6 with source_version >= 1.6,
-   because even Sun's javac doesn't support these combinations.
+     - target_version < 1.6 with source_version >= 1.6, or
+     - target_version < 1.7 with source_version >= 1.7, or
+     - target_version < 1.8 with source_version >= 1.8, or
+     - target_version < 1.9 with source_version >= 1.9,
+   because even Sun's/Oracle's javac doesn't support these combinations.
    It is redundant to ask for a target_version > source_version, since the
    smaller target_version = source_version will also always work and newer JVMs
    support the older target_versions too. Except for the case