diff options
Diffstat (limited to 'Python/ast.c')
-rw-r--r-- | Python/ast.c | 346 |
1 files changed, 252 insertions, 94 deletions
diff --git a/Python/ast.c b/Python/ast.c index d71f44a6db..855acca29e 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -580,10 +580,11 @@ static stmt_ty ast_for_for_stmt(struct compiling *, const node *, bool); /* Note different signature for ast_for_call */ static expr_ty ast_for_call(struct compiling *, const node *, expr_ty, - const node *); + const node *, const node *); static PyObject *parsenumber(struct compiling *, const char *); static expr_ty parsestrplus(struct compiling *, const node *n); +static void get_last_end_pos(asdl_seq *, int *, int *); #define COMP_GENEXP 0 #define COMP_LISTCOMP 1 @@ -810,6 +811,7 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags, if (!stmts) goto out; asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, arena)); if (!asdl_seq_GET(stmts, 0)) goto out; @@ -940,6 +942,8 @@ copy_location(expr_ty e, const node *n) if (e) { e->lineno = LINENO(n); e->col_offset = n->n_col_offset; + e->end_lineno = n->n_end_lineno; + e->end_col_offset = n->n_end_col_offset; } return e; } @@ -1228,7 +1232,8 @@ ast_for_arg(struct compiling *c, const node *n) return NULL; } - ret = arg(name, annotation, LINENO(n), n->n_col_offset, c->c_arena); + ret = arg(name, annotation, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!ret) return NULL; return ret; @@ -1287,6 +1292,7 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, if (forbidden_name(c, argname, ch, 0)) goto error; arg = arg(argname, annotation, LINENO(ch), ch->n_col_offset, + ch->n_end_lineno, ch->n_end_col_offset, c->c_arena); if (!arg) goto error; @@ -1480,16 +1486,19 @@ ast_for_dotted_name(struct compiling *c, const node *n) identifier id; int lineno, col_offset; int i; + node *ch; REQ(n, dotted_name); lineno = LINENO(n); col_offset = n->n_col_offset; - id = NEW_IDENTIFIER(CHILD(n, 0)); + ch = CHILD(n, 0); + id = NEW_IDENTIFIER(ch); if (!id) return NULL; - e = Name(id, Load, lineno, col_offset, c->c_arena); + e = Name(id, Load, lineno, col_offset, + ch->n_end_lineno, ch->n_end_col_offset, c->c_arena); if (!e) return NULL; @@ -1497,7 +1506,8 @@ ast_for_dotted_name(struct compiling *c, const node *n) id = NEW_IDENTIFIER(CHILD(n, i)); if (!id) return NULL; - e = Attribute(e, id, Load, lineno, col_offset, c->c_arena); + e = Attribute(e, id, Load, lineno, col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!e) return NULL; } @@ -1526,13 +1536,13 @@ ast_for_decorator(struct compiling *c, const node *n) } else if (NCH(n) == 5) { /* Call with no arguments */ d = Call(name_expr, NULL, NULL, LINENO(n), - n->n_col_offset, c->c_arena); + n->n_col_offset, n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!d) return NULL; name_expr = NULL; } else { - d = ast_for_call(c, CHILD(n, 3), name_expr, CHILD(n, 2)); + d = ast_for_call(c, CHILD(n, 3), name_expr, CHILD(n, 2), CHILD(n, 4)); if (!d) return NULL; name_expr = NULL; @@ -1573,6 +1583,7 @@ ast_for_funcdef_impl(struct compiling *c, const node *n0, asdl_seq *body; expr_ty returns = NULL; int name_i = 1; + int end_lineno, end_col_offset; REQ(n, funcdef); @@ -1593,13 +1604,14 @@ ast_for_funcdef_impl(struct compiling *c, const node *n0, body = ast_for_suite(c, CHILD(n, name_i + 3)); if (!body) return NULL; + get_last_end_pos(body, &end_lineno, &end_col_offset); if (is_async) return AsyncFunctionDef(name, args, body, decorator_seq, returns, - LINENO(n0), n0->n_col_offset, c->c_arena); + LINENO(n0), n0->n_col_offset, end_lineno, end_col_offset, c->c_arena); else return FunctionDef(name, args, body, decorator_seq, returns, - LINENO(n), n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, end_lineno, end_col_offset, c->c_arena); } static stmt_ty @@ -1704,7 +1716,8 @@ ast_for_lambdef(struct compiling *c, const node *n) return NULL; } - return Lambda(args, expression, LINENO(n), n->n_col_offset, c->c_arena); + return Lambda(args, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } static expr_ty @@ -1724,6 +1737,7 @@ ast_for_ifexpr(struct compiling *c, const node *n) if (!orelse) return NULL; return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } @@ -1852,8 +1866,9 @@ ast_for_comprehension(struct compiling *c, const node *n) comp = comprehension(first, expression, NULL, is_async, c->c_arena); else - comp = comprehension(Tuple(t, Store, first->lineno, - first->col_offset, c->c_arena), + comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset, + for_ch->n_end_lineno, for_ch->n_end_col_offset, + c->c_arena), expression, NULL, is_async, c->c_arena); if (!comp) return NULL; @@ -1918,11 +1933,14 @@ ast_for_itercomp(struct compiling *c, const node *n, int type) return NULL; if (type == COMP_GENEXP) - return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena); + return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); else if (type == COMP_LISTCOMP) - return ListComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena); + return ListComp(elt, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); else if (type == COMP_SETCOMP) - return SetComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena); + return SetComp(elt, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); else /* Should never happen */ return NULL; @@ -1984,7 +2002,8 @@ ast_for_dictcomp(struct compiling *c, const node *n) if (!comps) return NULL; - return DictComp(key, value, comps, LINENO(n), n->n_col_offset, c->c_arena); + return DictComp(key, value, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } static expr_ty @@ -2017,7 +2036,8 @@ ast_for_dictdisplay(struct compiling *c, const node *n) } keys->size = j; values->size = j; - return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena); + return Dict(keys, values, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } static expr_ty @@ -2060,7 +2080,8 @@ ast_for_setdisplay(struct compiling *c, const node *n) return NULL; asdl_seq_SET(elts, i / 2, expression); } - return Set(elts, LINENO(n), n->n_col_offset, c->c_arena); + return Set(elts, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } static expr_ty @@ -2079,17 +2100,21 @@ ast_for_atom(struct compiling *c, const node *n) size_t len = strlen(s); if (len >= 4 && len <= 5) { if (!strcmp(s, "None")) - return Constant(Py_None, LINENO(n), n->n_col_offset, c->c_arena); + return Constant(Py_None, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!strcmp(s, "True")) - return Constant(Py_True, LINENO(n), n->n_col_offset, c->c_arena); + return Constant(Py_True, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!strcmp(s, "False")) - return Constant(Py_False, LINENO(n), n->n_col_offset, c->c_arena); + return Constant(Py_False, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } name = new_identifier(s, c); if (!name) return NULL; /* All names start in Load context, but may later be changed. */ - return Name(name, Load, LINENO(n), n->n_col_offset, c->c_arena); + return Name(name, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } case STRING: { expr_ty str = parsestrplus(c, n); @@ -2128,15 +2153,18 @@ ast_for_atom(struct compiling *c, const node *n) Py_DECREF(pynum); return NULL; } - return Constant(pynum, LINENO(n), n->n_col_offset, c->c_arena); + return Constant(pynum, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } case ELLIPSIS: /* Ellipsis */ - return Constant(Py_Ellipsis, LINENO(n), n->n_col_offset, c->c_arena); + return Constant(Py_Ellipsis, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); case LPAR: /* some parenthesized expressions */ ch = CHILD(n, 1); if (TYPE(ch) == RPAR) - return Tuple(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena); + return Tuple(NULL, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (TYPE(ch) == yield_expr) return ast_for_expr(c, ch); @@ -2156,7 +2184,8 @@ ast_for_atom(struct compiling *c, const node *n) ch = CHILD(n, 1); if (TYPE(ch) == RSQB) - return List(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena); + return List(NULL, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); REQ(ch, testlist_comp); if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { @@ -2164,7 +2193,8 @@ ast_for_atom(struct compiling *c, const node *n) if (!elts) return NULL; - return List(elts, Load, LINENO(n), n->n_col_offset, c->c_arena); + return List(elts, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else { return copy_location(ast_for_listcomp(c, ch), n); @@ -2178,7 +2208,8 @@ ast_for_atom(struct compiling *c, const node *n) ch = CHILD(n, 1); if (TYPE(ch) == RBRACE) { /* It's an empty dict. */ - return Dict(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); + return Dict(NULL, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else { int is_dict = (TYPE(CHILD(ch, 0)) == DOUBLESTAR); @@ -2306,6 +2337,7 @@ ast_for_binop(struct compiling *c, const node *n) return NULL; result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, + CHILD(n, 2)->n_end_lineno, CHILD(n, 2)->n_end_col_offset, c->c_arena); if (!result) return NULL; @@ -2325,6 +2357,8 @@ ast_for_binop(struct compiling *c, const node *n) tmp_result = BinOp(result, newoperator, tmp, LINENO(next_oper), next_oper->n_col_offset, + CHILD(n, i * 2 + 2)->n_end_lineno, + CHILD(n, i * 2 + 2)->n_end_col_offset, c->c_arena); if (!tmp_result) return NULL; @@ -2340,20 +2374,22 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) subscriptlist: subscript (',' subscript)* [','] subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] */ + const node *n_copy = n; REQ(n, trailer); if (TYPE(CHILD(n, 0)) == LPAR) { if (NCH(n) == 2) - return Call(left_expr, NULL, NULL, LINENO(n), - n->n_col_offset, c->c_arena); + return Call(left_expr, NULL, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); else - return ast_for_call(c, CHILD(n, 1), left_expr, CHILD(n, 0)); + return ast_for_call(c, CHILD(n, 1), left_expr, CHILD(n, 0), CHILD(n, 2)); } else if (TYPE(CHILD(n, 0)) == DOT) { PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1)); if (!attr_id) return NULL; return Attribute(left_expr, attr_id, Load, - LINENO(n), n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else { REQ(CHILD(n, 0), LSQB); @@ -2364,6 +2400,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) if (!slc) return NULL; return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } else { @@ -2389,7 +2426,8 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) } if (!simple) { return Subscript(left_expr, ExtSlice(slices, c->c_arena), - Load, LINENO(n), n->n_col_offset, c->c_arena); + Load, LINENO(n), n->n_col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } /* extract Index values and put them in a Tuple */ elts = _Py_asdl_seq_new(asdl_seq_LEN(slices), c->c_arena); @@ -2400,11 +2438,13 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) assert(slc->kind == Index_kind && slc->v.Index.value); asdl_seq_SET(elts, j, slc->v.Index.value); } - e = Tuple(elts, Load, LINENO(n), n->n_col_offset, c->c_arena); + e = Tuple(elts, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!e) return NULL; return Subscript(left_expr, Index(e, c->c_arena), - Load, LINENO(n), n->n_col_offset, c->c_arena); + Load, LINENO(n), n->n_col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } } } @@ -2421,13 +2461,16 @@ ast_for_factor(struct compiling *c, const node *n) switch (TYPE(CHILD(n, 0))) { case PLUS: return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); case MINUS: return UnaryOp(USub, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); case TILDE: - return UnaryOp(Invert, expression, LINENO(n), - n->n_col_offset, c->c_arena); + return UnaryOp(Invert, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + c->c_arena); } PyErr_Format(PyExc_SystemError, "unhandled factor: %d", TYPE(CHILD(n, 0))); @@ -2454,7 +2497,8 @@ ast_for_atom_expr(struct compiling *c, const node *n) if (nch == 1) return e; if (start && nch == 2) { - return Await(e, LINENO(n), n->n_col_offset, c->c_arena); + return Await(e, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } for (i = start + 1; i < nch; i++) { @@ -2471,7 +2515,8 @@ ast_for_atom_expr(struct compiling *c, const node *n) if (start) { /* there was an 'await' */ - return Await(e, LINENO(n), n->n_col_offset, c->c_arena); + return Await(e, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else { return e; @@ -2494,7 +2539,8 @@ ast_for_power(struct compiling *c, const node *n) expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1)); if (!f) return NULL; - e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena); + e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } return e; } @@ -2510,7 +2556,8 @@ ast_for_starred(struct compiling *c, const node *n) return NULL; /* The Load context is changed later. */ - return Starred(tmp, Load, LINENO(n), n->n_col_offset, c->c_arena); + return Starred(tmp, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } @@ -2569,9 +2616,11 @@ ast_for_expr(struct compiling *c, const node *n) } if (!strcmp(STR(CHILD(n, 1)), "and")) return BoolOp(And, seq, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); assert(!strcmp(STR(CHILD(n, 1)), "or")); - return BoolOp(Or, seq, LINENO(n), n->n_col_offset, c->c_arena); + return BoolOp(Or, seq, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); case not_test: if (NCH(n) == 1) { n = CHILD(n, 0); @@ -2583,6 +2632,7 @@ ast_for_expr(struct compiling *c, const node *n) return NULL; return UnaryOp(Not, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } case comparison: @@ -2622,8 +2672,8 @@ ast_for_expr(struct compiling *c, const node *n) return NULL; } - return Compare(expression, ops, cmps, LINENO(n), - n->n_col_offset, c->c_arena); + return Compare(expression, ops, cmps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } break; @@ -2663,8 +2713,10 @@ ast_for_expr(struct compiling *c, const node *n) return NULL; } if (is_from) - return YieldFrom(exp, LINENO(n), n->n_col_offset, c->c_arena); - return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena); + return YieldFrom(exp, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + return Yield(exp, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } case factor: if (NCH(n) == 1) { @@ -2684,7 +2736,7 @@ ast_for_expr(struct compiling *c, const node *n) static expr_ty ast_for_call(struct compiling *c, const node *n, expr_ty func, - const node *maybegenbeg) + const node *maybegenbeg, const node *closepar) { /* arglist: argument (',' argument)* [','] @@ -2773,6 +2825,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, return NULL; starred = Starred(e, Load, LINENO(chch), chch->n_col_offset, + chch->n_end_lineno, chch->n_end_col_offset, c->c_arena); if (!starred) return NULL; @@ -2864,7 +2917,8 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, } } - return Call(func, args, keywords, func->lineno, func->col_offset, c->c_arena); + return Call(func, args, keywords, func->lineno, func->col_offset, + closepar->n_end_lineno, closepar->n_end_col_offset, c->c_arena); } static expr_ty @@ -2887,7 +2941,8 @@ ast_for_testlist(struct compiling *c, const node* n) asdl_seq *tmp = seq_for_testlist(c, n); if (!tmp) return NULL; - return Tuple(tmp, Load, LINENO(n), n->n_col_offset, c->c_arena); + return Tuple(tmp, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } } @@ -2909,7 +2964,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n) if (!e) return NULL; - return Expr(e, LINENO(n), n->n_col_offset, c->c_arena); + return Expr(e, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else if (TYPE(CHILD(n, 1)) == augassign) { expr_ty expr1, expr2; @@ -2947,7 +3003,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n) if (!newoperator) return NULL; - return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, c->c_arena); + return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else if (TYPE(CHILD(n, 1)) == annassign) { expr_ty expr1, expr2, expr3; @@ -3007,7 +3064,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n) } if (NCH(ann) == 2) { return AnnAssign(expr1, expr2, NULL, simple, - LINENO(n), n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else { ch = CHILD(ann, 3); @@ -3016,7 +3074,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n) return NULL; } return AnnAssign(expr1, expr2, expr3, simple, - LINENO(n), n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } } else { @@ -3054,7 +3113,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n) expression = ast_for_expr(c, value); if (!expression) return NULL; - return Assign(targets, expression, LINENO(n), n->n_col_offset, c->c_arena); + return Assign(targets, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } } @@ -3093,7 +3153,8 @@ ast_for_del_stmt(struct compiling *c, const node *n) expr_list = ast_for_exprlist(c, CHILD(n, 1), Del); if (!expr_list) return NULL; - return Delete(expr_list, LINENO(n), n->n_col_offset, c->c_arena); + return Delete(expr_list, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } static stmt_ty @@ -3115,27 +3176,33 @@ ast_for_flow_stmt(struct compiling *c, const node *n) ch = CHILD(n, 0); switch (TYPE(ch)) { case break_stmt: - return Break(LINENO(n), n->n_col_offset, c->c_arena); + return Break(LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); case continue_stmt: - return Continue(LINENO(n), n->n_col_offset, c->c_arena); + return Continue(LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); case yield_stmt: { /* will reduce to yield_expr */ expr_ty exp = ast_for_expr(c, CHILD(ch, 0)); if (!exp) return NULL; - return Expr(exp, LINENO(n), n->n_col_offset, c->c_arena); + return Expr(exp, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } case return_stmt: if (NCH(ch) == 1) - return Return(NULL, LINENO(n), n->n_col_offset, c->c_arena); + return Return(NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); else { expr_ty expression = ast_for_testlist(c, CHILD(ch, 1)); if (!expression) return NULL; - return Return(expression, LINENO(n), n->n_col_offset, c->c_arena); + return Return(expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } case raise_stmt: if (NCH(ch) == 1) - return Raise(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); + return Raise(NULL, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); else if (NCH(ch) >= 2) { expr_ty cause = NULL; expr_ty expression = ast_for_expr(c, CHILD(ch, 1)); @@ -3146,7 +3213,8 @@ ast_for_flow_stmt(struct compiling *c, const node *n) if (!cause) return NULL; } - return Raise(expression, cause, LINENO(n), n->n_col_offset, c->c_arena); + return Raise(expression, cause, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } /* fall through */ default: @@ -3307,11 +3375,14 @@ ast_for_import_stmt(struct compiling *c, const node *n) return NULL; asdl_seq_SET(aliases, i / 2, import_alias); } - return Import(aliases, lineno, col_offset, c->c_arena); + // Even though n is modified above, the end position is not changed + return Import(aliases, lineno, col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else if (TYPE(n) == import_from) { int n_children; int idx, ndots = 0; + const node *n_copy = n; alias_ty mod = NULL; identifier modname = NULL; @@ -3382,6 +3453,7 @@ ast_for_import_stmt(struct compiling *c, const node *n) if (mod != NULL) modname = mod->name; return ImportFrom(modname, aliases, ndots, lineno, col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); } PyErr_Format(PyExc_SystemError, @@ -3408,7 +3480,8 @@ ast_for_global_stmt(struct compiling *c, const node *n) return NULL; asdl_seq_SET(s, i / 2, name); } - return Global(s, LINENO(n), n->n_col_offset, c->c_arena); + return Global(s, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } static stmt_ty @@ -3429,7 +3502,8 @@ ast_for_nonlocal_stmt(struct compiling *c, const node *n) return NULL; asdl_seq_SET(s, i / 2, name); } - return Nonlocal(s, LINENO(n), n->n_col_offset, c->c_arena); + return Nonlocal(s, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } static stmt_ty @@ -3441,7 +3515,8 @@ ast_for_assert_stmt(struct compiling *c, const node *n) expr_ty expression = ast_for_expr(c, CHILD(n, 1)); if (!expression) return NULL; - return Assert(expression, NULL, LINENO(n), n->n_col_offset, c->c_arena); + return Assert(expression, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } else if (NCH(n) == 4) { expr_ty expr1, expr2; @@ -3453,7 +3528,8 @@ ast_for_assert_stmt(struct compiling *c, const node *n) if (!expr2) return NULL; - return Assert(expr1, expr2, LINENO(n), n->n_col_offset, c->c_arena); + return Assert(expr1, expr2, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } PyErr_Format(PyExc_SystemError, "improper number of parts to 'assert' statement: %d", @@ -3527,6 +3603,20 @@ ast_for_suite(struct compiling *c, const node *n) return seq; } +static void +get_last_end_pos(asdl_seq *s, int *end_lineno, int *end_col_offset) +{ + int tot = asdl_seq_LEN(s); + // Suite should not be empty, but it is safe to just ignore it + // if it will ever occur. + if (!tot) { + return; + } + stmt_ty last = asdl_seq_GET(s, tot - 1); + *end_lineno = last->end_lineno; + *end_col_offset = last->end_col_offset; +} + static stmt_ty ast_for_if_stmt(struct compiling *c, const node *n) { @@ -3534,6 +3624,7 @@ ast_for_if_stmt(struct compiling *c, const node *n) ['else' ':' suite] */ char *s; + int end_lineno, end_col_offset; REQ(n, if_stmt); @@ -3547,9 +3638,10 @@ ast_for_if_stmt(struct compiling *c, const node *n) suite_seq = ast_for_suite(c, CHILD(n, 3)); if (!suite_seq) return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, - c->c_arena); + end_lineno, end_col_offset, c->c_arena); } s = STR(CHILD(n, 4)); @@ -3570,9 +3662,10 @@ ast_for_if_stmt(struct compiling *c, const node *n) seq2 = ast_for_suite(c, CHILD(n, 6)); if (!seq2) return NULL; + get_last_end_pos(seq2, &end_lineno, &end_col_offset); return If(expression, seq1, seq2, LINENO(n), n->n_col_offset, - c->c_arena); + end_lineno, end_col_offset, c->c_arena); } else if (s[2] == 'i') { int i, n_elif, has_else = 0; @@ -3604,12 +3697,13 @@ ast_for_if_stmt(struct compiling *c, const node *n) suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1)); if (!suite_seq2) return NULL; + get_last_end_pos(suite_seq2, &end_lineno, &end_col_offset); asdl_seq_SET(orelse, 0, If(expression, suite_seq, suite_seq2, LINENO(CHILD(n, NCH(n) - 6)), CHILD(n, NCH(n) - 6)->n_col_offset, - c->c_arena)); + end_lineno, end_col_offset, c->c_arena)); /* the just-created orelse handled the last elif */ n_elif--; } @@ -3626,10 +3720,16 @@ ast_for_if_stmt(struct compiling *c, const node *n) if (!suite_seq) return NULL; + if (orelse != NULL) { + get_last_end_pos(orelse, &end_lineno, &end_col_offset); + } else { + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + } asdl_seq_SET(newobj, 0, If(expression, suite_seq, orelse, LINENO(CHILD(n, off)), - CHILD(n, off)->n_col_offset, c->c_arena)); + CHILD(n, off)->n_col_offset, + end_lineno, end_col_offset, c->c_arena)); orelse = newobj; } expression = ast_for_expr(c, CHILD(n, 1)); @@ -3638,8 +3738,10 @@ ast_for_if_stmt(struct compiling *c, const node *n) suite_seq = ast_for_suite(c, CHILD(n, 3)); if (!suite_seq) return NULL; + get_last_end_pos(orelse, &end_lineno, &end_col_offset); return If(expression, suite_seq, orelse, - LINENO(n), n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } PyErr_Format(PyExc_SystemError, @@ -3652,6 +3754,7 @@ ast_for_while_stmt(struct compiling *c, const node *n) { /* while_stmt: 'while' test ':' suite ['else' ':' suite] */ REQ(n, while_stmt); + int end_lineno, end_col_offset; if (NCH(n) == 4) { expr_ty expression; @@ -3663,7 +3766,9 @@ ast_for_while_stmt(struct compiling *c, const node *n) suite_seq = ast_for_suite(c, CHILD(n, 3)); if (!suite_seq) return NULL; - return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, c->c_arena); + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } else if (NCH(n) == 7) { expr_ty expression; @@ -3678,8 +3783,10 @@ ast_for_while_stmt(struct compiling *c, const node *n) seq2 = ast_for_suite(c, CHILD(n, 6)); if (!seq2) return NULL; + get_last_end_pos(seq2, &end_lineno, &end_col_offset); - return While(expression, seq1, seq2, LINENO(n), n->n_col_offset, c->c_arena); + return While(expression, seq1, seq2, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } PyErr_Format(PyExc_SystemError, @@ -3696,6 +3803,7 @@ ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async) expr_ty expression; expr_ty target, first; const node *node_target; + int end_lineno, end_col_offset; /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */ REQ(n, for_stmt); @@ -3715,7 +3823,9 @@ ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async) if (NCH(node_target) == 1) target = first; else - target = Tuple(_target, Store, first->lineno, first->col_offset, c->c_arena); + target = Tuple(_target, Store, first->lineno, first->col_offset, + node_target->n_end_lineno, node_target->n_end_col_offset, + c->c_arena); expression = ast_for_testlist(c, CHILD(n, 3)); if (!expression) @@ -3724,20 +3834,26 @@ ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async) if (!suite_seq) return NULL; + if (seq != NULL) { + get_last_end_pos(seq, &end_lineno, &end_col_offset); + } else { + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + } if (is_async) return AsyncFor(target, expression, suite_seq, seq, LINENO(n0), n0->n_col_offset, - c->c_arena); + end_lineno, end_col_offset, c->c_arena); else return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset, - c->c_arena); + end_lineno, end_col_offset, c->c_arena); } static excepthandler_ty ast_for_except_clause(struct compiling *c, const node *exc, node *body) { /* except_clause: 'except' [test ['as' test]] */ + int end_lineno, end_col_offset; REQ(exc, except_clause); REQ(body, suite); @@ -3745,9 +3861,11 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) asdl_seq *suite_seq = ast_for_suite(c, body); if (!suite_seq) return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); return ExceptHandler(NULL, NULL, suite_seq, LINENO(exc), - exc->n_col_offset, c->c_arena); + exc->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } else if (NCH(exc) == 2) { expr_ty expression; @@ -3759,9 +3877,11 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) suite_seq = ast_for_suite(c, body); if (!suite_seq) return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); return ExceptHandler(expression, NULL, suite_seq, LINENO(exc), - exc->n_col_offset, c->c_arena); + exc->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } else if (NCH(exc) == 4) { asdl_seq *suite_seq; @@ -3777,9 +3897,11 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) suite_seq = ast_for_suite(c, body); if (!suite_seq) return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); return ExceptHandler(expression, e, suite_seq, LINENO(exc), - exc->n_col_offset, c->c_arena); + exc->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } PyErr_Format(PyExc_SystemError, @@ -3792,8 +3914,9 @@ static stmt_ty ast_for_try_stmt(struct compiling *c, const node *n) { const int nch = NCH(n); - int n_except = (nch - 3)/3; + int end_lineno, end_col_offset, n_except = (nch - 3)/3; asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL; + excepthandler_ty last_handler; REQ(n, try_stmt); @@ -3849,7 +3972,20 @@ ast_for_try_stmt(struct compiling *c, const node *n) } assert(finally != NULL || asdl_seq_LEN(handlers)); - return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, c->c_arena); + if (finally != NULL) { + // finally is always last + get_last_end_pos(finally, &end_lineno, &end_col_offset); + } else if (orelse != NULL) { + // otherwise else is last + get_last_end_pos(orelse, &end_lineno, &end_col_offset); + } else { + // inline the get_last_end_pos logic due to layout mismatch + last_handler = (excepthandler_ty) asdl_seq_GET(handlers, n_except - 1); + end_lineno = last_handler->end_lineno; + end_col_offset = last_handler->end_col_offset; + } + return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } /* with_item: test ['as' expr] */ @@ -3881,7 +4017,7 @@ static stmt_ty ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async) { const node * const n = is_async ? CHILD(n0, 1) : n0; - int i, n_items; + int i, n_items, end_lineno, end_col_offset; asdl_seq *items, *body; REQ(n, with_stmt); @@ -3900,11 +4036,14 @@ ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async) body = ast_for_suite(c, CHILD(n, NCH(n) - 1)); if (!body) return NULL; + get_last_end_pos(body, &end_lineno, &end_col_offset); if (is_async) - return AsyncWith(items, body, LINENO(n0), n0->n_col_offset, c->c_arena); + return AsyncWith(items, body, LINENO(n0), n0->n_col_offset, + end_lineno, end_col_offset, c->c_arena); else - return With(items, body, LINENO(n), n->n_col_offset, c->c_arena); + return With(items, body, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } static stmt_ty @@ -3914,6 +4053,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) PyObject *classname; asdl_seq *s; expr_ty call; + int end_lineno, end_col_offset; REQ(n, classdef); @@ -3921,26 +4061,32 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) s = ast_for_suite(c, CHILD(n, 3)); if (!s) return NULL; + get_last_end_pos(s, &end_lineno, &end_col_offset); + classname = NEW_IDENTIFIER(CHILD(n, 1)); if (!classname) return NULL; if (forbidden_name(c, classname, CHILD(n, 3), 0)) return NULL; return ClassDef(classname, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */ s = ast_for_suite(c, CHILD(n, 5)); if (!s) return NULL; + get_last_end_pos(s, &end_lineno, &end_col_offset); + classname = NEW_IDENTIFIER(CHILD(n, 1)); if (!classname) return NULL; if (forbidden_name(c, classname, CHILD(n, 3), 0)) return NULL; return ClassDef(classname, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } /* class NAME '(' arglist ')' ':' suite */ @@ -3951,14 +4097,18 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) dummy_name = NEW_IDENTIFIER(CHILD(n, 1)); if (!dummy_name) return NULL; - dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, c->c_arena); - call = ast_for_call(c, CHILD(n, 3), dummy, NULL); + dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, + CHILD(n, 1)->n_end_lineno, CHILD(n, 1)->n_end_col_offset, + c->c_arena); + call = ast_for_call(c, CHILD(n, 3), dummy, NULL, CHILD(n, 4)); if (!call) return NULL; } s = ast_for_suite(c, CHILD(n, 6)); if (!s) return NULL; + get_last_end_pos(s, &end_lineno, &end_col_offset); + classname = NEW_IDENTIFIER(CHILD(n, 1)); if (!classname) return NULL; @@ -3966,7 +4116,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) return NULL; return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s, - decorator_seq, LINENO(n), n->n_col_offset, c->c_arena); + decorator_seq, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); } static stmt_ty @@ -3991,7 +4142,8 @@ ast_for_stmt(struct compiling *c, const node *n) case del_stmt: return ast_for_del_stmt(c, n); case pass_stmt: - return Pass(LINENO(n), n->n_col_offset, c->c_arena); + return Pass(LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); case flow_stmt: return ast_for_flow_stmt(c, n); case import_stmt: @@ -4248,6 +4400,7 @@ decode_bytes_with_escapes(struct compiling *c, const node *n, const char *s, static void fstring_shift_node_locations(node *n, int lineno, int col_offset) { n->n_col_offset = n->n_col_offset + col_offset; + n->n_end_col_offset = n->n_end_col_offset + col_offset; for (int i = 0; i < NCH(n); ++i) { if (n->n_lineno && n->n_lineno < CHILD(n, i)->n_lineno) { /* Shifting column offsets unnecessary if there's been newlines. */ @@ -4256,6 +4409,7 @@ static void fstring_shift_node_locations(node *n, int lineno, int col_offset) fstring_shift_node_locations(CHILD(n, i), lineno, col_offset); } n->n_lineno = n->n_lineno + lineno; + n->n_end_lineno = n->n_end_lineno + lineno; } /* Fix locations for the given node and its children. @@ -4672,6 +4826,7 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, entire expression with the conversion and format spec. */ *expression = FormattedValue(simple_expression, conversion, format_spec, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!*expression) return -1; @@ -4918,7 +5073,8 @@ make_str_node_and_del(PyObject **str, struct compiling *c, const node* n) Py_DECREF(s); return NULL; } - return Constant(s, LINENO(n), n->n_col_offset, c->c_arena); + return Constant(s, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } /* Add a non-f-string (that is, a regular literal string). str is @@ -5073,7 +5229,8 @@ FstringParser_Finish(FstringParser *state, struct compiling *c, if (!seq) goto error; - return JoinedStr(seq, LINENO(n), n->n_col_offset, c->c_arena); + return JoinedStr(seq, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); error: FstringParser_Dealloc(state); @@ -5283,7 +5440,8 @@ parsestrplus(struct compiling *c, const node *n) /* Just return the bytes object and we're done. */ if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0) goto error; - return Constant(bytes_str, LINENO(n), n->n_col_offset, c->c_arena); + return Constant(bytes_str, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); } /* We're not a bytes string, bytes_str should never have been set. */ |