[3.11] GH-94036: Fix more attribute location quirks (GH-95028) (GH-95156)

(cherry picked from commit 900bfc53cb)
This commit is contained in:
Brandt Bucher 2022-07-22 17:31:06 -07:00 committed by GitHub
parent bbdacb402b
commit 064462a719
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 20 deletions

View file

@ -4783,19 +4783,29 @@ is_import_originated(struct compiler *c, expr_ty e)
return flags & DEF_IMPORT;
}
// If an attribute access spans multiple lines, update the current start
// location to point to the attribute name.
static void
update_location_to_match_attr(struct compiler *c, expr_ty meth)
update_start_location_to_match_attr(struct compiler *c, expr_ty attr)
{
if (meth->lineno != meth->end_lineno) {
// Make start location match attribute
c->u->u_lineno = c->u->u_end_lineno = meth->end_lineno;
int len = (int)PyUnicode_GET_LENGTH(meth->v.Attribute.attr);
if (len <= meth->end_col_offset) {
c->u->u_col_offset = meth->end_col_offset - len;
assert(attr->kind == Attribute_kind);
if (c->u->u_lineno != attr->end_lineno) {
c->u->u_lineno = attr->end_lineno;
int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
if (len <= attr->end_col_offset) {
c->u->u_col_offset = attr->end_col_offset - len;
}
else {
// GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
c->u->u_col_offset = c->u->u_end_col_offset = -1;
c->u->u_col_offset = -1;
c->u->u_end_col_offset = -1;
}
// Make sure the end position still follows the start position, even for
// weird ASTs:
c->u->u_end_lineno = Py_MAX(c->u->u_lineno, c->u->u_end_lineno);
if (c->u->u_lineno == c->u->u_end_lineno) {
c->u->u_end_col_offset = Py_MAX(c->u->u_col_offset,
c->u->u_end_col_offset);
}
}
}
@ -4842,7 +4852,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
/* Alright, we can optimize the code. */
VISIT(c, expr, meth->v.Attribute.value);
SET_LOC(c, meth);
update_location_to_match_attr(c, meth);
update_start_location_to_match_attr(c, meth);
ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names);
VISIT_SEQ(c, expr, e->v.Call.args);
@ -4853,7 +4863,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
};
}
SET_LOC(c, e);
update_location_to_match_attr(c, meth);
update_start_location_to_match_attr(c, meth);
ADDOP_I(c, PRECALL, argsl + kwdsl);
ADDOP_I(c, CALL, argsl + kwdsl);
return 1;
@ -5863,23 +5873,18 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
/* The following exprs can be assignment targets. */
case Attribute_kind:
VISIT(c, expr, e->v.Attribute.value);
update_start_location_to_match_attr(c, e);
switch (e->v.Attribute.ctx) {
case Load:
{
int old_lineno = c->u->u_lineno;
c->u->u_lineno = e->end_lineno;
ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
c->u->u_lineno = old_lineno;
break;
}
case Store:
if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) {
return 0;
}
int old_lineno = c->u->u_lineno;
c->u->u_lineno = e->end_lineno;
ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
c->u->u_lineno = old_lineno;
break;
case Del:
ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);
@ -5945,10 +5950,8 @@ compiler_augassign(struct compiler *c, stmt_ty s)
case Attribute_kind:
VISIT(c, expr, e->v.Attribute.value);
ADDOP_I(c, COPY, 1);
int old_lineno = c->u->u_lineno;
c->u->u_lineno = e->end_lineno;
update_start_location_to_match_attr(c, e);
ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
c->u->u_lineno = old_lineno;
break;
case Subscript_kind:
VISIT(c, expr, e->v.Subscript.value);
@ -5980,7 +5983,7 @@ compiler_augassign(struct compiler *c, stmt_ty s)
switch (e->kind) {
case Attribute_kind:
c->u->u_lineno = e->end_lineno;
update_start_location_to_match_attr(c, e);
ADDOP_I(c, SWAP, 2);
ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
break;