Search in sources :

Example 11 with Backends

use of org.eclipse.ceylon.common.Backends in project ceylon by eclipse.

the class TreeUtil method getNativeBackend.

public static Backends getNativeBackend(Tree.AnnotationList al, Unit unit) {
    Tree.Annotation ann = getAnnotation(al, "native", unit);
    Backends backends = Backends.ANY;
    if (ann != null) {
        int cnt = getAnnotationArgumentCount(ann);
        if (cnt == 0) {
            backends = Backends.HEADER;
        } else {
            for (int i = 0; i < cnt; i++) {
                String be = getAnnotationArgument(ann, i, unit);
                if (be != null) {
                    backends = backends.merged(Backend.fromAnnotation(be));
                }
            }
        }
    }
    return backends;
}
Also used : Backends(org.eclipse.ceylon.common.Backends) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 12 with Backends

use of org.eclipse.ceylon.common.Backends in project ceylon by eclipse.

the class UsageVisitor method visit.

@Override
public void visit(Tree.Declaration that) {
    super.visit(that);
    Declaration declaration = that.getDeclarationModel();
    Backends bs = declaration.getNativeBackends();
    if (declaration != null && declaration.getName() != null && !declaration.isShared() && !declaration.isToplevel() && !rc.isReferenced(declaration) && !declaration.isParameter() && !(that instanceof Tree.Variable) && !(declaration instanceof TypeParameter && ((TypeParameter) declaration).getDeclaration() instanceof TypeParameter)) {
        if (bs.none() || isForBackend(bs, that.getUnit().getSupportedBackends())) {
            that.addUsageWarning(Warning.unusedDeclaration, "declaration is never used: " + kind(declaration) + " '" + declaration.getName() + "' has no local references");
        }
    }
}
Also used : Backends(org.eclipse.ceylon.common.Backends) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 13 with Backends

use of org.eclipse.ceylon.common.Backends in project ceylon by eclipse.

the class JsModuleSourceMapper method loadModuleFromMap.

protected void loadModuleFromMap(ArtifactResult artifact, Module module, LinkedList<Module> dependencyTree, List<PhasedUnits> phasedUnitsOfDependencies, boolean forCompiledModule, Map<String, Object> model) {
    @SuppressWarnings("unchecked") List<Object> deps = (List<Object>) model.get("$mod-deps");
    if (deps != null) {
        for (Object dep : deps) {
            final String s;
            boolean optional = false;
            boolean export = false;
            if (dep instanceof Map) {
                @SuppressWarnings("unchecked") final Map<String, Object> depmap = (Map<String, Object>) dep;
                s = (String) depmap.get("path");
                optional = depmap.containsKey("opt");
                export = depmap.containsKey("exp");
            } else {
                s = (String) dep;
            }
            int p = s.indexOf('/');
            String depuri = null;
            String depv = null;
            if (p > 0) {
                depuri = s.substring(0, p);
                depv = s.substring(p + 1);
                if (depv.isEmpty()) {
                    depv = null;
                }
                // TODO Remove this hack after next bin compat breaks
                if (LANGUAGE_MODULE_NAME.equals(depuri)) {
                    if ("1.1.0".equals(depv)) {
                        depv = "1.2.0";
                    } else if ("1.2.1".equals(depv)) {
                        depv = Versions.CEYLON_VERSION_NUMBER;
                    } else if ("1.2.2".equals(depv)) {
                        depv = Versions.CEYLON_VERSION_NUMBER;
                    } else if ("1.3.0".equals(depv)) {
                        depv = Versions.CEYLON_VERSION_NUMBER;
                    } else if ("1.3.1".equals(depv)) {
                        depv = Versions.CEYLON_VERSION_NUMBER;
                    } else if ("1.3.2".equals(depv)) {
                        depv = Versions.CEYLON_VERSION_NUMBER;
                    } else if ("1.3.3".equals(depv)) {
                        depv = Versions.CEYLON_VERSION_NUMBER;
                    }
                /*@NEW_VERSION@*/
                }
            } else {
                depuri = s;
            }
            String depnamespace = ModuleUtil.getNamespaceFromUri(depuri);
            String depname = ModuleUtil.getModuleNameFromUri(depuri);
            // This will cause the dependency to be loaded later
            JsonModule mod = (JsonModule) getModuleManager().getOrCreateModule(ModuleManager.splitModuleName(depname), depv);
            Backends backends = mod.getNativeBackends();
            ModuleImport imp = new ModuleImport(depnamespace, mod, optional, export, backends);
            module.addImport(imp);
        }
        model.remove("$mod-deps");
        overrideModuleImports(module, artifact);
    }
    ((JsonModule) module).setModel(model);
    ((JsonModule) module).loadDeclarations();
    return;
}
Also used : Backends(org.eclipse.ceylon.common.Backends) ModuleImport(org.eclipse.ceylon.model.typechecker.model.ModuleImport) List(java.util.List) LinkedList(java.util.LinkedList) Map(java.util.Map)

Example 14 with Backends

use of org.eclipse.ceylon.common.Backends in project ceylon by eclipse.

the class ModuleVisitor method visit.

