VISIT_SEQ(st, stmt, s->v.While.orelse); break; case If_kind: /* XXX if 0: and lookup_yield() hacks */ VISIT(st, expr, s->v.If.test); VISIT_SEQ(st, stmt, s->v.If.body); if (s->v.If.orelse) VISIT_SEQ(st, stmt, s->v.If.orelse); break; case Raise_kind: if (s->v.Raise.type) { VISIT(st, expr, s->v.Raise.type); if (s->v.Raise.inst) { VISIT(st, expr, s->v.Raise.inst); if (s->v.Raise.tback) VISIT(st, expr, s->v.Raise.tback); } } break; case TryExcept_kind: VISIT_SEQ(st, stmt, s->v.TryExcept.body); VISIT_SEQ(st, stmt, s->v.TryExcept.orelse); VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers); break; case TryFinally_kind: VISIT_SEQ(st, stmt, s->v.TryFinally.body); VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody); break; case Assert_kind: VISIT(st, expr, s->v.Assert.test); if (s->v.Assert.msg) VISIT(st, expr, s->v.Assert.msg); break; case Import_kind: VISIT_SEQ(st, alias, s->v.Import.names); /* XXX Don't have the lineno available inside visit_alias */ if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) st->st_cur->ste_opt_lineno = s->lineno; break; case ImportFrom_kind: VISIT_SEQ(st, alias, s->v.ImportFrom.names); /* XXX Don't have the lineno available inside visit_alias */ if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) st->st_cur->ste_opt_lineno = s->lineno; break; case Exec_kind: VISIT(st, expr, s->v.Exec.body); if (!st->st_cur->ste_opt_lineno) st->st_cur->ste_opt_lineno = s->lineno; if (s->v.Exec.globals) { st->st_cur->ste_unoptimized |= OPT_EXEC; VISIT(st, expr, s->v.Exec.globals); if (s->v.Exec.locals) VISIT(st, expr, s->v.Exec.locals); } else { st->st_cur->ste_unoptimized |= OPT_BARE_EXEC; } break; case Global_kind: { int i; asdl_seq *seq = s->v.Global.names; for (i = 0; i < asdl_seq_LEN(seq); i++) { identifier name = (identifier)asdl_seq_GET(seq, i); char *c_name = PyString_AS_STRING(name); long cur = symtable_lookup(st, name); if (cur < 0) return 0; if (cur & (DEF_LOCAL | USE)) { char buf[256]; if (cur & DEF_LOCAL) PyOS_snprintf(buf, sizeof(buf), GLOBAL_AFTER_ASSIGN, c_name); else PyOS_snprintf(buf, sizeof(buf), GLOBAL_AFTER_USE, c_name); if (!symtable_warn(st, buf, s->lineno)) return 0; } if (!symtable_add_def(st, name, DEF_GLOBAL)) return 0; } break; } case Expr_kind: VISIT(st, expr, s->v.Expr.value); break; case Pass_kind: case Break_kind: case Continue_kind: /* nothing to do here */ break; case With_kind: if (!symtable_new_tmpname(st)) return 0; VISIT(st, expr, s->v.With.context_expr); if (s->v.With.optional_vars) { if (!symtable_new_tmpname(st)) return 0; VISIT(st, expr, s->v.With.optional_vars); } VISIT_SEQ(st, stmt, s->v.With.body); break; } return 1;} static int symtable_visit_expr(struct symtable *st, expr_ty e){ switch (e->kind) { case BoolOp_kind: VISIT_SEQ(st, expr, e->v.BoolOp.values); break; case BinOp_kind: VISIT(st, expr, e->v.BinOp.left); VISIT(st, expr, e->v.BinOp.right); break; case UnaryOp_kind: VISIT(st, expr, e->v.UnaryOp.operand); break; case Lambda_kind: { if (!symtable_add_def(st, GET_IDENTIFIER(lambda), DEF_LOCAL)) return 0; if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); /* XXX how to get line numbers for expressions */ if (!symtable_enter_block(st, GET_IDENTIFIER(lambda), FunctionBlock, (void *)e, 0)) return 0; VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); if (!symtable_exit_block(st, (void *)e)) return 0; break; } case IfExp_kind: VISIT(st, expr, e->v.IfExp.test); VISIT(st, expr, e->v.IfExp.body); VISIT(st, expr, e->v.IfExp.orelse); break; case Dict_kind: VISIT_SEQ(st, expr, e->v.Dict.keys); VISIT_SEQ(st, expr, e->v.Dict.values); break; case ListComp_kind: if (!symtable_new_tmpname(st)) return 0; VISIT(st, expr, e->v.ListComp.elt); VISIT_SEQ(st, comprehension, e->v.ListComp.generators); break; case GeneratorExp_kind: if (!symtable_visit_genexp(st, e)) return 0; break; case Yield_kind: if (e->v.Yield.value) VISIT(st, expr, e->v.Yield.value); st->st_cur->ste_generator = 1; if (st->st_cur->ste_returns_value) { PyErr_SetString(PyExc_SyntaxError, RETURN_VAL_IN_GENERATOR); PyErr_SyntaxLocation(st->st_filename, e->lineno); return 0; } break; case Compare_kind: VISIT(st, expr, e->v.Compare.left); VISIT_SEQ(st, expr, e->v.Compare.comparators); break; case Call_kind: VISIT(st, expr, e->v.Call.func); VISIT_SEQ(st, expr, e->v.Call.args); VISIT_SEQ(st, keyword, e->v.Call.keywords); if (e->v.Call.starargs) VISIT(st, expr, e->v.Call.starargs); if (e->v.Call.kwargs) VISIT(st, expr, e->v.Call.kwargs); break; case Repr_kind: VISIT(st, expr, e->v.Repr.value); break; case Num_kind: case Str_kind: /* Nothing to do here. */ break; /* The following exprs can be assignment targets. */ case Attribute_kind: VISIT(st, expr, e->v.Attribute.value); break; case Subscript_kind: VISIT(st, expr, e->v.Subscript.value); VISIT(st, slice, e->v.Subscript.slice); break; case Name_kind: if (!symtable_add_def(st, e->v.Name.id, e->v.Name.ctx == Load ? USE : DEF_LOCAL)) return 0; break; /* child nodes of List and Tuple will have expr_context set */ case List_kind: VISIT_SEQ(st, expr, e->v.List.elts); break; case Tuple_kind: VISIT_SEQ(st, expr, e->v.Tuple.elts); break; } return 1;} static intsymtable_implicit_arg(struct symtable *st, int pos){ PyObject *id = PyString_FromFormat(".%d", pos); if (id == NULL) return 0; if (!symtable_add_def(st, id, DEF_PARAM)) { Py_DECREF(id); return 0; } Py_DECREF(id); return 1;} static int symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel){ int i; /* go through all the toplevel arguments first */ for (i = 0; i < asdl_seq_LEN(args); i++) { expr_ty arg = (expr_ty)asdl_seq_GET(args, i); if (arg->kind == Name_kind) { assert(arg->v.Name.ctx == Param || (arg->v.Name.ctx == Store && !toplevel)); if (!symtable_add_def(st, arg->v.Name.id, DEF_PARAM)) return 0; } else if (arg->kind == Tuple_kind) { assert(arg->v.Tuple.ctx == Store); if (toplevel) { if (!symtable_implicit_arg(st, i)) return 0; } } else { PyErr_SetString(PyExc_SyntaxError, "invalid expression in parameter list"); PyErr_SyntaxLocation(st->st_filename, st->st_cur->ste_lineno); return 0; } } if (!toplevel) { if (!symtable_visit_params_nested(st, args)) return 0; } return 1;} static intsymtable_visit_params_nested(struct symtable *st, asdl_seq *args){ int i; for (i = 0; i < asdl_seq_LEN(args); i++) { expr_ty arg = (expr_ty)asdl_seq_GET(args, i); if (arg->kind == Tuple_kind && !symtable_visit_params(st, arg->v.Tuple.elts, 0)) return 0; } return 1;} static int symtable_visit_arguments(struct symtable *st, arguments_ty a){ /* skip default arguments inside function block XXX should ast be different? */ if (a->args && !symtable_visit_params(st, a->args, 1)) return 0; if (a->vararg) { if (!symtable_add_def(st, a->vararg, DEF_PARAM)) return 0; st->st_cur->ste_varargs = 1; } if (a->kwarg) { if (!symtable_add_def(st, a->kwarg, DEF_PARAM)) return 0; st->st_cur->ste_varkeywords = 1; } if (a->args && !symtable_visit_params_nested(st, a->args)) return 0; return 1;} static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh){ if (eh->type) VISIT(st, expr, eh->type); if (eh->name) VISIT(st, expr, eh->name); VISIT_SEQ(st, stmt, eh->body); return 1;} static int symtable_visit_alias(struct symtable *st, alias_ty a){ /* Compute store_name, the name actually bound by the import operation. It is diferent than a->name when a->name is a dotted package name (e.g. spam.eggs) */ PyObject *store_name; PyObject *name = (a->asname == NULL) ? a->name : a->asname; const char *base = PyString_AS_STRING(name); char *dot = strchr(base, '.'); if (dot) { store_name = PyString_FromStringAndSize(base, dot - base); if (!store_name) return 0; } else { store_name = name; Py_INCREF(store_name); } if (strcmp(PyString_AS_STRING(name), "*")) { int r = symtable_add_def(st, store_name, DEF_IMPORT); Py_DECREF(store_name); return r; } else { if (st->st_cur->ste_type != ModuleBlock) { int lineno = st->st_cur->ste_lineno; if (!symtable_warn(st, IMPORT_STAR_WARNING, lineno)) { Py_DECREF(store_name); return 0; } } st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR; Py_DECREF(store_name); return 1; }} static int symtable_visit_comprehension(struct symtable *st, comprehension_ty lc){ VISIT(st, expr, lc->target); VISIT(st, expr, lc->iter); VISIT_SEQ(st, expr, lc->ifs); return 1;} static int symtable_visit_keyword(struct symtable *st, keyword_ty k){ VISIT(st, expr, k->value); return 1;} static int symtable_visit_slice(struct symtable *st, slice_ty s){ switch (s->kind) { case Slice_kind: if (s->v.Slice.lower) VISIT(st, expr, s->v.Slice.lower) if (s->v.Slice.upper) VISIT(st, expr, s->v.Slice.upper) if (s->v.Slice.step) VISIT(st, expr, s->v.Slice.step) break; case ExtSlice_kind: VISIT_SEQ(st, slice, s->v.ExtSlice.dims) break; case Index_kind: VISIT(st, expr, s->v.Index.value) break; case Ellipsis_kind: break; } return 1;} static int symtable_visit_genexp(struct symtable *st, expr_ty e){ comprehension_ty outermost = ((comprehension_ty) (asdl_seq_GET(e->v.GeneratorExp.generators, 0))); /* Outermost iterator is evaluated in current scope */ VISIT(st, expr, outermost->iter); /* Create generator scope for the rest */ if (!symtable_enter_block(st, GET_IDENTIFIER(genexpr), FunctionBlock, (void *)e, 0)) { return 0; } st->st_cur->ste_generator = 1; /* Outermost iter is received as an argument */ if (!symtable_implicit_arg(st, 0)) { symtable_exit_block(st, (void *)e); return 0; } VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e); VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e); VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension, e->v.GeneratorExp.generators, 1, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e); if (!symtable_exit_block(st, (void *)e)) return 0; return 1;}Lines 1001–1425 of 1425. Previous lines
VISIT_SEQ(st, stmt, s->v.While.orelse); break; case If_kind: /* XXX if 0: and lookup_yield() hacks */ VISIT(st, expr, s->v.If.test); VISIT_SEQ(st, stmt, s->v.If.body); if (s->v.If.orelse) VISIT_SEQ(st, stmt, s->v.If.orelse); break; case Raise_kind: if (s->v.Raise.type) { VISIT(st, expr, s->v.Raise.type); if (s->v.Raise.inst) { VISIT(st, expr, s->v.Raise.inst); if (s->v.Raise.tback) VISIT(st, expr, s->v.Raise.tback); } } break; case TryExcept_kind: VISIT_SEQ(st, stmt, s->v.TryExcept.body); VISIT_SEQ(st, stmt, s->v.TryExcept.orelse); VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers); break; case TryFinally_kind: VISIT_SEQ(st, stmt, s->v.TryFinally.body); VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody); break; case Assert_kind: VISIT(st, expr, s->v.Assert.test); if (s->v.Assert.msg) VISIT(st, expr, s->v.Assert.msg); break; case Import_kind: VISIT_SEQ(st, alias, s->v.Import.names); /* XXX Don't have the lineno available inside visit_alias */ if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) st->st_cur->ste_opt_lineno = s->lineno; break; case ImportFrom_kind: VISIT_SEQ(st, alias, s->v.ImportFrom.names); /* XXX Don't have the lineno available inside visit_alias */ if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) st->st_cur->ste_opt_lineno = s->lineno; break; case Exec_kind: VISIT(st, expr, s->v.Exec.body); if (!st->st_cur->ste_opt_lineno) st->st_cur->ste_opt_lineno = s->lineno; if (s->v.Exec.globals) { st->st_cur->ste_unoptimized |= OPT_EXEC; VISIT(st, expr, s->v.Exec.globals); if (s->v.Exec.locals) VISIT(st, expr, s->v.Exec.locals); } else { st->st_cur->ste_unoptimized |= OPT_BARE_EXEC; } break; case Global_kind: { int i; asdl_seq *seq = s->v.Global.names; for (i = 0; i < asdl_seq_LEN(seq); i++) { identifier name = (identifier)asdl_seq_GET(seq, i); char *c_name = PyString_AS_STRING(name); long cur = symtable_lookup(st, name); if (cur < 0) return 0; if (cur & (DEF_LOCAL | USE)) { char buf[256]; if (cur & DEF_LOCAL) PyOS_snprintf(buf, sizeof(buf), GLOBAL_AFTER_ASSIGN, c_name); else PyOS_snprintf(buf, sizeof(buf), GLOBAL_AFTER_USE, c_name); if (!symtable_warn(st, buf, s->lineno)) return 0; } if (!symtable_add_def(st, name, DEF_GLOBAL)) return 0; } break; } case Expr_kind: VISIT(st, expr, s->v.Expr.value); break; case Pass_kind: case Break_kind: case Continue_kind: /* nothing to do here */ break; case With_kind: if (!symtable_new_tmpname(st)) return 0; VISIT(st, expr, s->v.With.context_expr); if (s->v.With.optional_vars) { if (!symtable_new_tmpname(st)) return 0; VISIT(st, expr, s->v.With.optional_vars); } VISIT_SEQ(st, stmt, s->v.With.body); break; } return 1; } static int symtable_visit_expr(struct symtable *st, expr_ty e) { switch (e->kind) { case BoolOp_kind: VISIT_SEQ(st, expr, e->v.BoolOp.values); break; case BinOp_kind: VISIT(st, expr, e->v.BinOp.left); VISIT(st, expr, e->v.BinOp.right); break; case UnaryOp_kind: VISIT(st, expr, e->v.UnaryOp.operand); break; case Lambda_kind: { if (!symtable_add_def(st, GET_IDENTIFIER(lambda), DEF_LOCAL)) return 0; if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); /* XXX how to get line numbers for expressions */ if (!symtable_enter_block(st, GET_IDENTIFIER(lambda), FunctionBlock, (void *)e, 0)) return 0; VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); if (!symtable_exit_block(st, (void *)e)) return 0; break; } case IfExp_kind: VISIT(st, expr, e->v.IfExp.test); VISIT(st, expr, e->v.IfExp.body); VISIT(st, expr, e->v.IfExp.orelse); break; case Dict_kind: VISIT_SEQ(st, expr, e->v.Dict.keys); VISIT_SEQ(st, expr, e->v.Dict.values); break; case ListComp_kind: if (!symtable_new_tmpname(st)) return 0; VISIT(st, expr, e->v.ListComp.elt); VISIT_SEQ(st, comprehension, e->v.ListComp.generators); break; case GeneratorExp_kind: if (!symtable_visit_genexp(st, e)) return 0; break; case Yield_kind: if (e->v.Yield.value) VISIT(st, expr, e->v.Yield.value); st->st_cur->ste_generator = 1; if (st->st_cur->ste_returns_value) { PyErr_SetString(PyExc_SyntaxError, RETURN_VAL_IN_GENERATOR); PyErr_SyntaxLocation(st->st_filename, e->lineno); return 0; } break; case Compare_kind: VISIT(st, expr, e->v.Compare.left); VISIT_SEQ(st, expr, e->v.Compare.comparators); break; case Call_kind: VISIT(st, expr, e->v.Call.func); VISIT_SEQ(st, expr, e->v.Call.args); VISIT_SEQ(st, keyword, e->v.Call.keywords); if (e->v.Call.starargs) VISIT(st, expr, e->v.Call.starargs); if (e->v.Call.kwargs) VISIT(st, expr, e->v.Call.kwargs); break; case Repr_kind: VISIT(st, expr, e->v.Repr.value); break; case Num_kind: case Str_kind: /* Nothing to do here. */ break; /* The following exprs can be assignment targets. */ case Attribute_kind: VISIT(st, expr, e->v.Attribute.value); break; case Subscript_kind: VISIT(st, expr, e->v.Subscript.value); VISIT(st, slice, e->v.Subscript.slice); break; case Name_kind: if (!symtable_add_def(st, e->v.Name.id, e->v.Name.ctx == Load ? USE : DEF_LOCAL)) return 0; break; /* child nodes of List and Tuple will have expr_context set */ case List_kind: VISIT_SEQ(st, expr, e->v.List.elts); break; case Tuple_kind: VISIT_SEQ(st, expr, e->v.Tuple.elts); break; } return 1; } static int symtable_implicit_arg(struct symtable *st, int pos) { PyObject *id = PyString_FromFormat(".%d", pos); if (id == NULL) return 0; if (!symtable_add_def(st, id, DEF_PARAM)) { Py_DECREF(id); return 0; } Py_DECREF(id); return 1; } static int symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel) { int i; /* go through all the toplevel arguments first */ for (i = 0; i < asdl_seq_LEN(args); i++) { expr_ty arg = (expr_ty)asdl_seq_GET(args, i); if (arg->kind == Name_kind) { assert(arg->v.Name.ctx == Param || (arg->v.Name.ctx == Store && !toplevel)); if (!symtable_add_def(st, arg->v.Name.id, DEF_PARAM)) return 0; } else if (arg->kind == Tuple_kind) { assert(arg->v.Tuple.ctx == Store); if (toplevel) { if (!symtable_implicit_arg(st, i)) return 0; } } else { PyErr_SetString(PyExc_SyntaxError, "invalid expression in parameter list"); PyErr_SyntaxLocation(st->st_filename, st->st_cur->ste_lineno); return 0; } } if (!toplevel) { if (!symtable_visit_params_nested(st, args)) return 0; } return 1; } static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args) { int i; for (i = 0; i < asdl_seq_LEN(args); i++) { expr_ty arg = (expr_ty)asdl_seq_GET(args, i); if (arg->kind == Tuple_kind && !symtable_visit_params(st, arg->v.Tuple.elts, 0)) return 0; } return 1; } static int symtable_visit_arguments(struct symtable *st, arguments_ty a) { /* skip default arguments inside function block XXX should ast be different? */ if (a->args && !symtable_visit_params(st, a->args, 1)) return 0; if (a->vararg) { if (!symtable_add_def(st, a->vararg, DEF_PARAM)) return 0; st->st_cur->ste_varargs = 1; } if (a->kwarg) { if (!symtable_add_def(st, a->kwarg, DEF_PARAM)) return 0; st->st_cur->ste_varkeywords = 1; } if (a->args && !symtable_visit_params_nested(st, a->args)) return 0; return 1; } static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh) { if (eh->type) VISIT(st, expr, eh->type); if (eh->name) VISIT(st, expr, eh->name); VISIT_SEQ(st, stmt, eh->body); return 1; } static int symtable_visit_alias(struct symtable *st, alias_ty a) { /* Compute store_name, the name actually bound by the import operation. It is diferent than a->name when a->name is a dotted package name (e.g. spam.eggs) */ PyObject *store_name; PyObject *name = (a->asname == NULL) ? a->name : a->asname; const char *base = PyString_AS_STRING(name); char *dot = strchr(base, '.'); if (dot) { store_name = PyString_FromStringAndSize(base, dot - base); if (!store_name) return 0; } else { store_name = name; Py_INCREF(store_name); } if (strcmp(PyString_AS_STRING(name), "*")) { int r = symtable_add_def(st, store_name, DEF_IMPORT); Py_DECREF(store_name); return r; } else { if (st->st_cur->ste_type != ModuleBlock) { int lineno = st->st_cur->ste_lineno; if (!symtable_warn(st, IMPORT_STAR_WARNING, lineno)) { Py_DECREF(store_name); return 0; } } st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR; Py_DECREF(store_name); return 1; } } static int symtable_visit_comprehension(struct symtable *st, comprehension_ty lc) { VISIT(st, expr, lc->target); VISIT(st, expr, lc->iter); VISIT_SEQ(st, expr, lc->ifs); return 1; } static int symtable_visit_keyword(struct symtable *st, keyword_ty k) { VISIT(st, expr, k->value); return 1; } static int symtable_visit_slice(struct symtable *st, slice_ty s) { switch (s->kind) { case Slice_kind: if (s->v.Slice.lower) VISIT(st, expr, s->v.Slice.lower) if (s->v.Slice.upper) VISIT(st, expr, s->v.Slice.upper) if (s->v.Slice.step) VISIT(st, expr, s->v.Slice.step) break; case ExtSlice_kind: VISIT_SEQ(st, slice, s->v.ExtSlice.dims) break; case Index_kind: VISIT(st, expr, s->v.Index.value) break; case Ellipsis_kind: break; } return 1; } static int symtable_visit_genexp(struct symtable *st, expr_ty e) { comprehension_ty outermost = ((comprehension_ty) (asdl_seq_GET(e->v.GeneratorExp.generators, 0))); /* Outermost iterator is evaluated in current scope */ VISIT(st, expr, outermost->iter); /* Create generator scope for the rest */ if (!symtable_enter_block(st, GET_IDENTIFIER(genexpr), FunctionBlock, (void *)e, 0)) { return 0; } st->st_cur->ste_generator = 1; /* Outermost iter is received as an argument */ if (!symtable_implicit_arg(st, 0)) { symtable_exit_block(st, (void *)e); return 0; } VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e); VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e); VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension, e->v.GeneratorExp.generators, 1, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e); if (!symtable_exit_block(st, (void *)e)) return 0; return 1; }