Search in sources :

Example 6 with JCCompilationUnit

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

the class LanguageCompiler method loadModuleFromSource.

private Module loadModuleFromSource(String pkgName, LinkedList<JCCompilationUnit> moduleTrees, List<JCCompilationUnit> parsedTrees) {
    if (pkgName.isEmpty())
        return null;
    String moduleClassName = pkgName + ".module";
    JavaFileObject fileObject;
    try {
        if (options.get(Option.VERBOSE) != null) {
            log.printRawLines(WriterKind.NOTICE, "[Trying to load source for module " + moduleClassName + "]");
        }
        fileObject = fileManager.getJavaFileForInput(StandardLocation.SOURCE_PATH, moduleClassName, Kind.SOURCE);
        if (options.get(Option.VERBOSE) != null) {
            log.printRawLines(WriterKind.NOTICE, "[Got file object: " + fileObject + "]");
        }
    } catch (IOException e) {
        e.printStackTrace();
        return loadModuleFromSource(getParentPackage(pkgName), moduleTrees, parsedTrees);
    }
    if (fileObject != null) {
        // we really want to compile.
        for (JCCompilationUnit parsedTree : parsedTrees) {
            if (parsedTree.sourcefile.equals(fileObject) && parsedTree instanceof CeylonCompilationUnit) {
                // same file! we already parsed it, let's return this one's module
                PhasedUnit phasedUnit = ((CeylonCompilationUnit) parsedTree).phasedUnit;
                // the module visitor does load the module but does not set the unit's package module
                if (phasedUnit.getPackage().getModule() == null) {
                    // so find the module it created
                    for (Module mod : ceylonContext.getModules().getListOfModules()) {
                        // we recognise it with the unit
                        if (mod.getUnit() == phasedUnit.getUnit()) {
                            // set the package's module
                            Package pkg = phasedUnit.getPackage();
                            pkg.setModule(mod);
                            mod.getPackages().add(pkg);
                            modulesLoadedFromSource.add(mod);
                            break;
                        }
                    }
                }
                // now return it
                return phasedUnit.getPackage().getModule();
            }
        }
        JCCompilationUnit javaCompilationUnit = parse(fileObject);
        Module module;
        if (javaCompilationUnit instanceof CeylonCompilationUnit) {
            CeylonCompilationUnit ceylonCompilationUnit = (CeylonCompilationUnit) javaCompilationUnit;
            moduleTrees.add(ceylonCompilationUnit);
            // parse the module info from there
            module = ceylonCompilationUnit.phasedUnit.visitSrcModulePhase();
            ceylonCompilationUnit.phasedUnit.visitRemainingModulePhase();
            // now set the module
            if (module != null) {
                ceylonCompilationUnit.phasedUnit.getPackage().setModule(module);
            }
        } else {
            // there was a syntax error in the module descriptor, make a pretend module so that we can
            // correctly mark all declarations as part of that module, but we won't generate any code
            // for it
            ModuleManager moduleManager = phasedUnits.getModuleManager();
            module = moduleManager.getOrCreateModule(Arrays.asList(pkgName.split("\\.")), "bogus");
        }
        // now remember it
        if (module != null) {
            modulesLoadedFromSource.add(module);
            return module;
        }
    }
    return loadModuleFromSource(getParentPackage(pkgName), moduleTrees, parsedTrees);
}
Also used : JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) CeylonCompilationUnit(org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit) IOException(java.io.IOException) Package(org.eclipse.ceylon.model.typechecker.model.Package) Module(org.eclipse.ceylon.model.typechecker.model.Module) ModuleManager(org.eclipse.ceylon.model.typechecker.util.ModuleManager) PhasedUnit(org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit)

Example 7 with JCCompilationUnit

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

the class LanguageCompiler method loadCompiledModules.