@Override
public void visit(Tree.ImportModule that) {
    super.visit(that);
    String version = getVersionString(that.getVersion(), that.getConstantVersion(), that);
    if (that.getVersion() == null && version != null) {
        that.setVersion(new Tree.QuotedLiteral(new CommonToken(STRING_LITERAL, "\"" + version + "\"")));
    }
    List<String> name;
    Node node;
    Tree.ImportPath importPath = that.getImportPath();
    Tree.QuotedLiteral quotedLiteral = that.getQuotedLiteral();
    if (importPath != null) {
        name = getNameAsList(importPath);
        node = importPath;
    } else if (quotedLiteral != null) {
        String nameString = getNameString(quotedLiteral);
        name = asList(nameString.split("\\."));
        node = quotedLiteral;
    } else {
        name = Collections.emptyList();
        node = null;
    }
    if (node != null) {
        Tree.QuotedLiteral artifact = that.getArtifact();
        if (artifact != null) {
            name = new ArrayList<String>(name);
            String nameString = getNameString(artifact);
            name.add("");
            name.addAll(asList(nameString.split("\\.")));
        }
        Tree.QuotedLiteral classifier = that.getClassifier();
        if (classifier != null) {
            String nameString = getNameString(classifier);
            name.add("");
            name.addAll(asList(nameString.split("\\.")));
        }
    }
    if (phase == Phase.SRC_MODULE) {
        String path = formatPath(name);
        that.setName(path);
    } else if (phase == Phase.REMAINING) {
        // set in previous phase
        String path = that.getName();
        Tree.Identifier ns = that.getNamespace();
        String namespace = ns != null ? ns.getText() : null;
        boolean hasMavenName = isMavenModule(path);
        boolean forCeylon = (importPath != null && namespace == null) || (importPath == null && namespace == null && !hasMavenName) || DefaultRepository.NAMESPACE.equals(namespace);
        if (name.isEmpty()) {
            that.addError("missing module name");
        } else if (name.get(0).equals(DEFAULT_MODULE_NAME)) {
            if (forCeylon) {
                node.addError("reserved module name: 'default'");
            }
        } else if (name.size() == 1 && name.get(0).equals("ceylon")) {
            if (forCeylon) {
                node.addError("reserved module name: 'ceylon'");
            }
        } else if (name.size() > 1 && name.get(0).equals("ceylon") && name.get(1).equals("language")) {
            if (forCeylon) {
                node.addError("the language module is imported implicitly");
            }
        } else {
            if (namespace == null && hasMavenName) {
                namespace = MavenRepository.NAMESPACE;
                node.addUsageWarning(Warning.missingImportPrefix, "use of old style Maven imports is deprecated, prefix with 'maven:'");
            }
            Tree.AnnotationList al = that.getAnnotationList();
            Unit u = unit.getUnit();
            Backends bs = getNativeBackend(al, u);
            if (!bs.none()) {
                for (Backend b : bs) {
                    if (!b.isRegistered()) {
                        node.addError("illegal native backend name: '\"" + b.nativeAnnotation + "\"' (must be either '\"jvm\"' or '\"js\"')");
                    }
                }
                if (!moduleBackends.none() && !moduleBackends.supports(bs)) {
                    node.addError("native backend name on import conflicts with module descriptor: '\"" + bs.names() + "\"' is not in '\"" + moduleBackends.names() + "\"'");
                }
            }
            Module importedModule = moduleManager.getOrCreateModule(name, version);
            if (importPath != null) {
                importPath.setModel(importedModule);
            }
            if (!completeOnlyAST && mainModule != null) {
                if (importedModule.getVersion() == null) {
                    importedModule.setVersion(version);
                }
                ModuleImport moduleImport = moduleManager.findImport(mainModule, importedModule);
                if (moduleImport == null) {
                    boolean optional = hasAnnotation(al, "optional", u);
                    boolean export = hasAnnotation(al, "shared", u);
                    moduleImport = new ModuleImport(namespace, importedModule, optional, export, bs);
                    moduleImport.getAnnotations().clear();
                    buildAnnotations(al, moduleImport.getAnnotations());
                    mainModule.addImport(moduleImport);
                }
                moduleManagerUtil.addModuleDependencyDefinition(moduleImport, that);
            }
        }
    }
}
Also used : Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Backends(org.eclipse.ceylon.common.Backends) Backend(org.eclipse.ceylon.common.Backend) TreeUtil.getNativeBackend(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.getNativeBackend) ModuleImport(org.eclipse.ceylon.model.typechecker.model.ModuleImport) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) CommonToken(org.antlr.runtime.CommonToken) Module(org.eclipse.ceylon.model.typechecker.model.Module) ModuleUtil.isMavenModule(org.eclipse.ceylon.common.ModuleUtil.isMavenModule)

Example 15 with Backends

use of org.eclipse.ceylon.common.Backends in project ceylon by eclipse.

the class DeclarationVisitor method checkForNativeAnnotation.

