Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8327536

Allow to create a simple in-memory input JavaFileObject

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 23
    • tools
    • None
    • source
    • minimal
    • Java API
    • SE

      Summary

      There is a considerable amount of subclasses in various codebases of SimpleJavaFileObject, that implement input source files for a compilation. The proposal here is to add a factory to create such a simple input JavaFileObject.

      Problem

      Around various codebases, there are many subtypes of SimpleJavaFileObject like:

      private static class JavaSource extends SimpleJavaFileObject {
      
          private String code;
      
          public JavaSource(String code) {
              super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
              this.code = code;
          }
      
          @Override
          public CharSequence getCharContent(boolean ignoreEncodingErrors) {
              return code;
          }
      }

      This duplication of code seems unnecessary.

      Solution

      The proposal herein is to create a factory method that would create a subtype of SimpleJavaFileObject similar to the above, based on the provided URI and source code content.

      Specification

      The proposed addition, including API specification is:

      diff --git a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
      index a619cf34c9a..1e959133ff3 100644
      --- a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
      +++ b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
      @@ -223,4 +223,48 @@ public boolean isNameCompatible(String simpleName, Kind kind) {
           public String toString() {
               return getClass().getName() + "[" + toUri() + "]";
           }
      +
      +    /**
      +     * Creates a {@link JavaFileObject} which represents the given source content.
      +     *
      +     * <p>The provided {@code uri} will be returned from {@link #toUri()}.
      +     * The provided {@code content} will be returned from {@link #getCharContent(boolean)}.
      +     * The {@link #getKind()} method will return {@link Kind#SOURCE}.
      +     *
      +     * <p>All other methods will behave as described in the documentation in this class,
      +     * as if the constructor is called with {@code uri} and {@code Kind.SOURCE}.
      +     *
      +     * <p>This method can be, for example, used to compile an in-memory String
      +     * to a set of classfile in a target directory:
      +     * {@snippet lang="java":
      +     *      var code = """
      +     *                 public class CompiledCode {}
      +     *                 """;
      +     *      var compiler = ToolProvider.getSystemJavaCompiler();
      +     *      var targetDirectory = "...";
      +     *      var task = compiler.getTask(null,
      +     *                                  null,
      +     *                                  null,
      +     *                                  List.of("-d", targetDirectory),
      +     *                                  null,
      +     *                                  List.of(SimpleJavaFileObject.forSource(URI.create("CompiledCode.java"), code)));
      +     *      if (!task.call()) {
      +     *          throw new IllegalStateException("Compilation failed!");
      +     *      }
      +     * }
      +     *
      +     * @param uri that should be used for the resulting {@code JavaFileObject}
      +     * @param content the content of the {@code JavaFileObject}
      +     * @return a {@code JavaFileObject} representing the given source content.
      +     * @since 23
      +     */
      +    public static JavaFileObject forSource(URI uri, String content) {
      +        return new SimpleJavaFileObject(uri, Kind.SOURCE) {
      +            @Override
      +            public CharSequence getCharContent(boolean ignoreEncodingErrors) {
      +                return content;
      +            }
      +        };
      +    }
      +
       }

            jlahoda Jan Lahoda
            jlahoda Jan Lahoda
            Jim Laskey
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: