@@ -360,6 +360,50 @@ func TestDeclSelection_RemoveUnusedTypeConstraint(t *testing.T) {
360
360
sel .InitCode .IsDead (`ghost = new Bar\[\d+ /\* int \*/\]\.ptr\(7\)` )
361
361
}
362
362
363
+ func TestLengthParenthesizingIssue841 (t * testing.T ) {
364
+ // See issue https://github.com/gopherjs/gopherjs/issues/841
365
+ //
366
+ // Summary: Given `len(a+b)` where a and b are strings being concatenated
367
+ // together, the result was `a + b.length` instead of `(a+b).length`.
368
+ //
369
+ // The fix was to check if the expression in `len` contains a binary
370
+ // expression or not. If it does, then the expression is parenthesized.
371
+ // This will work for concatenations any combination of variables and literals.
372
+
373
+ src := `
374
+ package main
375
+
376
+ func main() {
377
+ a := "a"
378
+ b := "b"
379
+ ab := a + b
380
+ if len(a+b) != len(ab) {
381
+ panic("unreachable")
382
+ }
383
+ }`
384
+
385
+ srcFiles := []srctesting.Source {{Name : `main.go` , Contents : []byte (src )}}
386
+ root := srctesting .ParseSources (t , srcFiles , nil )
387
+ archives := compileProject (t , root , false )
388
+ mainPkg := archives [root .PkgPath ]
389
+
390
+ badRegex := regexp .MustCompile (`a\s*\+\s*b\.length` )
391
+ goodRegex := regexp .MustCompile (`\(a\s*\+\s*b\)\.length` )
392
+ goodFound := false
393
+ for i , decl := range mainPkg .Declarations {
394
+ if badRegex .Match (decl .DeclCode ) {
395
+ t .Errorf ("found length issue in decl #%d: %s" , i , decl .FullName )
396
+ t .Logf ("decl code:\n %s" , string (decl .DeclCode ))
397
+ }
398
+ if goodRegex .Match (decl .DeclCode ) {
399
+ goodFound = true
400
+ }
401
+ }
402
+ if ! goodFound {
403
+ t .Error ("parenthesized length not found" )
404
+ }
405
+ }
406
+
363
407
func compareOrder (t * testing.T , sourceFiles []srctesting.Source , minify bool ) {
364
408
t .Helper ()
365
409
outputNormal := compile (t , sourceFiles , minify )
0 commit comments