all: fn args => params
							parent
							
								
									e2c7126d11
								
							
						
					
					
						commit
						fca344d1fb
					
				| 
						 | 
				
			
			@ -238,7 +238,7 @@ pub struct FnDecl {
 | 
			
		|||
pub:
 | 
			
		||||
	name          string
 | 
			
		||||
	mod           string
 | 
			
		||||
	args          []table.Param
 | 
			
		||||
	params        []table.Param
 | 
			
		||||
	is_deprecated bool
 | 
			
		||||
	is_pub        bool
 | 
			
		||||
	is_variadic   bool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
 | 
			
		|||
		f.write('<T>')
 | 
			
		||||
	}
 | 
			
		||||
	f.write('(')
 | 
			
		||||
	for i, arg in node.args {
 | 
			
		||||
	for i, arg in node.params {
 | 
			
		||||
		// skip receiver
 | 
			
		||||
		// if (node.is_method || node.is_interface) && i == 0 {
 | 
			
		||||
		if node.is_method && i == 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -63,9 +63,9 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
 | 
			
		|||
		if arg.is_hidden {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		is_last_arg := i == node.args.len - 1
 | 
			
		||||
		should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ ||
 | 
			
		||||
			(node.is_variadic && i == node.args.len - 2)
 | 
			
		||||
		is_last_arg := i == node.params.len - 1
 | 
			
		||||
		should_add_type := is_last_arg || node.params[i + 1].typ != arg.typ ||
 | 
			
		||||
			(node.is_variadic && i == node.params.len - 2)
 | 
			
		||||
		if arg.is_mut {
 | 
			
		||||
			f.write(arg.typ.share().str() + ' ')
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,14 +118,14 @@ pub fn (mut c Checker) check_matching_function_symbols(got_type_sym, exp_type_sy
 | 
			
		|||
	exp_fn := exp_info.func
 | 
			
		||||
	// we are using check() to compare return type & args as they might include
 | 
			
		||||
	// functions themselves. TODO: optimize, only use check() when needed
 | 
			
		||||
	if got_fn.args.len != exp_fn.args.len {
 | 
			
		||||
	if got_fn.params.len != exp_fn.params.len {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if !c.check_basic(got_fn.return_type, exp_fn.return_type) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i, got_arg in got_fn.args {
 | 
			
		||||
		exp_arg := exp_fn.args[i]
 | 
			
		||||
	for i, got_arg in got_fn.params {
 | 
			
		||||
		exp_arg := exp_fn.params[i]
 | 
			
		||||
		exp_arg_is_ptr := exp_arg.typ.is_ptr() || exp_arg.typ.is_pointer()
 | 
			
		||||
		got_arg_is_ptr := got_arg.typ.is_ptr() || got_arg.typ.is_pointer()
 | 
			
		||||
		if exp_arg_is_ptr != got_arg_is_ptr {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -199,7 +199,7 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
 | 
			
		|||
					if stmt.is_pub {
 | 
			
		||||
						c.error('function `main` cannot be declared public', stmt.pos)
 | 
			
		||||
					}
 | 
			
		||||
					if stmt.args.len > 0 {
 | 
			
		||||
					if stmt.params.len > 0 {
 | 
			
		||||
						c.error('function `main` cannot have arguments', stmt.pos)
 | 
			
		||||
					}
 | 
			
		||||
					if stmt.return_type != table.void_type {
 | 
			
		||||
| 
						 | 
				
			
			@ -297,7 +297,7 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
 | 
			
		|||
			if ret_sym.kind == .placeholder {
 | 
			
		||||
				c.error("type `$ret_sym.source_name` doesn't exist", node.pos)
 | 
			
		||||
			}
 | 
			
		||||
			for arg in fn_info.args {
 | 
			
		||||
			for arg in fn_info.params {
 | 
			
		||||
				arg_sym := c.table.get_type_symbol(arg.typ)
 | 
			
		||||
				if arg_sym.kind == .placeholder {
 | 
			
		||||
					c.error("type `$arg_sym.source_name` doesn't exist", node.pos)
 | 
			
		||||
| 
						 | 
				
			
			@ -979,14 +979,14 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e
 | 
			
		|||
	elem_sym := c.table.get_type_symbol(elem_typ)
 | 
			
		||||
	match call_expr.args[0].expr as arg_expr {
 | 
			
		||||
		ast.AnonFn {
 | 
			
		||||
			if arg_expr.decl.args.len > 1 {
 | 
			
		||||
			if arg_expr.decl.params.len > 1 {
 | 
			
		||||
				c.error('function needs exactly 1 argument', call_expr.pos)
 | 
			
		||||
			} else if is_map &&
 | 
			
		||||
				(arg_expr.decl.return_type != elem_typ || arg_expr.decl.args[0].typ != elem_typ) {
 | 
			
		||||
				(arg_expr.decl.return_type != elem_typ || arg_expr.decl.params[0].typ != elem_typ) {
 | 
			
		||||
				c.error('type mismatch, should use `fn(a $elem_sym.source_name) $elem_sym.source_name {...}`',
 | 
			
		||||
					call_expr.pos)
 | 
			
		||||
			} else if !is_map &&
 | 
			
		||||
				(arg_expr.decl.return_type != table.bool_type || arg_expr.decl.args[0].typ != elem_typ) {
 | 
			
		||||
				(arg_expr.decl.return_type != table.bool_type || arg_expr.decl.params[0].typ != elem_typ) {
 | 
			
		||||
				c.error('type mismatch, should use `fn(a $elem_sym.source_name) bool {...}`',
 | 
			
		||||
					call_expr.pos)
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -997,13 +997,13 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e
 | 
			
		|||
					c.error('$arg_expr.name is not exist', arg_expr.pos)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				if func.args.len > 1 {
 | 
			
		||||
				if func.params.len > 1 {
 | 
			
		||||
					c.error('function needs exactly 1 argument', call_expr.pos)
 | 
			
		||||
				} else if is_map && (func.return_type != elem_typ || func.args[0].typ != elem_typ) {
 | 
			
		||||
				} else if is_map && (func.return_type != elem_typ || func.params[0].typ != elem_typ) {
 | 
			
		||||
					c.error('type mismatch, should use `fn(a $elem_sym.source_name) $elem_sym.source_name {...}`',
 | 
			
		||||
						call_expr.pos)
 | 
			
		||||
				} else if !is_map &&
 | 
			
		||||
					(func.return_type != table.bool_type || func.args[0].typ != elem_typ) {
 | 
			
		||||
					(func.return_type != table.bool_type || func.params[0].typ != elem_typ) {
 | 
			
		||||
					c.error('type mismatch, should use `fn(a $elem_sym.source_name) bool {...}`',
 | 
			
		||||
						call_expr.pos)
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1121,7 +1121,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
			// println('warn $method_name lef.mod=$left_type_sym.mod c.mod=$c.mod')
 | 
			
		||||
			c.error('method `${left_type_sym.source_name}.$method_name` is private', call_expr.pos)
 | 
			
		||||
		}
 | 
			
		||||
		if method.args[0].is_mut {
 | 
			
		||||
		if method.params[0].is_mut {
 | 
			
		||||
			c.fail_if_immutable(call_expr.left)
 | 
			
		||||
			// call_expr.is_mut = true
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1129,8 +1129,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
			method.ctdefine.len > 0 && method.ctdefine !in c.pref.compile_defines {
 | 
			
		||||
			call_expr.should_be_skipped = true
 | 
			
		||||
		}
 | 
			
		||||
		nr_args := if method.args.len == 0 { 0 } else { method.args.len - 1 }
 | 
			
		||||
		min_required_args := method.args.len - if method.is_variadic && method.args.len > 1 { 2 } else { 1 }
 | 
			
		||||
		nr_args := if method.params.len == 0 { 0 } else { method.params.len - 1 }
 | 
			
		||||
		min_required_args := method.params.len - if method.is_variadic && method.params.len > 1 { 2 } else { 1 }
 | 
			
		||||
		if call_expr.args.len < min_required_args {
 | 
			
		||||
			c.error('too few arguments in call to `${left_type_sym.source_name}.$method_name` ($call_expr.args.len instead of $min_required_args)',
 | 
			
		||||
				call_expr.pos)
 | 
			
		||||
| 
						 | 
				
			
			@ -1145,8 +1145,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
		// call_expr.args << method.args[0].typ
 | 
			
		||||
		// call_expr.exp_arg_types << method.args[0].typ
 | 
			
		||||
		for i, arg in call_expr.args {
 | 
			
		||||
			exp_arg_typ := if method.is_variadic && i >= method.args.len - 1 { method.args[method.args.len -
 | 
			
		||||
					1].typ } else { method.args[i + 1].typ }
 | 
			
		||||
			exp_arg_typ := if method.is_variadic && i >= method.params.len - 1 { method.params[method.params.len -
 | 
			
		||||
					1].typ } else { method.params[i + 1].typ }
 | 
			
		||||
			exp_arg_sym := c.table.get_type_symbol(exp_arg_typ)
 | 
			
		||||
			c.expected_type = exp_arg_typ
 | 
			
		||||
			got_arg_typ := c.expr(arg.expr)
 | 
			
		||||
| 
						 | 
				
			
			@ -1176,8 +1176,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
						call_expr.pos)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			param := if method.is_variadic && i >= method.args.len - 1 { method.args[method.args.len -
 | 
			
		||||
					1] } else { method.args[i + 1] }
 | 
			
		||||
			param := if method.is_variadic && i >= method.params.len - 1 { method.params[method.params.len -
 | 
			
		||||
					1] } else { method.params[i + 1] }
 | 
			
		||||
			if arg.is_mut {
 | 
			
		||||
				c.fail_if_immutable(arg.expr)
 | 
			
		||||
				if !param.is_mut {
 | 
			
		||||
| 
						 | 
				
			
			@ -1201,16 +1201,16 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
		}
 | 
			
		||||
		// TODO: typ optimize.. this node can get processed more than once
 | 
			
		||||
		if call_expr.expected_arg_types.len == 0 {
 | 
			
		||||
			for i in 1 .. method.args.len {
 | 
			
		||||
				call_expr.expected_arg_types << method.args[i].typ
 | 
			
		||||
			for i in 1 .. method.params.len {
 | 
			
		||||
				call_expr.expected_arg_types << method.params[i].typ
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if is_generic {
 | 
			
		||||
			// We need the receiver to be T in cgen.
 | 
			
		||||
			// TODO: cant we just set all these to the concrete type in checker? then no need in gen
 | 
			
		||||
			call_expr.receiver_type = left_type.derive(method.args[0].typ).set_flag(.generic)
 | 
			
		||||
			call_expr.receiver_type = left_type.derive(method.params[0].typ).set_flag(.generic)
 | 
			
		||||
		} else {
 | 
			
		||||
			call_expr.receiver_type = method.args[0].typ
 | 
			
		||||
			call_expr.receiver_type = method.params[0].typ
 | 
			
		||||
		}
 | 
			
		||||
		call_expr.return_type = method.return_type
 | 
			
		||||
		return method.return_type
 | 
			
		||||
| 
						 | 
				
			
			@ -1399,12 +1399,12 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
		}
 | 
			
		||||
		return f.return_type
 | 
			
		||||
	}
 | 
			
		||||
	min_required_args := if f.is_variadic { f.args.len - 1 } else { f.args.len }
 | 
			
		||||
	min_required_args := if f.is_variadic { f.params.len - 1 } else { f.params.len }
 | 
			
		||||
	if call_expr.args.len < min_required_args {
 | 
			
		||||
		c.error('too few arguments in call to `$fn_name` ($call_expr.args.len instead of $min_required_args)',
 | 
			
		||||
			call_expr.pos)
 | 
			
		||||
	} else if !f.is_variadic && call_expr.args.len > f.args.len {
 | 
			
		||||
		c.error('too many arguments in call to `$fn_name` ($call_expr.args.len instead of $f.args.len)',
 | 
			
		||||
	} else if !f.is_variadic && call_expr.args.len > f.params.len {
 | 
			
		||||
		c.error('too many arguments in call to `$fn_name` ($call_expr.args.len instead of $f.params.len)',
 | 
			
		||||
			call_expr.pos)
 | 
			
		||||
		return f.return_type
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1433,12 +1433,12 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
	}
 | 
			
		||||
	// TODO: typ optimize.. this node can get processed more than once
 | 
			
		||||
	if call_expr.expected_arg_types.len == 0 {
 | 
			
		||||
		for arg in f.args {
 | 
			
		||||
			call_expr.expected_arg_types << arg.typ
 | 
			
		||||
		for param in f.params {
 | 
			
		||||
			call_expr.expected_arg_types << param.typ
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for i, call_arg in call_expr.args {
 | 
			
		||||
		arg := if f.is_variadic && i >= f.args.len - 1 { f.args[f.args.len - 1] } else { f.args[i] }
 | 
			
		||||
		arg := if f.is_variadic && i >= f.params.len - 1 { f.params[f.params.len - 1] } else { f.params[i] }
 | 
			
		||||
		c.expected_type = arg.typ
 | 
			
		||||
		typ := c.expr(call_arg.expr)
 | 
			
		||||
		call_expr.args[i].typ = typ
 | 
			
		||||
| 
						 | 
				
			
			@ -3946,7 +3946,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
 | 
			
		|||
	}
 | 
			
		||||
	if node.language == .v {
 | 
			
		||||
		// Make sure all types are valid
 | 
			
		||||
		for arg in node.args {
 | 
			
		||||
		for arg in node.params {
 | 
			
		||||
			sym := c.table.get_type_symbol(arg.typ)
 | 
			
		||||
			if sym.kind == .placeholder {
 | 
			
		||||
				c.error('unknown type `$sym.source_name`', node.pos)
 | 
			
		||||
| 
						 | 
				
			
			@ -3957,12 +3957,12 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
 | 
			
		|||
		if node.return_type != table.string_type {
 | 
			
		||||
			c.error('.str() methods should return `string`', node.pos)
 | 
			
		||||
		}
 | 
			
		||||
		if node.args.len != 1 {
 | 
			
		||||
		if node.params.len != 1 {
 | 
			
		||||
			c.error('.str() methods should have 0 arguments', node.pos)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// TODO c.pref.is_vet
 | 
			
		||||
	if node.language == .v && !node.is_method && node.args.len == 0 && node.return_type == table.void_type_idx &&
 | 
			
		||||
	if node.language == .v && !node.is_method && node.params.len == 0 && node.return_type == table.void_type_idx &&
 | 
			
		||||
		node.name.after('.').starts_with('test_') && !c.file.path.ends_with('_test.v') {
 | 
			
		||||
		// simple heuristic
 | 
			
		||||
		for st in node.stmts {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -575,9 +575,9 @@ static inline void __${styp}_pushval($styp ch, $el_stype val) {
 | 
			
		|||
						c_name(func.name)
 | 
			
		||||
					}
 | 
			
		||||
					g.type_definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(')
 | 
			
		||||
					for i, arg in func.args {
 | 
			
		||||
						g.type_definitions.write(g.typ(arg.typ))
 | 
			
		||||
						if i < func.args.len - 1 {
 | 
			
		||||
					for i, param in func.params {
 | 
			
		||||
						g.type_definitions.write(g.typ(param.typ))
 | 
			
		||||
						if i < func.params.len - 1 {
 | 
			
		||||
							g.type_definitions.write(',')
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -1302,8 +1302,8 @@ fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) {
 | 
			
		|||
fn (mut g Gen) write_fn_ptr_decl(func &table.FnType, ptr_name string) {
 | 
			
		||||
	ret_styp := g.typ(func.func.return_type)
 | 
			
		||||
	g.write('$ret_styp (*$ptr_name) (')
 | 
			
		||||
	arg_len := func.func.args.len
 | 
			
		||||
	for i, arg in func.func.args {
 | 
			
		||||
	arg_len := func.func.params.len
 | 
			
		||||
	for i, arg in func.func.params {
 | 
			
		||||
		arg_styp := g.typ(arg.typ)
 | 
			
		||||
		g.write('$arg_styp $arg.name')
 | 
			
		||||
		if i < arg_len - 1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -1521,7 +1521,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
 | 
			
		|||
				ret_styp := g.typ(val.decl.return_type)
 | 
			
		||||
				g.write('$ret_styp (*$ident.name) (')
 | 
			
		||||
				def_pos := g.definitions.len
 | 
			
		||||
				g.fn_args(val.decl.args, val.decl.is_variadic)
 | 
			
		||||
				g.fn_args(val.decl.params, val.decl.is_variadic)
 | 
			
		||||
				g.definitions.go_back(g.definitions.len - def_pos)
 | 
			
		||||
				g.write(') = ')
 | 
			
		||||
				g.expr(*val)
 | 
			
		||||
| 
						 | 
				
			
			@ -1601,7 +1601,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
 | 
			
		|||
				ret_styp := g.typ(func.func.return_type)
 | 
			
		||||
				g.write('$ret_styp (*${g.get_ternary_name(ident.name)}) (')
 | 
			
		||||
				def_pos := g.definitions.len
 | 
			
		||||
				g.fn_args(func.func.args, func.func.is_variadic)
 | 
			
		||||
				g.fn_args(func.func.params, func.func.is_variadic)
 | 
			
		||||
				g.definitions.go_back(g.definitions.len - def_pos)
 | 
			
		||||
				g.write(')')
 | 
			
		||||
			} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -2279,7 +2279,7 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) {
 | 
			
		|||
		info := sym.info as table.FnType
 | 
			
		||||
		fn_info := info.func
 | 
			
		||||
		mut repr := 'fn ('
 | 
			
		||||
		for i, arg in fn_info.args {
 | 
			
		||||
		for i, arg in fn_info.params {
 | 
			
		||||
			if i > 0 {
 | 
			
		||||
				repr += ', '
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -3873,8 +3873,8 @@ fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
 | 
			
		|||
		func := value_sym.info as table.FnType
 | 
			
		||||
		ret_styp := g.typ(func.func.return_type)
 | 
			
		||||
		g.definitions.write('\t\t$ret_styp (*v) (')
 | 
			
		||||
		arg_len := func.func.args.len
 | 
			
		||||
		for i, arg in func.func.args {
 | 
			
		||||
		arg_len := func.func.params.len
 | 
			
		||||
		for i, arg in func.func.params {
 | 
			
		||||
			arg_styp := g.typ(arg.typ)
 | 
			
		||||
			g.definitions.write('$arg_styp $arg.name')
 | 
			
		||||
			if i < arg_len - 1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -3938,7 +3938,7 @@ fn (mut g Gen) write_init_function() {
 | 
			
		|||
		g.write(g.inits[mod_name].str())
 | 
			
		||||
		init_fn_name := '${mod_name}.init'
 | 
			
		||||
		if initfn := g.table.find_fn(init_fn_name) {
 | 
			
		||||
			if initfn.return_type == table.void_type && initfn.args.len == 0 {
 | 
			
		||||
			if initfn.return_type == table.void_type && initfn.params.len == 0 {
 | 
			
		||||
				mod_c_name := util.no_dots(mod_name)
 | 
			
		||||
				init_fn_c_name := '${mod_c_name}__init'
 | 
			
		||||
				g.writeln('\t${init_fn_c_name}();')
 | 
			
		||||
| 
						 | 
				
			
			@ -5124,8 +5124,8 @@ fn (mut g Gen) interface_table() string {
 | 
			
		|||
			ret_styp := g.typ(method.return_type)
 | 
			
		||||
			methods_typ_def.write('typedef $ret_styp (*$typ_name)(void* _')
 | 
			
		||||
			// the first param is the receiver, it's handled by `void*` above
 | 
			
		||||
			for i in 1 .. method.args.len {
 | 
			
		||||
				arg := method.args[i]
 | 
			
		||||
			for i in 1 .. method.params.len {
 | 
			
		||||
				arg := method.params[i]
 | 
			
		||||
				methods_typ_def.write(', ${g.typ(arg.typ)} $arg.name')
 | 
			
		||||
			}
 | 
			
		||||
			// TODO g.fn_args(method.args[1..], method.is_variadic)
 | 
			
		||||
| 
						 | 
				
			
			@ -5184,14 +5184,14 @@ _Interface* I_${cctype}_to_Interface_${interface_name}_ptr($cctype* x) {
 | 
			
		|||
				}
 | 
			
		||||
				// .speak = Cat_speak
 | 
			
		||||
				mut method_call := '${cctype}_$method.name'
 | 
			
		||||
				if !method.args[0].typ.is_ptr() {
 | 
			
		||||
				if !method.params[0].typ.is_ptr() {
 | 
			
		||||
					// inline void Cat_speak_method_wrapper(Cat c) { return Cat_speak(*c); }
 | 
			
		||||
					methods_wrapper.write('static inline ${g.typ(method.return_type)}')
 | 
			
		||||
					methods_wrapper.write(' ${method_call}_method_wrapper(')
 | 
			
		||||
					methods_wrapper.write('$cctype* ${method.args[0].name}')
 | 
			
		||||
					methods_wrapper.write('$cctype* ${method.params[0].name}')
 | 
			
		||||
					// TODO g.fn_args
 | 
			
		||||
					for j in 1 .. method.args.len {
 | 
			
		||||
						arg := method.args[j]
 | 
			
		||||
					for j in 1 .. method.params.len {
 | 
			
		||||
						arg := method.params[j]
 | 
			
		||||
						methods_wrapper.write(', ${g.typ(arg.typ)} $arg.name')
 | 
			
		||||
					}
 | 
			
		||||
					methods_wrapper.writeln(') {')
 | 
			
		||||
| 
						 | 
				
			
			@ -5199,9 +5199,9 @@ _Interface* I_${cctype}_to_Interface_${interface_name}_ptr($cctype* x) {
 | 
			
		|||
					if method.return_type != table.void_type {
 | 
			
		||||
						methods_wrapper.write('return ')
 | 
			
		||||
					}
 | 
			
		||||
					methods_wrapper.write('${method_call}(*${method.args[0].name}')
 | 
			
		||||
					for j in 1 .. method.args.len {
 | 
			
		||||
						methods_wrapper.write(', ${method.args[j].name}')
 | 
			
		||||
					methods_wrapper.write('${method_call}(*${method.params[0].name}')
 | 
			
		||||
					for j in 1 .. method.params.len {
 | 
			
		||||
						methods_wrapper.write(', ${method.params[j].name}')
 | 
			
		||||
					}
 | 
			
		||||
					methods_wrapper.writeln(');')
 | 
			
		||||
					methods_wrapper.writeln('}')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,24 +40,24 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
 | 
			
		|||
		*/
 | 
			
		||||
		g.write('${util.no_dots(node.sym.name)}_${g.comp_for_method}(')
 | 
			
		||||
		g.expr(node.left)
 | 
			
		||||
		if m.args.len > 1 {
 | 
			
		||||
		if m.params.len > 1 {
 | 
			
		||||
			g.write(', ')
 | 
			
		||||
		}
 | 
			
		||||
		for i in 1 .. m.args.len {
 | 
			
		||||
		for i in 1 .. m.params.len {
 | 
			
		||||
			if node.left is ast.Ident {
 | 
			
		||||
				left_name := node.left as ast.Ident
 | 
			
		||||
				if m.args[i].name == left_name.name {
 | 
			
		||||
				if m.params[i].name == left_name.name {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if m.args[i].typ.is_int() || m.args[i].typ.idx() == table.bool_type_idx {
 | 
			
		||||
			if m.params[i].typ.is_int() || m.params[i].typ.idx() == table.bool_type_idx {
 | 
			
		||||
				// Gets the type name and cast the string to the type with the string_<type> function
 | 
			
		||||
				type_name := g.table.types[int(m.args[i].typ)].str()
 | 
			
		||||
				type_name := g.table.types[int(m.params[i].typ)].str()
 | 
			
		||||
				g.write('string_${type_name}(((string*)${node.args_var}.data) [${i-1}])')
 | 
			
		||||
			} else {
 | 
			
		||||
				g.write('((string*)${node.args_var}.data) [${i-1}] ')
 | 
			
		||||
			}
 | 
			
		||||
			if i < m.args.len - 1 {
 | 
			
		||||
			if i < m.params.len - 1 {
 | 
			
		||||
				g.write(', ')
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
 | 
			
		|||
		if method.return_type != result_type {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if method.args.len != 1 {
 | 
			
		||||
		if method.params.len != 1 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// receiver := method.args[0]
 | 
			
		||||
| 
						 | 
				
			
			@ -221,14 +221,14 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
 | 
			
		|||
				g.writeln('\t${node.val_var}.attrs = new_array_from_c_array($attrs.len, $attrs.len, sizeof(string), _MOV((string[$attrs.len]){' +
 | 
			
		||||
					attrs.join(', ') + '}));')
 | 
			
		||||
			}
 | 
			
		||||
			if method.args.len < 2 {
 | 
			
		||||
			if method.params.len < 2 {
 | 
			
		||||
				// 0 or 1 (the receiver) args
 | 
			
		||||
				g.writeln('\t${node.val_var}.args = __new_array_with_default(0, 0, sizeof(MethodArgs), 0);')
 | 
			
		||||
			} else {
 | 
			
		||||
				len := method.args.len - 1
 | 
			
		||||
				len := method.params.len - 1
 | 
			
		||||
				g.write('\t${node.val_var}.args = new_array_from_c_array($len, $len, sizeof(MethodArgs), _MOV((MethodArgs[$len]){')
 | 
			
		||||
				// Skip receiver arg
 | 
			
		||||
				for j, arg in method.args[1..] {
 | 
			
		||||
				for j, arg in method.params[1..] {
 | 
			
		||||
					typ := arg.typ.idx()
 | 
			
		||||
					g.write(typ.str())
 | 
			
		||||
					if j < len - 1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -240,11 +240,11 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
 | 
			
		|||
			}
 | 
			
		||||
			mut sig := 'anon_fn_'
 | 
			
		||||
			// skip the first (receiver) arg
 | 
			
		||||
			for j, arg in method.args[1..] {
 | 
			
		||||
			for j, arg in method.params[1..] {
 | 
			
		||||
				// TODO: ignore mut/pts in sig for now
 | 
			
		||||
				typ := arg.typ.set_nr_muls(0)
 | 
			
		||||
				sig += '$typ'
 | 
			
		||||
				if j < method.args.len - 2 {
 | 
			
		||||
				if j < method.params.len - 2 {
 | 
			
		||||
					sig += '_'
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,7 +109,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
 | 
			
		|||
		g.write(fn_header)
 | 
			
		||||
	}
 | 
			
		||||
	arg_start_pos := g.out.len
 | 
			
		||||
	fargs, fargtypes := g.fn_args(it.args, it.is_variadic)
 | 
			
		||||
	fargs, fargtypes := g.fn_args(it.params, it.is_variadic)
 | 
			
		||||
	arg_str := g.out.after(arg_start_pos)
 | 
			
		||||
	if it.no_body || (g.pref.use_cache && it.is_builtin) || skip {
 | 
			
		||||
		// Just a function header. Builtin function bodies are defined in builtin.o
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +235,7 @@ fn (mut g Gen) fn_args(args []table.Param, is_variadic bool) ([]string, []string
 | 
			
		|||
			} else {
 | 
			
		||||
				g.write('${g.typ(func.return_type)} (*$caname)(')
 | 
			
		||||
				g.definitions.write('${g.typ(func.return_type)} (*$caname)(')
 | 
			
		||||
				g.fn_args(func.args, func.is_variadic)
 | 
			
		||||
				g.fn_args(func.params, func.is_variadic)
 | 
			
		||||
				g.write(')')
 | 
			
		||||
				g.definitions.write(')')
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -275,7 +275,7 @@ pub fn (mut g JsGen) typ(t table.Type) string {
 | 
			
		|||
		// 'anon_fn_7_7_1' => '(a number, b number) => void'
 | 
			
		||||
		.function {
 | 
			
		||||
			info := sym.info as table.FnType
 | 
			
		||||
			styp = g.fn_typ(info.func.args, info.func.return_type)
 | 
			
		||||
			styp = g.fn_typ(info.func.params, info.func.return_type)
 | 
			
		||||
		}
 | 
			
		||||
		.interface_ {
 | 
			
		||||
			styp = g.js_name(sym.name)
 | 
			
		||||
| 
						 | 
				
			
			@ -874,7 +874,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
 | 
			
		|||
			g.push_pub_var(name)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	mut args := it.args
 | 
			
		||||
	mut args := it.params
 | 
			
		||||
	if it.is_method {
 | 
			
		||||
		args = args[1..]
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -882,7 +882,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
 | 
			
		|||
	g.writeln(') {')
 | 
			
		||||
	if it.is_method {
 | 
			
		||||
		g.inc_indent()
 | 
			
		||||
		g.writeln('const ${it.args[0].name} = this;')
 | 
			
		||||
		g.writeln('const ${it.params[0].name} = this;')
 | 
			
		||||
		g.dec_indent()
 | 
			
		||||
	}
 | 
			
		||||
	g.stmts(it.stmts)
 | 
			
		||||
| 
						 | 
				
			
			@ -1489,7 +1489,7 @@ fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) {
 | 
			
		|||
		info := sym.info as table.FnType
 | 
			
		||||
		fn_info := info.func
 | 
			
		||||
		mut repr := 'fn ('
 | 
			
		||||
		for i, arg in fn_info.args {
 | 
			
		||||
		for i, arg in fn_info.params {
 | 
			
		||||
			if i > 0 {
 | 
			
		||||
				repr += ', '
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,12 +58,12 @@ fn (mut d JsDoc) gen_fn(it ast.FnDecl) {
 | 
			
		|||
	if it.is_deprecated {
 | 
			
		||||
		d.writeln(' * @deprecated')
 | 
			
		||||
	}
 | 
			
		||||
	for i, arg in it.args {
 | 
			
		||||
	for i, arg in it.params {
 | 
			
		||||
		if (it.is_method || it.receiver.typ == 0) && i == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		arg_type_name := d.gen.typ(arg.typ)
 | 
			
		||||
		is_varg := i == it.args.len - 1 && it.is_variadic
 | 
			
		||||
		is_varg := i == it.params.len - 1 && it.is_variadic
 | 
			
		||||
		name := d.gen.js_name(arg.name)
 | 
			
		||||
		if is_varg {
 | 
			
		||||
			d.writeln(' * @param {...$arg_type_name} $name')
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ fn (mut d JsDoc) gen_interface(it ast.InterfaceDecl) {
 | 
			
		|||
	d.writeln(' * @typedef $name')
 | 
			
		||||
	for method in it.methods {
 | 
			
		||||
		// Skip receiver
 | 
			
		||||
		typ := d.gen.fn_typ(method.args[1..], method.return_type)
 | 
			
		||||
		typ := d.gen.fn_typ(method.params[1..], method.return_type)
 | 
			
		||||
		method_name := d.gen.js_name(method.name)
 | 
			
		||||
		d.writeln(' * @property {$typ} $method_name')
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -834,13 +834,13 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
 | 
			
		|||
	// if !is_main {
 | 
			
		||||
	g.sub8(.rsp, 0x10)
 | 
			
		||||
	// }
 | 
			
		||||
	if node.args.len > 0 {
 | 
			
		||||
	if node.params.len > 0 {
 | 
			
		||||
		// g.mov(.r12, 0x77777777)
 | 
			
		||||
	}
 | 
			
		||||
	// Copy values from registers to local vars (calling convention)
 | 
			
		||||
	mut offset := 0
 | 
			
		||||
	for i in 0 .. node.args.len {
 | 
			
		||||
		name := node.args[i].name
 | 
			
		||||
	for i in 0 .. node.params.len {
 | 
			
		||||
		name := node.params[i].name
 | 
			
		||||
		// TODO optimize. Right now 2 mov's are used instead of 1.
 | 
			
		||||
		g.allocate_var(name, 4, 0)
 | 
			
		||||
		// `mov DWORD PTR [rbp-0x4],edi`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,7 +178,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
			
		|||
	mut receiver_pos := token.Position{}
 | 
			
		||||
	mut rec_type := table.void_type
 | 
			
		||||
	mut rec_mut := false
 | 
			
		||||
	mut args := []table.Param{}
 | 
			
		||||
	mut params := []table.Param{}
 | 
			
		||||
	if p.tok.kind == .lpar {
 | 
			
		||||
		p.next() // (
 | 
			
		||||
		is_method = true
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +217,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
			
		|||
			rec_type = rec_type.set_flag(.atomic_f)
 | 
			
		||||
		}
 | 
			
		||||
		sym := p.table.get_type_symbol(rec_type)
 | 
			
		||||
		args << table.Param{
 | 
			
		||||
		params << table.Param{
 | 
			
		||||
			pos: rec_start_pos
 | 
			
		||||
			name: rec_name
 | 
			
		||||
			is_mut: rec_mut
 | 
			
		||||
| 
						 | 
				
			
			@ -252,16 +252,16 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
			
		|||
	}
 | 
			
		||||
	// Args
 | 
			
		||||
	args2, are_args_type_only, is_variadic := p.fn_args()
 | 
			
		||||
	args << args2
 | 
			
		||||
	for arg in args {
 | 
			
		||||
		if p.scope.known_var(arg.name) {
 | 
			
		||||
			p.error_with_pos('redefinition of parameter `$arg.name`', arg.pos)
 | 
			
		||||
	params << args2
 | 
			
		||||
	for param in params {
 | 
			
		||||
		if p.scope.known_var(param.name) {
 | 
			
		||||
			p.error_with_pos('redefinition of parameter `$param.name`', param.pos)
 | 
			
		||||
		}
 | 
			
		||||
		p.scope.register(arg.name, ast.Var{
 | 
			
		||||
			name: arg.name
 | 
			
		||||
			typ: arg.typ
 | 
			
		||||
			is_mut: arg.is_mut
 | 
			
		||||
			pos: arg.pos
 | 
			
		||||
		p.scope.register(param.name, ast.Var{
 | 
			
		||||
			name: param.name
 | 
			
		||||
			typ: param.typ
 | 
			
		||||
			is_mut: param.is_mut
 | 
			
		||||
			pos: param.pos
 | 
			
		||||
			is_used: true
 | 
			
		||||
			is_arg: true
 | 
			
		||||
		})
 | 
			
		||||
| 
						 | 
				
			
			@ -281,7 +281,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
			
		|||
		// p.warn('reg method $type_sym.name . $name ()')
 | 
			
		||||
		type_sym.register_method(table.Fn{
 | 
			
		||||
			name: name
 | 
			
		||||
			args: args
 | 
			
		||||
			params: params
 | 
			
		||||
			return_type: return_type
 | 
			
		||||
			return_type_source_name: ret_type_sym.source_name
 | 
			
		||||
			is_variadic: is_variadic
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +307,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
			
		|||
		ret_type_sym := p.table.get_type_symbol(return_type)
 | 
			
		||||
		p.table.register_fn(table.Fn{
 | 
			
		||||
			name: name
 | 
			
		||||
			args: args
 | 
			
		||||
			params: params
 | 
			
		||||
			return_type: return_type
 | 
			
		||||
			return_type_source_name: ret_type_sym.source_name
 | 
			
		||||
			is_variadic: is_variadic
 | 
			
		||||
| 
						 | 
				
			
			@ -337,7 +337,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
			
		|||
		mod: p.mod
 | 
			
		||||
		stmts: stmts
 | 
			
		||||
		return_type: return_type
 | 
			
		||||
		args: args
 | 
			
		||||
		params: params
 | 
			
		||||
		is_deprecated: is_deprecated
 | 
			
		||||
		is_direct_arr: is_direct_arr
 | 
			
		||||
		is_pub: is_pub
 | 
			
		||||
| 
						 | 
				
			
			@ -388,7 +388,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
 | 
			
		|||
	p.close_scope()
 | 
			
		||||
	ret_type_sym := p.table.get_type_symbol(return_type)
 | 
			
		||||
	mut func := table.Fn{
 | 
			
		||||
		args: args
 | 
			
		||||
		params: args
 | 
			
		||||
		is_variadic: is_variadic
 | 
			
		||||
		return_type: return_type
 | 
			
		||||
		return_type_source_name: ret_type_sym.source_name
 | 
			
		||||
| 
						 | 
				
			
			@ -404,7 +404,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
 | 
			
		|||
			mod: p.mod
 | 
			
		||||
			stmts: stmts
 | 
			
		||||
			return_type: return_type
 | 
			
		||||
			args: args
 | 
			
		||||
			params: args
 | 
			
		||||
			is_variadic: is_variadic
 | 
			
		||||
			is_method: false
 | 
			
		||||
			is_anon: true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ pub fn (mut p Parser) parse_fn_type(name string) table.Type {
 | 
			
		|||
	ret_type_sym := p.table.get_type_symbol(return_type)
 | 
			
		||||
	func := table.Fn{
 | 
			
		||||
		name: name
 | 
			
		||||
		args: args
 | 
			
		||||
		params: args
 | 
			
		||||
		is_variadic: is_variadic
 | 
			
		||||
		return_type: return_type
 | 
			
		||||
		return_type_source_name: ret_type_sym.source_name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -396,7 +396,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
 | 
			
		|||
		mut method := ast.FnDecl{
 | 
			
		||||
			name: name
 | 
			
		||||
			mod: p.mod
 | 
			
		||||
			args: args
 | 
			
		||||
			params: args
 | 
			
		||||
			file: p.file_name
 | 
			
		||||
			return_type: table.void_type
 | 
			
		||||
			is_pub: true
 | 
			
		||||
| 
						 | 
				
			
			@ -410,7 +410,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
 | 
			
		|||
		return_type_sym := p.table.get_type_symbol(method.return_type)
 | 
			
		||||
		ts.register_method(table.Fn{
 | 
			
		||||
			name: name
 | 
			
		||||
			args: args
 | 
			
		||||
			params: args
 | 
			
		||||
			return_type: method.return_type
 | 
			
		||||
			return_type_source_name: return_type_sym.source_name
 | 
			
		||||
			is_pub: true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -852,13 +852,13 @@ pub fn (table &Table) type_to_str(t Type) string {
 | 
			
		|||
pub fn (t &Table) fn_to_str(func &Fn) string {
 | 
			
		||||
	mut sb := strings.new_builder(20)
 | 
			
		||||
	sb.write('${func.name}(')
 | 
			
		||||
	for i in 1 .. func.args.len {
 | 
			
		||||
		arg := func.args[i]
 | 
			
		||||
		sb.write('$arg.name')
 | 
			
		||||
		if i == func.args.len - 1 || func.args[i + 1].typ != arg.typ {
 | 
			
		||||
			sb.write(' ${t.type_to_str(arg.typ)}')
 | 
			
		||||
	for i in 1 .. func.params.len {
 | 
			
		||||
		param := func.params[i]
 | 
			
		||||
		sb.write('$param.name')
 | 
			
		||||
		if i == func.params.len - 1 || func.params[i + 1].typ != param.typ {
 | 
			
		||||
			sb.write(' ${t.type_to_str(param.typ)}')
 | 
			
		||||
		}
 | 
			
		||||
		if i != func.args.len - 1 {
 | 
			
		||||
		if i != func.params.len - 1 {
 | 
			
		||||
			sb.write(', ')
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -891,9 +891,9 @@ pub fn (t &TypeSymbol) str_method_info() (bool, bool, int) {
 | 
			
		|||
	mut nr_args := 0
 | 
			
		||||
	if sym_str_method := t.find_method('str') {
 | 
			
		||||
		has_str_method = true
 | 
			
		||||
		nr_args = sym_str_method.args.len
 | 
			
		||||
		nr_args = sym_str_method.params.len
 | 
			
		||||
		if nr_args > 0 {
 | 
			
		||||
			expects_ptr = sym_str_method.args[0].typ.is_ptr()
 | 
			
		||||
			expects_ptr = sym_str_method.params[0].typ.is_ptr()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return has_str_method, expects_ptr, nr_args
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ pub mut:
 | 
			
		|||
 | 
			
		||||
pub struct Fn {
 | 
			
		||||
pub:
 | 
			
		||||
	args                    []Param
 | 
			
		||||
	params                  []Param
 | 
			
		||||
	return_type             Type
 | 
			
		||||
	return_type_source_name string
 | 
			
		||||
	is_variadic             bool
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ pub fn new_table() &Table {
 | 
			
		|||
// used to compare fn's & for naming anon fn's
 | 
			
		||||
pub fn (f &Fn) signature() string {
 | 
			
		||||
	mut sig := ''
 | 
			
		||||
	for i, arg in f.args {
 | 
			
		||||
	for i, arg in f.params {
 | 
			
		||||
		// TODO: for now ignore mut/pts in sig for now
 | 
			
		||||
		typ := arg.typ.set_nr_muls(0)
 | 
			
		||||
		// if arg.is_mut {
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ pub fn (f &Fn) signature() string {
 | 
			
		|||
		// }
 | 
			
		||||
		// sig += '$arg.typ'
 | 
			
		||||
		sig += '$typ'
 | 
			
		||||
		if i < f.args.len - 1 {
 | 
			
		||||
		if i < f.params.len - 1 {
 | 
			
		||||
			sig += '_'
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -85,12 +85,12 @@ pub fn (f &Fn) signature() string {
 | 
			
		|||
// source_signature generates the signature of a function which looks like in the V source
 | 
			
		||||
pub fn (f &Fn) source_signature() string {
 | 
			
		||||
	mut sig := '('
 | 
			
		||||
	for i, arg in f.args {
 | 
			
		||||
	for i, arg in f.params {
 | 
			
		||||
		if arg.is_mut {
 | 
			
		||||
			sig += 'mut '
 | 
			
		||||
		}
 | 
			
		||||
		sig += '$arg.type_source_name'
 | 
			
		||||
		if i < f.args.len - 1 {
 | 
			
		||||
		if i < f.params.len - 1 {
 | 
			
		||||
			sig += ', '
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -102,11 +102,11 @@ pub fn (f &Fn) is_same_method_as(func &Fn) bool {
 | 
			
		|||
	if f.return_type != func.return_type {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if f.args.len != func.args.len {
 | 
			
		||||
	if f.params.len != func.params.len {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i in 1 .. f.args.len {
 | 
			
		||||
		if f.args[i].typ != func.args[i].typ {
 | 
			
		||||
	for i in 1 .. f.params.len {
 | 
			
		||||
		if f.params[i].typ != func.params[i].typ {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue