Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import java.io.*;
import java.net.URI;
import java.util.List;
import java.util.Objects;

public class Compiler {
public static void main(String[] args) {

JavaCompiler.CompilationTask jc = ToolProvider.getSystemJavaCompiler().getTask(
null, null, null, null, null,
List.of(
new JavaFileObject() {
@Override
public Kind getKind() {
return Kind.SOURCE;
}

@Override
public boolean isNameCompatible(String simpleName, Kind kind) {
return Objects.equals(simpleName, "Main");
}

@Override
public NestingKind getNestingKind() {
return null;
}

@Override
public Modifier getAccessLevel() {
return null;
}

@Override
public URI toUri() {
return URI.create("https://nonesuch.imaginary/somedir/Main.java");
}

@Override
public String getName() {
return "Main.java";
}

@Override
public InputStream openInputStream() throws IOException {
return new ByteArrayInputStream(this.getCharContent(true).toString().getBytes());
}

@Override
public OutputStream openOutputStream() throws IOException {
throw new IOException("No output allowed");
}

@Override
public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
return new StringReader(this.getCharContent(ignoreEncodingErrors).toString());
}

@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return "public class Main { }";
}

@Override
public Writer openWriter() throws IOException {
throw new IOException("No output allowed");
}

@Override
public long getLastModified() {
return 0;
}

@Override
public boolean delete() {
return false;
}

@Override
public String toString() {
return "In-memory file with URI " + this.toUri();
}
}
)
);

jc.call();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| Main |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this get some kind of location based on https://nonesuch.imaginary/somedir/Main.java?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the loc seen will be inside the db's scratch dir where the temporary is created. Almost necessarily the loc given by toURI or similar is going to be something vscode etc won't understand, like a jar-relative URI or the like; at least this location will be clickable, though considered outside the source-root. I haven't exposed it in this test because it isn't stable from test run to run (contains a temporary dirname).

I suggest we don't tackle this one at this juncture, since I'm not clear how we can give it a more useful location that makes sense to VSCode / another client, or the user.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import commands

def test(codeql, java):
commands.run("javac Compiler.java")
codeql.database.create(command = "java Compiler")
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import java

from Class c
where c.fromSource()
select c.getName()
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: minorAnalysis
---
* `JavacTool`-based compiler interception no longer requires an `--add-opens` directive when `FileObject.toUri` is accessible.
* `JavacTool`-based compiler interception no longer throws an exception visible to the program using `JavacTool` on failure to extract a file path from a passed `JavaFileObject`.
* `JavacTool`-based compiler interception now supports files that don't simply wrap a `file://` URL, such as a source file inside a JAR, or an in-memory file, but which do implement `getCharContent`.