Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ pub struct Block {
pub:
is_unsafe bool
pos token.Pos
scope &Scope
pub mut:
stmts []Stmt
}
Expand Down Expand Up @@ -808,6 +809,7 @@ pub struct BranchStmt {
pub:
kind token.Kind
label string
scope &Scope
pos token.Pos
}

Expand Down Expand Up @@ -887,6 +889,7 @@ pub mut:
// function return statement
pub struct Return {
pub:
scope &Scope
pos token.Pos
comments []Comment
pub mut:
Expand Down Expand Up @@ -1326,6 +1329,7 @@ pub:
is_else bool
is_timeout bool
post_comments []Comment
scope &Scope
pub mut:
stmt Stmt // `a := <-ch` or `ch <- a`
stmts []Stmt // right side
Expand Down Expand Up @@ -1542,13 +1546,20 @@ pub:
is_markused bool
}

pub enum DeferMode {
scoped // default
function
}

// TODO: handle this differently
// v1 excludes non current os ifdefs so
// the defer's never get added in the first place
@[minify]
pub struct DeferStmt {
pub:
pos token.Pos
pos token.Pos
scope &Scope
mode DeferMode
pub mut:
stmts []Stmt
defer_vars []Ident
Expand Down
9 changes: 9 additions & 0 deletions vlib/v/ast/scope.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// that can be found in the LICENSE file.
module ast

pub const empty_scope = &Scope{
parent: unsafe { nil }
}

@[heap]
pub struct Scope {
pub mut:
Expand Down Expand Up @@ -251,6 +255,11 @@ pub fn (s &Scope) contains(pos int) bool {
return pos >= s.start_pos && pos <= s.end_pos
}

@[inline]
pub fn (s &Scope) == (o &Scope) bool {
return s.start_pos == o.start_pos && s.end_pos == o.end_pos
}

pub fn (s &Scope) has_inherited_vars() bool {
for _, obj in s.objects {
if obj is Var {
Expand Down
6 changes: 4 additions & 2 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
node.stmts.last().pos
}
node.stmts << ast.Return{
pos: return_pos // node.pos
scope: node.scope
pos: return_pos // node.pos
}
}
}
Expand All @@ -512,7 +513,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
sym := c.table.sym(node.return_type)
if sym.kind == .void {
node.stmts << ast.Return{
pos: node.pos
scope: node.scope
pos: node.pos
}
}
}
Expand Down
1 change: 1 addition & 0 deletions vlib/v/checker/lambda_expr.v
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
}
} else {
stmts << ast.Return{
scope: node.scope
pos: node.pos
exprs: [node.expr]
}
Expand Down
6 changes: 6 additions & 0 deletions vlib/v/checker/tests/invalid_defer_mode_err.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
vlib/v/checker/tests/invalid_defer_mode_err.vv:4:8: error: unknown `defer` mode: `fn1`
2 | defer {} // ok
3 | defer(fn) {} // ok
4 | defer(fn1) {} // fail
| ~~~
5 | }
5 changes: 5 additions & 0 deletions vlib/v/checker/tests/invalid_defer_mode_err.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() {
defer {} // ok
defer(fn) {} // ok
defer(fn1) {} // fail
}
11 changes: 7 additions & 4 deletions vlib/v/fmt/fmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -981,12 +981,15 @@ pub fn (mut f Fmt) const_decl(node ast.ConstDecl) {
}

fn (mut f Fmt) defer_stmt(node ast.DeferStmt) {
f.write('defer ')
f.write('defer')
if node.mode == .function {
f.write('(fn)')
}
if node.stmts.len == 0 {
f.writeln('{}')
f.writeln(' {}')
} else if node.stmts.len == 1 && node.pos.line_nr == node.pos.last_line
&& stmt_is_single_line(node.stmts[0]) {
f.write('{ ')
f.write(' { ')
// the control stmts (return/break/continue...) print a newline inside them,
// so, since this'll all be on one line, trim any possible whitespace
str := f.node_str(node.stmts[0]).trim_space()
Expand All @@ -1000,7 +1003,7 @@ fn (mut f Fmt) defer_stmt(node ast.DeferStmt) {
// f.stmt(node.stmts[0])
f.writeln(' }')
} else {
f.writeln('{')
f.writeln(' {')
f.stmts(node.stmts)
f.writeln('}')
}
Expand Down
16 changes: 16 additions & 0 deletions vlib/v/fmt/tests/defer_mode_expected.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
fn main() {
defer(fn) { println('${@FN} - 0 - defer') }
{
defer { println('${@FN} - 1 - defer') }
{
defer { println('${@FN} - 2 - defer') }
println('exit fn main().scope.2')
}
println('exit fn main().scope.1')
}

defer(fn) {
println('defer(fn)')
}
println('exit fn main().scope.0')
}
17 changes: 17 additions & 0 deletions vlib/v/fmt/tests/defer_mode_input.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
fn main() {
defer (fn) { println('${@FN} - 0 - defer') }
{
defer { println('${@FN} - 1 - defer') }
{
defer { println('${@FN} - 2 - defer') }
println('exit fn main().scope.2')
}
println('exit fn main().scope.1')
}
defer
(fn)
{
println('defer(fn)')
}
println('exit fn main().scope.0')
}
Loading
Loading