Search in sources :

Example 1 with JavacProcessingEnvironment

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);
    }
}
Also used : JavacTaskImpl(org.eclipse.ceylon.langtools.tools.javac.api.JavacTaskImpl) SupportedAnnotationTypes(org.eclipse.ceylon.javax.annotation.processing.SupportedAnnotationTypes) Types(org.eclipse.ceylon.langtools.tools.javac.code.Types) Attribute(org.eclipse.ceylon.langtools.tools.javac.code.Attribute) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) ArrayList(java.util.ArrayList) Names(org.eclipse.ceylon.langtools.tools.javac.util.Names) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) StandardJavaFileManager(org.eclipse.ceylon.javax.tools.StandardJavaFileManager) Pool(org.eclipse.ceylon.langtools.tools.javac.jvm.Pool) HashSet(java.util.HashSet) Pair(org.eclipse.ceylon.langtools.tools.javac.util.Pair) JavaCompiler(org.eclipse.ceylon.javax.tools.JavaCompiler) ClassWriter(org.eclipse.ceylon.langtools.tools.javac.jvm.ClassWriter) Symtab(org.eclipse.ceylon.langtools.tools.javac.code.Symtab) JavacProcessingEnvironment(org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment) File(java.io.File) Location(org.eclipse.ceylon.javax.tools.JavaFileManager.Location) StandardLocation(org.eclipse.ceylon.javax.tools.StandardLocation)

Example 2 with JavacProcessingEnvironment

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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) JavacTask(org.eclipse.ceylon.langtools.source.util.JavacTask) BasicJavacTask(org.eclipse.ceylon.langtools.tools.javac.api.BasicJavacTask) PrintWriter(java.io.PrintWriter) JavaFileManager(org.eclipse.ceylon.javax.tools.JavaFileManager) IOException(java.io.IOException) JavacFileManager(org.eclipse.ceylon.langtools.tools.javac.file.JavacFileManager) AnnotationProcessingError(org.eclipse.ceylon.langtools.tools.javac.processing.AnnotationProcessingError) JavacProcessingEnvironment(org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment) File(java.io.File) Plugin(org.eclipse.ceylon.langtools.source.util.Plugin)

Example 3 with JavacProcessingEnvironment

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);
}
Also used : Context(org.eclipse.ceylon.langtools.tools.javac.util.Context) BasicJavacTask(org.eclipse.ceylon.langtools.tools.javac.api.BasicJavacTask) JavacProcessingEnvironment(org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment) BasicJavacTask(org.eclipse.ceylon.langtools.tools.javac.api.BasicJavacTask)

Aggregations

JavacProcessingEnvironment (org.eclipse.ceylon.langtools.tools.javac.processing.JavacProcessingEnvironment)3 File (java.io.File)2 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)2 BasicJavacTask (org.eclipse.ceylon.langtools.tools.javac.api.BasicJavacTask)2 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 SupportedAnnotationTypes (org.eclipse.ceylon.javax.annotation.processing.SupportedAnnotationTypes)1 JavaCompiler (org.eclipse.ceylon.javax.tools.JavaCompiler)1 JavaFileManager (org.eclipse.ceylon.javax.tools.JavaFileManager)1 Location (org.eclipse.ceylon.javax.tools.JavaFileManager.Location)1 StandardJavaFileManager (org.eclipse.ceylon.javax.tools.StandardJavaFileManager)1 StandardLocation (org.eclipse.ceylon.javax.tools.StandardLocation)1 JavacTask (org.eclipse.ceylon.langtools.source.util.JavacTask)1 Plugin (org.eclipse.ceylon.langtools.source.util.Plugin)1 JavacTaskImpl (org.eclipse.ceylon.langtools.tools.javac.api.JavacTaskImpl)1 Attribute (org.eclipse.ceylon.langtools.tools.javac.code.Attribute)1 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)1