org.eclipse.jdt.internal.compiler.tool.EclipseCompiler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ecj Show documentation
Show all versions of ecj Show documentation
Eclipse Compiler for Java(TM)
/*******************************************************************************
* Copyright (c) 2006, 2018 IBM Corporation and others.
*
* 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:
* IBM Corporation - initial API and implementation
* Frits Jalvingh - fix for bug 533830.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.tool;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import java.util.WeakHashMap;
import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import org.eclipse.jdt.internal.compiler.batch.Main;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
/**
* Implementation of a batch compiler that supports the jsr199
*/
public class EclipseCompiler implements JavaCompiler {
private static Set SupportedSourceVersions;
static {
// Eclipse compiler supports all possible versions from version 0 to
// the latest supported by the VM
// we don't care about the order
EnumSet enumSet = EnumSet.range(SourceVersion.RELEASE_0, SourceVersion.latest());
// we don't want anybody to modify this list
EclipseCompiler.SupportedSourceVersions = Collections.unmodifiableSet(enumSet);
}
WeakHashMap threadCache;
public DiagnosticListener super JavaFileObject> diagnosticListener;
public EclipseCompiler() {
this.threadCache = new WeakHashMap<>();
}
/*
* (non-Javadoc)
*
* @see javax.tools.Tool#getSourceVersions()
*/
@Override
public Set getSourceVersions() {
return EclipseCompiler.SupportedSourceVersions;
}
/*
* (non-Javadoc)
*
* @see javax.tools.JavaCompiler#getStandardFileManager(javax.tools.DiagnosticListener,
* java.util.Locale, java.nio.charset.Charset)
*/
@Override
public StandardJavaFileManager getStandardFileManager(DiagnosticListener super JavaFileObject> someDiagnosticListener, Locale locale, Charset charset) {
this.diagnosticListener = someDiagnosticListener;
return new EclipseFileManager(locale, charset);
}
/*
* (non-Javadoc)
*
* @see javax.tools.JavaCompiler#getTask(java.io.Writer,
* javax.tools.JavaFileManager, javax.tools.DiagnosticListener,
* java.lang.Iterable, java.lang.Iterable, java.lang.Iterable)
*/
@Override
public CompilationTask getTask(Writer out, JavaFileManager fileManager, DiagnosticListener super JavaFileObject> someDiagnosticListener, Iterable options, Iterable classes, Iterable extends JavaFileObject> compilationUnits) {
PrintWriter writerOut = null;
PrintWriter writerErr = null;
if (out == null) {
writerOut = new PrintWriter(System.err);
writerErr = new PrintWriter(System.err);
} else {
writerOut = new PrintWriter(out);
writerErr = new PrintWriter(out);
}
final Thread currentThread = Thread.currentThread();
EclipseCompilerImpl eclipseCompiler = this.threadCache.get(currentThread);
if (eclipseCompiler == null) {
eclipseCompiler = new EclipseCompilerImpl(writerOut, writerErr, false);
this.threadCache.put(currentThread, eclipseCompiler);
} else {
eclipseCompiler.initialize(writerOut, writerErr, false, null/*options*/, null/*progress*/);
}
final EclipseCompilerImpl eclipseCompiler2 = new EclipseCompilerImpl(writerOut, writerErr, false);
eclipseCompiler2.compilationUnits = compilationUnits;
eclipseCompiler2.diagnosticListener = someDiagnosticListener;
if (fileManager != null) {
eclipseCompiler2.fileManager = fileManager;
} else {
eclipseCompiler2.fileManager = this.getStandardFileManager(someDiagnosticListener, null, null);
}
String latest = CompilerOptions.getLatestVersion();
eclipseCompiler2.options.put(CompilerOptions.OPTION_Compliance, latest);
eclipseCompiler2.options.put(CompilerOptions.OPTION_Source, latest);
eclipseCompiler2.options.put(CompilerOptions.OPTION_TargetPlatform, latest);
ArrayList allOptions = new ArrayList<>();
if (options != null) {
for (Iterator iterator = options.iterator(); iterator.hasNext(); ) {
eclipseCompiler2.fileManager.handleOption(iterator.next(), iterator);
}
for (String option : options) {
allOptions.add(option);
}
}
if (compilationUnits != null) {
for (JavaFileObject javaFileObject : compilationUnits) {
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6419926
// compells us to check that the returned URIs are absolute,
// which they happen not to be for the default compiler on some
// unices
URI uri = javaFileObject.toUri();
if (!uri.isAbsolute()) {
uri = URI.create("file://" + uri.toString()); //$NON-NLS-1$
}
if (uri.getScheme().equals("file")) { //$NON-NLS-1$
allOptions.add(new File(uri).getAbsolutePath());
} else {
allOptions.add(uri.toString());
}
}
}
if (classes != null && classes.iterator().hasNext()) {
allOptions.add("-classNames"); //$NON-NLS-1$
StringBuilder builder = new StringBuilder();
int i = 0;
for (String className : classes) {
if (i != 0) {
builder.append(',');
}
builder.append(className);
i++;
}
allOptions.add(String.valueOf(builder));
}
final String[] optionsToProcess = new String[allOptions.size()];
allOptions.toArray(optionsToProcess);
try {
eclipseCompiler2.configure(optionsToProcess);
} catch (IllegalArgumentException e) {
if(null != someDiagnosticListener)
someDiagnosticListener.report(new ExceptionDiagnostic(e));
throw e;
}
if (eclipseCompiler2.fileManager instanceof StandardJavaFileManager) {
StandardJavaFileManager javaFileManager = (StandardJavaFileManager) eclipseCompiler2.fileManager;
Iterable extends File> location = javaFileManager.getLocation(StandardLocation.CLASS_OUTPUT);
if (location != null) {
eclipseCompiler2.setDestinationPath(location.iterator().next().getAbsolutePath());
}
}
return new CompilationTask() {
private boolean hasRun = false;
@Override
public Boolean call() {
// set up compiler with passed options
if (this.hasRun) {
throw new IllegalStateException("This task has already been run"); //$NON-NLS-1$
}
Boolean value = eclipseCompiler2.call() ? Boolean.TRUE : Boolean.FALSE;
this.hasRun = true;
return value;
}
@Override
public void setLocale(Locale locale) {
eclipseCompiler2.setLocale(locale);
}
@Override
public void setProcessors(Iterable extends Processor> processors) {
ArrayList temp = new ArrayList<>();
for (Processor processor : processors) {
temp.add(processor);
}
Processor[] processors2 = new Processor[temp.size()];
temp.toArray(processors2);
eclipseCompiler2.processors = processors2;
}
@Override
public void addModules(Iterable mods) {
if (eclipseCompiler2.rootModules == Collections.EMPTY_SET) {
eclipseCompiler2.rootModules = new HashSet<>();
}
for (String mod : mods) {
eclipseCompiler2.rootModules.add(mod);
}
}
};
}
/*
* (non-Javadoc)
*
* @see javax.tools.OptionChecker#isSupportedOption(java.lang.String)
*/
@Override
public int isSupportedOption(String option) {
return Options.processOptions(option);
}
/*
* (non-Javadoc)
*
* @see javax.tools.Tool#run(java.io.InputStream, java.io.OutputStream,
* java.io.OutputStream, java.lang.String[])
*/
@Override
public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
boolean succeed = new Main(
new PrintWriter(new OutputStreamWriter(out != null ? out : System.out)),
new PrintWriter(new OutputStreamWriter(err != null ? err : System.err)),
true/* systemExit */,
null/* options */,
null/* progress */).compile(arguments);
return succeed ? 0 : -1;
}
}