private List<JCCompilationUnit> loadCompiledModules(List<JCCompilationUnit> trees, LinkedList<JCCompilationUnit> moduleTrees) {
    compilerDelegate.visitModules(phasedUnits);
    Modules modules = ceylonContext.getModules();
    // now make sure the phase units have their modules and packages set correctly
    for (PhasedUnit pu : phasedUnits.getPhasedUnits()) {
        Package pkg = pu.getPackage();
        loadModuleFromSource(pkg, modules, moduleTrees, trees);
    }
    // also make sure we have packages and modules set up for every Java file we compile
    for (JCCompilationUnit cu : trees) {
        // skip Ceylon CUs
        if (cu instanceof CeylonCompilationUnit)
            continue;
        String packageName = "";
        if (cu.pid != null)
            packageName = TreeInfo.fullName(cu.pid).toString();
        /*
             * Stef: see javadoc for findOrCreateModulelessPackage() for why this is here.
             */
        Package pkg = modelLoader.findOrCreateModulelessPackage(packageName);
        loadModuleFromSource(pkg, modules, moduleTrees, trees);
    }
    for (PhasedUnit phasedUnit : phasedUnits.getPhasedUnits()) {
        if (!phasedUnit.getCompilationUnit().getModuleDescriptors().isEmpty()) {
            String name = phasedUnit.getPackage().getNameAsString();
            CeylonPhasedUnit cpu = (CeylonPhasedUnit) phasedUnit;
            CeylonFileObject cfo = (CeylonFileObject) cpu.getFileObject();
            moduleNamesToFileObjects.put(name, cfo);
        }
    }
    if (addModuleTrees) {
        for (JCCompilationUnit moduleTree : moduleTrees) {
            trees = trees.append(moduleTree);
        }
    }
    return trees;
}
Also used : JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) CeylonCompilationUnit(org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit) Modules(org.eclipse.ceylon.model.typechecker.model.Modules) Package(org.eclipse.ceylon.model.typechecker.model.Package) CeylonFileObject(org.eclipse.ceylon.compiler.java.codegen.CeylonFileObject) PhasedUnit(org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit)

Example 8 with JCCompilationUnit

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

the class LanguageCompiler method ceylonParse.

private JCCompilationUnit ceylonParse(JavaFileObject filename, CharSequence readSource) {
    if (ceylonEnter.hasRun())
        throw new RunTwiceException("Trying to load new source file after CeylonEnter has been called: " + filename);
    try {
        ModuleManager moduleManager = phasedUnits.getModuleManager();
        ModuleSourceMapper moduleSourceMapper = phasedUnits.getModuleSourceMapper();
        File sourceFile = new File(filename.getName());
        // FIXME: temporary solution
        VirtualFile file = vfs.getFromFile(sourceFile);
        VirtualFile srcDir = vfs.getFromFile(getSrcDir(sourceFile));
        String source = readSource.toString();
        char[] chars = source.toCharArray();
        LineMap map = Position.makeLineMap(chars, chars.length, false);
        PhasedUnit phasedUnit = null;
        PhasedUnit externalPhasedUnit = compilerDelegate.getExternalSourcePhasedUnit(srcDir, file);
        String suppressWarnings = options.get(Option.CEYLONSUPPRESSWARNINGS);
        final EnumSet<Warning> suppressedWarnings;
        if (suppressWarnings != null) {
            if (suppressWarnings.trim().isEmpty()) {
                suppressedWarnings = EnumSet.allOf(Warning.class);
            } else {
                suppressedWarnings = EnumSet.noneOf(Warning.class);
                for (String name : suppressWarnings.trim().split(" *, *")) {
                    suppressedWarnings.add(Warning.valueOf(name));
                }
            }
        } else {
            suppressedWarnings = EnumSet.noneOf(Warning.class);
        }
        if (externalPhasedUnit != null) {
            phasedUnit = new CeylonPhasedUnit(externalPhasedUnit, filename, map);
            phasedUnit.setSuppressedWarnings(suppressedWarnings);
            phasedUnits.addPhasedUnit(externalPhasedUnit.getUnitFile(), phasedUnit);
            gen.setMap(map);
            String pkgName = phasedUnit.getPackage().getQualifiedNameString();
            if ("".equals(pkgName)) {
                pkgName = null;
            }
            return gen.makeJCCompilationUnitPlaceholder(phasedUnit.getCompilationUnit(), filename, pkgName, phasedUnit);
        }
        if (phasedUnit == null) {
            ANTLRStringStream input = new NewlineFixingStringStream(source);
            CeylonLexer lexer = new CeylonLexer(input);
            CommonTokenStream tokens = new CommonTokenStream(new CeylonInterpolatingLexer(lexer));
            CeylonParser parser = new CeylonParser(tokens);
            CompilationUnit cu = parser.compilationUnit();
            java.util.List<LexError> lexerErrors = lexer.getErrors();
            for (LexError le : lexerErrors) {
                printError(le, le.getMessage(), "ceylon.lexer", map);
            }
            java.util.List<ParseError> parserErrors = parser.getErrors();
            for (ParseError pe : parserErrors) {
                printError(pe, pe.getMessage(), "ceylon.parser", map);
            }
            // if we continue and it's not a descriptor, we don't care about errors
            if ((options.get(Option.CEYLONCONTINUE) != null && !ModuleManager.MODULE_FILE.equals(sourceFile.getName()) && !ModuleManager.PACKAGE_FILE.equals(sourceFile.getName())) || // otherwise we care about errors
            (lexerErrors.size() == 0 && parserErrors.size() == 0)) {
                // FIXME: this is bad in many ways
                String pkgName = getPackage(filename);
                // make a Package with no module yet, we will resolve them later
                /*
                     * Stef: see javadoc for findOrCreateModulelessPackage() for why this is here.
                     */
                Package p = modelLoader.findOrCreateModulelessPackage(pkgName == null ? "" : pkgName);
                phasedUnit = new CeylonPhasedUnit(file, srcDir, cu, p, moduleManager, moduleSourceMapper, ceylonContext, filename, map);
                phasedUnit.setSuppressedWarnings(suppressedWarnings);
                phasedUnits.addPhasedUnit(file, phasedUnit);
                gen.setMap(map);
                return gen.makeJCCompilationUnitPlaceholder(cu, filename, pkgName, phasedUnit);
            }
        }
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    JCCompilationUnit result = make.TopLevel(List.<JCAnnotation>nil(), null, List.<JCTree>of(make.Erroneous()));
    result.sourcefile = filename;
    return result;
}
Also used : VirtualFile(org.eclipse.ceylon.compiler.typechecker.io.VirtualFile) JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) Warning(org.eclipse.ceylon.compiler.typechecker.analyzer.Warning) ModuleManager(org.eclipse.ceylon.model.typechecker.util.ModuleManager) NewlineFixingStringStream(org.eclipse.ceylon.compiler.typechecker.util.NewlineFixingStringStream) PhasedUnit(org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit) ParseError(org.eclipse.ceylon.compiler.typechecker.parser.ParseError) ModuleSourceMapper(org.eclipse.ceylon.compiler.typechecker.analyzer.ModuleSourceMapper) CeylonParser(org.eclipse.ceylon.compiler.typechecker.parser.CeylonParser) ANTLRStringStream(org.antlr.runtime.ANTLRStringStream) JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) CeylonCompilationUnit(org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit) CompilationUnit(org.eclipse.ceylon.compiler.typechecker.tree.Tree.CompilationUnit) CommonTokenStream(org.antlr.runtime.CommonTokenStream) LineMap(org.eclipse.ceylon.langtools.tools.javac.util.Position.LineMap) CeylonLexer(org.eclipse.ceylon.compiler.typechecker.parser.CeylonLexer) IOException(java.io.IOException) CeylonInterpolatingLexer(org.eclipse.ceylon.compiler.typechecker.parser.CeylonInterpolatingLexer) Package(org.eclipse.ceylon.model.typechecker.model.Package) VirtualFile(org.eclipse.ceylon.compiler.typechecker.io.VirtualFile) File(java.io.File) LexError(org.eclipse.ceylon.compiler.typechecker.parser.LexError)

