}
public final SimpleNode onCloseNode(SimpleNode n, int arity) throws Exception {
exprType value;
exprType[] exprs;
Suite orelseSuite;
stmtType[] body;
Suite suite;
int l;
switch (n.getId()) {
case JJTEXPR_STMT:
value = (exprType) stack.popNode();
if (arity > 1) {
exprs = makeExprs(arity - 1);
ctx.setStore(exprs);
return new Assign(exprs, value);
} else {
return new Expr(value);
}
case JJTINDEX_OP:
sliceType slice = (sliceType) stack.popNode();
value = (exprType) stack.popNode();
return new Subscript(value, slice, Subscript.Load);
case JJTBEGIN_FOR_ELSE_STMT:
return new Suite(null);
case JJTBEGIN_ELSE_STMT:
return new Suite(null);
case JJTBEGIN_WHILE_STMT:
return new While(null, null, null);
case JJTWHILE_STMT:
orelseSuite = null;
if (stack.nodeArity() == 5) {
orelseSuite = popSuiteAndSuiteType();
}
body = popSuite();
exprType test = (exprType) stack.popNode();
While w = (While) stack.popNode();
w.test = test;
w.body = body;
w.orelse = orelseSuite;
return w;
case JJTCALL_OP:
exprType starargs = null;
exprType kwargs = null;
java.util.List<exprType> args = new ArrayList<exprType>();
java.util.List<keywordType> keywords = new ArrayList<keywordType>();
for (int i = arity - 2; i >= 0; i--) {
SimpleNode node = stack.popNode();
if (node instanceof keywordType) {
keywordType keyword = (keywordType) node;
keywords.add(0, keyword);
if (starargs == null) {
keyword.afterstarargs = true; //note that we get things backward in the stack
}
} else if (node.getId() == JJTEXTRAARGVALUELIST) {
ExtraArgValue nstarargs = (ExtraArgValue) node;
starargs = nstarargs.value;
this.addSpecialsAndClearOriginal(nstarargs, starargs);
} else if (node.getId() == JJTEXTRAKEYWORDVALUELIST) {
ExtraArgValue nkwargs = (ExtraArgValue) node;
kwargs = nkwargs.value;
this.addSpecialsAndClearOriginal(nkwargs, kwargs);
} else if (node instanceof ComprehensionCollection) {
//what can happen is something like print sum(x for x in y), where we have already passed x in the args, and then get 'for x in y'
args.add(
0,
new ListComp((exprType) stack.popNode(), ((ComprehensionCollection) node)
.getGenerators(), ListComp.EmptyCtx));
i--; //popped node
} else {
args.add(0, (exprType) node);
}
}
exprType func = (exprType) stack.popNode();
Call c = new Call(func, args.toArray(new exprType[args.size()]),
keywords.toArray(new keywordType[keywords.size()]), starargs, kwargs);
addSpecialsAndClearOriginal(n, c);
return c;
case JJTFUNCDEF_RETURN_ANNOTTATION:
SimpleNode funcdefReturn = stack.popNode();
return new FuncDefReturnAnn(funcdefReturn);
case JJTFUNCDEF:
suite = (Suite) stack.popNode();
body = suite.body;
arity--;
SimpleNode funcDefReturnAnn = stack.peekNode();
exprType actualReturnAnnotation = null;
if (funcDefReturnAnn instanceof FuncDefReturnAnn) {
stack.popNode();
actualReturnAnnotation = (exprType) ((FuncDefReturnAnn) funcDefReturnAnn).node;
arity--;
addSpecialsAndClearOriginal(funcDefReturnAnn, actualReturnAnnotation);
}
argumentsType arguments = makeArguments(arity - 1);
NameTok nameTok = makeName(NameTok.FunctionName);
//decorator is always null at this point... it's decorated later on
FunctionDef funcDef = new FunctionDef(nameTok, arguments, body, null, actualReturnAnnotation);
addSpecialsAndClearOriginal(suite, funcDef);
setParentForFuncOrClass(body, funcDef);
return funcDef;
case JJTTFPDEF:
Name tfpdefName = null;
exprType typeDef = null;
if (arity == 1) {
tfpdefName = (Name) stack.popNode();
} else if (arity == 2) {
typeDef = (exprType) stack.popNode();
tfpdefName = (Name) stack.popNode();
} else {
throw new RuntimeException("Unexpected arity: " + arity);
}
return new JfpDef(tfpdefName, typeDef);
case JJTONLYKEYWORDARG2:
case JJTDEFAULTARG2:
DefaultArg defaultArg;
JfpDef jfpDef;
if (arity == 1) {
jfpDef = (JfpDef) stack.popNode();
defaultArg = new DefaultArg(jfpDef.nameNode, null, jfpDef.typeDef, n.getId());
} else if (arity == 2) {
exprType defaultValue = (exprType) stack.popNode();
jfpDef = (JfpDef) stack.popNode();
defaultArg = new DefaultArg(jfpDef.nameNode, defaultValue, jfpDef.typeDef, n.getId());
} else {
throw new RuntimeException("Unexpected arity: " + arity);
}
return defaultArg;
case JJTONLYKEYWORDARG:
case JJTDEFAULTARG:
//no type definition in this case
if (arity == 1) {
return new DefaultArg(((exprType) stack.popNode()), null, null, n.getId());
}
exprType parameter = (exprType) stack.popNode();
return new DefaultArg((exprType) stack.popNode(), parameter, null, n.getId());
case JJTEXTRAARGLIST:
if (arity == 0) {
//nothing here (just '*')
return new ExtraArg(null, JJTEXTRAARGLIST, null);
}
return new ExtraArg(makeName(NameTok.VarArg), JJTEXTRAARGLIST);
case JJTEXTRAKEYWORDLIST:
return new ExtraArg(makeName(NameTok.KwArg), JJTEXTRAKEYWORDLIST);
case JJTEXTRAARGLIST2: //with type declaration
if (arity == 0) {
//nothing here (just '*')
return new ExtraArg(null, JJTEXTRAARGLIST, null);
}
jfpDef = (JfpDef) stack.popNode();
NameTok jfpDefName = makeName(NameTok.VarArg, jfpDef.nameNode);
ExtraArg extra = new ExtraArg(jfpDefName, JJTEXTRAARGLIST, jfpDef.typeDef);
return extra;
case JJTEXTRAKEYWORDLIST2: //with type declaration
jfpDef = (JfpDef) stack.popNode();
return new ExtraArg(makeName(NameTok.KwArg, jfpDef.nameNode), JJTEXTRAKEYWORDLIST, jfpDef.typeDef);
case JJTDECORATED:
if (stack.nodeArity() != 2) {
throw new RuntimeException("Expected 2 nodes at this context, found: " + arity);
}
SimpleNode def = stack.popNode();
Decorators decorators = (Decorators) stack.popNode();
if (def instanceof ClassDef) {
ClassDef classDef = (ClassDef) def;
classDef.decs = decorators.exp;
} else {
FunctionDef fDef = (FunctionDef) def;
fDef.decs = decorators.exp;
}
return def;
case JJTCLASSDEF:
suite = (Suite) stack.popNode();
body = suite.body;
int nodeArity = stack.nodeArity() - 1;
ArrayList<keywordType> classDefKeywords = new ArrayList<keywordType>();
starargs = null;
kwargs = null;
int loopTo = nodeArity;
for (int i = 0; i < loopTo; i++) {
SimpleNode node = stack.peekNode();
if (node instanceof keywordType) {
stack.popNode();
keywordType keyword = (keywordType) node;
classDefKeywords.add(keyword);
if (starargs == null) {
keyword.afterstarargs = true; //note that we get things backward in the stack
}
nodeArity--;
} else if (node instanceof ExtraArgValue) {
if (node.getId() == JJTEXTRAARGVALUELIST) {
ExtraArgValue nstarargs = (ExtraArgValue) stack.popNode();
starargs = nstarargs.value;
this.addSpecialsAndClearOriginal(nstarargs, starargs);
nodeArity--;
} else if (node.getId() == JJTEXTRAKEYWORDVALUELIST) {
ExtraArgValue nkwargs = (ExtraArgValue) stack.popNode();
kwargs = nkwargs.value;
this.addSpecialsAndClearOriginal(nkwargs, kwargs);
nodeArity--;
}
} else {
break;
}
}
if (classDefKeywords.size() > 1) {
Collections.reverse(classDefKeywords);
}
exprType[] bases = makeExprs(nodeArity);
nameTok = makeName(NameTok.ClassName);
//decorator is always null at this point... it's decorated later on
ClassDef classDef = new ClassDef(nameTok, bases, body, null,
classDefKeywords.toArray(new keywordType[classDefKeywords.size()]), starargs, kwargs);
addSpecialsAndClearOriginal(suite, classDef);
setParentForFuncOrClass(body, classDef);
return classDef;
case JJTBEGIN_RETURN_STMT:
return new Return(null);
case JJTRETURN_STMT:
value = arity == 2 ? ((exprType) stack.popNode()) : null;
Return ret = (Return) stack.popNode();
ret.value = value;
return ret;
case JJTYIELD_STMT:
return stack.popNode();
case JJTYIELD_EXPR:
exprType yieldExpr = null;
if (arity > 0) {
//we may have an empty yield, so, we have to check it before
yieldExpr = (exprType) stack.popNode();
}
return new Yield(yieldExpr, false);
case JJTRAISE_STMT:
exprType from = arity >= 2 ? ((exprType) stack.popNode()) : null;
exprType type = arity >= 1 ? ((exprType) stack.popNode()) : null;
return new Raise(type, null, null, from);
case JJTGLOBAL_STMT:
return new Global(makeIdentifiers(NameTok.GlobalName), null);
case JJTNONLOCAL_STMT:
return new NonLocal(makeIdentifiers(NameTok.NonLocalName), null);
case JJTASSERT_STMT:
exprType msg = arity == 2 ? ((exprType) stack.popNode()) : null;
test = (exprType) stack.popNode();
return new Assert(test, msg);
case JJTBEGIN_TRY_STMT:
//we do that just to get the specials
return new TryExcept(null, null, null);
case JJTTRYELSE_STMT:
orelseSuite = popSuiteAndSuiteType();
return orelseSuite;
case JJTTRYFINALLY_OUTER_STMT:
orelseSuite = popSuiteAndSuiteType();
return new TryFinally(null, orelseSuite); //it does not have a body at this time... it will be filled with the inner try..except
case JJTTRY_STMT:
TryFinally outer = null;
if (stack.peekNode() instanceof TryFinally) {
outer = (TryFinally) stack.popNode();
arity--;
}
orelseSuite = null;
if (stack.peekNode() instanceof suiteType) {
orelseSuite = (Suite) stack.popNode();
arity--;
}
l = arity;
excepthandlerType[] handlers = new excepthandlerType[l];
for (int i = l - 1; i >= 0; i--) {
handlers[i] = (excepthandlerType) stack.popNode();
}
suite = (Suite) stack.popNode();
TryExcept tryExc = (TryExcept) stack.popNode();
if (outer != null) {
outer.beginLine = tryExc.beginLine;
}
tryExc.body = suite.body;
tryExc.handlers = handlers;
tryExc.orelse = orelseSuite;
addSpecials(suite, tryExc);
if (outer == null) {
return tryExc;
} else {
if (outer.body != null) {
throw new RuntimeException("Error. Expecting null body to be filled on try..except..finally");
}
outer.body = new stmtType[] { tryExc };
return outer;
}
case JJTBEGIN_TRY_ELSE_STMT:
//we do that just to get the specials
return new Suite(null);
case JJTBEGIN_EXCEPT_CLAUSE:
return new excepthandlerType(null, null, null);
case JJTEXCEPT_CLAUSE:
suite = (Suite) stack.popNode();
body = suite.body;
exprType excname = arity == 4 ? ((exprType) stack.popNode()) : null;
if (excname != null) {
ctx.setStore(excname);
}
type = arity >= 3 ? ((exprType) stack.popNode()) : null;
excepthandlerType handler = (excepthandlerType) stack.popNode();
handler.type = type;
handler.name = excname;
handler.body = body;
addSpecials(suite, handler);
return handler;
case JJTBEGIN_FINALLY_STMT:
//we do that just to get the specials
return new Suite(null);
case JJTTRYFINALLY_STMT:
suiteType finalBody = popSuiteAndSuiteType();
body = popSuite();
//We have a try..except in the stack, but we will change it for a try..finally
//This is because we recognize a try..except in the 'try:' token, but actually end up with a try..finally