public LanguageCompiler(Context context) { super(context); ceylonContext = getCeylonContextInstance(context); vfs = ceylonContext.getVfs(); compilerDelegate = getCompilerDelegate(context); phasedUnits = getPhasedUnitsInstance(context); try { gen = CeylonTransformer.getInstance(context); } catch (Exception e) { throw new RuntimeException(e); } modelLoader = CeylonModelLoader.instance(context); ceylonEnter = CeylonEnter.instance(context); options = Options.instance(context); isBootstrap = options.get(Option.BOOTSTRAPCEYLON) != null; timer = Timer.instance(context); sourceLanguage = SourceLanguage.instance(context); boolean isProgressPrinted = options.get(Option.CEYLONPROGRESS) != null && StatusPrinter.canPrint(); if (isProgressPrinted) { sp = getStatusPrinterInstance(context); if (taskListener == null) { taskListener.add(new StatusPrinterTaskListener(sp)); } } }
/** Get the JavaCompiler instance for this context. */ public static JavaCompiler instance(Context context) { Options options = Options.instance(context); options.put("-Xprefer", "source"); // make sure it's registered Log log = CeylonLog.instance(context); CeylonEnter.instance(context); CeylonClassWriter.instance(context); JavaCompiler instance = context.get(compilerKey); if (instance == null) instance = new LanguageCompiler(context); return instance; }
@Override public void initProcessAnnotations(Iterable<? extends Processor> processors) { java.util.List<String> aptModules = options.getMulti(Option.CEYLONAPT); if (aptModules != null) { CeyloncFileManager dfm = (CeyloncFileManager) fileManager; RepositoryManager repositoryManager = dfm.getRepositoryManager(); final Set<ModuleSpec> visited = new HashSet<>(); StatusPrinterAptProgressListener progressListener = null; if (sp != null) { progressListener = new StatusPrinterAptProgressListener(sp) { @Override protected long getNumberOfModulesResolved() { return visited.size(); } }; sp.clearLine(); sp.log("Starting APT resolving"); } for (String aptModule : aptModules) { ModuleSpec moduleSpec = ModuleSpec.parse(aptModule); addDependenciesToAptPath(repositoryManager, moduleSpec, visited, progressListener); } if (sp != null) { sp.clearLine(); sp.log("Done APT resolving"); } // we only run APT if asked explicitly with the --apt flag super.initProcessAnnotations(processors); } // else don't do anything, which will leave the "processAnnotations" field to false }
private JavaFileObject genCodeUnlessError(Env<AttrContext> env, JCClassDecl cdef) throws IOException { CeylonFileObject sourcefile = (CeylonFileObject) env.toplevel.sourcefile; try { // do not look at the global number of errors but only those for this file if (super.gen.genClass(env, cdef)) { String packageName = cdef.sym.packge().getQualifiedName().toString(); Package pkg = modelLoader.findPackage(packageName); if (pkg == null) throw new RuntimeException("Failed to find package: " + packageName); Module module = pkg.getModule(); if (!module.isDefaultModule()) { String moduleName = module.getNameAsString(); CeylonFileObject moduleFileObject = moduleNamesToFileObjects.get(moduleName); // if there's no module source file object it means the module descriptor had parse errors if (moduleFileObject == null || moduleFileObject.hasError()) { // we do not produce any class files for modules with errors if (options.get(Option.VERBOSE) != null) { log.printRawLines( WriterKind.NOTICE, "[Not writing class " + cdef.sym.className() + " because its module has errors: " + moduleName + "]"); } return null; } } return writer.writeClass(cdef.sym); } } catch (ClassWriter.PoolOverflow ex) { log.error(cdef.pos(), "limit.pool"); } catch (ClassWriter.StringOverflow ex) { log.error(cdef.pos(), "limit.string.overflow", ex.value.substring(0, 20)); } catch (CompletionFailure ex) { chk.completionError(cdef.pos(), ex); } catch (AssertionError e) { throw new RuntimeException("Error generating bytecode for " + sourcefile.getName(), e); } return null; }
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) { // first make sure we're not already compiling it: this can happen if we have several versions // of the // same module already loaded: we will get one which isn't the one we compile, but that's not // the one // 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); }
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(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. */ com.redhat.ceylon.model.typechecker.model.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; }