feat: allow importing off validators in validators/tests/*
This commit is contained in:
parent
b25e82ed36
commit
07122aaa88
|
@ -66,25 +66,6 @@ fn validator_illegal_return_type() {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn validator_useless_pub() {
|
|
||||||
let source_code = r#"
|
|
||||||
type Datum {
|
|
||||||
thing: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
validator {
|
|
||||||
pub fn foo(_d: Datum, _r, _c) {
|
|
||||||
True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let (warnings, _) = check_validator(parse(source_code)).unwrap();
|
|
||||||
|
|
||||||
assert!(matches!(warnings[0], Warning::PubInValidatorModule { .. }))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validator_illegal_arity() {
|
fn validator_illegal_arity() {
|
||||||
let source_code = r#"
|
let source_code = r#"
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub struct Environment<'a> {
|
||||||
/// Accessors defined in the current module
|
/// Accessors defined in the current module
|
||||||
pub accessors: HashMap<String, AccessorsMap>,
|
pub accessors: HashMap<String, AccessorsMap>,
|
||||||
pub current_module: &'a String,
|
pub current_module: &'a String,
|
||||||
|
pub current_kind: &'a ModuleKind,
|
||||||
/// entity_usages is a stack of scopes. When an entity is created it is
|
/// entity_usages is a stack of scopes. When an entity is created it is
|
||||||
/// added to the top scope. When an entity is used we crawl down the scope
|
/// added to the top scope. When an entity is used we crawl down the scope
|
||||||
/// stack for an entity with that name and mark it as used.
|
/// stack for an entity with that name and mark it as used.
|
||||||
|
@ -244,12 +245,44 @@ impl<'a> Environment<'a> {
|
||||||
can_error,
|
can_error,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Definition::Validator(Validator {
|
||||||
|
doc,
|
||||||
|
end_position,
|
||||||
|
fun,
|
||||||
|
other_fun,
|
||||||
|
location,
|
||||||
|
params,
|
||||||
|
}) => {
|
||||||
|
let Definition::Fn(fun) =
|
||||||
|
self.generalise_definition(Definition::Fn(fun), module_name)
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let other_fun = other_fun.map(|other_fun| {
|
||||||
|
let Definition::Fn(other_fun) =
|
||||||
|
self.generalise_definition(Definition::Fn(other_fun), module_name)
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
other_fun
|
||||||
|
});
|
||||||
|
|
||||||
|
Definition::Validator(Validator {
|
||||||
|
doc,
|
||||||
|
end_position,
|
||||||
|
fun,
|
||||||
|
other_fun,
|
||||||
|
location,
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
definition @ (Definition::TypeAlias { .. }
|
definition @ (Definition::TypeAlias { .. }
|
||||||
| Definition::DataType { .. }
|
| Definition::DataType { .. }
|
||||||
| Definition::Use { .. }
|
| Definition::Use { .. }
|
||||||
| Definition::Test { .. }
|
| Definition::Test { .. }
|
||||||
| Definition::Validator { .. }
|
|
||||||
| Definition::ModuleConstant { .. }) => definition,
|
| Definition::ModuleConstant { .. }) => definition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,6 +633,7 @@ impl<'a> Environment<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id_gen: IdGenerator,
|
id_gen: IdGenerator,
|
||||||
current_module: &'a String,
|
current_module: &'a String,
|
||||||
|
current_kind: &'a ModuleKind,
|
||||||
importable_modules: &'a HashMap<String, TypeInfo>,
|
importable_modules: &'a HashMap<String, TypeInfo>,
|
||||||
warnings: &'a mut Vec<Warning>,
|
warnings: &'a mut Vec<Warning>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -622,6 +656,7 @@ impl<'a> Environment<'a> {
|
||||||
importable_modules,
|
importable_modules,
|
||||||
imported_types: HashSet::new(),
|
imported_types: HashSet::new(),
|
||||||
current_module,
|
current_module,
|
||||||
|
current_kind,
|
||||||
warnings,
|
warnings,
|
||||||
entity_usages: vec![HashMap::new()],
|
entity_usages: vec![HashMap::new()],
|
||||||
}
|
}
|
||||||
|
@ -677,7 +712,9 @@ impl<'a> Environment<'a> {
|
||||||
imported_modules: self.imported_modules.keys().cloned().collect(),
|
imported_modules: self.imported_modules.keys().cloned().collect(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if module_info.kind.is_validator() {
|
if module_info.kind.is_validator()
|
||||||
|
&& (self.current_kind.is_lib() || !self.current_module.starts_with("tests"))
|
||||||
|
{
|
||||||
return Err(Error::ValidatorImported {
|
return Err(Error::ValidatorImported {
|
||||||
location: *location,
|
location: *location,
|
||||||
name,
|
name,
|
||||||
|
@ -1086,7 +1123,7 @@ impl<'a> Environment<'a> {
|
||||||
&fun.location,
|
&fun.location,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if !fun.public && kind.is_lib() {
|
if !fun.public {
|
||||||
self.init_usage(fun.name.clone(), EntityKind::PrivateFunction, fun.location);
|
self.init_usage(fun.name.clone(), EntityKind::PrivateFunction, fun.location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1363,13 +1363,6 @@ pub enum Warning {
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I found a public definition in a validator module.\nDefinitions in validator modules do not need to be public.\n")]
|
|
||||||
#[diagnostic(code("redundant::pub"))]
|
|
||||||
PubInValidatorModule {
|
|
||||||
#[label]
|
|
||||||
location: Span,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error("I found a when expression with a single clause.")]
|
#[error("I found a when expression with a single clause.")]
|
||||||
#[diagnostic(
|
#[diagnostic(
|
||||||
code("single_when_clause"),
|
code("single_when_clause"),
|
||||||
|
@ -1607,7 +1600,6 @@ impl ExtraData for Warning {
|
||||||
Warning::AllFieldsRecordUpdate { .. }
|
Warning::AllFieldsRecordUpdate { .. }
|
||||||
| Warning::ImplicitlyDiscardedResult { .. }
|
| Warning::ImplicitlyDiscardedResult { .. }
|
||||||
| Warning::NoFieldsRecordUpdate { .. }
|
| Warning::NoFieldsRecordUpdate { .. }
|
||||||
| Warning::PubInValidatorModule { .. }
|
|
||||||
| Warning::SingleConstructorExpect { .. }
|
| Warning::SingleConstructorExpect { .. }
|
||||||
| Warning::SingleWhenClause { .. }
|
| Warning::SingleWhenClause { .. }
|
||||||
| Warning::Todo { .. }
|
| Warning::Todo { .. }
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
ArgName, DataType, Definition, Function, Layer, ModuleConstant, ModuleKind,
|
ArgName, DataType, Definition, Function, Layer, ModuleConstant, ModuleKind,
|
||||||
RecordConstructor, RecordConstructorArg, Span, Tracing, TypeAlias, TypedDefinition,
|
RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedDefinition,
|
||||||
TypedFunction, TypedModule, UntypedDefinition, UntypedModule, Use, Validator,
|
TypedFunction, TypedModule, UntypedDefinition, UntypedModule, Use, Validator,
|
||||||
},
|
},
|
||||||
builtins,
|
builtins,
|
||||||
|
@ -19,8 +19,6 @@ use super::{
|
||||||
TypeInfo, ValueConstructor, ValueConstructorVariant,
|
TypeInfo, ValueConstructor, ValueConstructorVariant,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PUB_OFFSET: usize = 3;
|
|
||||||
|
|
||||||
impl UntypedModule {
|
impl UntypedModule {
|
||||||
pub fn infer(
|
pub fn infer(
|
||||||
mut self,
|
mut self,
|
||||||
|
@ -33,7 +31,7 @@ impl UntypedModule {
|
||||||
) -> Result<TypedModule, Error> {
|
) -> Result<TypedModule, Error> {
|
||||||
let name = self.name.clone();
|
let name = self.name.clone();
|
||||||
let docs = std::mem::take(&mut self.docs);
|
let docs = std::mem::take(&mut self.docs);
|
||||||
let mut environment = Environment::new(id_gen.clone(), &name, modules, warnings);
|
let mut environment = Environment::new(id_gen.clone(), &name, &kind, modules, warnings);
|
||||||
|
|
||||||
let mut type_names = HashMap::with_capacity(self.definitions.len());
|
let mut type_names = HashMap::with_capacity(self.definitions.len());
|
||||||
let mut value_names = HashMap::with_capacity(self.definitions.len());
|
let mut value_names = HashMap::with_capacity(self.definitions.len());
|
||||||
|
@ -82,7 +80,7 @@ impl UntypedModule {
|
||||||
|
|
||||||
for def in consts.into_iter().chain(not_consts) {
|
for def in consts.into_iter().chain(not_consts) {
|
||||||
let definition =
|
let definition =
|
||||||
infer_definition(def, &name, &mut hydrators, &mut environment, tracing, kind)?;
|
infer_definition(def, &name, &mut hydrators, &mut environment, tracing)?;
|
||||||
definitions.push(definition);
|
definitions.push(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +146,6 @@ fn infer_definition(
|
||||||
hydrators: &mut HashMap<String, Hydrator>,
|
hydrators: &mut HashMap<String, Hydrator>,
|
||||||
environment: &mut Environment<'_>,
|
environment: &mut Environment<'_>,
|
||||||
tracing: Tracing,
|
tracing: Tracing,
|
||||||
kind: ModuleKind,
|
|
||||||
) -> Result<TypedDefinition, Error> {
|
) -> Result<TypedDefinition, Error> {
|
||||||
match def {
|
match def {
|
||||||
Definition::Fn(Function {
|
Definition::Fn(Function {
|
||||||
|
@ -163,15 +160,6 @@ fn infer_definition(
|
||||||
can_error,
|
can_error,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if public && kind.is_validator() {
|
|
||||||
environment.warnings.push(Warning::PubInValidatorModule {
|
|
||||||
location: Span {
|
|
||||||
start: location.start,
|
|
||||||
end: location.start + PUB_OFFSET,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let preregistered_fn = environment
|
let preregistered_fn = environment
|
||||||
.get_variable(&name)
|
.get_variable(&name)
|
||||||
.expect("Could not find preregistered type for function");
|
.expect("Could not find preregistered type for function");
|
||||||
|
@ -306,7 +294,6 @@ fn infer_definition(
|
||||||
hydrators,
|
hydrators,
|
||||||
environment,
|
environment,
|
||||||
tracing,
|
tracing,
|
||||||
kind,
|
|
||||||
)?
|
)?
|
||||||
else {
|
else {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
|
@ -357,7 +344,6 @@ fn infer_definition(
|
||||||
hydrators,
|
hydrators,
|
||||||
environment,
|
environment,
|
||||||
tracing,
|
tracing,
|
||||||
kind,
|
|
||||||
)?
|
)?
|
||||||
else {
|
else {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
|
@ -419,7 +405,6 @@ fn infer_definition(
|
||||||
hydrators,
|
hydrators,
|
||||||
environment,
|
environment,
|
||||||
tracing,
|
tracing,
|
||||||
kind,
|
|
||||||
)? {
|
)? {
|
||||||
environment.unify(f.return_type.clone(), builtins::bool(), f.location, false)?;
|
environment.unify(f.return_type.clone(), builtins::bool(), f.location, false)?;
|
||||||
|
|
||||||
|
@ -438,15 +423,6 @@ fn infer_definition(
|
||||||
annotation,
|
annotation,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if public && kind.is_validator() {
|
|
||||||
environment.warnings.push(Warning::PubInValidatorModule {
|
|
||||||
location: Span {
|
|
||||||
start: location.start,
|
|
||||||
end: location.start + PUB_OFFSET,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let tipo = environment
|
let tipo = environment
|
||||||
.get_type_constructor(&None, &alias, location)
|
.get_type_constructor(&None, &alias, location)
|
||||||
.expect("Could not find existing type for type alias")
|
.expect("Could not find existing type for type alias")
|
||||||
|
@ -474,15 +450,6 @@ fn infer_definition(
|
||||||
constructors: untyped_constructors,
|
constructors: untyped_constructors,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if public && kind.is_validator() {
|
|
||||||
environment.warnings.push(Warning::PubInValidatorModule {
|
|
||||||
location: Span {
|
|
||||||
start: location.start,
|
|
||||||
end: location.start + PUB_OFFSET,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let constructors = untyped_constructors
|
let constructors = untyped_constructors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(
|
.map(
|
||||||
|
@ -617,15 +584,6 @@ fn infer_definition(
|
||||||
value,
|
value,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if public && kind.is_validator() {
|
|
||||||
environment.warnings.push(Warning::PubInValidatorModule {
|
|
||||||
location: Span {
|
|
||||||
start: location.start,
|
|
||||||
end: location.start + PUB_OFFSET,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let typed_expr =
|
let typed_expr =
|
||||||
ExprTyper::new(environment, tracing).infer_const(&annotation, *value)?;
|
ExprTyper::new(environment, tracing).infer_const(&annotation, *value)?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue