private void 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()) { for (Tree.ModuleDescriptor modDescr : phasedUnit.getCompilationUnit().getModuleDescriptors()) { String name = phasedUnit.getPackage().getNameAsString(); CeylonPhasedUnit cpu = (CeylonPhasedUnit) phasedUnit; CeylonFileObject cfo = (CeylonFileObject) cpu.getFileObject(); moduleNamesToFileObjects.put(name, cfo); } } }
private void addResources() throws Abort { HashSet<String> written = new HashSet<String>(); try { for (JavaFileObject fo : resourceFileObjects) { CeyloncFileManager dfm = (CeyloncFileManager) fileManager; String jarFileName = JarUtils.toPlatformIndependentPath( dfm.getLocation(CeylonLocation.RESOURCE_PATH), fo.getName()); if (!written.contains(jarFileName)) { dfm.setModule(modelLoader.findModuleForFile(new File(jarFileName))); FileObject outFile = dfm.getFileForOutput(StandardLocation.CLASS_OUTPUT, "", jarFileName, null); OutputStream out = outFile.openOutputStream(); try { InputStream in = new FileInputStream(new File(fo.getName())); try { JarUtils.copy(in, out); } finally { in.close(); } } finally { out.close(); } written.add(jarFileName); } } } catch (IOException ex) { throw new Abort(ex); } }
// FIXME: This is only here for wildcard imports, and we should be able to make it lazy like the // rest // with a bit of work in the typechecker // FIXME: redo this method better: https://github.com/ceylon/ceylon-spec/issues/90 @Override public List<Declaration> getMembers() { synchronized (modelLoader) { // make sure the package is loaded modelLoader.loadPackage(getQualifiedNameString(), true); List<Declaration> sourceDeclarations = super.getMembers(); LinkedList<Declaration> ret = new LinkedList<Declaration>(); ret.addAll(sourceDeclarations); ret.addAll(compiledDeclarations); return ret; } }
// FIXME: redo this method better: https://github.com/ceylon/ceylon-spec/issues/90 @Override public Declaration getDirectMember(String name, List<ProducedType> signature) { synchronized (modelLoader) { String pkgName = getQualifiedNameString(); // we need its package ready first modelLoader.loadPackage(pkgName, false); // make sure we iterate over a copy of compiledDeclarations, to avoid lazy loading to modify // it and // cause a ConcurrentModificationException: // https://github.com/ceylon/ceylon-compiler/issues/399 Declaration d = lookupMember(copy(compiledDeclarations), name, signature, false); if (d != null) { return d; } String className = getQualifiedName(pkgName, name); ClassMirror classSymbol = modelLoader.lookupClassMirror(className); // only get it from the classpath if we're not compiling it, unless // it happens to be a java source if (classSymbol != null && (!classSymbol.isLoadedFromSource() || classSymbol.isJavaSource())) { d = modelLoader.convertToDeclaration(className, DeclarationType.VALUE); if (d instanceof Class) { if (((Class) d).isAbstraction()) { // make sure we iterate over a copy of compiledDeclarations, to avoid lazy loading to // modify it and // cause a ConcurrentModificationException: // https://github.com/ceylon/ceylon-compiler/issues/399 return lookupMember(copy(compiledDeclarations), name, signature, false); } } return d; } return getDirectMemberFromSource(name); } }
@Override public List<JCCompilationUnit> parseFiles(Iterable<JavaFileObject> fileObjects) { timer.startTask("parse"); /* * Stef: see javadoc for fixDefaultPackage() for why this is here. */ modelLoader.fixDefaultPackage(); List<JCCompilationUnit> trees = super.parseFiles(fileObjects); timer.startTask("loadCompiledModules"); LinkedList<JCCompilationUnit> moduleTrees = new LinkedList<JCCompilationUnit>(); // now load modules and associate their moduleless packages with the corresponding modules loadCompiledModules(trees, moduleTrees); for (JCCompilationUnit moduleTree : moduleTrees) { trees = trees.append(moduleTree); } /* * Stef: see javadoc for cacheModulelessPackages() for why this is here. */ modelLoader.cacheModulelessPackages(); timer.endTask(); return trees; }
@Override public void removeUnit(Unit unit) { synchronized (modelLoader) { if (lazyUnits.remove(unit)) { for (Declaration d : unit.getDeclarations()) { compiledDeclarations.remove(d); // TODO : remove the declaration from the declaration map in AbstractModelLoader } modelLoader.removeDeclarations(unit.getDeclarations()); } else { super.removeUnit(unit); } } }
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) && !sourcefile.hasError(cdef.pos)) { 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.isDefault()) { 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(OptionName.VERBOSE) != null) { Log.printLines( log.noticeWriter, "[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 JCCompilationUnit ceylonParse(JavaFileObject filename, CharSequence readSource) { if (ceylonEnter.hasRun()) throw new RuntimeException( "Trying to load new source file after CeylonEnter has been called: " + filename); try { ModuleManager moduleManager = phasedUnits.getModuleManager(); 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); if (externalPhasedUnit != null) { phasedUnit = new CeylonPhasedUnit(externalPhasedUnit, filename, map); 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 ANTLRStringStream(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 (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.compiler.typechecker.model.Package p = modelLoader.findOrCreateModulelessPackage(pkgName == null ? "" : pkgName); phasedUnit = new CeylonPhasedUnit( file, srcDir, cu, p, moduleManager, ceylonContext, filename, map); 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; }