Example 9 with JCCompilationUnit

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

the class CeylonEnter method completeCeylonTrees.

public List<JCCompilationUnit> completeCeylonTrees(List<JCCompilationUnit> trees) {
    // run the type checker
    timer.startTask("Ceylon type checking");
    typeCheck();
    // some debugging
    // printModules();
    timer.startTask("Ceylon code generation");
    /*
         * Here we convert the ceylon tree to its javac AST, after the typechecker has run
         */
    Timer nested = timer.nestedTimer();
    if (sp != null) {
        sp.clearLine();
        sp.log("Generating AST");
    }
    int i = 1;
    int size = countCeylonFiles(trees);
    List<JCCompilationUnit> packageInfos = List.<JCCompilationUnit>nil();
    for (JCCompilationUnit tree : trees) {
        if (tree instanceof CeylonCompilationUnit) {
            CeylonCompilationUnit ceylonTree = (CeylonCompilationUnit) tree;
            gen.setMap(ceylonTree.lineMap);
            CeylonPhasedUnit phasedUnit = (CeylonPhasedUnit) ceylonTree.phasedUnit;
            if (sp != null) {
                sp.clearLine();
                sp.log("Generating [" + (i++) + "/" + size + "] ");
                sp.log(phasedUnit.getPathRelativeToSrcDir());
            }
            gen.setFileObject(phasedUnit.getFileObject());
            nested.startTask("Ceylon code generation for " + phasedUnit.getUnitFile().getName());
            TaskEvent event = new TaskEvent(TaskEvent.Kind.PARSE, tree);
            if (taskListener != null) {
                taskListener.started(event);
            }
            ceylonTree.defs = gen.transformAfterTypeChecking(ceylonTree.ceylonTree).toList();
            if (taskListener != null) {
                taskListener.finished(event);
            }
            packageInfos = packageInfos.prependList(gen.transformPackageInfo(ceylonTree));
            nested.endTask();
            if (isVerbose("ast")) {
                log.printRawLines(WriterKind.ERROR, "Model tree for " + tree.getSourceFile());
                log.printRawLines(WriterKind.ERROR, ceylonTree.ceylonTree.toString());
            }
            if (isVerbose("code")) {
                log.printRawLines(WriterKind.ERROR, "Java code generated for " + tree.getSourceFile());
                log.printRawLines(WriterKind.ERROR, ceylonTree.toString());
            }
        }
    }
    if (isVerbose("code")) {
        for (JCCompilationUnit packageInfo : packageInfos) {
            log.printRawLines(WriterKind.ERROR, packageInfo.toString());
        }
    }
    if (sp != null) {
        sp.clearLine();
    }
    timer.startTask("Ceylon error generation");
    printGeneratorErrors();
    timer.endTask();
    // write some stats
    if (verbose)
        modelLoader.printStats();
    return packageInfos;
}
Also used : JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) CeylonCompilationUnit(org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit) Timer(org.eclipse.ceylon.model.loader.Timer) CeylonPhasedUnit(org.eclipse.ceylon.compiler.java.tools.CeylonPhasedUnit) TaskEvent(org.eclipse.ceylon.langtools.source.util.TaskEvent)

