Search in sources :

Example 36 with Module

use of com.redhat.ceylon.model.typechecker.model.Module in project ceylon-compiler by ceylon.

the class AbstractTransformer method makeAtModule.

List<JCAnnotation> makeAtModule(ModuleDescriptor moduleDescriptor) {
    Module module = moduleDescriptor.getUnit().getPackage().getModule();
    ListBuffer<JCExpression> imports = new ListBuffer<JCTree.JCExpression>();
    for (ModuleImport dependency : module.getImports()) {
        if (!isForBackend(dependency.getNativeBackends(), Backend.Java)) {
            continue;
        }
        Module dependencyModule = dependency.getModule();
        JCExpression dependencyName = make().Assign(naming.makeUnquotedIdent("name"), make().Literal(dependencyModule.getNameAsString()));
        JCExpression dependencyVersion = null;
        String versionInDescriptor = getImportVersionFromDescriptor(moduleDescriptor, dependency, dependencyModule);
        if (versionInDescriptor != null)
            dependencyVersion = make().Assign(naming.makeUnquotedIdent("version"), make().Literal(versionInDescriptor));
        List<JCExpression> spec;
        if (dependencyVersion != null)
            spec = List.<JCExpression>of(dependencyName, dependencyVersion);
        else
            spec = List.<JCExpression>of(dependencyName);
        if (Util.getAnnotation(dependency, "shared") != null) {
            JCExpression exported = make().Assign(naming.makeUnquotedIdent("export"), make().Literal(true));
            spec = spec.append(exported);
        }
        if (Util.getAnnotation(dependency, "optional") != null) {
            JCExpression exported = make().Assign(naming.makeUnquotedIdent("optional"), make().Literal(true));
            spec = spec.append(exported);
        }
        JCExpression nativeBackendsAnnotationValue = makeNativeBackendsAnnotationValue(dependency.getNativeBackends());
        if (nativeBackendsAnnotationValue != null)
            spec = spec.append(nativeBackendsAnnotationValue);
        JCAnnotation atImport = make().Annotation(makeIdent(syms().ceylonAtImportType), spec);
        imports.add(atImport);
    }
    ListBuffer<JCExpression> annotationArgs = getLicenseAuthorsDocAnnotationArguments(module.getNameAsString(), module.getAnnotations());
    annotationArgs.add(make().Assign(naming.makeUnquotedIdent("version"), make().Literal(module.getVersion())));
    annotationArgs.add(make().Assign(naming.makeUnquotedIdent("dependencies"), make().NewArray(null, null, imports.toList())));
    JCExpression nativeBackendsAnnotationValue = makeNativeBackendsAnnotationValue(module.getNativeBackends());
    if (nativeBackendsAnnotationValue != null)
        annotationArgs.add(nativeBackendsAnnotationValue);
    return makeModelAnnotation(syms().ceylonAtModuleType, annotationArgs.toList());
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ListBuffer(com.sun.tools.javac.util.ListBuffer) ModuleImport(com.redhat.ceylon.model.typechecker.model.ModuleImport) JCTree(com.sun.tools.javac.tree.JCTree) Module(com.redhat.ceylon.model.typechecker.model.Module) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 37 with Module

use of com.redhat.ceylon.model.typechecker.model.Module in project ceylon-compiler by ceylon.

the class LazyModuleSourceMapper method resolveModule.

@Override
public void resolveModule(ArtifactResult artifact, Module module, ModuleImport moduleImport, LinkedList<Module> dependencyTree, List<PhasedUnits> phasedUnitsOfDependencies, boolean forCompiledModule) {
    String moduleName = module.getNameAsString();
    LazyModuleManager moduleManager = getModuleManager();
    boolean moduleLoadedFromSource = moduleManager.isModuleLoadedFromSource(moduleName);
    boolean isLanguageModule = module == module.getLanguageModule();
    // module in question will be in the classpath
    if (moduleLoadedFromSource || forCompiledModule) {
        String standardisedModuleName = ModuleUtil.toCeylonModuleName(moduleName);
        // check for an already loaded module with the same name but different version
        for (Module loadedModule : getContext().getModules().getListOfModules()) {
            String loadedModuleName = loadedModule.getNameAsString();
            String standardisedLoadedModuleName = ModuleUtil.toCeylonModuleName(loadedModuleName);
            boolean sameModule = loadedModuleName.equals(moduleName);
            boolean similarModule = standardisedLoadedModuleName.equals(standardisedModuleName);
            if ((sameModule || similarModule) && !loadedModule.getVersion().equals(module.getVersion()) && moduleManager.getModelLoader().isModuleInClassPath(loadedModule)) {
                if (sameModule) {
                    String[] versions = VersionComparator.orderVersions(module.getVersion(), loadedModule.getVersion());
                    String error = "source code imports two different versions of module '" + moduleName + "': " + "version '" + versions[0] + "' and version '" + versions[1] + "'";
                    addErrorToModule(dependencyTree.getFirst(), error);
                } else {
                    String moduleA;
                    String moduleB;
                    if (loadedModuleName.compareTo(moduleName) < 0) {
                        moduleA = ModuleUtil.makeModuleName(loadedModuleName, loadedModule.getVersion());
                        moduleB = ModuleUtil.makeModuleName(moduleName, module.getVersion());
                    } else {
                        moduleA = ModuleUtil.makeModuleName(moduleName, module.getVersion());
                        moduleB = ModuleUtil.makeModuleName(loadedModuleName, loadedModule.getVersion());
                    }
                    String error = "source code imports two different versions of similar modules '" + moduleA + "' and '" + moduleB + "'";
                    addWarningToModule(dependencyTree.getFirst(), Warning.similarModule, error);
                }
                return;
            }
        }
    }
    if (moduleLoadedFromSource) {
        super.resolveModule(artifact, module, moduleImport, dependencyTree, phasedUnitsOfDependencies, forCompiledModule);
    } else if (forCompiledModule || isLanguageModule || moduleManager.shouldLoadTransitiveDependencies()) {
        // we only add stuff to the classpath and load the modules if we need them to compile our modules
        // To be able to load it from the corresponding archive
        moduleManager.getModelLoader().addModuleToClassPath(module, artifact);
        if (!module.isDefault() && !moduleManager.getModelLoader().loadCompiledModule(module)) {
            // we didn't find module.class so it must be a java module if it's not the default module
            ((LazyModule) module).setJava(true);
            module.setNativeBackends(Backend.Java.asSet());
            List<ArtifactResult> deps = artifact.dependencies();
            for (ArtifactResult dep : deps) {
                Module dependency = moduleManager.getOrCreateModule(ModuleManager.splitModuleName(dep.name()), dep.version());
                ModuleImport depImport = moduleManager.findImport(module, dependency);
                if (depImport == null) {
                    moduleImport = new ModuleImport(dependency, dep.importType() == ImportType.OPTIONAL, dep.importType() == ImportType.EXPORT, Backend.Java);
                    module.addImport(moduleImport);
                }
            }
        }
        LazyModule lazyModule = (LazyModule) module;
        if (!lazyModule.isJava() && !module.isDefault()) {
            // it must be a Ceylon module
            // default modules don't have any module descriptors so we can't check them
            Overrides overrides = getContext().getRepositoryManager().getOverrides();
            if (overrides != null) {
                if (overrides.getArtifactOverrides(new ArtifactContext(artifact.name(), artifact.version())) != null) {
                    Set<ModuleDependencyInfo> existingModuleDependencies = new HashSet<>();
                    for (ModuleImport i : lazyModule.getImports()) {
                        Module m = i.getModule();
                        if (m != null) {
                            existingModuleDependencies.add(new ModuleDependencyInfo(m.getNameAsString(), m.getVersion(), i.isOptional(), i.isExport()));
                        }
                    }
                    ModuleInfo sourceModuleInfo = new ModuleInfo(null, existingModuleDependencies);
                    ModuleInfo newModuleInfo = overrides.applyOverrides(artifact.name(), artifact.version(), sourceModuleInfo);
                    List<ModuleImport> newModuleImports = new ArrayList<>();
                    for (ModuleDependencyInfo dep : newModuleInfo.getDependencies()) {
                        Module dependency = moduleManager.getOrCreateModule(ModuleManager.splitModuleName(dep.getName()), dep.getVersion());
                        Backends backends = dependency.getNativeBackends();
                        moduleImport = new ModuleImport(dependency, dep.isOptional(), dep.isExport(), backends);
                        newModuleImports.add(moduleImport);
                    }
                    module.overrideImports(newModuleImports);
                }
            }
            if (!Versions.isJvmBinaryVersionSupported(lazyModule.getMajor(), lazyModule.getMinor())) {
                attachErrorToDependencyDeclaration(moduleImport, dependencyTree, "version '" + lazyModule.getVersion() + "' of module '" + module.getNameAsString() + "' was compiled by an incompatible version of the compiler (binary version " + lazyModule.getMajor() + "." + lazyModule.getMinor() + " of module is not compatible with binary version " + Versions.JVM_BINARY_MAJOR_VERSION + "." + Versions.JVM_BINARY_MINOR_VERSION + " of this compiler)");
            }
        }
        // module is now available
        module.setAvailable(true);
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) LazyModuleManager(com.redhat.ceylon.model.loader.model.LazyModuleManager) ArtifactContext(com.redhat.ceylon.cmr.api.ArtifactContext) LazyModule(com.redhat.ceylon.model.loader.model.LazyModule) ArtifactResult(com.redhat.ceylon.model.cmr.ArtifactResult) Backends(com.redhat.ceylon.common.Backends) ModuleInfo(com.redhat.ceylon.cmr.api.ModuleInfo) ModuleImport(com.redhat.ceylon.model.typechecker.model.ModuleImport) Overrides(com.redhat.ceylon.cmr.api.Overrides) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) ModuleDependencyInfo(com.redhat.ceylon.cmr.api.ModuleDependencyInfo) LazyModule(com.redhat.ceylon.model.loader.model.LazyModule) Module(com.redhat.ceylon.model.typechecker.model.Module)

Example 38 with Module

use of com.redhat.ceylon.model.typechecker.model.Module in project ceylon-compiler by ceylon.

the class LanguageCompiler method loadModuleFromSource.

private void loadModuleFromSource(Package pkg, Modules modules, LinkedList<JCCompilationUnit> moduleTrees, List<JCCompilationUnit> parsedTrees) {
    // skip it if we already resolved the package
    if (pkg.getModule() != null) {
        // make sure the default module is always added to the classpath, it will be the only one to have a module
        if (!addedDefaultModuleToClassPath && pkg.getModule().isDefault()) {
            addedDefaultModuleToClassPath = true;
            ceylonEnter.addOutputModuleToClassPath(pkg.getModule());
        }
        return;
    }
    String pkgName = pkg.getQualifiedNameString();
    Module module = null;
    // FIXME: is this true? what if we have a module.ceylon at toplevel?
    if (pkgName.isEmpty())
        module = modules.getDefaultModule();
    else {
        for (Module m : modulesLoadedFromSource) {
            if (JvmBackendUtil.isSubPackage(m.getNameAsString(), pkgName)) {
                module = m;
                break;
            }
        }
        if (module == null) {
            module = loadModuleFromSource(pkgName, moduleTrees, parsedTrees);
        } else if (!module.isAvailable()) {
            loadModuleFromSource(pkgName, moduleTrees, parsedTrees);
        }
        if (module == null) {
            // because we have some com.redhat.ceylon packages that must go in the language module
            if (isBootstrap)
                module = modules.getLanguageModule();
            else
                module = modules.getDefaultModule();
        }
    }
    // bind module and package together
    pkg.setModule(module);
    if (!module.getPackages().contains(pkg)) {
        module.getPackages().add(pkg);
    }
    // automatically add this module's jar to the classpath if it exists
    ceylonEnter.addOutputModuleToClassPath(module);
}
Also used : Module(com.redhat.ceylon.model.typechecker.model.Module) ImportModule(com.redhat.ceylon.compiler.typechecker.tree.Tree.ImportModule)

Example 39 with Module

use of com.redhat.ceylon.model.typechecker.model.Module in project ceylon-compiler by ceylon.

the class LanguageCompiler method genCodeUnlessError.

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.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;
}
Also used : CompletionFailure(com.sun.tools.javac.code.Symbol.CompletionFailure) CeylonFileObject(com.redhat.ceylon.compiler.java.codegen.CeylonFileObject) Package(com.redhat.ceylon.model.typechecker.model.Package) Module(com.redhat.ceylon.model.typechecker.model.Module) ImportModule(com.redhat.ceylon.compiler.typechecker.tree.Tree.ImportModule) ClassWriter(com.sun.tools.javac.jvm.ClassWriter) CeylonClassWriter(com.redhat.ceylon.compiler.java.codegen.CeylonClassWriter)

