diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 5cc56005b3..fe8d197d4c 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -384,6 +384,7 @@ pub: cond Expr stmts []Stmt pos token.Position + comment Comment } pub struct MatchExpr { @@ -392,6 +393,7 @@ pub: cond Expr branches []MatchBranch pos token.Position + is_mut bool // `match mut ast_node {` mut: is_expr bool // returns a value return_type table.Type @@ -405,6 +407,7 @@ pub: exprs []Expr stmts []Stmt pos token.Position + comment Comment // comment above `xxx {` } pub struct CompIf { diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index e0cc9322e6..25d4d16800 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -38,11 +38,18 @@ pub fn (node &FnDecl) str(t &table.Table) string { should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || (node.is_variadic && i == node.args.len - 2) f.write(arg.name) + mut s := t.type_to_str(arg.typ) + if arg.is_mut { + f.write(' mut') + if s.starts_with('&') { + s = s[1..] + } + } if should_add_type { if node.is_variadic && is_last_arg { - f.write(' ...' + t.type_to_str(arg.typ)) + f.write(' ...' + s) } else { - f.write(' ' + t.type_to_str(arg.typ)) + f.write(' ' + s) } } if !is_last_arg { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index a1bb8a6553..38c30bed88 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -28,14 +28,12 @@ mut: fn_return_type table.Type // current function's return type const_decl string const_deps []string - //assigned_var_name string - // fn_decl ast.FnDecl pref &pref.Preferences // Preferences shared from V struct in_for_count int // if checker is currently in an for loop } pub fn new_checker(table &table.Table, pref &pref.Preferences) Checker { - return Checker{ + return checker.Checker{ table: table pref: pref } @@ -119,7 +117,8 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type { } } if !found_field { - c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos) + c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', + struct_init.pos) continue } } @@ -128,7 +127,8 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type { expr_type_sym := c.table.get_type_symbol(expr_type) field_type_sym := c.table.get_type_symbol(field.typ) if !c.table.check(expr_type, field.typ) { - c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$field.name`', struct_init.pos) + c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$field.name`', + struct_init.pos) } struct_init.expr_types << expr_type struct_init.expected_types << field.typ @@ -160,7 +160,7 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type { left := c.table.get_type_symbol(left_type) if infix_expr.op == .left_shift { if left.kind != .array && !left.is_int() { - //c.error('<< can only be used with numbers and arrays', infix_expr.pos) + // c.error('<< can only be used with numbers and arrays', infix_expr.pos) c.error('incompatible types: $left.name << $right.name', infix_expr.pos) return table.void_type } @@ -224,7 +224,8 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { left_type_sym := c.table.get_type_symbol(left_type) method_name := call_expr.name // TODO: remove this for actual methods, use only for compiler magic - if left_type_sym.kind == .array && method_name in ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice'] { + if left_type_sym.kind == .array && method_name in ['filter', 'clone', 'repeat', 'reverse', 'map', + 'slice'] { if method_name in ['filter', 'map'] { array_info := left_type_sym.info as table.Array mut scope := c.file.scope.innermost(call_expr.pos.pos) @@ -239,13 +240,11 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { // in ['clone', 'str'] { call_expr.receiver_type = table.type_to_ptr(left_type) // call_expr.return_type = call_expr.receiver_type - } - else { + } else { call_expr.receiver_type = left_type } return left_type - } - else if left_type_sym.kind == .array && method_name in ['first', 'last'] { + } else if left_type_sym.kind == .array && method_name in ['first', 'last'] { info := left_type_sym.info as table.Array call_expr.return_type = info.elem_type call_expr.receiver_type = left_type @@ -255,10 +254,11 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { no_args := method.args.len - 1 min_required_args := method.args.len - if method.is_variadic && method.args.len > 1 { 2 } else { 1 } if call_expr.args.len < min_required_args { - c.error('too few arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $min_required_args)', call_expr.pos) - } - else if !method.is_variadic && call_expr.args.len > no_args { - c.error('too many arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $no_args)', call_expr.pos) + c.error('too few arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $min_required_args)', + call_expr.pos) + } else if !method.is_variadic && call_expr.args.len > no_args { + c.error('too many arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $no_args)', + call_expr.pos) return method.return_type } // if method_name == 'clone' { @@ -267,7 +267,11 @@ pub fn (c mut Checker) call_expr(call_expr mut 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 { - c.expected_type = if method.is_variadic && i >= method.args.len - 1 { method.args[method.args.len - 1].typ } else { method.args[i + 1].typ } + c.expected_type = if method.is_variadic && i >= method.args.len - 1 { + method.args[method.args.len - 1].typ + } else { + method.args[i + 1].typ + } call_expr.args[i].typ = c.expr(arg.expr) } // TODO: typ optimize.. this node can get processed more than once @@ -293,8 +297,7 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { } c.error('unknown method: ${left_type_sym.name}.$method_name', call_expr.pos) return table.void_type - } - else { + } else { fn_name := call_expr.name // TODO: impl typeof properly (probably not going to be a fn call) if fn_name == 'typeof' { @@ -346,10 +349,11 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { } min_required_args := if f.is_variadic { f.args.len - 1 } else { f.args.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)', call_expr.pos) + 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)', + call_expr.pos) return f.return_type } // println can print anything @@ -379,9 +383,11 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { if typ_sym.kind == .void && arg_typ_sym.kind == .string { continue } - if typ_sym.kind == .array_fixed {} + if typ_sym.kind == .array_fixed { + } // println('fixed') - c.error('cannot use type `$typ_sym.str()` as type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`', call_expr.pos) + c.error('cannot use type `$typ_sym.str()` as type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`', + call_expr.pos) } } return f.return_type @@ -409,8 +415,7 @@ pub fn (c mut Checker) selector_expr(selector_expr mut ast.SelectorExpr) table.T } if typ_sym.kind != .struct_ { c.error('`$typ_sym.name` is not a struct', selector_expr.pos) - } - else { + } else { c.error('unknown field `${typ_sym.name}.$field_name`', selector_expr.pos) } return table.void_type @@ -453,13 +458,14 @@ pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) { if !c.table.check(got_typ, exp_typ) { got_typ_sym := c.table.get_type_symbol(got_typ) exp_typ_sym := c.table.get_type_symbol(exp_typ) - c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument', return_stmt.pos) + c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument', + return_stmt.pos) } } } pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) { - c.expected_type = table.none_type // TODO a hack to make `x := if ... work` + c.expected_type = table.none_type // TODO a hack to make `x := if ... work` // multi return if assign_stmt.left.len > assign_stmt.right.len { match assign_stmt.right[0] { @@ -467,7 +473,7 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) { else { c.error('assign_stmt: expected call', assign_stmt.pos) } - } + } right_type := c.expr(assign_stmt.right[0]) right_type_sym := c.table.get_type_symbol(right_type) mr_info := right_type_sym.mr_info() @@ -494,9 +500,8 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) { assign_stmt.right_types << val_type scope.update_var_type(ident.name, val_type) } - } - // `a := 1` | `a,b := 1,2` - else { + } else { + // `a := 1` | `a,b := 1,2` if assign_stmt.left.len != assign_stmt.right.len { c.error('wrong number of vars', assign_stmt.pos) } @@ -504,7 +509,7 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) { for i, _ in assign_stmt.left { mut ident := assign_stmt.left[i] mut ident_var_info := ident.var_info() - //c.assigned_var_name = ident.name + // c.assigned_var_name = ident.name val_type := c.expr(assign_stmt.right[i]) if assign_stmt.op == .assign { var_type := c.expr(ident) @@ -523,7 +528,7 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) { } } c.expected_type = table.void_type - //c.assigned_var_name = '' + // c.assigned_var_name = '' } pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { @@ -542,8 +547,8 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { } // TODO: seperate errors once bug is fixed with `x := if expr { ... } else { ... }` // if c.expected_type == table.void_type { - // c.error('array_init: use `[]Type` instead of `[]`', array_init.pos) - // return table.void_type + // c.error('array_init: use `[]Type` instead of `[]`', array_init.pos) + // return table.void_type // } array_info := type_sym.array_info() array_init.elem_type = array_info.elem_type @@ -567,9 +572,8 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { idx := c.table.find_or_register_array(elem_type, 1) array_init.typ = table.new_type(idx) array_init.elem_type = elem_type - } - // [50]byte - else if array_init.exprs.len == 1 && array_init.elem_type != table.void_type { + } else if array_init.exprs.len == 1 && array_init.elem_type != table.void_type { + // [50]byte mut fixed_size := 1 match array_init.exprs[0] { ast.IntegerLiteral { @@ -578,7 +582,7 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { else { c.error('expecting `int` for fixed size', array_init.pos) } - } + } idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size, 1) array_type := table.new_type(idx) array_init.typ = array_type @@ -655,12 +659,12 @@ fn (c mut Checker) stmt(node ast.Stmt) { c.expected_type = table.void_type } ast.FnDecl { - //if it.is_method { - //sym := c.table.get_type_symbol(it.receiver.typ) - //if sym.has_method(it.name) { - //c.warn('duplicate method `$it.name`', it.pos) - //} - //} + // if it.is_method { + // sym := c.table.get_type_symbol(it.receiver.typ) + // if sym.has_method(it.name) { + // c.warn('duplicate method `$it.name`', it.pos) + // } + // } c.expected_type = table.void_type c.fn_return_type = it.return_type c.stmts(it.stmts) @@ -690,17 +694,17 @@ fn (c mut Checker) stmt(node ast.Stmt) { typ := c.expr(it.cond) if it.is_range { c.expr(it.high) - } - else { + } else { mut scope := c.file.scope.innermost(it.pos.pos) sym := c.table.get_type_symbol(typ) if it.key_var.len > 0 { key_type := match sym.kind { - .map{ + .map { sym.map_info().key_type } else { - table.int_type} + table.int_type + } } it.key_type = key_type scope.update_var_type(it.key_var, key_type) @@ -718,12 +722,12 @@ fn (c mut Checker) stmt(node ast.Stmt) { c.stmts(it.stmts) c.in_for_count-- } - ast.GoStmt{ + ast.GoStmt { c.expr(it.call_expr) } - // ast.GlobalDecl {} // ast.HashStmt {} ast.Import {} + // ast.GlobalDecl {} ast.Return { c.return_stmt(mut it) } @@ -731,10 +735,10 @@ fn (c mut Checker) stmt(node ast.Stmt) { ast.UnsafeStmt { c.stmts(it.stmts) } - else {} - // println('checker.stmt(): unhandled node') - // println('checker.stmt(): unhandled node (${typeof(node)})') - // } + else { + // println('checker.stmt(): unhandled node') + // println('checker.stmt(): unhandled node (${typeof(node)})') + } } } @@ -761,8 +765,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { c.error('cannot cast `$expr_type_sym.name` to `$type_sym.name`', it.pos) // c.error('only $info.variants can be casted to `$typ`', it.pos) } - } - else { + } else { c.error('cannot cast non sum type `$type_sym.name` using `as`', it.pos) } return it.typ @@ -909,17 +912,14 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type { if ident.kind == .variable { info := ident.info as ast.IdentVar return info.typ - } - else if ident.kind == .constant { + } else if ident.kind == .constant { info := ident.info as ast.IdentVar return info.typ - } - else if ident.kind == .function { + } else if ident.kind == .function { info := ident.info as ast.IdentFn return info.typ - } - // first use - else if ident.kind == .unresolved { + } else if ident.kind == .unresolved { + // first use start_scope := c.file.scope.innermost(ident.pos.pos) if obj := start_scope.find(ident.name) { match obj { @@ -1009,7 +1009,8 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type { typ := c.expr(expr) typ_sym := c.table.get_type_symbol(typ) // TODO: - if typ_sym.kind == .sum_type {} + if typ_sym.kind == .sum_type { + } } c.stmts(branch.stmts) // If the last statement is an expression, return its type @@ -1018,14 +1019,15 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type { ast.ExprStmt { ret_type = c.expr(it.expr) } - // TODO: ask alex about this - // typ := c.expr(it.expr) - // type_sym := c.table.get_type_symbol(typ) - // p.warn('match expr ret $type_sym.name') - // node.typ = typ - // return typ - else {} - } + else { + // TODO: ask alex about this + // typ := c.expr(it.expr) + // type_sym := c.table.get_type_symbol(typ) + // p.warn('match expr ret $type_sym.name') + // node.typ = typ + // return typ + } + } } } // if ret_type != table.void_type { @@ -1039,19 +1041,21 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type { } pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type { - if c.expected_type != table.void_type { // || c.assigned_var_name != '' { - //sym := c.table.get_type_symbol(c.expected_type) - //println('$c.file.path $node.pos.line_nr IF is expr: checker exp type = ' + sym.name) + if c.expected_type != table.void_type { + // | c.assigned_var_name != '' { + // sym := c.table.get_type_symbol(c.expected_type) + // println('$c.file.path $node.pos.line_nr IF is expr: checker exp type = ' + sym.name) node.is_expr = true } node.typ = table.void_type for i, branch in node.branches { match branch.cond { ast.ParExpr { - c.error('unnecessary `()` in an if condition. use `if expr {` instead of `if (expr) {`.', node.pos) + c.error('unnecessary `()` in an if condition. use `if expr {` instead of `if (expr) {`.', + node.pos) } else {} - } + } typ := c.expr(branch.cond) if i < node.branches.len - 1 || !node.has_else { typ_sym := c.table.get_type_symbol(typ) @@ -1074,7 +1078,7 @@ pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type { return t } else {} - } + } } } return table.bool_type @@ -1088,7 +1092,7 @@ pub fn (c mut Checker) postfix_expr(node ast.PostfixExpr) table.Type { } else {} } - */ +*/ typ := c.expr(node.expr) typ_sym := c.table.get_type_symbol(typ) // if !table.is_number(typ) { @@ -1102,7 +1106,7 @@ pub fn (c mut Checker) postfix_expr(node ast.PostfixExpr) table.Type { pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { typ := c.expr(node.left) node.left_type = typ - mut is_range := false // TODO is_range := node.index is ast.RangeExpr + mut is_range := false // TODO is_range := node.index is ast.RangeExpr match node.index { ast.RangeExpr { is_range = true @@ -1122,18 +1126,17 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { // println('index expr left=$typ_sym.name $node.pos.line_nr') // if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) && // index_type_sym.kind != .enum_) { - if typ_sym.kind in [.array, .array_fixed] && !(table.is_number(index_type) || index_type_sym.kind == .enum_) { + if typ_sym.kind in [.array, .array_fixed] && !(table.is_number(index_type) || index_type_sym.kind == + .enum_) { c.error('non-integer index `$index_type_sym.name` (array type `$typ_sym.name`)', node.pos) - } - else if typ_sym.kind == .map && table.type_idx(index_type) != table.string_type_idx { + } else if typ_sym.kind == .map && table.type_idx(index_type) != table.string_type_idx { c.error('non-string map index (map type `$typ_sym.name`)', node.pos) } value_type := c.table.value_type(typ) if value_type != table.void_type { return value_type } - } - else if is_range { + } else if is_range { // array[1..2] => array // fixed_array[1..2] => array if typ_sym.kind == .array_fixed { @@ -1149,8 +1152,11 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { // If a short form is used, `expected_type` needs to be an enum // with this value. pub fn (c mut Checker) enum_val(node mut ast.EnumVal) table.Type { - typ_idx := if node.enum_name == '' { table.type_idx(c.expected_type) } else { // - c.table.find_type_idx(node.enum_name) } + typ_idx := if node.enum_name == '' { + table.type_idx(c.expected_type) + } else { // + c.table.find_type_idx(node.enum_name) + } // println('checker: enum_val: $node.enum_name typeidx=$typ_idx') if typ_idx == 0 { c.error('not an enum (name=$node.enum_name) (type_idx=0)', node.pos) @@ -1209,8 +1215,8 @@ pub fn (c mut Checker) map_init(node mut ast.MapInit) table.Type { } pub fn (c mut Checker) warn(s string, pos token.Position) { - allow_warnings := !c.pref.is_prod // allow warnings only in dev builds - c.warn_or_error(s, pos, allow_warnings) // allow warnings only in dev builds + allow_warnings := !c.pref.is_prod // allow warnings only in dev builds + c.warn_or_error(s, pos, allow_warnings) // allow warnings only in dev builds } pub fn (c mut Checker) error(s string, pos token.Position) { @@ -1221,16 +1227,12 @@ fn (c mut Checker) warn_or_error(s string, pos token.Position, warn bool) { if !warn { c.nr_errors++ } - //if c.pref.is_verbose { + // if c.pref.is_verbose { if c.pref.is_verbose { print_backtrace() } typ := if warn { 'warning' } else { 'error' } - kind := if c.pref.is_verbose { - 'checker $typ #$c.nr_errors:' - } else { - '$typ:' - } + kind := if c.pref.is_verbose { 'checker $typ #$c.nr_errors:' } else { '$typ:' } ferror := util.formated_error(kind, s, c.file.path, pos) c.errors << ferror if !(pos.line_nr in c.error_lines) { diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 92dbf4f07a..76e2bd1c92 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -10,8 +10,7 @@ import ( ) const ( - tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', - '\t\t\t\t\t\t\t'] + tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t'] max_len = 100 ) @@ -25,8 +24,8 @@ mut: single_line_if bool cur_mod string file ast.File - did_imports bool - is_assign bool + did_imports bool + is_assign bool } pub fn fmt(file ast.File, table &table.Table) string { @@ -87,9 +86,7 @@ fn (f mut Fmt) imports(imports []ast.Import) { if imports.len == 1 { imp_stmt_str := f.imp_stmt_str(imports[0]) f.writeln('import ${imp_stmt_str}\n') - } - // - else if imports.len > 1 { + } else if imports.len > 1 { f.writeln('import (') f.indent++ for imp in imports { @@ -102,11 +99,7 @@ fn (f mut Fmt) imports(imports []ast.Import) { fn (f Fmt) imp_stmt_str(imp ast.Import) string { is_diff := imp.alias != imp.mod && !imp.mod.ends_with('.' + imp.alias) - imp_alias_suffix := if is_diff { - ' as ${imp.alias}' - } else { - '' - } + imp_alias_suffix := if is_diff { ' as ${imp.alias}' } else { '' } return '${imp.mod}${imp_alias_suffix}' } @@ -291,11 +284,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) { f.writeln('') } ast.CompIf { - inversion := if it.is_not { - '!' - } else { - '' - } + inversion := if it.is_not { '!' } else { '' } f.writeln('\$if ${inversion}${it.val} {') f.stmts(it.stmts) if it.has_else { @@ -504,10 +493,16 @@ fn (f mut Fmt) expr(node ast.Expr) { } ast.MatchExpr { f.write('match ') + if it.is_mut { + f.write('mut ') + } f.expr(it.cond) f.writeln(' {') f.indent++ for i, branch in it.branches { + if branch.comment.text != '' { + f.comment(branch.comment) + } if i < it.branches.len - 1 { // normal branch for j, expr in branch.exprs { @@ -683,10 +678,13 @@ fn short_module(name string) string { } fn (f mut Fmt) if_expr(it ast.IfExpr) { - single_line := it.branches.len == 2 && it.has_else && it.branches[0].stmts.len == - 1 && it.branches[1].stmts.len == 1 && (it.is_expr || f.is_assign) + single_line := it.branches.len == 2 && it.has_else && it.branches[0].stmts.len == 1 && it.branches[1].stmts.len == + 1 && (it.is_expr || f.is_assign) f.single_line_if = single_line for i, branch in it.branches { + if branch.comment.text != '' { + f.comment(branch.comment) + } if i == 0 { f.write('if ') f.expr(branch.cond) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 62634bd272..2c178efe42 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -337,6 +337,7 @@ pub fn (p mut Parser) check_comment() ast.Comment { if p.tok.kind == .comment { return p.comment() } + return ast.Comment{} } pub fn (p mut Parser) comment() ast.Comment { @@ -1182,10 +1183,15 @@ fn (p mut Parser) if_expr() ast.IfExpr { mut has_else := false for p.tok.kind in [.key_if, .key_else] { branch_pos := p.tok.position() + mut comment := ast.Comment{} if p.tok.kind == .key_if { p.check(.key_if) } else { + //if p.tok.kind == .comment { + //p.error('place comments inside {}') + //} + //comment = p.check_comment() p.check(.key_else) if p.tok.kind == .key_if { p.check(.key_if) @@ -1195,6 +1201,7 @@ fn (p mut Parser) if_expr() ast.IfExpr { branches << ast.IfBranch{ stmts: p.parse_block() pos: branch_pos + comment: comment } break } @@ -1229,6 +1236,7 @@ fn (p mut Parser) if_expr() ast.IfExpr { cond: cond stmts: stmts pos: branch_pos + comment: ast.Comment{}// comment } if p.tok.kind != .key_else { break @@ -1811,6 +1819,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr { mut branches := []ast.MatchBranch mut have_final_else := false for { + comment := p.check_comment() // comment before {} mut exprs := []ast.Expr branch_pos := p.tok.position() p.open_scope() @@ -1862,6 +1871,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr { exprs: exprs stmts: stmts pos: branch_pos + comment: comment } p.close_scope() if p.tok.kind == .rcbr { @@ -1877,6 +1887,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr { cond: cond is_sum_type: is_sum_type pos: pos + is_mut: is_mut } }