Example 10 with JCCompilationUnit

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

the class CeylonEnter method main.

@Override
public void main(List<JCCompilationUnit> trees) {
    // complete the javac AST with a completed ceylon model
    timer.startTask("prepareForTypeChecking");
    prepareForTypeChecking(trees);
    timer.endTask();
    List<JCCompilationUnit> javaTrees = List.nil();
    List<JCCompilationUnit> ceylonTrees = List.nil();
    // split them in two sets: java and ceylon
    for (JCCompilationUnit tree : trees) {
        if (tree instanceof CeylonCompilationUnit)
            ceylonTrees = ceylonTrees.prepend(tree);
        else
            javaTrees = javaTrees.prepend(tree);
    }
    timer.startTask("Enter on Java trees");
    boolean needsModelReset = isBootstrap;
    // enter java trees first to set up their ClassSymbol objects for ceylon trees to use during type-checking
    if (!javaTrees.isEmpty()) {
        setupImportedPackagesForJavaTrees(javaTrees);
        hasJavaAndCeylonSources = true;
        needsModelReset = true;
    }
    // this is false if we're in an APT round where we did not generate the trees
    if (!compiler.isAddModuleTrees()) {
        setupImportedPackagesForJavaTrees(ceylonTrees);
    }
    if (isBootstrap || hasJavaAndCeylonSources) {
        super.main(trees);
    }
    // now we can type-check the Ceylon code
    List<JCCompilationUnit> packageInfo = completeCeylonTrees(trees);
    trees = trees.prependList(packageInfo);
    ceylonTrees = ceylonTrees.prependList(packageInfo);
    if (compiler.isHadRunTwiceException()) {
        needsModelReset = true;
    }
    if (needsModelReset) {
        // bootstrapping the language module is a bit more complex
        resetAndRunEnterAgain(trees);
    } else {
        timer.startTask("Enter on Ceylon trees");
        // and complete their new trees
        try {
            sourceLanguage.push(Language.CEYLON);
            super.main(ceylonTrees);
        } finally {
            sourceLanguage.pop();
        }
        timer.endTask();
    }
}
Also used : JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) CeylonCompilationUnit(org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit)

Aggregations

JCCompilationUnit (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit)13 IOException (java.io.IOException)5 CeylonCompilationUnit (org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit)5 File (java.io.File)4 TaskEvent (org.eclipse.ceylon.langtools.source.util.TaskEvent)4 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)4 ZipFile (java.util.zip.ZipFile)3 CeyloncTaskImpl (org.eclipse.ceylon.compiler.java.tools.CeyloncTaskImpl)3 PhasedUnit (org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit)3 DiagnosticListener (org.eclipse.ceylon.javax.tools.DiagnosticListener)3 TaskListener (org.eclipse.ceylon.langtools.source.util.TaskListener)3 Package (org.eclipse.ceylon.model.typechecker.model.Package)3 JavaPositionsRetriever (org.eclipse.ceylon.compiler.java.codegen.JavaPositionsRetriever)2 ExitState (org.eclipse.ceylon.compiler.java.launcher.Main.ExitState)2 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)2 JCAnnotation (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)2 JCBlock (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock)2 JCClassDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCClassDecl)2 JCMethodDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCMethodDecl)2 JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)2