From 10dcb2e0d9e93c0473d8e91a9886fbc09c8a8dfb Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Sun, 6 Feb 2022 23:20:34 +0100 Subject: [PATCH] parser: allow embedding interfaces from other modules (#13385) --- vlib/v/parser/struct.v | 26 +++++++++++++++++++ .../interface_from_another_module/main_test.v | 15 +++++++++++ .../interface_from_another_module/mod/mod.v | 3 +++ 3 files changed, 44 insertions(+) create mode 100644 vlib/v/tests/modules/interface_from_another_module/main_test.v create mode 100644 vlib/v/tests/modules/interface_from_another_module/mod/mod.v diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 1b670371a06498..12d7ceae57215d 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -519,6 +519,32 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { } continue } + + // Check embedded interface from external module + if p.tok.kind == .name && p.peek_tok.kind == .dot { + if p.tok.lit !in p.imports { + p.error_with_pos('mod `$p.tok.lit` not imported', p.tok.pos()) + break + } + mod_name := p.tok.lit + from_mod_typ := p.parse_type() + from_mod_name := '${mod_name}.$p.prev_tok.lit' + if from_mod_name.is_lower() { + p.error_with_pos('The interface name need to have the pascal case', p.prev_tok.pos()) + break + } + comments := p.eat_comments() + ifaces << ast.InterfaceEmbedding{ + name: from_mod_name + typ: from_mod_typ + pos: p.prev_tok.pos() + comments: comments + } + if p.tok.kind == .rcbr { + break + } + } + if p.tok.kind == .key_mut { if is_mut { p.error_with_pos('redefinition of `mut` section', p.tok.pos()) diff --git a/vlib/v/tests/modules/interface_from_another_module/main_test.v b/vlib/v/tests/modules/interface_from_another_module/main_test.v new file mode 100644 index 00000000000000..4cb878f50f848d --- /dev/null +++ b/vlib/v/tests/modules/interface_from_another_module/main_test.v @@ -0,0 +1,15 @@ +module main + +import interface_from_another_module.mod + +interface IBar { + mod.IFoo +} + +struct Abc {} + +fn test_interface() { + a := IBar(Abc{}) + dump(a) + assert true +} diff --git a/vlib/v/tests/modules/interface_from_another_module/mod/mod.v b/vlib/v/tests/modules/interface_from_another_module/mod/mod.v new file mode 100644 index 00000000000000..d5da0bfd1ecc90 --- /dev/null +++ b/vlib/v/tests/modules/interface_from_another_module/mod/mod.v @@ -0,0 +1,3 @@ +module mod + +pub interface IFoo {}