@@ -82,7 +82,7 @@ fn (p &Parser) is_array_type() bool {
8282}
8383
8484fn (mut p Parser) is_following_concrete_types () bool {
85- if ! (p.tok.kind in [.lt, . lsbr] && p.tok.is_next_to (p.prev_tok)) {
85+ if ! (p.tok.kind == . lsbr && p.tok.is_next_to (p.prev_tok)) {
8686 return false
8787 }
8888 mut i := 1
@@ -113,34 +113,30 @@ fn (mut p Parser) is_following_concrete_types() bool {
113113@[direct_array_access]
114114fn (p &Parser) is_generic_struct_init () bool {
115115 lit0_is_capital := p.tok.kind != .eof && p.tok.lit.len > 0 && p.tok.lit[0 ].is_capital ()
116- if ! lit0_ is_capital || p.peek_tok.kind ! in [.lt, . lsbr] {
116+ if ! lit0_ is_capital || p.peek_tok.kind != . lsbr {
117117 return false
118118 }
119- if p.peek_tok.kind == .lt {
120- return true
121- } else {
122- mut i := 2
123- mut nested_sbr_count := 0
124- for {
125- cur_tok := p.peek_token (i)
126- if cur_tok.kind == .eof
127- || cur_tok.kind ! in [.amp, .dot, .comma, .name, .lpar, .rpar, .lsbr, .rsbr, .key_fn] {
128- break
129- }
130- if cur_tok.kind == .lsbr {
131- nested_sbr_count++
132- } else if cur_tok.kind == .rsbr {
133- if nested_sbr_count > 0 {
134- nested_sbr_count--
135- } else {
136- if p.peek_token (i + 1 ).kind == .lcbr {
137- return true
138- }
139- break
119+ mut i := 2
120+ mut nested_sbr_count := 0
121+ for {
122+ cur_tok := p.peek_token (i)
123+ if cur_tok.kind == .eof
124+ || cur_tok.kind ! in [.amp, .dot, .comma, .name, .lpar, .rpar, .lsbr, .rsbr, .key_fn] {
125+ break
126+ }
127+ if cur_tok.kind == .lsbr {
128+ nested_sbr_count++
129+ } else if cur_tok.kind == .rsbr {
130+ if nested_sbr_count > 0 {
131+ nested_sbr_count--
132+ } else {
133+ if p.peek_token (i + 1 ).kind == .lcbr {
134+ return true
140135 }
136+ break
141137 }
142- i++
143138 }
139+ i++
144140 }
145141 return false
146142}
@@ -150,22 +146,22 @@ fn (p &Parser) is_typename(t token.Token) bool {
150146 return t.kind == .name && (t.lit[0 ].is_capital () || p.table.known_type (t.lit))
151147}
152148
153- // heuristics to detect `func<T> ()` from `var < expr`
154- // 1. `f<[ ]` is generic(e.g. `f<[ ]int> `) because `var < []` is invalid
155- // 2. `f< map[` is generic(e.g. `f< map[string]string> )
156- // 3. `f< foo> ` is generic because `v1 < foo > v2` is invalid syntax
157- // 4. `f< foo< bar` is generic when bar is not generic T (f< foo<T> (), in contrast, is not generic!)
158- // 5. `f< Foo,` is generic when Foo is typename.
159- // otherwise it is not generic because it may be multi-value (e.g. `return f < foo, 0`).
160- // 6. `f< mod.Foo> ` is same as case 3
161- // 7. `f< mod.Foo,` is same as case 5
149+ // heuristics to detect `func[T] ()` from `var [ expr`
150+ // 1. `f[[ ]` is generic(e.g. `f[[ ]int] `) because `var [ []` is invalid
151+ // 2. `f[ map[` is generic(e.g. `f[ map[string]string] )
152+ // 3. `f[ foo] ` is generic because `v1 [ foo ] v2` is invalid syntax
153+ // 4. `f[ foo[ bar` is generic when bar is not generic T (f[ foo[T] (), in contrast, is not generic!)
154+ // 5. `f[ Foo,` is generic when Foo is typename.
155+ // otherwise it is not generic because it may be multi-value (e.g. `return f [ foo, 0`).
156+ // 6. `f[ mod.Foo] ` is same as case 3
157+ // 7. `f[ mod.Foo,` is same as case 5
162158// 8. if there is a &, ignore the & and see if it is a type
163159// 9. otherwise, it's not generic
164160// see also test_generic_detection in vlib/v/tests/generics_test.v
165161@[direct_array_access]
166162fn (p &Parser) is_generic_call () bool {
167163 lit0_is_capital := p.tok.kind != .eof && p.tok.lit.len > 0 && p.tok.lit[0 ].is_capital ()
168- if lit0_ is_capital || p.peek_tok.kind ! in [.lt, . lsbr] {
164+ if lit0_ is_capital || p.peek_tok.kind != . lsbr {
169165 return false
170166 }
171167 mut tok2 := p.peek_token (2 )
@@ -194,16 +190,7 @@ fn (p &Parser) is_generic_call() bool {
194190 // case 2
195191 return true
196192 }
197- if p.peek_tok.kind == .lt {
198- return match kind3 {
199- .gt { true } // case 3
200- .lt { ! (tok4 .lit.len == 1 && tok4 .lit[0 ].is_capital ()) } // case 4
201- .comma { p.is_typename (tok2 ) } // case 5
202- // case 6 and 7
203- .dot { kind4 == .name && (kind5 == .gt || (kind5 == .comma && p.is_typename (tok4 ))) }
204- else { false }
205- }
206- } else if p.peek_tok.kind == .lsbr {
193+ if p.peek_tok.kind == .lsbr {
207194 mut i := 3
208195 mut nested_sbr_count := 0
209196 for {
@@ -237,7 +224,7 @@ fn (p &Parser) is_generic_call() bool {
237224 return false
238225}
239226
240- const valid_tokens_inside_types = [token.Kind.lsbr, .rsbr, .name, .dot, .comma, .key_fn, .lt ]
227+ const valid_tokens_inside_types = [token.Kind.lsbr, .rsbr, .name, .dot, .comma, .key_fn]
241228
242229fn (mut p Parser) is_generic_cast () bool {
243230 if ! ast.type_can_start_with_token (& p.tok) {
@@ -250,10 +237,10 @@ fn (mut p Parser) is_generic_cast() bool {
250237 i++
251238 tok := p.peek_token (i)
252239
253- if tok.kind in [.lt, . lsbr] {
240+ if tok.kind == . lsbr {
254241 lt_count++
255242 level++
256- } else if tok.kind in [.gt, . rsbr] {
243+ } else if tok.kind == . rsbr {
257244 level--
258245 }
259246 if lt_count > 0 && level == 0 {
@@ -265,10 +252,10 @@ fn (mut p Parser) is_generic_cast() bool {
265252 }
266253 }
267254 next_tok := p.peek_token (i + 1 )
268- // `next_tok` is the token following the closing `> ` of the generic type: MyType< int> {
255+ // `next_tok` is the token following the closing `] ` of the generic type: MyType[ int] {
269256 // ^
270257 // if `next_tok` is a left paren, then the full expression looks something like
271- // `Foo< string> (` or `Foo< mod.Type> (`, which are valid type casts - return true
258+ // `Foo[ string] (` or `Foo[ mod.Type] (`, which are valid type casts - return true
272259 if next_tok.kind == .lpar {
273260 return true
274261 }
0 commit comments