org.python.indexer.ast.NLambda 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.Indexer;
import org.python.indexer.NBinding;
import org.python.indexer.Scope;
import org.python.indexer.types.NFuncType;
import org.python.indexer.types.NTupleType;
import org.python.indexer.types.NType;
import org.python.indexer.types.NUnknownType;
import java.util.List;
public class NLambda extends NFunctionDef {
static final long serialVersionUID = 7737836525970653522L;
private NName fname;
public NLambda(List args, NNode body, List defaults,
NName varargs, NName kwargs) {
this(args, body, defaults, varargs, kwargs, 0, 1);
}
public NLambda(List args, NNode body, List defaults,
NName varargs, NName kwargs, int start, int end) {
super(null, args, null, defaults, varargs, kwargs, start, end);
this.body = body instanceof NBlock ? new NBody((NBlock)body) : body;
addChildren(this.body);
}
@Override
public boolean isLambda() {
return true;
}
/**
* Returns the name of the function for indexing/qname purposes.
*/
@Override
protected String getBindingName(Scope s) {
if (fname != null) {
return fname.id;
}
String fn = s.newLambdaName();
fname = new NName(fn, start(), start() + "lambda".length());
fname.setParent(this);
return fn;
}
@Override
protected void bindFunctionName(Scope owner) throws Exception {
NameBinder.make(NBinding.Kind.FUNCTION).bindName(owner, fname, getType());
}
@Override
protected void bindMethodAttrs(Scope owner) throws Exception {
// no-op
}
@Override
public NType resolve(Scope s) throws Exception {
if (!getType().isFuncType()) {
org.python.indexer.Indexer.idx.reportFailedAssertion(
"Bad type on " + this + ": type=" + getType() +
" in file " + getFile() + " at " + start());
}
NTupleType fromType = new NTupleType();
NameBinder param = NameBinder.make(NBinding.Kind.PARAMETER);
resolveList(defaults, s);
Scope funcTable = getTable();
int argnum = 0;
for (NNode a : args) {
NType argtype = NFunctionDef.getArgType(args, defaults, argnum++);
param.bind(funcTable, a, argtype);
fromType.add(argtype);
}
if (varargs != null) {
NType u = new NUnknownType();
param.bind(funcTable, varargs, u);
fromType.add(u);
}
if (kwargs != null) {
NType u = new NUnknownType();
param.bind(funcTable, kwargs, u);
fromType.add(u);
}
// A lambda body is not an NBody, so it doesn't undergo the two
// pre-resolve passes for finding global statements and name-binding
// constructs. However, the lambda expression may itself contain
// name-binding constructs (generally, other lambdas), so we need to
// perform the name-binding pass on it before resolving.
try {
funcTable.setNameBindingPhase(true);
body.visit(new BindingFinder(funcTable));
} finally {
funcTable.setNameBindingPhase(false);
}
NType toType = resolveExpr(body, funcTable);
if (getType().isFuncType()) { // else warning logged at method entry above
getType().asFuncType().setReturnType(toType);
}
return getType();
}
@Override
public String toString() {
return "";
}
@Override
public void visit(NNodeVisitor v) {
if (v.visit(this)) {
visitNodeList(args, v);
visitNodeList(defaults, v);
visitNode(varargs, v);
visitNode(kwargs, v);
visitNode(body, v);
}
}
}