private void checkForNativeAnnotation(Tree.Declaration that, Declaration model, Scope scope) {
    Unit unit = model.getUnit();
    if (model.isNative()) {
        Backends mbackends = model.getNativeBackends();
        boolean isHeader = model.isNativeHeader();
        String name = model.getName();
        boolean canBeNative = canBeNative(that);
        if (canBeNative) {
            Backends moduleBackends = unit.getPackage().getModule().getNativeBackends();
            Backends backends = model.getScope().getScopedBackends();
            if (!isHeader && !moduleBackends.none() && !mbackends.supports(moduleBackends)) {
                that.addError("native backend name on declaration conflicts with module descriptor: '\"" + mbackends.names() + "\"' is not '\"" + moduleBackends.names() + "\"' for '" + name + "'");
            } else if (!isHeader && !backends.none() && !backends.supports(mbackends)) {
                that.addError("native backend for declaration conflicts with its scope: native implementation '" + name + "' for '\"" + mbackends.names() + "\"' occurs in a scope which only supports '\"" + backends.names() + "\"'");
            }
            if (isHeader && existImplementations(model)) {
                that.addError("native header must be declared before its implementations: the native header '" + name + "' is declared after an implementation");
            }
            if (model instanceof Interface && ((Interface) model).isAlias()) {
                that.addError("interface alias may not be marked native: '" + name + "' (add a body if a native interface was intended)");
            }
            model.setNativeBackends(mbackends);
            Declaration member = getNativeHeader(model);
            if (member == null || member.isNativeImplementation()) {
                // it's not shared
                if (!isHeader && mustHaveHeader(model) && !moduleBackends.equals(mbackends)) {
                    that.addError("shared native implementation must have a header: '" + model.getName() + "' has no native header");
                }
            }
            if (member == null) {
                if (model.isNativeHeader()) {
                    handleNativeHeader(model, name);
                    if (that instanceof Tree.ObjectDefinition) {
                        Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
                        handleNativeHeader(od.getAnonymousClass(), name);
                    } else if (that instanceof Tree.Constructor) {
                        Tree.Constructor c = (Tree.Constructor) that;
                        handleNativeHeader(c.getConstructor(), name);
                    }
                } else {
                    member = model.getContainer().getDirectMemberForBackend(model.getName(), mbackends);
                    if (member != null && member != model) {
                        that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
                        unit.getDuplicateDeclarations().add(member);
                    }
                }
            } else {
                if (member.isNative()) {
                    List<Declaration> overloads = member.getOverloads();
                    if (isHeader && member.isNativeHeader()) {
                        that.addError("duplicate native header: the header for '" + name + "' is not unique");
                        unit.getDuplicateDeclarations().add(member);
                    } else {
                        Declaration overload = findOverloadForBackend(mbackends, model, overloads);
                        if (overload != null) {
                            that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
                            unit.getDuplicateDeclarations().add(overload);
                        }
                    }
                    if (isAllowedToChangeModel(member) && !hasModelInOverloads(model, overloads)) {
                        overloads.add(model);
                        if (that instanceof Tree.ObjectDefinition) {
                            Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
                            Declaration objImplCls = od.getAnonymousClass();
                            Value value = (Value) member;
                            Class objHdrCls = (Class) value.getType().getDeclaration();
                            objHdrCls.getOverloads().add(objImplCls);
                        } else if (that instanceof Tree.Constructor) {
                            Tree.Constructor c = (Tree.Constructor) that;
                            Declaration cd = c.getConstructor();
                            FunctionOrValue fov = (FunctionOrValue) member;
                            Constructor hdr = (Constructor) fov.getType().getDeclaration();
                            hdr.getOverloads().add(cd);
                        }
                    }
                } else {
                    if (isHeader) {
                        that.addError("native header for non-native declaration: '" + name + "' is not declared native");
                    } else {
                        that.addError("native implementation for non-native header: '" + name + "' is not declared native");
                    }
                }
            }
        } else if (!(model instanceof Setter) && !isHeader) {
            if (!canBeNative) {
                that.addError("native declaration is not a class, constructor, method, attribute or object: '" + name + "' may not be annotated 'native'");
            }
        }
    }
}
Also used : ModelUtil.isDefaultConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isDefaultConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Backends(org.eclipse.ceylon.common.Backends) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) ModelUtil.isAnonymousClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isAnonymousClass) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Aggregations

Backends (org.eclipse.ceylon.common.Backends)21 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)7 Module (org.eclipse.ceylon.model.typechecker.model.Module)7 HashSet (java.util.HashSet)6 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)6 ModuleImport (org.eclipse.ceylon.model.typechecker.model.ModuleImport)6 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)5 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)4 ArrayList (java.util.ArrayList)3 LinkedList (java.util.LinkedList)3 List (java.util.List)3 ModuleDependencyInfo (org.eclipse.ceylon.cmr.api.ModuleDependencyInfo)3 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)3 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)3 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)3 ModelUtil.getNativeDeclaration (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration)3 Unit (org.eclipse.ceylon.model.typechecker.model.Unit)3 ModuleInfo (org.eclipse.ceylon.cmr.api.ModuleInfo)2 Backend (org.eclipse.ceylon.common.Backend)2 AnalyzerUtil.getPackageTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration)2