parser/checker: [ref_only] attribute

pull/4805/head
Alexander Medvednikov 2020-05-09 23:45:41 +02:00
parent 3052266a40
commit 09f6cd6a75
4 changed files with 15 additions and 5 deletions

View File

@ -153,6 +153,7 @@ pub:
is_c bool
is_js bool
is_union bool
attr string
}
pub struct InterfaceDecl {

View File

@ -232,6 +232,12 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
if sym.kind == .placeholder && !decl.is_c && !sym.name.starts_with('C.') {
c.error('unknown type `$sym.name`', field.pos)
}
if sym.kind == .struct_ {
info:=sym.info as table.Struct
if info.is_ref_only && !field.typ.is_ptr() {
c.error('`$sym.name` type can only be used as a reference: `&$sym.name`', field.pos)
}
}
if field.has_default_expr {
c.expected_type = field.typ
field_expr_type := c.expr(field.default_expr)

View File

@ -166,6 +166,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
fields: fields
is_typedef: is_typedef
is_union: is_union
is_ref_only: p.attr == 'ref_only'
}
mod: p.mod
is_public: is_pub
@ -193,6 +194,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
is_c: is_c
is_js: is_js
is_union: is_union
attr: p.attr
}
}

View File

@ -531,9 +531,10 @@ pub fn (kinds []Kind) str() string {
pub struct Struct {
pub mut:
fields []Field
is_typedef bool // C. [typedef]
is_union bool
fields []Field
is_typedef bool // C. [typedef]
is_union bool
is_ref_only bool
}
pub struct Interface {
@ -641,7 +642,7 @@ pub fn (table &Table) type_to_str(t Type) string {
return res
}
pub fn(t &Table) fn_to_str(func &Fn) string {
pub fn (t &Table) fn_to_str(func &Fn) string {
mut sb := strings.new_builder(20)
sb.write('${func.name}(')
for i in 1 .. func.args.len {
@ -655,7 +656,7 @@ pub fn(t &Table) fn_to_str(func &Fn) string {
}
}
sb.write(')')
if func.return_type != table.void_type {
if func.return_type != void_type {
sb.write(' ${t.type_to_str(func.return_type)}')
}
return sb.str()