Example 40 with Module

use of com.redhat.ceylon.model.typechecker.model.Module in project ceylon-compiler by ceylon.

the class MavenPomUtil method writePomXml.

private static void writePomXml(JarOutputStream jarOutputStream, String path, String groupId, String artifactId, Module module) {
    try {
        jarOutputStream.putNextEntry(new ZipEntry(path + "pom.xml"));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    try {
        XMLStreamWriter out = XMLOutputFactory.newInstance().createXMLStreamWriter(new OutputStreamWriter(jarOutputStream, "utf-8"));
        out.writeStartDocument();
        out.writeCharacters("\n");
        // FIXME: what to do with the default module?
        out.writeStartElement("project");
        out.writeAttribute("xmlns", "http://maven.apache.org/POM/4.0.0");
        out.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
        out.writeAttribute("xsi:schemaLocation", "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd");
        out.writeCharacters("\n ");
        out.writeStartElement("modelVersion");
        out.writeCharacters("4.0.0");
        out.writeEndElement();
        out.writeCharacters("\n ");
        out.writeStartElement("groupId");
        out.writeCharacters(groupId);
        out.writeEndElement();
        out.writeCharacters("\n ");
        out.writeStartElement("artifactId");
        out.writeCharacters(artifactId);
        out.writeEndElement();
        out.writeCharacters("\n ");
        out.writeStartElement("version");
        out.writeCharacters(module.getVersion());
        out.writeEndElement();
        out.writeCharacters("\n ");
        out.writeStartElement("name");
        out.writeCharacters(module.getNameAsString());
        out.writeEndElement();
        List<ModuleImport> imports = module.getImports();
        if (!imports.isEmpty()) {
            out.writeCharacters("\n ");
            out.writeStartElement("dependencies");
            for (ModuleImport dep : imports) {
                if (!ModelUtil.isForBackend(dep.getNativeBackends(), Backend.Java)) {
                    continue;
                }
                Module moduleDependency = dep.getModule();
                String dependencyName = moduleDependency.getNameAsString();
                // skip c.l and jdk
                if (dependencyName.equals(Module.LANGUAGE_MODULE_NAME) || JDKUtils.isJDKModule(dependencyName) || JDKUtils.isOracleJDKModule(dependencyName))
                    continue;
                String[] mavenCoordinates = getMavenCoordinates(moduleDependency.getNameAsString());
                out.writeCharacters("\n  ");
                out.writeStartElement("dependency");
                out.writeCharacters("\n    ");
                out.writeStartElement("groupId");
                out.writeCharacters(mavenCoordinates[0]);
                out.writeEndElement();
                out.writeCharacters("\n    ");
                out.writeStartElement("artifactId");
                out.writeCharacters(mavenCoordinates[1]);
                out.writeEndElement();
                out.writeCharacters("\n    ");
                out.writeStartElement("version");
                out.writeCharacters(moduleDependency.getVersion());
                out.writeEndElement();
                if (dep.isOptional()) {
                    out.writeCharacters("\n    ");
                    out.writeStartElement("optional");
                    out.writeCharacters("true");
                    out.writeEndElement();
                }
                out.writeCharacters("\n  ");
                out.writeEndElement();
            }
            out.writeCharacters("\n ");
            out.writeEndElement();
        }
        out.writeCharacters("\n");
        out.writeEndElement();
        out.writeEndDocument();
        out.flush();
    } catch (IOException | XMLStreamException e) {
        throw new RuntimeException(e);
    } finally {
        try {
            jarOutputStream.closeEntry();
        } catch (IOException ignore) {
        }
    }
}
Also used : XMLStreamException(javax.xml.stream.XMLStreamException) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) ZipEntry(java.util.zip.ZipEntry) ModuleImport(com.redhat.ceylon.model.typechecker.model.ModuleImport) OutputStreamWriter(java.io.OutputStreamWriter) IOException(java.io.IOException) Module(com.redhat.ceylon.model.typechecker.model.Module)

Aggregations

Module (com.redhat.ceylon.model.typechecker.model.Module)50 Package (com.redhat.ceylon.model.typechecker.model.Package)16 File (java.io.File)14 Test (org.junit.Test)12 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)10 CeylonDocTool (com.redhat.ceylon.ceylondoc.CeylonDocTool)9 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)9 ArrayList (java.util.ArrayList)6 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)5 ModuleImport (com.redhat.ceylon.model.typechecker.model.ModuleImport)5 ImportModule (com.redhat.ceylon.compiler.typechecker.tree.Tree.ImportModule)4 Class (com.redhat.ceylon.model.typechecker.model.Class)4 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)4 ErrorCollector (com.redhat.ceylon.compiler.java.test.ErrorCollector)3 CeyloncTaskImpl (com.redhat.ceylon.compiler.java.tools.CeyloncTaskImpl)3 PhasedUnit (com.redhat.ceylon.compiler.typechecker.context.PhasedUnit)3 LazyModule (com.redhat.ceylon.model.loader.model.LazyModule)3 Function (com.redhat.ceylon.model.typechecker.model.Function)3 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)3 Type (com.redhat.ceylon.model.typechecker.model.Type)3