gpt4 book ai didi

java - 如何以编程方式验证 Java 代码?

转载 作者:行者123 更新时间:2023-12-05 06:11:15 31 4
gpt4 key购买 nike

鉴于源代码和 Java 版本,我需要能够验证代码是否可以编译。如果代码无法编译,我需要能够在源代码中返回错误。

以下解决方案有效,但仅适用于您机器上当前使用的 Java 版本。

import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Validator {
private final JavaCompiler COMPILER = ToolProvider.getSystemJavaCompiler();

//Assume srcFiles are java files that can be read
public final boolean compiles(Set<File> srcFiles) throws IOException {

//Convert files to JavaCompiler API compatible files
List<JavaFileObject> compilationUnits = new ArrayList<>();
for (File file : srcFiles) {
CompilableFile compilableFile = new CompilableFile(file.getName(), Files.readString(file.toPath()));
compilationUnits.add(compilableFile);
}

DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
JavaCompiler.CompilationTask task = COMPILER.getTask(null, null, diagnosticCollector, null, null, compilationUnits);
boolean success = task.call();

//Displaying the info of each warning, error, etc
diagnosticCollector.getDiagnostics().forEach(Validator::printDiagnostic);

return success;
}

private static void printDiagnostic(Diagnostic<?> diagnostic) {
System.out.println(diagnostic.getCode());
System.out.println(diagnostic.getKind());
System.out.println(diagnostic.getPosition());
System.out.println(diagnostic.getStartPosition());
System.out.println(diagnostic.getEndPosition());
System.out.println(diagnostic.getSource());
System.out.println(diagnostic.getMessage(null));
}

/**
* Instances of this class can be compiled with the JavaCompiler API
*/
private static final class CompilableFile extends SimpleJavaFileObject {
final String code;

CompilableFile(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}

@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
}

有没有办法实现下面的功能?

public final boolean compiles(Set<File> srcFiles, SourceVersion version) {...}

最佳答案

此解决方案适用的版本范围似乎是特定于编译器的,但对于 OpenJDK 11 和 15,我注意到此解决方案适用于 [7,SYSTEM_COMPILER_VERSION]

JavaCompiler API 允许您将命令行选项作为 Iterable 传递当您调用方法时 JavaCompiler.CompilationTask::getTask , 所以你可以通过 List.of("--release", "<version>")其中 <version>替换为您正在验证的版本

考虑到这一点,解决方案就变成了

import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Validator {
private final JavaCompiler COMPILER = ToolProvider.getSystemJavaCompiler();

//Assume srcFiles are java files that can be read
public final boolean compiles(Set<File> srcFiles, String javaVersion) throws IOException {

//Convert files to JavaCompiler API compatible files
List<JavaFileObject> compilationUnits = new ArrayList<>();
for (File file : srcFiles) {
CompilableFile compilableFile = new CompilableFile(file.getName(), Files.readString(file.toPath()));
compilationUnits.add(compilableFile);
}

DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
JavaCompiler.CompilationTask task = COMPILER.getTask(null, null, diagnosticCollector, List.of("--release", javaVersion), null, compilationUnits);
boolean success = task.call();

//Displaying the info of each warning, error, etc
diagnosticCollector.getDiagnostics().forEach(Validator::printDiagnostic);

return success;
}

private static void printDiagnostic(Diagnostic<?> diagnostic) {
System.out.println(diagnostic.getCode());
System.out.println(diagnostic.getKind());
System.out.println(diagnostic.getPosition());
System.out.println(diagnostic.getStartPosition());
System.out.println(diagnostic.getEndPosition());
System.out.println(diagnostic.getSource());
System.out.println(diagnostic.getMessage(null));
}

/**
* Instances of this class can be compiled with the JavaCompiler API
*/
private static final class CompilableFile extends SimpleJavaFileObject {
final String code;

CompilableFile(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}

@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
}


关于java - 如何以编程方式验证 Java 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64067188/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com