Skip to content

Commit

Permalink
Fixed issue in len with string concatenation in argument
Browse files Browse the repository at this point in the history
  • Loading branch information
grantnelson-wf committed Oct 28, 2024
1 parent 8a27348 commit 3a364dc
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
45 changes: 45 additions & 0 deletions compiler/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,51 @@ func TestDeclSelection_RemoveUnusedTypeConstraint(t *testing.T) {
sel.InitCode.IsDead(`ghost = new Bar\[\d+ /\* int \*/\]\.ptr\(7\)`)
}

func TestLengthParenthesizingIssue841(t *testing.T) {
// See issue https://github.com/gopherjs/gopherjs/issues/841
//
// Summary: Given `len(a+b)` where a and b are strings being concatenated
// together, the result was `a + b.length` instead of `(a+b).length`.
//
// The fix was to check if the expression in `len` is a binary
// expression or not. If it is, then the expression is parenthesized.
// This will work for concatenations any combination of variables and
// literals but won't pick up `len(Foo(a+b))` or `len(a[0:i+3])`.

src := `
package main
func main() {
a := "a"
b := "b"
ab := a + b
if len(a+b) != len(ab) {
panic("unreachable")
}
}`

srcFiles := []srctesting.Source{{Name: `main.go`, Contents: []byte(src)}}
root := srctesting.ParseSources(t, srcFiles, nil)
archives := compileProject(t, root, false)
mainPkg := archives[root.PkgPath]

badRegex := regexp.MustCompile(`a\s*\+\s*b\.length`)
goodRegex := regexp.MustCompile(`\(a\s*\+\s*b\)\.length`)
goodFound := false
for i, decl := range mainPkg.Declarations {
if badRegex.Match(decl.DeclCode) {
t.Errorf("found length issue in decl #%d: %s", i, decl.FullName)
t.Logf("decl code:\n%s", string(decl.DeclCode))
}
if goodRegex.Match(decl.DeclCode) {
goodFound = true
}
}
if !goodFound {
t.Error("parenthesized length not found")
}
}

func compareOrder(t *testing.T, sourceFiles []srctesting.Source, minify bool) {
t.Helper()
outputNormal := compile(t, sourceFiles, minify)
Expand Down
4 changes: 4 additions & 0 deletions compiler/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,10 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
case "len":
switch argType := fc.typeOf(args[0]).Underlying().(type) {
case *types.Basic:
// If the argument is a concatenation of strings, then add parentheses.
if _, ok := args[0].(*ast.BinaryExpr); ok {
return fc.formatExpr("(%e).length", args[0])
}
return fc.formatExpr("%e.length", args[0])
case *types.Slice:
return fc.formatExpr("%e.$length", args[0])
Expand Down

0 comments on commit 3a364dc

Please sign in to comment.