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

src.org.python.indexer.ast.NModule Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
/**
 * Copyright 2009, Google Inc.  All rights reserved.
 * Licensed to PSF under a Contributor Agreement.
 */
package org.python.indexer.ast;

import org.python.indexer.Def;
import org.python.indexer.Indexer;
import org.python.indexer.NBinding;
import org.python.indexer.Scope;
import org.python.indexer.Util;
import org.python.indexer.types.NModuleType;
import org.python.indexer.types.NType;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class NModule extends NNode {

    static final long serialVersionUID = -7737089963380450802L;

    public String name;
    public NBody body;

    private String file;  // input source file path
    private String md5;   // input source file md5

    public NModule() {
    }

    public NModule(String name) {
        this.name = name;
    }

    public NModule(NBlock body, int start, int end) {
        super(start, end);
        this.body = new NBody(body);
        addChildren(this.body);
    }

    public void setFile(String file) throws Exception {
        this.file = file;
        this.name = Util.moduleNameFor(file);
        this.md5 = Util.getMD5(new File(file));
    }

    public void setFile(File path) throws Exception {
        file = path.getCanonicalPath();
        name = Util.moduleNameFor(file);
        md5 = Util.getMD5(path);
    }

    /**
     * Used when module is parsed from an in-memory string.
     * @param path file path
     * @param md5 md5 message digest for source contents
     */
    public void setFileAndMD5(String path, String md5) throws Exception {
        file = path;
        name = Util.moduleNameFor(file);
        this.md5 = md5;
    }

    @Override
    public String getFile() {
        return file;
    }

    public String getMD5() {
        return md5;
    }

    @Override
    public NType resolve(Scope s) throws Exception {
        NBinding mb = Indexer.idx.moduleTable.lookupLocal(file);
        if (mb == null ) {
            Indexer.idx.reportFailedAssertion("No module for " + name + ": " + file);
            setType(new NModuleType(name, file, s));
        } else {
            setType(mb.getType());
        }

        resolveExpr(body, getTable());

        resolveExportedNames();
        return getType();
    }

    /**
     * If the module defines an {@code __all__} variable, resolve references
     * to each of the elements.
     */
    private void resolveExportedNames() throws Exception {
        NModuleType mtype = null;
        NType thisType = getType();
        if (thisType.isModuleType()) {
            mtype = thisType.asModuleType();
        } else if (thisType.isUnionType()) {
            for (NType u : thisType.asUnionType().getTypes()) {
                if (u.isModuleType()) {
                    mtype = u.asModuleType();
                    break;
                }
            }
        }

        if (mtype == null) {
            Indexer.idx.reportFailedAssertion("Found non-module type for "
                                              + this + " in " + getFile() + ": " + thisType);
            return;
        }

        Scope table = mtype.getTable();
        for (NStr nstr : getExportedNameNodes()) {
            String name = nstr.n.toString();
            NBinding b = table.lookupLocal(name);
            if (b != null) {
                Indexer.idx.putLocation(nstr, b);
            }
        }
    }

    /**
     * Attempt to determine the actual value of the "__all__" variable in the
     * target module.  If we can parse it, return the list of exported names.

* * @return the list of exported names. Returns {@code null} if __all__ is * missing, or if its initializer is not a simple list of strings. * We don't generate a warning, since complex expressions such as * {@code __all__ = [name for name in dir() if name[0] == "e"]} * are valid provided the expr result is a string list. */ public List getExportedNames() throws Exception { List exports = new ArrayList(); if (!getType().isModuleType()) { return exports; } for (NStr nstr : getExportedNameNodes()) { exports.add(nstr.n.toString()); } return exports; } /** * If the module defines an {@code __all__} variable, returns the string * elements of the variable's list value. * @return any exported name nodes found, or an empty list if none found */ public List getExportedNameNodes() throws Exception { List exports = new ArrayList(); if (!getType().isModuleType()) { return exports; } NBinding all = getTable().lookupLocal("__all__"); if (all== null) { return exports; } Def def = all.getSignatureNode(); if (def == null) { return exports; } NNode __all__ = getDeepestNodeAtOffset(def.start()); if (!(__all__ instanceof NName)) { return exports; } NNode assign = __all__.getParent(); if (!(assign instanceof NAssign)) { return exports; } NNode rvalue = ((NAssign)assign).rvalue; if (!(rvalue instanceof NList)) { return exports; } for (NNode elt : ((NList)rvalue).elts) { if (elt instanceof NStr) { NStr nstr = (NStr)elt; if (nstr.n != null) { exports.add(nstr); } } } return exports; } public String toLongString() { return ""; } @Override public String toString() { return ""; } @Override public void visit(NNodeVisitor v) { if (v.visit(this)) { visitNode(body, v); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy