fmt: fix `map[string][]string`; parser: allow `foo<int>(10)`

pull/4967/head
Alexander Medvednikov 2020-05-20 21:39:59 +02:00
parent e3a162db77
commit 82cedbaf62
5 changed files with 31 additions and 15 deletions

View File

@ -476,8 +476,8 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
fn (f &Fmt) type_to_str(t table.Type) string {
mut res := f.table.type_to_str(t)
// type_ptr => &type
if res.ends_with('_ptr') {
// type_ptr => &type
res = res[0..res.len - 4]
start_pos := 2 * res.count('[]')
res = res[0..start_pos] + '&' + res[start_pos..res.len]

View File

@ -21,10 +21,16 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
}
mut is_or_block_used := false
if fn_name == 'json.decode' {
p.expecting_type = true // Makes name_expr() parse the type (`User` in `json.decode(User, txt)`)`
p.expecting_type = true // Makes name_expr() parse the type `User` in `json.decode(User, txt)`
p.expr_mod = ''
is_or_block_used = true
}
if p.tok.kind == .lt {
// `foo<int>(10)`
p.next() // `<`
p.parse_type()
p.check(.gt) // `>`
}
p.check(.lpar)
args := p.call_args()
last_pos := p.tok.position()

View File

@ -803,7 +803,8 @@ pub fn (mut p Parser) name_expr() ast.Expr {
}
// p.warn('name expr $p.tok.lit $p.peek_tok.str()')
// fn call or type cast
if p.peek_tok.kind == .lpar {
if p.peek_tok.kind == .lpar || (p.peek_tok.kind == .lt && p.peek_tok.pos == p.peek_tok2.pos -
1) { // foo() or foo<int>()
mut name := p.tok.lit
if mod.len > 0 {
name = '${mod}.$name'

View File

@ -15,7 +15,8 @@ import strings
pub type Type int
pub type TypeInfo = Alias | Array | ArrayFixed | Enum | FnType | Interface | Map | MultiReturn | Struct | SumType
pub type TypeInfo = Alias | Array | ArrayFixed | Enum | FnType | Interface | Map | MultiReturn |
Struct | SumType
pub enum Language {
v
@ -490,6 +491,11 @@ pub fn (mut t Table) register_builtin_type_symbols() {
mod: 'builtin'
parent_idx: map_string_int_idx
})
t.register_type_symbol(TypeSymbol{
kind: .any
name: 'T'
mod: 'builtin'
})
}
[inline]
@ -629,6 +635,7 @@ pub:
variants []Type
}
// TODO simplify this method
pub fn (table &Table) type_to_str(t Type) string {
sym := table.get_type_symbol(t)
mut res := sym.name
@ -649,7 +656,8 @@ pub fn (table &Table) type_to_str(t Type) string {
}
if sym.kind == .array || 'array_' in res {
res = res.replace('array_', '[]')
} else if sym.kind == .map || 'map_string_' in res {
}
if sym.kind == .map || 'map_string_' in res {
res = res.replace('map_string_', 'map[string]')
}
// mod.submod.submod2.Type => submod2.Type

View File

@ -8,13 +8,14 @@ import v.cflag
pub struct Table {
pub mut:
types []TypeSymbol
type_idxs map[string]int
fns map[string]Fn
imports []string // List of all imports
modules []string // List of all modules registered by the application
cflags []cflag.CFlag
redefined_fns []string
types []TypeSymbol
type_idxs map[string]int
fns map[string]Fn
imports []string // List of all imports
modules []string // List of all modules registered by the application
cflags []cflag.CFlag
redefined_fns []string
fn_gen_types map[string][]string
}
pub struct Fn {
@ -467,9 +468,9 @@ pub fn (t &Table) check(got, expected Type) bool {
got_idx in number_type_idxs) {
return true
}
//if exp_idx in pointer_type_idxs && got_idx in pointer_type_idxs {
//return true
//}
// if exp_idx in pointer_type_idxs && got_idx in pointer_type_idxs {
// return true
// }
// see hack in checker IndexExpr line #691
if (got_idx == byte_type_idx && exp_idx == byteptr_type_idx) || (exp_idx == byte_type_idx &&
got_idx == byteptr_type_idx) {