Fix missing locations from generated handler code.
This commit is contained in:
parent
2f33c4a8f4
commit
6a438bc8cd
|
@ -565,15 +565,15 @@ impl TypedValidator {
|
||||||
|
|
||||||
TypedExpr::sequence(&[
|
TypedExpr::sequence(&[
|
||||||
TypedExpr::let_(
|
TypedExpr::let_(
|
||||||
TypedExpr::local_var(var_context, Type::script_context()),
|
TypedExpr::local_var(var_context, Type::script_context(), self.location),
|
||||||
TypedPattern::Constructor {
|
TypedPattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
name: well_known::SCRIPT_CONTEXT_CONSTRUCTORS[0].to_string(),
|
name: well_known::SCRIPT_CONTEXT_CONSTRUCTORS[0].to_string(),
|
||||||
arguments: vec![
|
arguments: vec![
|
||||||
CallArg::var(var_transaction),
|
CallArg::var(var_transaction, Span::empty()),
|
||||||
CallArg::var(var_redeemer),
|
CallArg::var(var_redeemer, Span::empty()),
|
||||||
CallArg::var(var_purpose),
|
CallArg::var(var_purpose, Span::empty()),
|
||||||
],
|
],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: PatternConstructor::Record {
|
constructor: PatternConstructor::Record {
|
||||||
|
@ -587,11 +587,13 @@ impl TypedValidator {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Type::script_context(),
|
Type::script_context(),
|
||||||
|
Span::empty(),
|
||||||
),
|
),
|
||||||
TypedExpr::When {
|
TypedExpr::When {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
tipo: Type::bool(),
|
tipo: Type::bool(),
|
||||||
subject: TypedExpr::local_var(var_purpose, Type::script_purpose()).into(),
|
subject: TypedExpr::local_var(var_purpose, Type::script_purpose(), Span::empty())
|
||||||
|
.into(),
|
||||||
clauses: self
|
clauses: self
|
||||||
.handlers
|
.handlers
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -611,13 +613,37 @@ impl TypedValidator {
|
||||||
|
|
||||||
let transaction = handler.arguments.last().unwrap();
|
let transaction = handler.arguments.last().unwrap();
|
||||||
|
|
||||||
|
println!("REDEEMER SPAN: {:?}", redeemer.location);
|
||||||
|
|
||||||
let pattern = match handler.name.as_str() {
|
let pattern = match handler.name.as_str() {
|
||||||
"spend" => TypedPattern::spend_purpose(var_purpose_arg, var_datum),
|
"spend" => TypedPattern::spend_purpose(
|
||||||
"mint" => TypedPattern::mint_purpose(var_purpose_arg),
|
(var_purpose_arg, purpose_arg.location),
|
||||||
"withdraw" => TypedPattern::withdraw_purpose(var_purpose_arg),
|
(
|
||||||
"publish" => TypedPattern::publish_purpose(var_purpose_arg),
|
var_datum,
|
||||||
"propose" => TypedPattern::propose_purpose(var_purpose_arg),
|
datum.map(|x| x.location).unwrap_or(Span::empty()),
|
||||||
"vote" => TypedPattern::vote_purpose(var_purpose_arg),
|
),
|
||||||
|
redeemer.location,
|
||||||
|
),
|
||||||
|
"mint" => TypedPattern::mint_purpose(
|
||||||
|
(var_purpose_arg, purpose_arg.location),
|
||||||
|
redeemer.location,
|
||||||
|
),
|
||||||
|
"withdraw" => TypedPattern::withdraw_purpose(
|
||||||
|
(var_purpose_arg, purpose_arg.location),
|
||||||
|
redeemer.location,
|
||||||
|
),
|
||||||
|
"publish" => TypedPattern::publish_purpose(
|
||||||
|
(var_purpose_arg, purpose_arg.location),
|
||||||
|
redeemer.location,
|
||||||
|
),
|
||||||
|
"propose" => TypedPattern::propose_purpose(
|
||||||
|
(var_purpose_arg, purpose_arg.location),
|
||||||
|
redeemer.location,
|
||||||
|
),
|
||||||
|
"vote" => TypedPattern::vote_purpose(
|
||||||
|
(var_purpose_arg, purpose_arg.location),
|
||||||
|
redeemer.location,
|
||||||
|
),
|
||||||
purpose => {
|
purpose => {
|
||||||
unreachable!("unexpected/unknown purpose: {:?}", purpose)
|
unreachable!("unexpected/unknown purpose: {:?}", purpose)
|
||||||
}
|
}
|
||||||
|
@ -627,36 +653,52 @@ impl TypedValidator {
|
||||||
|
|
||||||
// expect redeemer: tipo = __redeemer__
|
// expect redeemer: tipo = __redeemer__
|
||||||
then.push(TypedExpr::flexible_expect(
|
then.push(TypedExpr::flexible_expect(
|
||||||
TypedExpr::local_var(var_redeemer, Type::data()),
|
TypedExpr::local_var(var_redeemer, Type::data(), redeemer.location),
|
||||||
TypedPattern::var(redeemer.get_variable_name().unwrap_or("_")),
|
TypedPattern::var(redeemer.get_variable_name().unwrap_or("_")),
|
||||||
redeemer.tipo.clone(),
|
redeemer.tipo.clone(),
|
||||||
|
redeemer.location,
|
||||||
));
|
));
|
||||||
|
|
||||||
// Cast the datum, if any
|
// Cast the datum, if any
|
||||||
if let Some(datum) = datum {
|
if let Some(datum) = datum {
|
||||||
// expect datum: tipo = __datum__
|
// expect datum: tipo = __datum__
|
||||||
then.push(TypedExpr::flexible_expect(
|
then.push(TypedExpr::flexible_expect(
|
||||||
TypedExpr::local_var(var_datum, Type::option(Type::data())),
|
TypedExpr::local_var(
|
||||||
|
var_datum,
|
||||||
|
Type::option(Type::data()),
|
||||||
|
datum.location,
|
||||||
|
),
|
||||||
TypedPattern::var(datum.get_variable_name().unwrap_or("_")),
|
TypedPattern::var(datum.get_variable_name().unwrap_or("_")),
|
||||||
datum.tipo.clone(),
|
datum.tipo.clone(),
|
||||||
|
datum.location,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// let purpose_arg = __purpose_arg__
|
// let purpose_arg = __purpose_arg__
|
||||||
if let Some(arg_name) = purpose_arg.get_variable_name() {
|
if let Some(arg_name) = purpose_arg.get_variable_name() {
|
||||||
then.push(TypedExpr::let_(
|
then.push(TypedExpr::let_(
|
||||||
TypedExpr::local_var(var_purpose_arg, Type::data()),
|
TypedExpr::local_var(
|
||||||
|
var_purpose_arg,
|
||||||
|
Type::data(),
|
||||||
|
purpose_arg.location,
|
||||||
|
),
|
||||||
TypedPattern::var(arg_name),
|
TypedPattern::var(arg_name),
|
||||||
purpose_arg.tipo.clone(),
|
purpose_arg.tipo.clone(),
|
||||||
|
purpose_arg.location,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// let last_arg_name = __transaction__
|
// let last_arg_name = __transaction__
|
||||||
if let Some(arg_name) = transaction.get_variable_name() {
|
if let Some(arg_name) = transaction.get_variable_name() {
|
||||||
then.push(TypedExpr::let_(
|
then.push(TypedExpr::let_(
|
||||||
TypedExpr::local_var(var_transaction, Type::data()),
|
TypedExpr::local_var(
|
||||||
|
var_transaction,
|
||||||
|
Type::data(),
|
||||||
|
transaction.location,
|
||||||
|
),
|
||||||
TypedPattern::var(arg_name),
|
TypedPattern::var(arg_name),
|
||||||
Type::data(),
|
Type::data(),
|
||||||
|
transaction.location,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,14 +718,15 @@ impl TypedValidator {
|
||||||
|
|
||||||
let then = &[
|
let then = &[
|
||||||
TypedExpr::let_(
|
TypedExpr::let_(
|
||||||
TypedExpr::local_var(var_context, arg.tipo.clone()),
|
TypedExpr::local_var(var_context, arg.tipo.clone(), arg.location),
|
||||||
arg.get_variable_name().map(TypedPattern::var).unwrap_or(
|
arg.get_variable_name().map(TypedPattern::var).unwrap_or(
|
||||||
TypedPattern::Discard {
|
TypedPattern::Discard {
|
||||||
name: var_context.to_string(),
|
name: var_context.to_string(),
|
||||||
location: Span::empty(),
|
location: arg.location,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
arg.tipo.clone(),
|
arg.tipo.clone(),
|
||||||
|
arg.location,
|
||||||
),
|
),
|
||||||
fallback.body.clone(),
|
fallback.body.clone(),
|
||||||
];
|
];
|
||||||
|
@ -879,12 +922,12 @@ impl TypedCallArg {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallArg<TypedPattern> {
|
impl CallArg<TypedPattern> {
|
||||||
pub fn var(name: &str) -> Self {
|
pub fn var(name: &str, location: Span) -> Self {
|
||||||
CallArg {
|
CallArg {
|
||||||
label: None,
|
label: None,
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
value: TypedPattern::Var {
|
value: TypedPattern::Var {
|
||||||
location: Span::empty(),
|
location,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1456,10 +1499,15 @@ impl TypedPattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn constructor(name: &str, arguments: &[CallArg<TypedPattern>], tipo: Rc<Type>) -> Self {
|
pub fn constructor(
|
||||||
|
name: &str,
|
||||||
|
arguments: &[CallArg<TypedPattern>],
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
location: Span,
|
||||||
|
) -> Self {
|
||||||
TypedPattern::Constructor {
|
TypedPattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::empty(),
|
location,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
arguments: arguments.to_vec(),
|
arguments: arguments.to_vec(),
|
||||||
module: None,
|
module: None,
|
||||||
|
@ -1472,60 +1520,88 @@ impl TypedPattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mint_purpose(var_purpose_arg: &str) -> Self {
|
pub fn mint_purpose(
|
||||||
|
(var_purpose_arg, purpose_span): (&str, Span),
|
||||||
|
redeemer_span: Span,
|
||||||
|
) -> Self {
|
||||||
TypedPattern::constructor(
|
TypedPattern::constructor(
|
||||||
well_known::SCRIPT_PURPOSE_MINT,
|
well_known::SCRIPT_PURPOSE_MINT,
|
||||||
&[CallArg::var(var_purpose_arg)],
|
&[CallArg::var(var_purpose_arg, purpose_span)],
|
||||||
Type::function(vec![Type::byte_array()], Type::script_purpose()),
|
Type::function(vec![Type::byte_array()], Type::script_purpose()),
|
||||||
|
redeemer_span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spend_purpose(var_purpose_arg: &str, var_datum: &str) -> Self {
|
pub fn spend_purpose(
|
||||||
|
(var_purpose_arg, purpose_span): (&str, Span),
|
||||||
|
(var_datum, datum_span): (&str, Span),
|
||||||
|
redeemer_span: Span,
|
||||||
|
) -> Self {
|
||||||
TypedPattern::constructor(
|
TypedPattern::constructor(
|
||||||
well_known::SCRIPT_PURPOSE_SPEND,
|
well_known::SCRIPT_PURPOSE_SPEND,
|
||||||
&[CallArg::var(var_purpose_arg), CallArg::var(var_datum)],
|
&[
|
||||||
|
CallArg::var(var_purpose_arg, purpose_span),
|
||||||
|
CallArg::var(var_datum, datum_span),
|
||||||
|
],
|
||||||
Type::function(
|
Type::function(
|
||||||
vec![Type::data(), Type::option(Type::data())],
|
vec![Type::data(), Type::option(Type::data())],
|
||||||
Type::script_purpose(),
|
Type::script_purpose(),
|
||||||
),
|
),
|
||||||
|
redeemer_span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn withdraw_purpose(var_purpose_arg: &str) -> Self {
|
pub fn withdraw_purpose(
|
||||||
|
(var_purpose_arg, purpose_span): (&str, Span),
|
||||||
|
redeemer_span: Span,
|
||||||
|
) -> Self {
|
||||||
TypedPattern::constructor(
|
TypedPattern::constructor(
|
||||||
well_known::SCRIPT_PURPOSE_WITHDRAW,
|
well_known::SCRIPT_PURPOSE_WITHDRAW,
|
||||||
&[CallArg::var(var_purpose_arg)],
|
&[CallArg::var(var_purpose_arg, purpose_span)],
|
||||||
Type::function(vec![Type::data()], Type::script_purpose()),
|
Type::function(vec![Type::data()], Type::script_purpose()),
|
||||||
|
redeemer_span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn publish_purpose(var_purpose_arg: &str) -> Self {
|
pub fn publish_purpose(
|
||||||
|
(var_purpose_arg, purpose_span): (&str, Span),
|
||||||
|
redeemer_span: Span,
|
||||||
|
) -> Self {
|
||||||
TypedPattern::constructor(
|
TypedPattern::constructor(
|
||||||
well_known::SCRIPT_PURPOSE_PUBLISH,
|
well_known::SCRIPT_PURPOSE_PUBLISH,
|
||||||
&[
|
&[
|
||||||
CallArg::var("__discarded_purpose_ix__"),
|
CallArg::var("__discarded_purpose_ix__", purpose_span),
|
||||||
CallArg::var(var_purpose_arg),
|
CallArg::var(var_purpose_arg, purpose_span),
|
||||||
],
|
],
|
||||||
Type::function(vec![Type::int(), Type::data()], Type::script_purpose()),
|
Type::function(vec![Type::int(), Type::data()], Type::script_purpose()),
|
||||||
|
redeemer_span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vote_purpose(var_purpose_arg: &str) -> Self {
|
pub fn vote_purpose(
|
||||||
|
(var_purpose_arg, purpose_span): (&str, Span),
|
||||||
|
redeemer_span: Span,
|
||||||
|
) -> Self {
|
||||||
TypedPattern::constructor(
|
TypedPattern::constructor(
|
||||||
well_known::SCRIPT_PURPOSE_VOTE,
|
well_known::SCRIPT_PURPOSE_VOTE,
|
||||||
&[CallArg::var(var_purpose_arg)],
|
&[CallArg::var(var_purpose_arg, purpose_span)],
|
||||||
Type::function(vec![Type::data()], Type::script_purpose()),
|
Type::function(vec![Type::data()], Type::script_purpose()),
|
||||||
|
redeemer_span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn propose_purpose(var_purpose_arg: &str) -> Self {
|
pub fn propose_purpose(
|
||||||
|
(var_purpose_arg, purpose_span): (&str, Span),
|
||||||
|
redeemer_span: Span,
|
||||||
|
) -> Self {
|
||||||
TypedPattern::constructor(
|
TypedPattern::constructor(
|
||||||
well_known::SCRIPT_PURPOSE_PROPOSE,
|
well_known::SCRIPT_PURPOSE_PROPOSE,
|
||||||
&[
|
&[
|
||||||
CallArg::var("__discarded_purpose_ix__"),
|
CallArg::var("__discarded_purpose_ix__", purpose_span),
|
||||||
CallArg::var(var_purpose_arg),
|
CallArg::var(var_purpose_arg, purpose_span),
|
||||||
],
|
],
|
||||||
Type::function(vec![Type::int(), Type::data()], Type::script_purpose()),
|
Type::function(vec![Type::int(), Type::data()], Type::script_purpose()),
|
||||||
|
redeemer_span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,20 +210,24 @@ impl TypedExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn let_(value: Self, pattern: TypedPattern, tipo: Rc<Type>) -> Self {
|
pub fn let_(value: Self, pattern: TypedPattern, tipo: Rc<Type>, location: Span) -> Self {
|
||||||
TypedExpr::Assignment {
|
TypedExpr::Assignment {
|
||||||
location: Span::empty(),
|
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
value: value.into(),
|
value: value.into(),
|
||||||
pattern,
|
pattern,
|
||||||
kind: AssignmentKind::let_(),
|
kind: AssignmentKind::let_(),
|
||||||
|
location,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an expect assignment, unless the target type is `Data`; then fallback to a let.
|
// Create an expect assignment, unless the target type is `Data`; then fallback to a let.
|
||||||
pub fn flexible_expect(value: Self, pattern: TypedPattern, tipo: Rc<Type>) -> Self {
|
pub fn flexible_expect(
|
||||||
|
value: Self,
|
||||||
|
pattern: TypedPattern,
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
location: Span,
|
||||||
|
) -> Self {
|
||||||
TypedExpr::Assignment {
|
TypedExpr::Assignment {
|
||||||
location: Span::empty(),
|
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
value: value.into(),
|
value: value.into(),
|
||||||
pattern,
|
pattern,
|
||||||
|
@ -232,12 +236,12 @@ impl TypedExpr {
|
||||||
} else {
|
} else {
|
||||||
AssignmentKind::expect()
|
AssignmentKind::expect()
|
||||||
},
|
},
|
||||||
|
location,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_var(name: &str, tipo: Rc<Type>) -> Self {
|
pub fn local_var(name: &str, tipo: Rc<Type>, location: Span) -> Self {
|
||||||
TypedExpr::Var {
|
TypedExpr::Var {
|
||||||
location: Span::empty(),
|
|
||||||
constructor: ValueConstructor {
|
constructor: ValueConstructor {
|
||||||
public: true,
|
public: true,
|
||||||
variant: ValueConstructorVariant::LocalVariable {
|
variant: ValueConstructorVariant::LocalVariable {
|
||||||
|
@ -246,6 +250,7 @@ impl TypedExpr {
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
},
|
},
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
location,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1719,6 +1719,11 @@ pub fn get_src_code_by_span(
|
||||||
span: &Span,
|
span: &Span,
|
||||||
module_src: &IndexMap<&str, &(String, LineNumbers)>,
|
module_src: &IndexMap<&str, &(String, LineNumbers)>,
|
||||||
) -> String {
|
) -> String {
|
||||||
|
assert!(
|
||||||
|
*span != Span::empty(),
|
||||||
|
"tried to lookup source code from empty location"
|
||||||
|
);
|
||||||
|
|
||||||
let (src, _) = module_src
|
let (src, _) = module_src
|
||||||
.get(module_name)
|
.get(module_name)
|
||||||
.unwrap_or_else(|| panic!("Missing module {module_name}"));
|
.unwrap_or_else(|| panic!("Missing module {module_name}"));
|
||||||
|
@ -1733,6 +1738,11 @@ pub fn get_line_columns_by_span(
|
||||||
span: &Span,
|
span: &Span,
|
||||||
module_src: &IndexMap<&str, &(String, LineNumbers)>,
|
module_src: &IndexMap<&str, &(String, LineNumbers)>,
|
||||||
) -> LineColumn {
|
) -> LineColumn {
|
||||||
|
assert!(
|
||||||
|
*span != Span::empty(),
|
||||||
|
"tried to lookup line & columns from empty location"
|
||||||
|
);
|
||||||
|
|
||||||
let (_, lines) = module_src
|
let (_, lines) = module_src
|
||||||
.get(module_name)
|
.get(module_name)
|
||||||
.unwrap_or_else(|| panic!("Missing module {module_name}"));
|
.unwrap_or_else(|| panic!("Missing module {module_name}"));
|
||||||
|
|
Loading…
Reference in New Issue