Report error context in expressions more precisely
This commit is contained in:
parent
7708ed1a75
commit
2ea075dc4f
6 changed files with 27 additions and 17 deletions
|
|
@ -295,7 +295,7 @@ namespace {
|
|||
|
||||
foreach (post_t * p, account.posts) {
|
||||
bind_scope_t bound_scope(args, *p);
|
||||
if (expr->calc(bound_scope).to_boolean())
|
||||
if (expr->calc(bound_scope, args.locus, args.depth).to_boolean())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -308,7 +308,7 @@ namespace {
|
|||
|
||||
foreach (post_t * p, account.posts) {
|
||||
bind_scope_t bound_scope(args, *p);
|
||||
if (! expr->calc(bound_scope).to_boolean())
|
||||
if (! expr->calc(bound_scope, args.locus, args.depth).to_boolean())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
|||
// Evaluating an identifier is the same as calling its definition
|
||||
// directly, so we create an empty call_scope_t to reflect the scope for
|
||||
// this implicit call.
|
||||
call_scope_t call_args(scope, scope.type_context(), scope.type_required());
|
||||
call_scope_t call_args(scope, locus, depth);
|
||||
result = left()->compile(call_args, depth + 1)
|
||||
->calc(call_args, locus, depth + 1);
|
||||
check_type_context(scope, result);
|
||||
|
|
@ -168,7 +168,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
|||
// Evaluating a FUNCTION is the same as calling it directly; this happens
|
||||
// when certain functions-that-look-like-variables (such as "amount") are
|
||||
// resolved.
|
||||
call_scope_t call_args(scope, scope.type_context(), scope.type_required());
|
||||
call_scope_t call_args(scope, locus, depth);
|
||||
result = as_function()(call_args);
|
||||
check_type_context(scope, result);
|
||||
#if defined(DEBUG_ON)
|
||||
|
|
@ -235,7 +235,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
|||
}
|
||||
|
||||
case O_CALL: {
|
||||
call_scope_t call_args(scope, scope.type_context(), scope.type_required());
|
||||
call_scope_t call_args(scope, locus, depth);
|
||||
if (has_right())
|
||||
call_args.set_args(split_cons_expr(right()->kind == O_SEQ ?
|
||||
right()->left() : right()));
|
||||
|
|
|
|||
12
src/post.cc
12
src/post.cc
|
|
@ -353,12 +353,14 @@ namespace {
|
|||
foreach (post_t * p, post.xact->posts) {
|
||||
bind_scope_t bound_scope(args, *p);
|
||||
if (p == &post && args.has<expr_t::ptr_op_t>(1) &&
|
||||
! args.get<expr_t::ptr_op_t>(1)->calc(bound_scope).to_boolean()) {
|
||||
! args.get<expr_t::ptr_op_t>(1)
|
||||
->calc(bound_scope, args.locus, args.depth).to_boolean()) {
|
||||
// If the user specifies any(EXPR, false), and the context is a
|
||||
// posting, then that posting isn't considered by the test.
|
||||
; // skip it
|
||||
}
|
||||
else if (expr->calc(bound_scope).to_boolean()) {
|
||||
else if (expr->calc(bound_scope, args.locus,
|
||||
args.depth).to_boolean()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -373,12 +375,14 @@ namespace {
|
|||
foreach (post_t * p, post.xact->posts) {
|
||||
bind_scope_t bound_scope(args, *p);
|
||||
if (p == &post && args.has<expr_t::ptr_op_t>(1) &&
|
||||
! args.get<expr_t::ptr_op_t>(1)->calc(bound_scope).to_boolean()) {
|
||||
! args.get<expr_t::ptr_op_t>(1)
|
||||
->calc(bound_scope, args.locus, args.depth).to_boolean()) {
|
||||
// If the user specifies any(EXPR, false), and the context is a
|
||||
// posting, then that posting isn't considered by the test.
|
||||
; // skip it
|
||||
}
|
||||
else if (! expr->calc(bound_scope).to_boolean()) {
|
||||
else if (! expr->calc(bound_scope, args.locus,
|
||||
args.depth).to_boolean()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ value_t& call_scope_t::resolve(const std::size_t index,
|
|||
value_t& value(args[index]);
|
||||
if (value.is_any()) {
|
||||
context_scope_t scope(*this, context, required);
|
||||
value = as_expr(value)->calc(scope);
|
||||
value = as_expr(value)->calc(scope, locus, depth);
|
||||
if (required && ! value.is_type(context))
|
||||
throw_(calc_error, _("Expected %1 for argument %2, but received %3")
|
||||
<< value.label(context) << index
|
||||
|
|
|
|||
16
src/scope.h
16
src/scope.h
|
|
@ -335,11 +335,17 @@ class call_scope_t : public context_scope_t
|
|||
const bool required = false);
|
||||
|
||||
public:
|
||||
explicit call_scope_t(scope_t& _parent,
|
||||
value_t::type_t _type_context = value_t::VOID,
|
||||
const bool _required = true)
|
||||
: context_scope_t(_parent, _type_context, _required), ptr(NULL) {
|
||||
TRACE_CTOR(call_scope_t, "scope_t&, value_t::type_t, bool");
|
||||
expr_t::ptr_op_t * locus;
|
||||
const int depth;
|
||||
|
||||
explicit call_scope_t(scope_t& _parent,
|
||||
expr_t::ptr_op_t * _locus = NULL,
|
||||
const int _depth = 0)
|
||||
: context_scope_t(_parent, _parent.type_context(),
|
||||
_parent.type_required()),
|
||||
ptr(NULL), locus(_locus), depth(_depth) {
|
||||
TRACE_CTOR(call_scope_t,
|
||||
"scope_t&, value_t::type_t, bool, expr_t::ptr_op_t *, int");
|
||||
}
|
||||
virtual ~call_scope_t() {
|
||||
TRACE_DTOR(call_scope_t);
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ namespace {
|
|||
|
||||
foreach (post_t * p, post.xact->posts) {
|
||||
bind_scope_t bound_scope(args, *p);
|
||||
if (expr->calc(bound_scope).to_boolean())
|
||||
if (expr->calc(bound_scope, args.locus, args.depth).to_boolean())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -522,7 +522,7 @@ namespace {
|
|||
|
||||
foreach (post_t * p, post.xact->posts) {
|
||||
bind_scope_t bound_scope(args, *p);
|
||||
if (! expr->calc(bound_scope).to_boolean())
|
||||
if (! expr->calc(bound_scope, args.locus, args.depth).to_boolean())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue