org.python.indexer.ast.NImport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-slim Show documentation
Show all versions of jython-slim Show documentation
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.
/**
* Copyright 2009, Google Inc. All rights reserved.
* Licensed to PSF under a Contributor Agreement.
*/
package org.python.indexer.ast;
import org.python.indexer.Builtins;
import org.python.indexer.Indexer;
import org.python.indexer.NBinding;
import org.python.indexer.Scope;
import org.python.indexer.types.NModuleType;
import org.python.indexer.types.NType;
import org.python.indexer.types.NUnknownType;
import java.util.List;
public class NImport extends NNode {
static final long serialVersionUID = -2180402676651342012L;
public List aliases; // import foo.bar as bar, ..x.y as y
public NImport(List aliases) {
this(aliases, 0, 1);
}
public NImport(List aliases, int start, int end) {
super(start, end);
this.aliases = aliases;
addChildren(aliases);
}
@Override
public boolean bindsName() {
return true;
}
@Override
protected void bindNames(Scope s) throws Exception {
bindAliases(s, aliases);
}
static void bindAliases(Scope s, List aliases) throws Exception {
NameBinder binder = NameBinder.make();
for (NAlias a : aliases) {
if (a.aname != null) {
binder.bind(s, a.aname, new NUnknownType());
}
}
}
@Override
public NType resolve(Scope s) throws Exception {
Scope scope = s.getScopeSymtab();
for (NAlias a : aliases) {
NType modtype = resolveExpr(a, s);
if (modtype.isModuleType()) {
importName(scope, a, modtype.asModuleType());
}
}
return getType();
}
/**
* Import a module's alias (if present) or top-level name into the current
* scope. Creates references to the other names in the alias.
*
* @param mt the module that is actually bound to the imported name.
* for {@code import x.y.z as foo}, it is {@code z}, a sub-module
* of {@code x.y}. For {@code import x.y.z} it is {@code x}.
*/
private void importName(Scope s, NAlias a, NModuleType mt) throws Exception {
if (a.aname != null) {
if (mt.getFile() != null) {
NameBinder.make().bind(s, a.aname, mt);
} else {
// XXX: seems like the url should be set in loadModule, not here.
// Can't the moduleTable store url-keyed modules too?
s.update(a.aname.id,
new NUrl(Builtins.LIBRARY_URL + mt.getTable().getPath() + ".html"),
mt, NBinding.Kind.SCOPE);
}
}
addReferences(s, a.qname, true/*put top name in scope*/);
}
static void addReferences(Scope s, NQname qname, boolean putTopInScope) {
if (qname == null) {
return;
}
if (!qname.getType().isModuleType()) {
return;
}
NModuleType mt = qname.getType().asModuleType();
String modQname = mt.getTable().getPath();
NBinding mb = Indexer.idx.lookupQname(modQname);
if (mb == null) {
mb = Indexer.idx.moduleTable.lookup(modQname);
}
if (mb == null) {
Indexer.idx.putProblem(qname.getName(), "module not found");
return;
}
Indexer.idx.putLocation(qname.getName(), mb);
// All other references in the file should also point to this binding.
if (putTopInScope && qname.isTop()) {
s.put(qname.getName().id, mb);
}
addReferences(s, qname.getNext(), false);
}
@Override
public String toString() {
return "";
}
@Override
public void visit(NNodeVisitor v) {
if (v.visit(this)) {
visitNodeList(aliases, v);
}
}
}