lang: ast, interpolate: Pass through uninterpolated strings

We don't need to make a new reference for nothing.
This commit is contained in:
James Shubin
2025-06-06 00:35:52 -04:00
parent 4f977dbe57
commit 5d44cd28db
2 changed files with 17 additions and 11 deletions

View File

@@ -7527,7 +7527,8 @@ func (obj *ExprStr) Interpolate() (interfaces.Expr, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if result == nil { // a nil result means unchanged, string didn't need interpolating done
if result == nil { // we still copy since Interpolate always "copies"
return &ExprStr{ return &ExprStr{
Textarea: obj.Textarea, Textarea: obj.Textarea,
data: obj.data, data: obj.data,

View File

@@ -55,7 +55,8 @@ const (
UseOptimizedConcat = true UseOptimizedConcat = true
) )
// StrInterpolate interpolates a string and returns the representative AST. // StrInterpolate interpolates a string and returns the representative AST. If
// there was nothing to interpolate, this returns (nil, nil).
func StrInterpolate(str string, pos *interfaces.Pos, data *interfaces.Data) (interfaces.Expr, error) { func StrInterpolate(str string, pos *interfaces.Pos, data *interfaces.Data) (interfaces.Expr, error) {
if data.Debug { if data.Debug {
data.Logf("interpolating: %s", str) data.Logf("interpolating: %s", str)
@@ -68,13 +69,25 @@ func StrInterpolate(str string, pos *interfaces.Pos, data *interfaces.Data) (int
} }
// RagelInterpolate interpolates a string and returns the representative AST. It // RagelInterpolate interpolates a string and returns the representative AST. It
// uses the ragel parser to perform the string interpolation. // uses the ragel parser to perform the string interpolation. If there was
// nothing to interpolate, this returns (nil, nil).
func RagelInterpolate(str string, pos *interfaces.Pos, data *interfaces.Data) (interfaces.Expr, error) { func RagelInterpolate(str string, pos *interfaces.Pos, data *interfaces.Data) (interfaces.Expr, error) {
sequence, err := Parse(str) sequence, err := Parse(str)
if err != nil { if err != nil {
return nil, errwrap.Wrapf(err, "parser failed") return nil, errwrap.Wrapf(err, "parser failed")
} }
// If we didn't find anything of value, we got an empty string...
if len(sequence) == 0 && str == "" { // be doubly sure...
return nil, nil // pass through, nothing changed
}
if len(sequence) == 1 {
if x, ok := sequence[0].(Literal); ok && x.Value == str {
return nil, nil // pass through, nothing changed
}
}
exprs := []interfaces.Expr{} exprs := []interfaces.Expr{}
for _, term := range sequence { for _, term := range sequence {
@@ -95,14 +108,6 @@ func RagelInterpolate(str string, pos *interfaces.Pos, data *interfaces.Data) (i
} }
} }
// If we didn't find anything of value, we got an empty string...
if len(sequence) == 0 && str == "" { // be doubly sure...
expr := &ast.ExprStr{
V: "",
}
exprs = append(exprs, expr)
}
// The parser produces non-optimal results where two strings are next to // The parser produces non-optimal results where two strings are next to
// each other, when they could be statically combined together. // each other, when they could be statically combined together.
simplified, err := simplifyExprList(exprs) simplified, err := simplifyExprList(exprs)