Skip to content

Commit

Permalink
add support for @[expand_simple_interpolation] in the compiler, so …
Browse files Browse the repository at this point in the history
…that both Gen.write/1 and Builder.write_string/1 can use the same transformation mechanism for simplifying string interpolations in their arguments
  • Loading branch information
spytheman committed Sep 27, 2024
1 parent 7d5b3b1 commit 46e5ffe
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 5 deletions.
10 changes: 10 additions & 0 deletions vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,8 @@ pub mut:
scope &Scope = unsafe { nil }
label_names []string
pos token.Pos // function declaration position
//
is_expand_simple_interpolation bool // true, when @[expand_simple_interpolation] is used on a fn. It should have a single string argument.
}

pub fn (f &FnDecl) new_method_with_receiver_type(new_type_ Type) FnDecl {
Expand Down Expand Up @@ -682,6 +684,10 @@ pub mut:
ctdefine_idx int // the index of the attribute, containing the compile time define [if mytag]
from_embedded_type Type // for interface only, fn from the embedded interface
from_embeded_type Type @[deprecated: 'use from_embedded_type instead'; deprecated_after: '2024-03-31']
//
is_expand_simple_interpolation bool // for tagging b.f(s string), which is then called with `b.f('some $x $y')`,
// when that call, should be expanded to `b.f('some '); b.f(x); b.f(' '); b.f(y);`
// Note: the same type, has to support also a .write_decimal(n i64) method.
}

fn (f &Fn) method_equals(o &Fn) bool {
Expand Down Expand Up @@ -805,6 +811,10 @@ pub mut:
scope &Scope = unsafe { nil }
from_embed_types []Type // holds the type of the embed that the method is called from
comments []Comment
//
is_expand_simple_interpolation bool // true, when the function/method is marked as @[expand_simple_interpolation]
// Calls to it with an interpolation argument like `b.f('x ${y}')`, will be converted to `b.f('x ')` followed by `b.f(y)`.
// The same type, has to support also a .write_decimal(n i64) method.
}

/*
Expand Down
19 changes: 19 additions & 0 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,23 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
}
}
}
if node.is_expand_simple_interpolation {
match true {
!node.is_method {
c.error('@[expand_simple_interpolation] is supported only on methods',
node.pos)
}
node.params.len != 2 {
c.error('methods tagged with @[expand_simple_interpolation], should have exactly 1 argument',
node.pos)
}
!node.params[1].typ.is_string() {
c.error('methods tagged with @[expand_simple_interpolation], should accept a single string',
node.pos)
}
else {}
}
}
}

// check_same_type_ignoring_pointers util function to check if the Types are the same, including all
Expand Down Expand Up @@ -1180,6 +1197,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
}
node.is_file_translated = func.is_file_translated
node.is_noreturn = func.is_noreturn
node.is_expand_simple_interpolation = func.is_expand_simple_interpolation
node.is_ctor_new = func.is_ctor_new
if !found_in_args {
if node.scope.known_var(fn_name) {
Expand Down Expand Up @@ -2330,6 +2348,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
c.need_recheck_generic_fns = true
}
node.is_noreturn = method.is_noreturn
node.is_expand_simple_interpolation = method.is_expand_simple_interpolation
node.is_ctor_new = method.is_ctor_new
node.return_type = method.return_type
if method.return_type.has_flag(.generic) {
Expand Down
10 changes: 10 additions & 0 deletions vlib/v/parser/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
mut is_ctor_new := false
mut is_c2v_variadic := false
mut is_markused := false
mut is_expand_simple_interpolation := false
mut comments := []ast.Comment{}
for fna in p.attrs {
match fna.name {
Expand Down Expand Up @@ -254,6 +255,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
p.prev_tok.pos())
}
}
'expand_simple_interpolation' {
is_expand_simple_interpolation = true
}
else {}
}
}
Expand Down Expand Up @@ -550,6 +554,8 @@ run them via `v file.v` instead',
pos: start_pos
name_pos: name_pos
language: language
//
is_expand_simple_interpolation: is_expand_simple_interpolation
})
} else {
name = match language {
Expand Down Expand Up @@ -603,6 +609,8 @@ run them via `v file.v` instead',
pos: start_pos
name_pos: name_pos
language: language
//
is_expand_simple_interpolation: is_expand_simple_interpolation
})
}
/*
Expand Down Expand Up @@ -688,6 +696,8 @@ run them via `v file.v` instead',
label_names: p.label_names
end_comments: p.eat_comments(same_line: true)
comments: comments
//
is_expand_simple_interpolation: is_expand_simple_interpolation
}
if generic_names.len > 0 {
p.table.register_fn_generic_types(fn_decl.fkey())
Expand Down
7 changes: 2 additions & 5 deletions vlib/v/transformer/transformer.v
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,8 @@ pub fn (mut t Transformer) stmt(mut node ast.Stmt) ast.Stmt {
t.expr(mut node.expr)
}
}
if mut node.expr is ast.CallExpr {
if node.expr.is_method && node.expr.left_type == t.strings_builder_type
&& node.expr.name == 'write_string' {
t.simplify_nested_interpolation_in_sb(mut onode, mut node.expr, node.typ)
}
if mut node.expr is ast.CallExpr && node.expr.is_expand_simple_interpolation {
t.simplify_nested_interpolation_in_sb(mut onode, mut node.expr, node.typ)
}
}
ast.FnDecl {
Expand Down

0 comments on commit 46e5ffe

Please sign in to comment.