Skip to content

Commit

Permalink
Merge branch 'dom-with-javac' into dom-with-javac-mine
Browse files Browse the repository at this point in the history
  • Loading branch information
robstryker authored Apr 16, 2024
2 parents f14d6bc + 364001e commit 9a86bc2
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,21 @@
package org.eclipse.jdt.internal.javac;

import java.nio.charset.Charset;
import java.util.Objects;
import java.util.stream.Stream;

import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;

import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CompilerConfiguration;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.tool.EclipseFileObject;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.builder.SourceFile;
Expand All @@ -37,10 +35,12 @@
import com.sun.tools.javac.util.List;

public class JavacCompiler extends Compiler {
CompilerConfiguration compilerConfig;

public JavacCompiler(INameEnvironment environment, IErrorHandlingPolicy policy, CompilerOptions options,
public JavacCompiler(INameEnvironment environment, IErrorHandlingPolicy policy, CompilerConfiguration compilerConfig,
ICompilerRequestor requestor, IProblemFactory problemFactory) {
super(environment, policy, options, requestor, problemFactory);
super(environment, policy, compilerConfig.getOptions(), requestor, problemFactory);
this.compilerConfig = compilerConfig;
}

@Override
Expand All @@ -56,7 +56,7 @@ public void compile(ICompilationUnit[] sourceUnits) {
// res.setProblems(newProblems);
// }
// });
JavacUtils.configureJavacContext(javacContext, this.options.getMap(), Stream.of(sourceUnits)
JavacUtils.configureJavacContext(javacContext, this.compilerConfig, Stream.of(sourceUnits)
.filter(SourceFile.class::isInstance)
.map(SourceFile.class::cast)
.map(source -> source.resource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CompilerConfiguration;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.core.JavaProject;

Expand All @@ -37,20 +38,37 @@
public class JavacUtils {

public static void configureJavacContext(Context context, Map<String, String> compilerOptions, IJavaProject javaProject) {
configureJavacContext(context, compilerOptions, javaProject, null);
}

public static void configureJavacContext(Context context, CompilerConfiguration compilerConfig, IJavaProject javaProject) {
configureJavacContext(context, compilerConfig.getOptions().getMap(), javaProject, compilerConfig);
}

private static void configureJavacContext(Context context, Map<String, String> compilerOptions, IJavaProject javaProject, CompilerConfiguration compilerConfig) {
Options options = Options.instance(context);
options.put(Option.XLINT, Boolean.TRUE.toString()); // TODO refine according to compilerOptions
if (Boolean.parseBoolean(compilerOptions.get(CompilerOptions.OPTION_EnablePreviews))) {
options.put(Option.PREVIEW, Boolean.toString(true));
}
String release = compilerOptions.get(CompilerOptions.OPTION_Release);
if (release != null) {
options.put(Option.RELEASE, release);
String compliance = compilerOptions.get(CompilerOptions.OPTION_Compliance);
if (CompilerOptions.ENABLED.equals(release) && compliance != null && !compliance.isEmpty()) {
options.put(Option.RELEASE, compliance);
}
String source = compilerOptions.get(CompilerOptions.OPTION_Source);
if (source != null && !source.isEmpty()) {
options.put(Option.SOURCE, source);
}
String target = compilerOptions.get(CompilerOptions.OPTION_TargetPlatform);
if (target != null && !target.isEmpty()) {
options.put(Option.TARGET, target);
}
options.put(Option.XLINT_CUSTOM, "all"); // TODO refine according to compilerOptions
// TODO populate more from compilerOptions and/or project settings
JavacFileManager.preRegister(context);
if (javaProject instanceof JavaProject internal) {
configurePaths(internal, context);
configurePaths(internal, context, compilerConfig);
}
Todo.instance(context); // initialize early
com.sun.tools.javac.main.JavaCompiler javac = new com.sun.tools.javac.main.JavaCompiler(context);
Expand All @@ -59,23 +77,69 @@ public static void configureJavacContext(Context context, Map<String, String> co
javac.lineDebugInfo = true;
}

private static void configurePaths(JavaProject javaProject, Context context) {
private static void configurePaths(JavaProject javaProject, Context context, CompilerConfiguration compilerConfig) {
JavacFileManager fileManager = (JavacFileManager)context.get(JavaFileManager.class);
try {
if (javaProject.getJavaProject() != null) {
if (compilerConfig != null && !compilerConfig.getSourceOutputMapping().isEmpty()) {
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, compilerConfig.getSourceOutputMapping().values().stream().distinct().toList());
} else if (javaProject.getJavaProject() != null) {
IResource member = javaProject.getProject().getParent().findMember(javaProject.getOutputLocation());
if( member != null ) {
File f = member.getLocation().toFile();
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, List.of(f));
}
}
fileManager.setLocation(StandardLocation.SOURCE_PATH, classpathEntriesToFiles(javaProject, entry -> entry.getEntryKind() == IClasspathEntry.CPE_SOURCE));
fileManager.setLocation(StandardLocation.CLASS_PATH, classpathEntriesToFiles(javaProject, entry -> entry.getEntryKind() != IClasspathEntry.CPE_SOURCE));

boolean sourcePathEnabled = false;
if (compilerConfig != null && !isEmpty(compilerConfig.getSourcepaths())) {
fileManager.setLocation(StandardLocation.SOURCE_PATH,
compilerConfig.getSourcepaths()
.stream()
.map(File::new)
.toList());
sourcePathEnabled = true;
}
if (compilerConfig != null && !isEmpty(compilerConfig.getModuleSourcepaths())) {
fileManager.setLocation(StandardLocation.MODULE_SOURCE_PATH,
compilerConfig.getModuleSourcepaths()
.stream()
.map(File::new)
.toList());
sourcePathEnabled = true;
}
if (!sourcePathEnabled) {
fileManager.setLocation(StandardLocation.SOURCE_PATH, classpathEntriesToFiles(javaProject, entry -> entry.getEntryKind() == IClasspathEntry.CPE_SOURCE));
}

boolean classpathEnabled = false;
if (compilerConfig != null && !isEmpty(compilerConfig.getClasspaths())) {
fileManager.setLocation(StandardLocation.CLASS_PATH,
compilerConfig.getClasspaths()
.stream()
.map(File::new)
.toList());
classpathEnabled = true;
}
if (compilerConfig != null && !isEmpty(compilerConfig.getModulepaths())) {
fileManager.setLocation(StandardLocation.MODULE_PATH,
compilerConfig.getModulepaths()
.stream()
.map(File::new)
.toList());
classpathEnabled = true;
}
if (!classpathEnabled) {
fileManager.setLocation(StandardLocation.CLASS_PATH, classpathEntriesToFiles(javaProject, entry -> entry.getEntryKind() != IClasspathEntry.CPE_SOURCE));
}
} catch (Exception ex) {
ILog.get().error(ex.getMessage(), ex);
}
}

private static <T> boolean isEmpty(List<T> list) {
return list == null || list.isEmpty();
}

private static List<File> classpathEntriesToFiles(JavaProject project, Predicate<IClasspathEntry> select) {
try {
IClasspathEntry[] selected = Arrays.stream(project.getRawClasspath())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*******************************************************************************
* 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.core.compiler;

import java.io.File;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;

public class CompilerConfiguration {
List<String> sourcepaths;
List<String> moduleSourcepaths;
List<String> classpaths;
List<String> modulepaths;
Map<File, File> sourceOutputMapping;
CompilerOptions options;

public List<String> getClasspaths() {
return this.classpaths;
}

public void setClasspaths(List<String> classpaths) {
this.classpaths = classpaths;
}

public List<String> getModulepaths() {
return this.modulepaths;
}

public void setModulepaths(List<String> modulepaths) {
this.modulepaths = modulepaths;
}

public List<String> getSourcepaths() {
return this.sourcepaths;
}

public void setSourcepaths(List<String> sourcepaths) {
this.sourcepaths = sourcepaths;
}

public List<String> getModuleSourcepaths() {
return this.moduleSourcepaths;
}

public void setModuleSourcepaths(List<String> moduleSourcepaths) {
this.moduleSourcepaths = moduleSourcepaths;
}

public Map<File, File> getSourceOutputMapping() {
return this.sourceOutputMapping;
}

public void setSourceOutputMapping(Map<File, File> sourceOutputMapping) {
this.sourceOutputMapping = sourceOutputMapping;
}

public CompilerOptions getOptions() {
return this.options;
}

public void setOptions(CompilerOptions options) {
this.options = options;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,12 @@ protected Compiler newCompiler() {
Constructor<? extends Compiler> constructor = compilerClass.getDeclaredConstructor(
INameEnvironment.class,
IErrorHandlingPolicy.class,
CompilerOptions.class,
CompilerConfiguration.class,
ICompilerRequestor.class,
IProblemFactory.class);
newCompiler = constructor.newInstance(this.nameEnvironment,
DefaultErrorHandlingPolicies.proceedWithAllProblems(),
compilerOptions,
prepareCompilerConfiguration(compilerOptions),
this,
ProblemFactory.getProblemFactory(Locale.getDefault()));
} catch (ClassNotFoundException e) {
Expand Down Expand Up @@ -624,6 +624,54 @@ protected Compiler newCompiler() {
return newCompiler;
}

private CompilerConfiguration prepareCompilerConfiguration(CompilerOptions options) {
CompilerConfiguration configuration = new CompilerConfiguration();
configuration.setOptions(options);

ClasspathLocation[] classpathLocations = this.nameEnvironment.binaryLocations;
List<String> classpaths = new ArrayList<>();
List<String> modulepaths = new ArrayList<>();
for (ClasspathLocation location : classpathLocations) {
if (location instanceof ClasspathDirectory cpDirectory) {
String filepath = cpDirectory.binaryFolder.getLocation().toFile().getAbsolutePath();
if (cpDirectory.isOnModulePath && !modulepaths.contains(filepath)) {
modulepaths.add(filepath);
} else if (!cpDirectory.isOnModulePath && !classpaths.contains(filepath)) {
classpaths.add(filepath);
}
} else if (location instanceof ClasspathJar cpJar) {
String filepath = cpJar.zipFilename;
if (cpJar.isOnModulePath && !modulepaths.contains(filepath)) {
modulepaths.add(filepath);
} else if (!cpJar.isOnModulePath && !classpaths.contains(filepath)) {
classpaths.add(filepath);
}
}
}
configuration.setClasspaths(classpaths);
configuration.setModulepaths(modulepaths);

Map<File, File> sourceOutputMapping = new HashMap<>();
List<String> sourcepaths = new ArrayList<>();
List<String> moduleSourcepaths = new ArrayList<>();
ClasspathMultiDirectory[] srcLocations = this.nameEnvironment.sourceLocations;
for (ClasspathMultiDirectory sourceLocation : srcLocations) {
File sourceFolder = sourceLocation.sourceFolder.getLocation().toFile();
File outputFolder = sourceLocation.binaryFolder.getLocation().toFile();
sourceOutputMapping.put(sourceFolder, outputFolder);
String sourcepath = sourceFolder.getAbsolutePath();
if (sourceLocation.isOnModulePath && !moduleSourcepaths.contains(sourcepath)) {
moduleSourcepaths.add(sourcepath);
} else if (!sourceLocation.isOnModulePath && !sourcepaths.contains(sourcepath)) {
sourcepaths.add(sourcepath);
}
}
configuration.setSourceOutputMapping(sourceOutputMapping);
configuration.setSourcepaths(sourcepaths);
configuration.setModuleSourcepaths(moduleSourcepaths);
return configuration;
}

protected CompilationParticipantResult[] notifyParticipants(SourceFile[] unitsAboutToCompile) {
CompilationParticipantResult[] results = new CompilationParticipantResult[unitsAboutToCompile.length];
for (int i = unitsAboutToCompile.length; --i >= 0;)
Expand Down

0 comments on commit 9a86bc2

Please sign in to comment.