forked from eclipse-jdt/eclipse.jdt.core
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Populate the compiled types and reference info to the CompilationResu…
…lt to support incremental build
- Loading branch information
1 parent
a9ccec4
commit 454ed58
Showing
6 changed files
with
459 additions
and
51 deletions.
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacClassFile.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Microsoft Corporation and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License 2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Microsoft Corporation - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.jdt.internal.javac; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
|
||
import org.eclipse.core.resources.IContainer; | ||
import org.eclipse.core.resources.IFile; | ||
import org.eclipse.core.resources.IProject; | ||
import org.eclipse.core.runtime.CoreException; | ||
import org.eclipse.core.runtime.IPath; | ||
import org.eclipse.core.runtime.Path; | ||
import org.eclipse.jdt.core.JavaCore; | ||
import org.eclipse.jdt.internal.compiler.ClassFile; | ||
import org.eclipse.jdt.internal.compiler.util.SuffixConstants; | ||
|
||
public class JavacClassFile extends ClassFile { | ||
private String fullName; | ||
private IContainer outputDir; | ||
private byte[] bytes = null; | ||
private File proxyFile = null; | ||
|
||
public JavacClassFile(String qualifiedName, ClassFile enclosingClass, IContainer outputDir) { | ||
this.fullName = qualifiedName; | ||
this.isNestedType = enclosingClass != null; | ||
this.enclosingClassFile = enclosingClass; | ||
this.outputDir = outputDir; | ||
} | ||
|
||
@Override | ||
public char[][] getCompoundName() { | ||
String[] names = this.fullName.split("\\."); | ||
char[][] compoundNames = new char[names.length][]; | ||
for (int i = 0; i < names.length; i++) { | ||
compoundNames[i] = names[i].toCharArray(); | ||
} | ||
|
||
return compoundNames; | ||
} | ||
|
||
@Override | ||
public char[] fileName() { | ||
String compoundName = this.fullName.replace('.', '/'); | ||
return compoundName.toCharArray(); | ||
} | ||
|
||
@Override | ||
public byte[] getBytes() { | ||
if (this.bytes == null) { | ||
File tempClassFile = this.getProxyTempClassFile(); | ||
if (tempClassFile == null || !tempClassFile.exists()) { | ||
this.bytes = new byte[0]; | ||
} else { | ||
try { | ||
this.bytes = Files.readAllBytes(tempClassFile.toPath()); | ||
} catch (IOException e) { | ||
this.bytes = new byte[0]; | ||
} | ||
} | ||
} | ||
|
||
return this.bytes; | ||
} | ||
|
||
File getProxyTempClassFile() { | ||
if (this.proxyFile == null) { | ||
this.proxyFile = computeMappedTempClassFile(this.outputDir, this.fullName); | ||
} | ||
|
||
return this.proxyFile; | ||
} | ||
|
||
void deleteTempClassFile() { | ||
File tempClassFile = this.getProxyTempClassFile(); | ||
if (tempClassFile != null && tempClassFile.exists()) { | ||
tempClassFile.delete(); | ||
} | ||
} | ||
|
||
void deleteExpectedClassFile() { | ||
IFile targetClassFile = computeExpectedClassFile(this.outputDir, this.fullName); | ||
if (targetClassFile != null) { | ||
try { | ||
targetClassFile.delete(true, null); | ||
} catch (CoreException e) { | ||
// ignore | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Returns the mapped temporary class file for the specified class symbol. | ||
*/ | ||
public static File computeMappedTempClassFile(IContainer expectedOutputDir, String qualifiedClassName) { | ||
if (expectedOutputDir != null) { | ||
IPath baseOutputPath = getMappedTempOutput(expectedOutputDir); | ||
String fileName = qualifiedClassName.replace('.', File.separatorChar); | ||
IPath filePath = new Path(fileName); | ||
return baseOutputPath.append(filePath.addFileExtension(SuffixConstants.EXTENSION_class)).toFile(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Returns the expected class file for the specified class symbol. | ||
*/ | ||
public static IFile computeExpectedClassFile(IContainer expectedOutputDir, String qualifiedClassName) { | ||
if (expectedOutputDir != null) { | ||
String fileName = qualifiedClassName.replace('.', File.separatorChar); | ||
IPath filePath = new Path(fileName); | ||
return expectedOutputDir.getFile(filePath.addFileExtension(SuffixConstants.EXTENSION_class)); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* The upstream ImageBuilder expects the Javac Compiler to return the | ||
* class file as bytes instead of writing it directly to the target | ||
* output directory. To prevent conflicts with the ImageBuilder, we | ||
* configure Javac to generate the class file in a temporary location. | ||
* This method returns the mapped temporary output location for the | ||
* specified output directory. | ||
*/ | ||
public static IPath getMappedTempOutput(IContainer expectedOutput) { | ||
IProject project = expectedOutput.getProject(); | ||
if (project == null) { | ||
return expectedOutput.getRawLocation(); | ||
} | ||
|
||
IPath workingLocation = project.getWorkingLocation(JavaCore.PLUGIN_ID); | ||
String tempOutputName = expectedOutput.getName() + "_" + Integer.toHexString(expectedOutput.hashCode()); | ||
return workingLocation.append("javac/" + tempOutputName); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacCompilationResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Microsoft Corporation and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License 2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Microsoft Corporation - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.jdt.internal.javac; | ||
|
||
import java.util.Arrays; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
import java.util.stream.Stream; | ||
|
||
import org.eclipse.jdt.internal.compiler.CompilationResult; | ||
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; | ||
|
||
public class JavacCompilationResult extends CompilationResult { | ||
private Set<String[]> javacQualifiedReferences = new TreeSet<>((a, b) -> Arrays.compare(a, b)); | ||
private Set<String> javacSimpleNameReferences = new TreeSet<>(); | ||
private Set<String> javacRootReferences = new TreeSet<>(); | ||
private boolean isMigrated = false; | ||
|
||
public JavacCompilationResult(ICompilationUnit compilationUnit) { | ||
this(compilationUnit, 0, 0, Integer.MAX_VALUE); | ||
} | ||
|
||
public JavacCompilationResult(ICompilationUnit compilationUnit, int unitIndex, int totalUnitsKnown, | ||
int maxProblemPerUnit) { | ||
super(compilationUnit, unitIndex, totalUnitsKnown, maxProblemPerUnit); | ||
} | ||
|
||
public boolean addQualifiedReference(String[] qualifiedReference) { | ||
return this.javacQualifiedReferences.add(qualifiedReference); | ||
} | ||
|
||
public boolean addSimpleNameReference(String simpleNameReference) { | ||
return this.javacSimpleNameReferences.add(simpleNameReference); | ||
} | ||
|
||
public boolean addRootReference(String rootReference) { | ||
return this.javacRootReferences.add(rootReference); | ||
} | ||
|
||
public void migrateReferenceInfo() { | ||
if (isMigrated) { | ||
return; | ||
} | ||
|
||
this.simpleNameReferences = this.javacSimpleNameReferences.stream().map(String::toCharArray).toArray(char[][]::new); | ||
this.rootReferences = this.javacRootReferences.stream().map(String::toCharArray).toArray(char[][]::new); | ||
this.qualifiedReferences = this.javacQualifiedReferences.stream().map(qualifiedNames -> { | ||
// convert String[] to char[][] | ||
return Stream.of(qualifiedNames).map(String::toCharArray).toArray(char[][]::new); | ||
}).toArray(char[][][]::new); | ||
|
||
this.javacSimpleNameReferences.clear(); | ||
this.javacRootReferences.clear(); | ||
this.javacQualifiedReferences.clear(); | ||
this.isMigrated = true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.