v: support `$for attr in Test.attributes` (#9836)
parent
515e83dcbc
commit
fc3b628440
|
@ -121,3 +121,18 @@ pub:
|
||||||
is_mut bool
|
is_mut bool
|
||||||
typ int
|
typ int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum AttributeKind {
|
||||||
|
plain // [name]
|
||||||
|
string // ['name']
|
||||||
|
number // [123]
|
||||||
|
comptime_define // [if name]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StructAttribute {
|
||||||
|
pub:
|
||||||
|
name string
|
||||||
|
has_arg bool
|
||||||
|
arg string
|
||||||
|
kind AttributeKind
|
||||||
|
}
|
||||||
|
|
|
@ -786,6 +786,7 @@ pub:
|
||||||
pub enum CompForKind {
|
pub enum CompForKind {
|
||||||
methods
|
methods
|
||||||
fields
|
fields
|
||||||
|
attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CompFor {
|
pub struct CompFor {
|
||||||
|
|
|
@ -488,5 +488,6 @@ pub fn (e CompForKind) str() string {
|
||||||
match e {
|
match e {
|
||||||
.methods { return 'methods' }
|
.methods { return 'methods' }
|
||||||
.fields { return 'fields' }
|
.fields { return 'fields' }
|
||||||
|
.attributes { return 'attributes' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -468,6 +468,22 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
|
||||||
}
|
}
|
||||||
g.comptime_var_type_map.delete(node.val_var)
|
g.comptime_var_type_map.delete(node.val_var)
|
||||||
}
|
}
|
||||||
|
} else if node.kind == .attributes {
|
||||||
|
if sym.info is ast.Struct {
|
||||||
|
if sym.info.attrs.len > 0 {
|
||||||
|
g.writeln('\tStructAttribute $node.val_var = {0};')
|
||||||
|
}
|
||||||
|
for attr in sym.info.attrs {
|
||||||
|
g.writeln('/* attribute $i */ {')
|
||||||
|
|
||||||
|
g.writeln('\t${node.val_var}.name = _SLIT("$attr.name");')
|
||||||
|
g.writeln('\t${node.val_var}.has_arg = $attr.has_arg;')
|
||||||
|
g.writeln('\t${node.val_var}.arg = _SLIT("$attr.arg");')
|
||||||
|
g.writeln('\t${node.val_var}.kind = AttributeKind_$attr.kind;')
|
||||||
|
|
||||||
|
g.writeln('}')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g.indent--
|
g.indent--
|
||||||
g.writeln('}// \$for')
|
g.writeln('}// \$for')
|
||||||
|
|
|
@ -253,8 +253,15 @@ fn (mut p Parser) comp_for() ast.CompFor {
|
||||||
pos: var_pos
|
pos: var_pos
|
||||||
})
|
})
|
||||||
kind = .fields
|
kind = .fields
|
||||||
|
} else if for_val == 'attributes' {
|
||||||
|
p.scope.register(ast.Var{
|
||||||
|
name: val_var
|
||||||
|
typ: p.table.find_type_idx('StructAttribute')
|
||||||
|
pos: var_pos
|
||||||
|
})
|
||||||
|
kind = .attributes
|
||||||
} else {
|
} else {
|
||||||
p.error_with_pos('unknown kind `$for_val`, available are: `methods` or `fields`',
|
p.error_with_pos('unknown kind `$for_val`, available are: `methods`, `fields` or `attributes`',
|
||||||
p.prev_tok.position())
|
p.prev_tok.position())
|
||||||
return ast.CompFor{}
|
return ast.CompFor{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
[test: 'hello']
|
||||||
|
[abc]
|
||||||
|
struct Test {}
|
||||||
|
|
||||||
|
fn test_attributes() {
|
||||||
|
$for attr in Test.attributes {
|
||||||
|
if attr.has_arg {
|
||||||
|
assert attr.name == 'test'
|
||||||
|
assert attr.arg == 'hello'
|
||||||
|
} else {
|
||||||
|
assert attr.name == 'abc'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue