Search in sources :

Example 31 with JCTree

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.

the class JavaCompiler method enterTrees.

/**
 * Enter the symbols found in a list of parse trees.
 * As a side-effect, this puts elements on the "todo" list.
 * Also stores a list of all top level classes in rootClasses.
 */
public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
    // enter symbols for all files
    if (!taskListener.isEmpty()) {
        for (JCCompilationUnit unit : roots) {
            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
            taskListener.started(e);
        }
    }
    enter.main(roots);
    if (!taskListener.isEmpty()) {
        for (JCCompilationUnit unit : roots) {
            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
            taskListener.finished(e);
        }
    }
    // the original compilation units listed on the command line.
    if (needRootClasses || sourceOutput || stubOutput) {
        ListBuffer<JCClassDecl> cdefs = new ListBuffer<>();
        for (JCCompilationUnit unit : roots) {
            for (List<JCTree> defs = unit.defs; defs.nonEmpty(); defs = defs.tail) {
                if (defs.head instanceof JCClassDecl)
                    cdefs.append((JCClassDecl) defs.head);
            }
        }
        rootClasses = cdefs.toList();
    }
    // cleaned and are being reused.
    for (JCCompilationUnit unit : roots) {
        inputFiles.add(unit.sourcefile);
    }
    return roots;
}
Also used : TaskEvent(org.eclipse.ceylon.langtools.source.util.TaskEvent) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)

Example 32 with JCTree

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.

the class JavaCompiler method desugar.

/**
 * Prepare attributed parse trees, in conjunction with their attribution contexts,
 * for source or code generation. If the file was not listed on the command line,
 * the current implicitSourcePolicy is taken into account.
 * The preparation stops as soon as an error is found.
 */
protected void desugar(final Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) {
    if (shouldStop(CompileState.TRANSTYPES))
        return;
    if (implicitSourcePolicy == ImplicitSourcePolicy.NONE && !inputFiles.contains(env.toplevel.sourcefile)) {
        return;
    }
    if (compileStates.isDone(env, CompileState.LOWER)) {
        results.addAll(desugaredEnvs.get(env));
        return;
    }
    /**
     * Ensure that superclasses of C are desugared before C itself. This is
     * required for two reasons: (i) as erasure (TransTypes) destroys
     * information needed in flow analysis and (ii) as some checks carried
     * out during lowering require that all synthetic fields/methods have
     * already been added to C and its superclasses.
     */
    class ScanNested extends TreeScanner {

        Set<Env<AttrContext>> dependencies = new LinkedHashSet<Env<AttrContext>>();

        protected boolean hasLambdas;

        @Override
        public void visitClassDef(JCClassDecl node) {
            Type st = types.supertype(node.sym.type);
            boolean envForSuperTypeFound = false;
            while (!envForSuperTypeFound && st.hasTag(CLASS)) {
                ClassSymbol c = st.tsym.outermostClass();
                Env<AttrContext> stEnv = enter.getEnv(c);
                if (stEnv != null && env != stEnv) {
                    if (dependencies.add(stEnv)) {
                        boolean prevHasLambdas = hasLambdas;
                        try {
                            scan(stEnv.tree);
                        } finally {
                            /*
                                 * ignore any updates to hasLambdas made during
                                 * the nested scan, this ensures an initalized
                                 * LambdaToMethod is available only to those
                                 * classes that contain lambdas
                                 */
                            hasLambdas = prevHasLambdas;
                        }
                    }
                    envForSuperTypeFound = true;
                }
                st = types.supertype(st);
            }
            super.visitClassDef(node);
        }

        @Override
        public void visitLambda(JCLambda tree) {
            hasLambdas = true;
            super.visitLambda(tree);
        }

        @Override
        public void visitReference(JCMemberReference tree) {
            hasLambdas = true;
            super.visitReference(tree);
        }
    }
    ScanNested scanner = new ScanNested();
    scanner.scan(env.tree);
    for (Env<AttrContext> dep : scanner.dependencies) {
        if (!compileStates.isDone(dep, CompileState.FLOW))
            desugaredEnvs.put(dep, desugar(flow(attribute(dep))));
    }
    // have been attributed and analyzed at this stage
    if (shouldStop(CompileState.TRANSTYPES))
        return;
    if (verboseCompilePolicy)
        printNote("[desugar " + env.enclClass.sym + "]");
    JavaFileObject prev = log.useSource(env.enclClass.sym.sourcefile != null ? env.enclClass.sym.sourcefile : env.toplevel.sourcefile);
    try {
        // save tree prior to rewriting
        JCTree untranslated = env.tree;
        make.at(Position.FIRSTPOS);
        TreeMaker localMake = make.forToplevel(env.toplevel);
        if (env.tree instanceof JCCompilationUnit) {
            if (!(stubOutput || sourceOutput || printFlat)) {
                if (shouldStop(CompileState.LOWER))
                    return;
                List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake);
                if (pdef.head != null) {
                    Assert.check(pdef.tail.isEmpty());
                    results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl) pdef.head));
                }
            }
            return;
        }
        if (stubOutput) {
            // emit stub Java source file, only for compilation
            // units enumerated explicitly on the command line
            JCClassDecl cdef = (JCClassDecl) env.tree;
            if (untranslated instanceof JCClassDecl && rootClasses.contains((JCClassDecl) untranslated) && ((cdef.mods.flags & (Flags.PROTECTED | Flags.PUBLIC)) != 0 || cdef.sym.packge().getQualifiedName() == names.java_lang)) {
                results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef)));
            }
            return;
        }
        if (shouldStop(CompileState.TRANSTYPES))
            return;
        env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
        compileStates.put(env, CompileState.TRANSTYPES);
        if (source.allowLambda() && scanner.hasLambdas) {
            if (shouldStop(CompileState.UNLAMBDA))
                return;
            env.tree = LambdaToMethod.instance(context).translateTopLevelClass(env, env.tree, localMake);
            compileStates.put(env, CompileState.UNLAMBDA);
        }
        if (shouldStop(CompileState.LOWER))
            return;
        if (sourceOutput) {
            // emit standard Java source file, only for compilation
            // units enumerated explicitly on the command line
            JCClassDecl cdef = (JCClassDecl) env.tree;
            if (untranslated instanceof JCClassDecl && rootClasses.contains((JCClassDecl) untranslated)) {
                results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
            }
            return;
        }
        // translate out inner classes
        List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);
        compileStates.put(env, CompileState.LOWER);
        if (shouldStop(CompileState.LOWER))
            return;
        // generate code for each class
        for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
            JCClassDecl cdef = (JCClassDecl) l.head;
            results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
        }
    } finally {
        log.useSource(prev);
    }
}
Also used : HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject)

