Skip to content

Commit

Permalink
Compile the generated sources into the expected target directory
Browse files Browse the repository at this point in the history
  • Loading branch information
testforstephen committed Oct 9, 2024
1 parent fd2da7c commit a9019cf
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ public void finished(TaskEvent e) {
for (Entry<IContainer, List<ICompilationUnit>> outputSourceSet : outputSourceMapping.entrySet()) {
// Configure Javac to generate the class files in a mapped temporary location
var outputDir = JavacClassFile.getMappedTempOutput(outputSourceSet.getKey()).toFile();
javacListener.setOutputDir(outputSourceSet.getKey());
JavacUtils.configureJavacContext(javacContext, this.compilerConfig, javaProject, outputDir, true);
JavaCompiler javac = new JavaCompiler(javacContext) {
boolean isInGeneration = false;
Expand Down Expand Up @@ -197,6 +198,7 @@ public int errorCount() {
// TODO fail
ILog.get().error("compilation failed", e);
}

for (int i = 0; i < sourceUnits.length; i++) {
ICompilationUnit in = sourceUnits[i];
CompilationResult result = new CompilationResult(in, i, sourceUnits.length, Integer.MAX_VALUE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

package org.eclipse.jdt.internal.javac;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -26,10 +31,16 @@
import javax.tools.JavaFileObject;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;

import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
Expand All @@ -48,13 +59,15 @@
import com.sun.tools.javac.code.Type.UnknownType;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCModuleDecl;

public class JavacTaskListener implements TaskListener {
private Map<ICompilationUnit, IContainer> sourceOutputMapping = new HashMap<>();
private Map<ICompilationUnit, JavacCompilationResult> results = new HashMap<>();
private UnusedProblemFactory problemFactory;
private JavacConfig config;
private IContainer outputDir;
private final Map<JavaFileObject, ICompilationUnit> fileObjectToCUMap;
private static final Set<String> PRIMITIVE_TYPES = new HashSet<String>(Arrays.asList(
"byte",
Expand All @@ -71,6 +84,7 @@ public class JavacTaskListener implements TaskListener {

public JavacTaskListener(JavacConfig config, Map<IContainer, List<ICompilationUnit>> outputSourceMapping,
IProblemFactory problemFactory, Map<JavaFileObject, ICompilationUnit> fileObjectToCUMap) {
this.config = config;
this.problemFactory = new UnusedProblemFactory(problemFactory, config.compilerOptions());
this.fileObjectToCUMap = fileObjectToCUMap;
for (Entry<IContainer, List<ICompilationUnit>> entry : outputSourceMapping.entrySet()) {
Expand All @@ -81,7 +95,18 @@ public JavacTaskListener(JavacConfig config, Map<IContainer, List<ICompilationUn

@Override
public void finished(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.ANALYZE) {
if (e.getKind() == TaskEvent.Kind.GENERATE) {
final JavaFileObject file = e.getSourceFile();
final ICompilationUnit cu = this.fileObjectToCUMap.get(file);
if (cu == null && e.getTypeElement() instanceof ClassSymbol clazz && isGeneratedSource(file)) {
try {
// Write the class files for the generated sources.
writeClassFile(clazz);
} catch (CoreException e1) {
// TODO
}
}
} else if (e.getKind() == TaskEvent.Kind.ANALYZE) {
final JavaFileObject file = e.getSourceFile();
final ICompilationUnit cu = this.fileObjectToCUMap.get(file);
if (cu == null) {
Expand Down Expand Up @@ -251,6 +276,73 @@ private void recordTypeHierarchy(ClassSymbol classSymbol) {
}
}

private boolean isGeneratedSource(JavaFileObject file) {
List<IContainer> generatedSourcePaths = this.config.originalConfig().generatedSourcePaths();
if (generatedSourcePaths == null || generatedSourcePaths.isEmpty()) {
return false;
}

URI uri = file.toUri();
if (uri != null && uri.getPath() != null) {
File ioFile = new File(uri.getPath());
Path fileIOPath = ioFile.toPath();
return generatedSourcePaths.stream().anyMatch(container -> {
IPath location = container.getRawLocation();
if (location != null) {
Path locationIOPath = location.toPath();
return fileIOPath.startsWith(locationIOPath);
}
return false;
});
}
return false;
}

private void writeClassFile(ClassSymbol clazz) throws CoreException {
if (this.outputDir == null) {
return;
}

String qualifiedName = clazz.flatName().toString().replace('.', '/');
IPath filePath = new org.eclipse.core.runtime.Path(qualifiedName);
IContainer fileFolder = this.outputDir;
if (filePath.segmentCount() > 1) {
fileFolder = createFolder(filePath.removeLastSegments(1), this.outputDir);
filePath = new org.eclipse.core.runtime.Path(filePath.lastSegment());
}

IFile classFile = fileFolder.getFile(filePath.addFileExtension(SuffixConstants.EXTENSION_class));
File tmpJavacClassFile = JavacClassFile.computeMappedTempClassFile(this.outputDir, qualifiedName);
if (tmpJavacClassFile == null || !tmpJavacClassFile.exists()) {
return;
}

try {
byte[] bytes = Files.readAllBytes(tmpJavacClassFile.toPath());
classFile.write(bytes, true, true, false, null);
tmpJavacClassFile.delete();
} catch (IOException e) {
// ignore
}
}

private IContainer createFolder(IPath packagePath, IContainer outputFolder) throws CoreException {
if (packagePath.isEmpty()) {
return outputFolder;
}

IFolder folder = outputFolder.getFolder(packagePath);
if (!folder.exists()) {
createFolder(packagePath.removeLastSegments(1), outputFolder);
folder.create(IResource.FORCE | IResource.DERIVED, true, null);
}
return folder;
}

public void setOutputDir(IContainer outputDir) {
this.outputDir = outputDir;
}

public Map<ICompilationUnit, JavacCompilationResult> getResults() {
return this.results;
}
Expand Down

0 comments on commit a9019cf

Please sign in to comment.