use of org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment in project ceylon by eclipse.
the class CreateSymbols method createSymbols.
void createSymbols() throws IOException {
Set<String> legacy = getLegacyPackages();
Set<String> legacyProprietary = getLegacyPackages();
Set<String> documented = new HashSet<String>();
Set<PackageSymbol> packages = ((JavacProcessingEnvironment) processingEnv).getSpecifiedPackages();
Map<String, String> pOptions = processingEnv.getOptions();
String jarName = pOptions.get("org.eclipse.ceylon.langtools.tools.javac.sym.Jar");
if (jarName == null)
throw new RuntimeException("Must use -Aorg.eclipse.ceylon.langtools.tools.javac.sym.Jar=LOCATION_OF_JAR");
String destName = pOptions.get("org.eclipse.ceylon.langtools.tools.javac.sym.Dest");
if (destName == null)
throw new RuntimeException("Must use -Aorg.eclipse.ceylon.langtools.tools.javac.sym.Dest=LOCATION_OF_JAR");
String profileSpec = pOptions.get("org.eclipse.ceylon.langtools.tools.javac.sym.Profiles");
if (profileSpec == null)
throw new RuntimeException("Must use -Aorg.eclipse.ceylon.langtools.tools.javac.sym.Profiles=PROFILES_SPEC");
Profiles profiles = Profiles.read(new File(profileSpec));
for (PackageSymbol psym : packages) {
String name = psym.getQualifiedName().toString();
legacyProprietary.remove(name);
documented.add(name);
}
JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
Location jarLocation = StandardLocation.locationFor(jarName);
File jarFile = new File(jarName);
fm.setLocation(jarLocation, List.of(jarFile));
fm.setLocation(StandardLocation.CLASS_PATH, List.<File>nil());
fm.setLocation(StandardLocation.SOURCE_PATH, List.<File>nil());
{
ArrayList<File> bootClassPath = new ArrayList<File>();
bootClassPath.add(jarFile);
for (File path : fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) {
if (!new File(path.getName()).equals(new File("rt.jar")))
bootClassPath.add(path);
}
System.err.println("Using boot class path = " + bootClassPath);
fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);
}
// System.out.println(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH));
File destDir = new File(destName);
if (!destDir.exists())
if (!destDir.mkdirs())
throw new RuntimeException("Could not create " + destDir);
fm.setLocation(StandardLocation.CLASS_OUTPUT, List.of(destDir));
Set<String> hiddenPackages = new HashSet<String>();
Set<String> crisp = new HashSet<String>();
List<String> options = List.of("-XDdev");
// options = options.prepend("-doe");
// options = options.prepend("-verbose");
JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, options, null, null);
org.eclipse.ceylon.langtools.tools.javac.main.JavaCompiler compiler = org.eclipse.ceylon.langtools.tools.javac.main.JavaCompiler.instance(task.getContext());
ClassWriter writer = ClassWriter.instance(task.getContext());
Symtab syms = Symtab.instance(task.getContext());
Names names = Names.instance(task.getContext());
Attribute.Compound proprietaryAnno = new Attribute.Compound(syms.proprietaryType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
Attribute.Compound[] profileAnnos = new Attribute.Compound[profiles.getProfileCount() + 1];
Symbol.MethodSymbol profileValue = (MethodSymbol) syms.profileType.tsym.members().lookup(names.value).sym;
for (int i = 1; i < profileAnnos.length; i++) {
profileAnnos[i] = new Attribute.Compound(syms.profileType, List.<Pair<Symbol.MethodSymbol, Attribute>>of(new Pair<Symbol.MethodSymbol, Attribute>(profileValue, new Attribute.Constant(syms.intType, i))));
}
Type.moreInfo = true;
Types types = Types.instance(task.getContext());
Pool pool = new Pool(types);
for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(JavaFileObject.Kind.CLASS), true)) {
String className = fm.inferBinaryName(jarLocation, file);
int index = className.lastIndexOf('.');
String pckName = index == -1 ? "" : className.substring(0, index);
boolean addLegacyAnnotation = false;
if (documented.contains(pckName)) {
if (!legacy.contains(pckName))
crisp.add(pckName);
// System.out.println("Documented: " + className);
} else if (legacyProprietary.contains(pckName)) {
addLegacyAnnotation = true;
// System.out.println("Legacy proprietary: " + className);
} else {
// System.out.println("Hidden " + className);
hiddenPackages.add(pckName);
continue;
}
TypeSymbol sym = (TypeSymbol) compiler.resolveIdent(className);
if (sym.kind != Kinds.TYP) {
if (className.indexOf('$') < 0) {
System.err.println("Ignoring (other) " + className + " : " + sym);
System.err.println(" " + sym.getClass().getSimpleName() + " " + sym.type);
}
continue;
}
sym.complete();
if (sym.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
System.err.println("Ignoring (bad) " + sym.getQualifiedName());
continue;
}
ClassSymbol cs = (ClassSymbol) sym;
if (addLegacyAnnotation) {
cs.prependAttributes(List.of(proprietaryAnno));
}
int p = profiles.getProfile(cs.fullname.toString().replace(".", "/"));
if (0 < p && p < profileAnnos.length)
cs.prependAttributes(List.of(profileAnnos[p]));
writeClass(pool, cs, writer);
}
if (false) {
for (String pckName : crisp) System.out.println("Crisp: " + pckName);
for (String pckName : hiddenPackages) System.out.println("Hidden: " + pckName);
for (String pckName : legacyProprietary) System.out.println("Legacy proprietary: " + pckName);
for (String pckName : documented) System.out.println("Documented: " + pckName);
}
}
use of org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment in project ceylon by eclipse.
the class Main method compile.
public Result compile(String[] args, String[] classNames, Context context, List<JavaFileObject> fileObjects, Iterable<? extends Processor> processors) {
context.put(Log.outKey, out);
log = Log.instance(context);
if (options == null)
// creates a new one
options = Options.instance(context);
filenames = new LinkedHashSet<File>();
classnames = new ListBuffer<String>();
JavaCompiler comp = null;
/*
* TODO: Logic below about what is an acceptable command line
* should be updated to take annotation processing semantics
* into account.
*/
try {
if (args.length == 0 && (classNames == null || classNames.length == 0) && fileObjects.isEmpty()) {
Option.HELP.process(optionHelper, "-help");
return Result.CMDERR;
}
Collection<File> files;
try {
files = processArgs(CommandLine.parse(args), classNames);
if (files == null) {
// null signals an error in options, abort
return Result.CMDERR;
} else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) {
// it is allowed to compile nothing if just asking for help or version info
if (options.isSet(HELP) || options.isSet(X) || options.isSet(VERSION) || options.isSet(FULLVERSION))
return Result.OK;
if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
error("err.no.source.files.classes");
} else {
error("err.no.source.files");
}
return Result.CMDERR;
}
} catch (java.io.FileNotFoundException e) {
warning("err.file.not.found", e.getMessage());
return Result.SYSERR;
}
boolean forceStdOut = options.isSet("stdout");
if (forceStdOut) {
log.flush();
log.setWriters(new PrintWriter(System.out, true));
}
// allow System property in following line as a Mustang legacy
boolean batchMode = (options.isUnset("nonBatchMode") && System.getProperty("nonBatchMode") == null);
if (batchMode)
CacheFSInfo.preRegister(context);
// FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
// invoke any available plugins
String plugins = options.get(PLUGIN);
if (plugins != null) {
JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
ClassLoader cl = pEnv.getProcessorClassLoader();
ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, cl);
Set<List<String>> pluginsToCall = new LinkedHashSet<List<String>>();
for (String plugin : plugins.split("\\x00")) {
pluginsToCall.add(List.from(plugin.split("\\s+")));
}
JavacTask task = null;
Iterator<Plugin> iter = sl.iterator();
while (iter.hasNext()) {
Plugin plugin = iter.next();
for (List<String> p : pluginsToCall) {
if (plugin.getName().equals(p.head)) {
pluginsToCall.remove(p);
try {
if (task == null)
task = JavacTask.instance(pEnv);
plugin.init(task, p.tail.toArray(new String[p.tail.size()]));
} catch (Throwable ex) {
if (apiMode)
throw new RuntimeException(ex);
pluginMessage(ex);
return Result.SYSERR;
}
}
}
}
for (List<String> p : pluginsToCall) {
log.printLines(PrefixKind.JAVAC, "msg.plugin.not.found", p.head);
}
}
comp = JavaCompiler.instance(context);
fileManager = context.get(JavaFileManager.class);
if (!files.isEmpty()) {
// add filenames to fileObjects
comp = JavaCompiler.instance(context);
List<JavaFileObject> otherFiles = List.nil();
JavacFileManager dfm = (JavacFileManager) fileManager;
for (JavaFileObject fo : dfm.getJavaFileObjectsFromFiles(files)) otherFiles = otherFiles.prepend(fo);
for (JavaFileObject fo : otherFiles) fileObjects = fileObjects.prepend(fo);
}
comp.compile(fileObjects, classnames.toList(), processors);
if (log.expectDiagKeys != null) {
if (log.expectDiagKeys.isEmpty()) {
log.printRawLines("all expected diagnostics found");
return Result.OK;
} else {
log.printRawLines("expected diagnostic keys not found: " + log.expectDiagKeys);
return Result.ERROR;
}
}
if (comp.errorCount() != 0)
return Result.ERROR;
} catch (IOException ex) {
ioMessage(ex);
return Result.SYSERR;
} catch (OutOfMemoryError ex) {
resourceMessage(ex);
return Result.SYSERR;
} catch (StackOverflowError ex) {
resourceMessage(ex);
return Result.SYSERR;
} catch (FatalError ex) {
feMessage(ex);
return Result.SYSERR;
} catch (AnnotationProcessingError ex) {
if (apiMode)
throw new RuntimeException(ex.getCause());
apMessage(ex);
return Result.SYSERR;
} catch (ClientCodeException ex) {
// and org.eclipse.ceylon.javax.tools.JavaCompiler.CompilationTask#call
throw new RuntimeException(ex.getCause());
} catch (PropagatedException ex) {
throw ex.getCause();
} catch (Throwable ex) {
// exceptions.
if (comp == null || comp.errorCount() == 0 || options == null || options.isSet("dev"))
bugMessage(ex);
return Result.ABNORMAL;
} finally {
if (comp != null) {
try {
comp.close();
} catch (ClientCodeException ex) {
throw new RuntimeException(ex.getCause());
}
}
filenames = null;
options = null;
}
return Result.OK;
}
use of org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment in project ceylon by eclipse.
the class JavacTask method instance.
/**
* Get the {@code JavacTask} for a {@code ProcessingEnvironment}.
* If the compiler is being invoked using a
* {@link org.eclipse.ceylon.javax.tools.JavaCompiler.CompilationTask CompilationTask},
* then that task will be returned.
* @param processingEnvironment the processing environment
* @return the {@code JavacTask} for a {@code ProcessingEnvironment}
* @since 1.8
*/
public static JavacTask instance(ProcessingEnvironment processingEnvironment) {
if (!processingEnvironment.getClass().getName().equals("org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment"))
throw new IllegalArgumentException();
Context c = ((JavacProcessingEnvironment) processingEnvironment).getContext();
JavacTask t = c.get(JavacTask.class);
return (t != null) ? t : new BasicJavacTask(c, true);
}
Aggregations