All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.ceylon.compiler.js.loader.JsonModule Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
package com.redhat.ceylon.compiler.js.loader;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import com.redhat.ceylon.common.Backend;
import com.redhat.ceylon.common.Backends;
import com.redhat.ceylon.model.typechecker.model.Annotation;
import com.redhat.ceylon.model.typechecker.model.Module;
import com.redhat.ceylon.model.typechecker.model.ModuleImport;
import com.redhat.ceylon.model.typechecker.model.Package;

public class JsonModule extends Module implements NpmAware {

    private Map model;
    private boolean loaded = false;
    private String npmPath;

    public void setModel(Map value) {
        if (model != null) {
            final String modName = (String)model.get("$mod-name");
            final String modVers = (String)model.get("$mod-version");
            if (!(Objects.equals(modName, value.get("$mod-name"))
                    && Objects.equals(modVers, value.get("$mod-version")))) {
                throw new IllegalStateException("JsonModule " + modName+"/"+modVers
                        + " receives new module " + value.get("$mod-name")+"/"+value.get("$mod-version"));
            }
            return;
        }
        model = value;
        final String binVersion = (String)model.get("$mod-bin");
        final int dotidx = binVersion.indexOf('.');
        setJsMajor(Integer.parseInt(binVersion.substring(0,dotidx), 10));
        setJsMinor(Integer.parseInt(binVersion.substring(dotidx+1), 10));
        if (model.get("$mod-pa") != null) {
            int bits = (int)model.get("$mod-pa");
            setNativeBackends(JsonPackage.hasAnnotationBit(bits, "native") ? Backend.JavaScript.asSet() : Backends.ANY);
        }
        @SuppressWarnings("unchecked")
        final Object moduleAnns = model.get("$mod-anns");
        if (moduleAnns instanceof List) {
            JsonPackage.setNewAnnotations(getAnnotations(), (List>>)moduleAnns);
        } else if (moduleAnns instanceof Map) {
            JsonPackage.setOldAnnotations(getAnnotations(), (Map>)moduleAnns);
        } else if (moduleAnns != null) {
            throw new IllegalArgumentException("Annotations should be a List (new format) or a Map (old format)");
        }
    }
    public Map getModel() {
        return model;
    }

    void loadDeclarations() {
        if (loaded)return;
        if (model != null) {
            if (!loaded) {
                loaded=true;
                for (Map.Entry e : model.entrySet()) {
                    if (!e.getKey().startsWith("$mod-")) {
                        JsonPackage p = new JsonPackage(e.getKey());
                        p.setModule(this);
                        getPackages().add(p);
                    }
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public Map getModelForPackage(String name) {
        return model == null ? null : (Map)model.get(name);
    }

    @Override
    public Package getPackage(String name) {
        if ("default".equals(name)) {
            name = "";
        }
        // search direct packages
        Package p = getDirectPackage(name);
        if (p != null) {
            return p;
        }

        // search imported modules
        HashSet visited = new HashSet();
        visited.add(this);
        for (ModuleImport imp : getImports()) {
            p = getPackageFromImport(name, imp.getModule(), visited);
            if (p != null) {
                return p;
            }
        }

        // not found
        return null;
    }

    @Override
    public Package getDirectPackage(String name) {
        Package pkg = super.getDirectPackage(name);
        if (pkg == null && npmPath != null) {
            String modName = getNameAsString();
            if (getNameAsString().indexOf('-') > 0) {
                modName = modName.replace('-', '.');
            }
            if (modName.equals(name)) {
                pkg = new NpmPackage(this, name);
                getPackages().add(pkg);
            }
        }
        return pkg;
    }

    private Package getPackageFromImport(String name, Module module, Set visited) {
        // break circularities
        if (!visited.add(module)) {
            return null;
        }

        // search direct packages
        Package p = module.getDirectPackage(name);
        if (p != null) {
            return p;
        }

        // search exports
        for (ModuleImport imp : module.getImports()) {
            if (imp.isExport()) {
                p = getPackageFromImport(name, imp.getModule(), visited);
                if (p != null) {
                    return p;
                }
            }
        }

        // not found
        return null;
    }

    public List getImports() {
        final List s = super.getImports();
        ArrayList r = new ArrayList<>(s.size());
        r.addAll(s);
        return r;
    }

    public void setNpmPath(String value) {
        npmPath = value;
    }
    public String getNpmPath() {
        return npmPath;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy