mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 18:52:58 +03:00
add checks for ident types being allowed built in types
This commit is contained in:
parent
2db204b81e
commit
1da03e728b
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1344,6 +1344,7 @@ dependencies = [
|
||||
name = "leo-stdlib"
|
||||
version = "1.5.3"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"leo-ast",
|
||||
"leo-errors",
|
||||
"leo-span",
|
||||
|
@ -26,6 +26,7 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
self.parent = Some(input.name());
|
||||
input.input.iter().for_each(|i| {
|
||||
let input_var = i.get_variable();
|
||||
self.validate_ident_type(&Some(input_var.type_));
|
||||
|
||||
if let Err(err) = self.symbol_table.insert_variable(
|
||||
input_var.identifier.name,
|
||||
|
@ -29,10 +29,10 @@ impl<'a> StatementVisitorDirector<'a> for Director<'a> {
|
||||
// statements should always have some parent block
|
||||
let parent = self.visitor.parent.unwrap();
|
||||
|
||||
self.visit_expression(
|
||||
&input.expression,
|
||||
&self.visitor.symbol_table.lookup_fn(&parent).map(|f| f.output),
|
||||
);
|
||||
let return_type = &self.visitor.symbol_table.lookup_fn(&parent).map(|f| f.output);
|
||||
self.visitor.validate_ident_type(return_type);
|
||||
|
||||
self.visit_expression(&input.expression, return_type);
|
||||
}
|
||||
|
||||
fn visit_definition(&mut self, input: &'a DefinitionStatement) {
|
||||
@ -43,6 +43,8 @@ impl<'a> StatementVisitorDirector<'a> for Director<'a> {
|
||||
};
|
||||
|
||||
input.variable_names.iter().for_each(|v| {
|
||||
self.visitor.validate_ident_type(&Some(input.type_));
|
||||
|
||||
if let Err(err) = self.visitor.symbol_table.insert_variable(
|
||||
v.identifier.name,
|
||||
VariableSymbol {
|
||||
@ -83,6 +85,7 @@ impl<'a> StatementVisitorDirector<'a> for Director<'a> {
|
||||
};
|
||||
|
||||
if var_type.is_some() {
|
||||
self.visitor.validate_ident_type(&var_type);
|
||||
self.visit_expression(&input.value, &var_type);
|
||||
}
|
||||
}
|
||||
@ -103,8 +106,10 @@ impl<'a> StatementVisitorDirector<'a> for Director<'a> {
|
||||
self.visitor.handler.emit_err(err);
|
||||
}
|
||||
|
||||
self.visit_expression(&input.start, &Some(input.type_));
|
||||
self.visit_expression(&input.stop, &Some(input.type_));
|
||||
let iter_type = &Some(input.type_);
|
||||
self.visitor.validate_ident_type(iter_type);
|
||||
self.visit_expression(&input.start, iter_type);
|
||||
self.visit_expression(&input.stop, iter_type);
|
||||
}
|
||||
|
||||
fn visit_console(&mut self, input: &'a ConsoleStatement) {
|
||||
|
@ -14,9 +14,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_ast::{IntegerType, Type};
|
||||
use indexmap::IndexSet;
|
||||
use leo_ast::{IntegerType, Node, Type};
|
||||
use leo_errors::{emitter::Handler, TypeCheckerError};
|
||||
use leo_span::{Span, Symbol};
|
||||
use leo_stdlib::*;
|
||||
|
||||
use crate::SymbolTable;
|
||||
|
||||
@ -25,6 +27,8 @@ pub struct TypeChecker<'a> {
|
||||
pub(crate) handler: &'a Handler,
|
||||
pub(crate) parent: Option<Symbol>,
|
||||
pub(crate) negate: bool,
|
||||
pub(crate) account_types: IndexSet<Symbol>,
|
||||
pub(crate) algorithms_types: IndexSet<Symbol>,
|
||||
}
|
||||
|
||||
const INT_TYPES: [Type; 10] = [
|
||||
@ -74,6 +78,18 @@ impl<'a> TypeChecker<'a> {
|
||||
handler,
|
||||
parent: None,
|
||||
negate: false,
|
||||
account_types: Account::types(),
|
||||
algorithms_types: Algorithms::types(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates that an ident type is a valid one.
|
||||
pub(crate) fn validate_ident_type(&self, type_: &Option<Type>) {
|
||||
if let Some(Type::Identifier(ident)) = type_ {
|
||||
if !(self.account_types.contains(&ident.name) || self.algorithms_types.contains(&ident.name)) {
|
||||
self.handler
|
||||
.emit_err(TypeCheckerError::invalid_built_in_type(&ident.name, ident.span()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,9 @@ version = "1.5.3"
|
||||
path = "../../leo/errors"
|
||||
version = "1.5.3"
|
||||
|
||||
|
||||
[dependencies.leo-span]
|
||||
path = "../../leo/span"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies]
|
||||
indexmap = "1.7.0"
|
@ -16,34 +16,20 @@
|
||||
|
||||
use crate::Types;
|
||||
|
||||
use leo_ast::{Identifier, Type};
|
||||
use leo_span::{Span, Symbol};
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use leo_span::Symbol;
|
||||
|
||||
pub struct Account;
|
||||
|
||||
impl Types for Account {
|
||||
fn types() -> Vec<Type> {
|
||||
vec![
|
||||
Type::Identifier(Identifier {
|
||||
name: Symbol::intern("ComputeKey"),
|
||||
span: Span::dummy(),
|
||||
}),
|
||||
Type::Identifier(Identifier {
|
||||
name: Symbol::intern("PrivateKey"),
|
||||
span: Span::dummy(),
|
||||
}),
|
||||
Type::Identifier(Identifier {
|
||||
name: Symbol::intern("Record"),
|
||||
span: Span::dummy(),
|
||||
}),
|
||||
Type::Identifier(Identifier {
|
||||
name: Symbol::intern("Signature"),
|
||||
span: Span::dummy(),
|
||||
}),
|
||||
Type::Identifier(Identifier {
|
||||
name: Symbol::intern("ViewKey"),
|
||||
span: Span::dummy(),
|
||||
}),
|
||||
]
|
||||
fn types() -> IndexSet<Symbol> {
|
||||
IndexSet::from([
|
||||
Symbol::intern("ComputeKey"),
|
||||
Symbol::intern("PrivateKey"),
|
||||
Symbol::intern("Record"),
|
||||
Symbol::intern("Signature"),
|
||||
Symbol::intern("ViewKey"),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -16,16 +16,13 @@
|
||||
|
||||
use crate::Types;
|
||||
|
||||
use leo_ast::{Identifier, Type};
|
||||
use leo_span::{Span, Symbol};
|
||||
use indexmap::IndexSet;
|
||||
use leo_span::Symbol;
|
||||
|
||||
pub struct Algorithms;
|
||||
|
||||
impl Types for Algorithms {
|
||||
fn types() -> Vec<Type> {
|
||||
vec![Type::Identifier(Identifier {
|
||||
name: Symbol::intern("Poseidon"),
|
||||
span: Span::dummy(),
|
||||
})]
|
||||
fn types() -> IndexSet<Symbol> {
|
||||
IndexSet::from([Symbol::intern("Poseidon")])
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
use leo_ast::Type;
|
||||
use indexmap::IndexSet;
|
||||
use leo_span::Symbol;
|
||||
|
||||
mod account;
|
||||
pub use account::*;
|
||||
@ -25,5 +26,5 @@ mod algorithms;
|
||||
pub use algorithms::*;
|
||||
|
||||
pub trait Types {
|
||||
fn types() -> Vec<Type>;
|
||||
fn types() -> IndexSet<Symbol>;
|
||||
}
|
||||
|
@ -132,4 +132,14 @@ create_messages!(
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
|
||||
/// For when an invalid built in type is used.
|
||||
@formatted
|
||||
invalid_built_in_type {
|
||||
args: (type_: impl Display),
|
||||
msg: format!(
|
||||
"The type {type_} is not a valid built in type.",
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user