v: fix for `import cli { Command }`

pull/5937/head
Ryan Willis 2020-07-22 10:33:43 -07:00 committed by GitHub
parent ee349691f9
commit 938e71b468
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 1 deletions

View File

@ -955,6 +955,10 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
// if exp_arg_sym.kind == .string && got_arg_sym.has_method('str') { // if exp_arg_sym.kind == .string && got_arg_sym.has_method('str') {
// continue // continue
// } // }
// same ancestor? let it be
if exp_arg_sym.parent_idx == got_arg_sym.parent_idx {
continue
}
if got_arg_typ != table.void_type { if got_arg_typ != table.void_type {
c.error('cannot use type `$got_arg_sym.str()` as type `$exp_arg_sym.str()` in argument ${i+1} to `${left_type_sym.name}.$method_name`', c.error('cannot use type `$got_arg_sym.str()` as type `$exp_arg_sym.str()` in argument ${i+1} to `${left_type_sym.name}.$method_name`',
call_expr.pos) call_expr.pos)

View File

@ -3011,7 +3011,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
g.go_back_out(3) g.go_back_out(3)
return return
} }
sym := g.table.get_type_symbol(struct_init.typ) sym := g.table.get_final_type_symbol(struct_init.typ)
is_amp := g.is_amp is_amp := g.is_amp
is_multiline := struct_init.fields.len > 5 is_multiline := struct_init.fields.len > 5
g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly

View File

@ -926,12 +926,14 @@ pub fn (mut p Parser) name_expr() ast.Expr {
mut is_mod_cast := false mut is_mod_cast := false
if p.peek_tok.kind == .dot && !known_var && if p.peek_tok.kind == .dot && !known_var &&
(language != .v || p.known_import(p.tok.lit) || p.mod.all_after_last('.') == p.tok.lit) { (language != .v || p.known_import(p.tok.lit) || p.mod.all_after_last('.') == p.tok.lit) {
// p.tok.lit has been recognized as a module
if language == .c { if language == .c {
mod = 'C' mod = 'C'
} else if language == .js { } else if language == .js {
mod = 'JS' mod = 'JS'
} else { } else {
if p.tok.lit in p.imports { if p.tok.lit in p.imports {
// mark the imported module as used
p.register_used_import(p.tok.lit) p.register_used_import(p.tok.lit)
if p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital() { if p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital() {
is_mod_cast = true is_mod_cast = true

View File

@ -197,6 +197,22 @@ pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
panic('get_type_symbol: invalid type (typ=$typ idx=${idx}). Compiler bug. This should never happen') panic('get_type_symbol: invalid type (typ=$typ idx=${idx}). Compiler bug. This should never happen')
} }
// get_final_type_symbol follows aliases until it gets to a "real" Type
[inline]
pub fn (t &Table) get_final_type_symbol(typ Type) &TypeSymbol {
idx := typ.idx()
if idx > 0 {
current_type := t.types[idx]
if current_type.kind == .alias {
alias_info := current_type.info as Alias
return t.get_final_type_symbol(alias_info.parent_type)
}
return &t.types[idx]
}
// this should never happen
panic('get_final_type_symbol: invalid type (typ=$typ idx=${idx}). Compiler bug. This should never happen')
}
[inline] [inline]
pub fn (t &Table) get_type_name(typ Type) string { pub fn (t &Table) get_type_name(typ Type) string {
typ_sym := t.get_type_symbol(typ) typ_sym := t.get_type_symbol(typ)

View File

@ -6,6 +6,7 @@ import log as l
import time as t { now, utc, Time } import time as t { now, utc, Time }
import math import math
import crypto.sha512 import crypto.sha512
import cli { Command }
struct TestAliasInStruct { struct TestAliasInStruct {
time t.Time time t.Time
@ -24,6 +25,17 @@ fn test_import() {
assert t.utc().unix_time() == utc().unix_time() assert t.utc().unix_time() == utc().unix_time()
} }
fn test_imports_array_as_fn_arg() {
mut cmd := Command {
name: 'module test'
}
c1 := Command{}
c2 := Command{
name: 'cmd2'
}
cmd.add_commands([c1, c2])
}
fn test_alias_in_struct_field() { fn test_alias_in_struct_field() {
a := TestAliasInStruct{ a := TestAliasInStruct{
time: t.Time{ time: t.Time{