From 0b3412cdb5bcd40b9aa1f0e1b2e3cf6e488f0e52 Mon Sep 17 00:00:00 2001 From: Enzo Baldisserri Date: Sun, 26 Apr 2020 06:40:54 +0200 Subject: [PATCH] checker: check that type exists in TypeDecl --- vlib/v/checker/checker.v | 72 +++++++++++++------ .../checker/tests/inout/alias_type_exists.out | 5 ++ .../checker/tests/inout/alias_type_exists.vv | 5 ++ vlib/v/checker/tests/inout/fn_type_exists.out | 12 ++++ vlib/v/checker/tests/inout/fn_type_exists.vv | 7 ++ .../v/checker/tests/inout/sum_type_exists.out | 5 ++ vlib/v/checker/tests/inout/sum_type_exists.vv | 5 ++ 7 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 vlib/v/checker/tests/inout/alias_type_exists.out create mode 100644 vlib/v/checker/tests/inout/alias_type_exists.vv create mode 100644 vlib/v/checker/tests/inout/fn_type_exists.out create mode 100644 vlib/v/checker/tests/inout/fn_type_exists.vv create mode 100644 vlib/v/checker/tests/inout/sum_type_exists.out create mode 100644 vlib/v/checker/tests/inout/sum_type_exists.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index d57cb2be62..c0246e36a0 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -155,6 +155,40 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool { return has_main_fn } +pub fn (mut c Checker) type_decl(node ast.TypeDecl) { + match node { + ast.AliasTypeDecl { + typ_sym := c.table.get_type_symbol(it.parent_type) + if typ_sym.kind == .placeholder { + c.error("type `$typ_sym.name` doesn't exist", it.pos) + } + } + ast.FnTypeDecl { + typ_sym := c.table.get_type_symbol(it.typ) + fn_typ_info := typ_sym.info as table.FnType + fn_info := fn_typ_info.func + ret_sym := c.table.get_type_symbol(fn_info.return_type) + if ret_sym.kind == .placeholder { + c.error("type `$ret_sym.name` doesn't exist", it.pos) + } + for arg in fn_info.args { + arg_sym := c.table.get_type_symbol(arg.typ) + if arg_sym.kind == .placeholder { + c.error("type `$arg_sym.name` doesn't exist", it.pos) + } + } + } + ast.SumTypeDecl { + for typ in it.sub_types { + typ_sym := c.table.get_type_symbol(typ) + if typ_sym.kind == .placeholder { + c.error("type `$typ_sym.name` doesn't exist", it.pos) + } + } + } + } +} + pub fn (mut c Checker) struct_decl(decl ast.StructDecl) { splitted_full_name := decl.name.split('.') is_builtin := splitted_full_name[0] == 'builtin' @@ -1088,6 +1122,7 @@ fn (mut c Checker) stmt(node ast.Stmt) { it.pos) } } + // ast.Attr {} ast.AssignStmt { c.assign_stmt(mut it) } @@ -1099,7 +1134,6 @@ fn (mut c Checker) stmt(node ast.Stmt) { c.error('$it.tok.lit statement not within a loop', it.tok.position()) } } - // ast.Attr {} ast.CompIf { // c.expr(it.cond) c.stmts(it.stmts) @@ -1170,17 +1204,6 @@ fn (mut c Checker) stmt(node ast.Stmt) { } c.returns = false } - ast.ForStmt { - c.in_for_count++ - typ := c.expr(it.cond) - if !it.is_inf && typ.idx() != table.bool_type_idx { - c.error('non-bool used as for condition', it.pos) - } - // TODO: update loop var type - // how does this work currenly? - c.stmts(it.stmts) - c.in_for_count-- - } ast.ForCStmt { c.in_for_count++ c.stmt(it.init) @@ -1230,8 +1253,20 @@ fn (mut c Checker) stmt(node ast.Stmt) { c.stmts(it.stmts) c.in_for_count-- } + ast.ForStmt { + c.in_for_count++ + typ := c.expr(it.cond) + if !it.is_inf && typ.idx() != table.bool_type_idx { + c.error('non-bool used as for condition', it.pos) + } + // TODO: update loop var type + // how does this work currenly? + c.stmts(it.stmts) + c.in_for_count-- + } + // ast.GlobalDecl {} ast.GoStmt { - if !is_call_expr(it.call_expr) { + if !(it.call_expr is ast.CallExpr) { c.error('expression in `go` must be a function call', it.call_expr.position()) } c.expr(it.call_expr) @@ -1242,7 +1277,6 @@ fn (mut c Checker) stmt(node ast.Stmt) { c.mod = it.name c.is_builtin_mod = it.name == 'builtin' } - // ast.GlobalDecl {} ast.Return { c.returns = true c.return_stmt(mut it) @@ -1250,6 +1284,9 @@ fn (mut c Checker) stmt(node ast.Stmt) { ast.StructDecl { c.struct_decl(it) } + ast.TypeDecl { + c.type_decl(it) + } ast.UnsafeStmt { c.stmts(it.stmts) } @@ -1260,13 +1297,6 @@ fn (mut c Checker) stmt(node ast.Stmt) { } } -fn is_call_expr(expr ast.Expr) bool { - return match expr { - ast.CallExpr { true } - else { false } - } -} - fn (mut c Checker) stmts(stmts []ast.Stmt) { c.expected_type = table.void_type for stmt in stmts { diff --git a/vlib/v/checker/tests/inout/alias_type_exists.out b/vlib/v/checker/tests/inout/alias_type_exists.out new file mode 100644 index 0000000000..ee2d255187 --- /dev/null +++ b/vlib/v/checker/tests/inout/alias_type_exists.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/inout/alias_type_exists.v:1:1: error: type `Bird` doesn't exist + 1| type Pigeon = Bird + ~~~~~~~~~~~ + 2| + 3| fn main() { diff --git a/vlib/v/checker/tests/inout/alias_type_exists.vv b/vlib/v/checker/tests/inout/alias_type_exists.vv new file mode 100644 index 0000000000..e8d6948b25 --- /dev/null +++ b/vlib/v/checker/tests/inout/alias_type_exists.vv @@ -0,0 +1,5 @@ +type Pigeon = Bird + +fn main() { + +} diff --git a/vlib/v/checker/tests/inout/fn_type_exists.out b/vlib/v/checker/tests/inout/fn_type_exists.out new file mode 100644 index 0000000000..c800caff70 --- /dev/null +++ b/vlib/v/checker/tests/inout/fn_type_exists.out @@ -0,0 +1,12 @@ +vlib/v/checker/tests/inout/fn_type_exists.v:1:1: error: type `Pants` doesn't exist + 1| type PantsCreator = fn (a Shirt) Pants + ~~~~~~~~~~~~~~~~~ + 2| + 3| type PantsConsumer = fn (p Pants) +vlib/v/checker/tests/inout/fn_type_exists.v:3:1: error: type `Pants` doesn't exist + 1| type PantsCreator = fn (a Shirt) Pants + 2| + 3| type PantsConsumer = fn (p Pants) + ~~~~~~~~~~~~~~~~~~ + 4| + 5| fn main() { diff --git a/vlib/v/checker/tests/inout/fn_type_exists.vv b/vlib/v/checker/tests/inout/fn_type_exists.vv new file mode 100644 index 0000000000..a61c83c170 --- /dev/null +++ b/vlib/v/checker/tests/inout/fn_type_exists.vv @@ -0,0 +1,7 @@ +type PantsCreator = fn (a Shirt) Pants + +type PantsConsumer = fn (p Pants) + +fn main() { + +} diff --git a/vlib/v/checker/tests/inout/sum_type_exists.out b/vlib/v/checker/tests/inout/sum_type_exists.out new file mode 100644 index 0000000000..f726c17b04 --- /dev/null +++ b/vlib/v/checker/tests/inout/sum_type_exists.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/inout/sum_type_exists.v:1:1: error: type `Nope` doesn't exist + 1| type Miscellaneous = Nope | Inexistant | int + ~~~~~~~~~~~~~~~~~~ + 2| + 3| fn main() { diff --git a/vlib/v/checker/tests/inout/sum_type_exists.vv b/vlib/v/checker/tests/inout/sum_type_exists.vv new file mode 100644 index 0000000000..f55fa0ae41 --- /dev/null +++ b/vlib/v/checker/tests/inout/sum_type_exists.vv @@ -0,0 +1,5 @@ +type Miscellaneous = Nope | Inexistant | int + +fn main() { + +}