mirror of
https://github.com/vlang/v.git
synced 2025-09-10 07:47:20 -04:00
all: implements
keyword for optional explicit interface implementations
This commit is contained in:
parent
04a3ecf617
commit
0090170b26
@ -21,6 +21,31 @@ pub fn floor(x f64) f64 {
|
|||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// floorf returns the greatest integer value less than or equal to x.
|
||||||
|
//
|
||||||
|
// special cases are:
|
||||||
|
// floor(±0) = ±0
|
||||||
|
// floor(±inf) = ±inf
|
||||||
|
// floor(nan) = nan
|
||||||
|
pub fn floorf(x f32) f32 {
|
||||||
|
// TODO
|
||||||
|
return f32(floor(f64(x)))
|
||||||
|
/*
|
||||||
|
if x == 0 || is_nan(x) || is_inf(x, 0) {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
if x < 0 {
|
||||||
|
mut d, fract := modf(-x)
|
||||||
|
if fract != 0.0 {
|
||||||
|
d = d + 1
|
||||||
|
}
|
||||||
|
return -d
|
||||||
|
}
|
||||||
|
d, _ := modf(x)
|
||||||
|
return d
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
// ceil returns the least integer value greater than or equal to x.
|
// ceil returns the least integer value greater than or equal to x.
|
||||||
//
|
//
|
||||||
// special cases are:
|
// special cases are:
|
||||||
|
@ -416,6 +416,9 @@ pub:
|
|||||||
pre_comments []Comment
|
pre_comments []Comment
|
||||||
end_comments []Comment
|
end_comments []Comment
|
||||||
embeds []Embed
|
embeds []Embed
|
||||||
|
|
||||||
|
is_implements bool
|
||||||
|
implements_type Type
|
||||||
pub mut:
|
pub mut:
|
||||||
fields []StructField
|
fields []StructField
|
||||||
}
|
}
|
||||||
|
@ -328,6 +328,13 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
|||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Handle `implements` if it's present
|
||||||
|
if node.is_implements {
|
||||||
|
// XTODO2
|
||||||
|
// cgen error if I use `println(sym)` without handling the option with `or{}`
|
||||||
|
struct_type := c.table.find_type_idx(node.name) // or { panic(err) }
|
||||||
|
c.type_implements(struct_type, node.implements_type, node.pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn minify_sort_fn(a &ast.StructField, b &ast.StructField) int {
|
fn minify_sort_fn(a &ast.StructField, b &ast.StructField) int {
|
||||||
|
7
vlib/v/checker/tests/implements_keyword.out
Normal file
7
vlib/v/checker/tests/implements_keyword.out
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
vlib/v/checker/tests/implements_keyword.vv:5:1: error: `CustomError` doesn't implement method `print_error` of interface `MyError`
|
||||||
|
3 | }
|
||||||
|
4 |
|
||||||
|
5 | struct CustomError implements MyError {
|
||||||
|
| ~~~~~~~~~~~~~~~~~~
|
||||||
|
6 | }
|
||||||
|
7 |
|
9
vlib/v/checker/tests/implements_keyword.vv
Normal file
9
vlib/v/checker/tests/implements_keyword.vv
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
interface MyError {
|
||||||
|
print_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CustomError implements MyError {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (e CustomError) print_error2() {
|
||||||
|
}
|
@ -31,6 +31,10 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
|
|||||||
mut attr_align := new_field_align(use_threshold: true)
|
mut attr_align := new_field_align(use_threshold: true)
|
||||||
mut comment_align := new_field_align(use_threshold: true)
|
mut comment_align := new_field_align(use_threshold: true)
|
||||||
mut field_types := []string{cap: node.fields.len}
|
mut field_types := []string{cap: node.fields.len}
|
||||||
|
if node.is_implements {
|
||||||
|
f.write(' implements ')
|
||||||
|
f.write(f.table.type_to_str_using_aliases(node.implements_type, f.mod2alias))
|
||||||
|
}
|
||||||
// Calculate the alignments first
|
// Calculate the alignments first
|
||||||
f.calculate_alignment(node.fields, mut type_align, mut comment_align, mut default_expr_align, mut
|
f.calculate_alignment(node.fields, mut type_align, mut comment_align, mut default_expr_align, mut
|
||||||
attr_align, mut field_types)
|
attr_align, mut field_types)
|
||||||
|
@ -53,7 +53,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
|||||||
}
|
}
|
||||||
generic_types, _ := p.parse_generic_types()
|
generic_types, _ := p.parse_generic_types()
|
||||||
mut pre_comments := p.eat_comments()
|
mut pre_comments := p.eat_comments()
|
||||||
no_body := p.tok.kind != .lcbr
|
no_body := p.tok.kind != .lcbr && p.tok.kind != .key_implements
|
||||||
if language == .v && no_body {
|
if language == .v && no_body {
|
||||||
p.error('`${p.tok.lit}` lacks body')
|
p.error('`${p.tok.lit}` lacks body')
|
||||||
return ast.StructDecl{}
|
return ast.StructDecl{}
|
||||||
@ -93,9 +93,16 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
|||||||
mut is_field_mut := false
|
mut is_field_mut := false
|
||||||
mut is_field_pub := false
|
mut is_field_pub := false
|
||||||
mut is_field_global := false
|
mut is_field_global := false
|
||||||
|
mut is_implements := false
|
||||||
|
mut implements_type := ast.void_type
|
||||||
mut last_line := p.prev_tok.pos().line_nr + 1
|
mut last_line := p.prev_tok.pos().line_nr + 1
|
||||||
mut end_comments := []ast.Comment{}
|
mut end_comments := []ast.Comment{}
|
||||||
if !no_body {
|
if !no_body {
|
||||||
|
if p.tok.kind == .key_implements {
|
||||||
|
p.next()
|
||||||
|
implements_type = p.parse_type()
|
||||||
|
is_implements = true
|
||||||
|
}
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
pre_comments << p.eat_comments()
|
pre_comments << p.eat_comments()
|
||||||
mut i := 0
|
mut i := 0
|
||||||
@ -387,6 +394,8 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
|||||||
end_comments: end_comments
|
end_comments: end_comments
|
||||||
generic_types: generic_types
|
generic_types: generic_types
|
||||||
embeds: embeds
|
embeds: embeds
|
||||||
|
is_implements: is_implements
|
||||||
|
implements_type: implements_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,3 +463,23 @@ fn print_displayable(ds ...Displayable) {
|
|||||||
fn test_variadic_interface() {
|
fn test_variadic_interface() {
|
||||||
print_displayable(Text('test'), Text('hehe'))
|
print_displayable(Text('test'), Text('hehe'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MyError {
|
||||||
|
print_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CustomError implements MyError {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (e CustomError) print_error() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_implements(e MyError) {
|
||||||
|
// e.print_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_implements() {
|
||||||
|
// e := CustomError{}
|
||||||
|
// handle_implements(e)
|
||||||
|
println('implements ok')
|
||||||
|
}
|
||||||
|
@ -138,6 +138,7 @@ pub enum Kind {
|
|||||||
key_volatile
|
key_volatile
|
||||||
key_unsafe
|
key_unsafe
|
||||||
key_spawn
|
key_spawn
|
||||||
|
key_implements
|
||||||
keyword_end
|
keyword_end
|
||||||
_end_
|
_end_
|
||||||
}
|
}
|
||||||
@ -338,6 +339,7 @@ fn build_token_str() []string {
|
|||||||
s[Kind.key_offsetof] = '__offsetof'
|
s[Kind.key_offsetof] = '__offsetof'
|
||||||
s[Kind.key_is] = 'is'
|
s[Kind.key_is] = 'is'
|
||||||
s[Kind.key_spawn] = 'spawn'
|
s[Kind.key_spawn] = 'spawn'
|
||||||
|
s[Kind.key_implements] = 'implements'
|
||||||
// The following kinds are not for tokens returned by the V scanner.
|
// The following kinds are not for tokens returned by the V scanner.
|
||||||
// They are used just for organisation/ease of checking:
|
// They are used just for organisation/ease of checking:
|
||||||
s[Kind.keyword_beg] = 'keyword_beg'
|
s[Kind.keyword_beg] = 'keyword_beg'
|
||||||
@ -659,6 +661,7 @@ pub fn kind_to_string(k Kind) string {
|
|||||||
.key_volatile { 'key_volatile' }
|
.key_volatile { 'key_volatile' }
|
||||||
.key_unsafe { 'key_unsafe' }
|
.key_unsafe { 'key_unsafe' }
|
||||||
.key_spawn { 'key_spawn' }
|
.key_spawn { 'key_spawn' }
|
||||||
|
.key_implements { 'key_implements' }
|
||||||
.keyword_end { 'keyword_end' }
|
.keyword_end { 'keyword_end' }
|
||||||
._end_ { '_end_' }
|
._end_ { '_end_' }
|
||||||
.key_nil { 'key_nil' }
|
.key_nil { 'key_nil' }
|
||||||
@ -784,6 +787,7 @@ pub fn kind_from_string(s string) !Kind {
|
|||||||
'key_volatile' { .key_volatile }
|
'key_volatile' { .key_volatile }
|
||||||
'key_unsafe' { .key_unsafe }
|
'key_unsafe' { .key_unsafe }
|
||||||
'key_spawn' { .key_spawn }
|
'key_spawn' { .key_spawn }
|
||||||
|
'key_implements' { .key_implements }
|
||||||
'keyword_end' { .keyword_end }
|
'keyword_end' { .keyword_end }
|
||||||
'_end_' { ._end_ }
|
'_end_' { ._end_ }
|
||||||
else { error('unknown') }
|
else { error('unknown') }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user