Example 33 with JCTree

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.

the class JavaCompiler method parse.

/**
 * Parse contents of input stream.
 *  @param filename     The name of the file from which input stream comes.
 *  @param content      The characters to be parsed.
 */
protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {
    long msec = now();
    JCCompilationUnit tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
    if (content != null) {
        if (verbose) {
            log.printVerbose("parsing.started", filename);
        }
        if (!taskListener.isEmpty()) {
            TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, filename);
            taskListener.started(e);
            keepComments = true;
            genEndPos = true;
        }
        Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo);
        tree = parser.parseCompilationUnit();
        if (verbose) {
            log.printVerbose("parsing.done", Long.toString(elapsed(msec)));
        }
    }
    tree.sourcefile = filename;
    if (content != null && !taskListener.isEmpty()) {
        TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, tree);
        taskListener.finished(e);
    }
    return tree;
}
Also used : TaskEvent(org.eclipse.ceylon.langtools.source.util.TaskEvent) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)

Example 34 with JCTree

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.

the class JavaCompiler method resolveIdent.

/**
 * Resolve an identifier.
 * @param name      The identifier to resolve
 */
public Symbol resolveIdent(String name) {
    if (name.equals(""))
        return syms.errSymbol;
    JavaFileObject prev = log.useSource(null);
    try {
        JCExpression tree = null;
        for (String s : name.split("\\.", -1)) {
            if (// TODO: check for keywords
            !SourceVersion.isIdentifier(s))
                return syms.errSymbol;
            tree = (tree == null) ? make.Ident(names.fromString(s)) : make.Select(tree, names.fromString(s));
        }
        JCCompilationUnit toplevel = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
        toplevel.packge = syms.unnamedPackage;
        return attr.attribIdent(tree, toplevel);
    } finally {
        log.useSource(prev);
    }
}
Also used : JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)

Example 35 with JCTree

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.

the class JavaCompiler method complete.

/**
 * Complete compiling a source file that has been accessed
 *  by the class file reader.
 *  @param c          The class the source file of which needs to be compiled.
 */
public void complete(ClassSymbol c) throws CompletionFailure {
    // System.err.println("completing " + c);//DEBUG
    if (completionFailureName == c.fullname) {
        throw new CompletionFailure(c, "user-selected completion failure by class name");
    }
    JCCompilationUnit tree;
    JavaFileObject filename = c.classfile;
    JavaFileObject prev = log.useSource(filename);
    try {
        tree = parse(filename, filename.getCharContent(false));
    } catch (IOException e) {
        log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
        tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
    } finally {
        log.useSource(prev);
    }
    if (!taskListener.isEmpty()) {
        TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
        taskListener.started(e);
    }
    enter.complete(List.of(tree), c);
    if (!taskListener.isEmpty()) {
        TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
        taskListener.finished(e);
    }
    if (enter.getEnv(c) == null) {
        boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
        if (isPkgInfo) {
            if (enter.getEnv(tree.packge) == null) {
                JCDiagnostic diag = diagFactory.fragment("file.does.not.contain.package", c.location());
                throw reader.new BadClassFile(c, filename, diag);
            }
        } else {
            JCDiagnostic diag = diagFactory.fragment("file.doesnt.contain.class", c.getQualifiedName());
            throw reader.new BadClassFile(c, filename, diag);
        }
    }
    implicitSourceFilesRead = true;
}
Also used : JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) TaskEvent(org.eclipse.ceylon.langtools.source.util.TaskEvent) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)

Aggregations

JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)101 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)19 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)18 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)12 JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)10 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)9 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)8 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)8 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)8 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)8 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)7 Type (org.eclipse.ceylon.model.typechecker.model.Type)6 JCAnnotation (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)5 JCBlock (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock)4 JCClassDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCClassDecl)4 JCCompilationUnit (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit)4 JCPrimitiveTypeTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree)4 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)4 IOException (java.io.IOException)3 TaskEvent (org.eclipse.ceylon.langtools.source.util.TaskEvent)3