Repository: goplus/gop
Pull request #1033 (2021-12-07 13:34:36)

format gopstyle
- fmtToBuiltin
- commandStyleFirst
- fncallStartingLowerCase



Patch:
diff --git a/x/format/README.md b/x/format/README.md
index 8b76f1bb..956992d8 100644
--- a/x/format/README.md
+++ b/x/format/README.md
@@ -40,7 +40,7 @@ a := 0
 ```
 
 
-### Replace fmt.Print to builtin (NotImpl)
+### Replace fmt.Print to builtin
 
 ```go
 import "fmt"
@@ -62,7 +62,7 @@ Note:
 * ...
 
 
-### Command style first (NotImpl)
+### Command style first
 
 ```go
 import "fmt"
@@ -83,7 +83,7 @@ Note:
 * Only the outermost function call statement is converted into command style. So `fmt.Println(fmt.Println("Hello world"))` is converted into `println println("Hello world")`, not `println println "Hello world"`.
 
 
-### Function call starting with lowercase (NotImpl)
+### Function call starting with lowercase
 
 ```go
 import "math"
diff --git a/x/format/format.go b/x/format/format.go
new file mode 100644
index 00000000..846a3b9e
--- /dev/null
+++ b/x/format/format.go
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package format
+
+import (
+	"github.com/goplus/gop/ast"
+)
+
+// -----------------------------------------------------------------------------
+
+var printFuncs = map[string]string{
+	"Errorf":   "errorf",
+	"Print":    "print",
+	"Printf":   "printf",
+	"Println":  "println",
+	"Fprint":   "fprint",
+	"Fprintf":  "fprintf",
+	"Fprintln": "fprintln",
+	"Sprint":   "sprint",
+	"Sprintf":  "sprintf",
+	"Sprintln": "sprintln",
+}
+
+func fmtToBuiltin(ctx *importCtx, sel *ast.Ident, ref *ast.Expr) bool {
+	if ctx.pkgPath == "fmt" {
+		if v, ok := printFuncs[sel.Name]; ok {
+			*ref = &ast.Ident{NamePos: sel.NamePos, Name: v}
+			return true
+		}
+	}
+	return false
+}
+
+func commandStyleFirst(v *ast.CallExpr) {
+	v.NoParenEnd = v.Rparen
+}
+
+func fncallStartingLowerCase(v *ast.CallExpr) {
+	switch fn := v.Fun.(type) {
+	case *ast.SelectorExpr:
+		startWithLowerCase(fn.Sel)
+	case *ast.Ident:
+		startWithLowerCase(fn)
+	}
+}
+
+// -----------------------------------------------------------------------------
diff --git a/x/format/gopstyle.go b/x/format/gopstyle.go
index 4acf7b2f..9afe25ee 100644
--- a/x/format/gopstyle.go
+++ b/x/format/gopstyle.go
@@ -1,7 +1,25 @@
+/*
+ * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package format
 
 import (
 	"bytes"
+	"path"
+	"strconv"
 
 	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/format"
@@ -9,19 +27,6 @@ import (
 	"github.com/goplus/gop/token"
 )
 
-var printFuncs = map[string]string{
-	"Errorf":   "errorf",
-	"Print":    "print",
-	"Printf":   "printf",
-	"Println":  "println",
-	"Fprint":   "fprint",
-	"Fprintf":  "fprintf",
-	"Fprintln": "fprintln",
-	"Sprint":   "sprint",
-	"Sprintf":  "sprintf",
-	"Sprintln": "sprintln",
-}
-
 // -----------------------------------------------------------------------------
 
 func GopstyleSource(src []byte, filename ...string) (ret []byte, err error) {
@@ -60,38 +65,7 @@ func Gopstyle(file *ast.File) {
 			*/
 		}
 	}
-
-	replacePrintCalls(file)
-}
-
-func identEqual(v *ast.Ident, name string) bool {
-	return v != nil && v.Name == name
-}
-
-func findFmtImports(decls []ast.Decl) []string {
-	var aliases []string
-
-	for _, decl := range decls {
-		if genDecl, ok := decl.(*ast.GenDecl); ok {
-			if genDecl.Tok != token.IMPORT {
-				continue
-			}
-
-			for _, spec := range genDecl.Specs {
-				if imp, ok := spec.(*ast.ImportSpec); ok {
-					if imp.Path.Value == `"fmt"` {
-						if imp.Name != nil {
-							aliases = append(aliases, imp.Name.Name)
-						} else {
-							aliases = append(aliases, "fmt")
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return aliases
+	formatFile(file)
 }
 
 func findFuncDecl(decls []ast.Decl, name string) int {
@@ -105,183 +79,131 @@ func findFuncDecl(decls []ast.Decl, name string) int {
 	return -1
 }
 
-func processAssignment(stmt *ast.AssignStmt, fmts []string) []string {
-	var keeps []string
-
-	for _, expr := range stmt.Rhs {
-		switch val := expr.(type) {
-		case *ast.CallExpr:
-			keeps = append(keeps, processCallExpr(val, fmts)...)
-		case *ast.SelectorExpr:
-			keeps = append(keeps, processSelectorExpr(val, fmts)...)
+func findDecl(decls []ast.Decl, v ast.Decl) int {
+	for i, decl := range decls {
+		if decl == v {
+			return i
 		}
 	}
-
-	return keeps
+	return -1
 }
 
-func processCallExpr(expr *ast.CallExpr, fmts []string) (keeps []string) {
-	if selExpr, ok := expr.Fun.(*ast.SelectorExpr); ok {
-		if ident, ok := selExpr.X.(*ast.Ident); ok {
-			if contains(fmts, ident.Name) {
-				p, ok := printFuncs[selExpr.Sel.Name]
-				if !ok {
-					return []string{ident.Name}
-				}
-
-				selExpr.Sel.Name = p
-				expr.Fun = selExpr.Sel
-			}
+func findSpec(specs []ast.Spec, v ast.Spec) int {
+	for i, spec := range specs {
+		if spec == v {
+			return i
 		}
 	}
-
-	return
+	return -1
 }
 
-func processDeclStmt(stmt *ast.DeclStmt, fmts []string) []string {
-	var keeps []string
-	if decl, ok := stmt.Decl.(*ast.GenDecl); ok {
-		for _, spec := range decl.Specs {
-			if valSpec, ok := spec.(*ast.ValueSpec); ok {
-				if selExpr, ok := valSpec.Type.(*ast.SelectorExpr); ok {
-					keeps = append(keeps, processSelectorExpr(selExpr, fmts)...)
-				}
-			}
-		}
+func deleteDecl(decls []ast.Decl, v ast.Decl) []ast.Decl {
+	if idx := findDecl(decls, v); idx >= 0 {
+		decls = append(decls[:idx], decls[idx+1:]...)
 	}
-
-	return keeps
+	return decls
 }
 
-func processExprStmt(stmt *ast.ExprStmt, fmts []string) (keeps []string) {
-	if callExpr, ok := stmt.X.(*ast.CallExpr); ok {
-		return processCallExpr(callExpr, fmts)
+func deleteSpec(specs []ast.Spec, v ast.Spec) []ast.Spec {
+	if idx := findSpec(specs, v); idx >= 0 {
+		specs = append(specs[:idx], specs[idx+1:]...)
 	}
-
-	return
+	return specs
 }
 
-func processSelectorExpr(expr *ast.SelectorExpr, fmts []string) (keeps []string) {
-	if ident, ok := expr.X.(*ast.Ident); ok {
-		if contains(fmts, ident.Name) {
-			if _, ok := printFuncs[expr.Sel.Name]; !ok {
-				return []string{ident.Name}
-			}
-		}
+func startWithLowerCase(v *ast.Ident) {
+	if c := v.Name[0]; c >= 'A' && c <= 'Z' {
+		v.Name = string(c+('a'-'A')) + v.Name[1:]
 	}
-
-	return
 }
 
-// replacePrintCalls replaces fmt print funcs to builtin print funcs.
-// also removes fmt import if necessary.
-func replacePrintCalls(file *ast.File) {
-	var keeps []string
-	fmts := findFmtImports(file.Decls)
-	for _, decl := range file.Decls {
-		keeps = append(keeps, replacePrintCall(decl, fmts)...)
-	}
-
-	trimFmtImport(file, keeps)
+func identEqual(v *ast.Ident, name string) bool {
+	return v != nil && v.Name == name
 }
 
-func replacePrintCall(decl ast.Decl, fmts []string) []string {
-	var keeps []string
-
-	if fn, ok := decl.(*ast.FuncDecl); ok {
-		for _, stmt := range fn.Body.List {
-			switch val := stmt.(type) {
-			case *ast.AssignStmt:
-				keeps = append(keeps, processAssignment(val, fmts)...)
-			case *ast.DeclStmt:
-				keeps = append(keeps, processDeclStmt(val, fmts)...)
-			case *ast.ExprStmt:
-				keeps = append(keeps, processExprStmt(val, fmts)...)
-			}
+func toString(l *ast.BasicLit) string {
+	if l.Kind == token.STRING {
+		s, err := strconv.Unquote(l.Value)
+		if err == nil {
+			return s
 		}
 	}
-
-	return keeps
+	panic("TODO: toString - convert ast.BasicLit to string failed")
 }
 
-func trimFmtImport(file *ast.File, keeps []string) {
-	var declIndice []int
+// -----------------------------------------------------------------------------
 
-	for i, decl := range file.Decls {
-		genDecl, ok := decl.(*ast.GenDecl)
-		if !ok {
-			continue
-		}
-		if genDecl.Tok != token.IMPORT {
-			continue
-		}
+type importCtx struct {
+	pkgPath string
+	decl    *ast.GenDecl
+	spec    *ast.ImportSpec
+	isUsed  bool
+}
 
-		var indice []int
-		for j, spec := range genDecl.Specs {
-			if imp, ok := spec.(*ast.ImportSpec); ok {
-				if imp.Path.Value == `"fmt"` {
-					// has alias
-					if imp.Name != nil && !contains(keeps, imp.Name.Name) {
-						indice = append(indice, j)
-					} else if !contains(keeps, "fmt") {
-						indice = append(indice, j)
-					}
-				}
-			}
-		}
+type formatCtx struct {
+	imports map[string]*importCtx
+}
 
-		genDecl.Specs = removeSpecsIf(genDecl.Specs, func(i int) bool {
-			for _, val := range indice {
-				if i == val {
-					return true
+func formatFile(file *ast.File) {
+	ctx := &formatCtx{
+		imports: make(map[string]*importCtx),
+	}
+	for _, decl := range file.Decls {
+		switch v := decl.(type) {
+		case *ast.FuncDecl:
+			formatFuncDecl(ctx, v)
+		case *ast.GenDecl:
+			switch v.Tok {
+			case token.IMPORT:
+				for _, item := range v.Specs {
+					var spec = item.(*ast.ImportSpec)
+					var pkgPath = toString(spec.Path)
+					var name string
+					if spec.Name == nil {
+						name = path.Base(pkgPath) // TODO: open pkgPath to get pkgName
+					} else {
+						name = spec.Name.Name
+						if name == "." || name == "_" {
+							continue
+						}
+					}
+					ctx.imports[name] = &importCtx{pkgPath: pkgPath, decl: v, spec: spec}
 				}
+			default:
+				formatGenDecl(ctx, v)
 			}
-			return false
-		})
-		if len(genDecl.Specs) == 0 {
-			declIndice = append(declIndice, i)
 		}
 	}
-
-	file.Decls = removeDeclsIf(file.Decls, func(i int) bool {
-		for _, val := range declIndice {
-			if i == val {
-				return true
+	for _, imp := range ctx.imports {
+		if imp.pkgPath == "fmt" && !imp.isUsed {
+			if len(imp.decl.Specs) == 1 {
+				file.Decls = deleteDecl(file.Decls, imp.decl)
+			} else {
+				imp.decl.Specs = deleteSpec(imp.decl.Specs, imp.spec)
 			}
 		}
-		return false
-	})
-}
-
-// -----------------------------------------------------------------------------
-
-func contains(items []string, val string) bool {
-	for _, item := range items {
-		if val == item {
-			return true
-		}
 	}
-	return false
 }
 
-func removeDeclsIf(decls []ast.Decl, fn func(i int) bool) []ast.Decl {
-	ret := decls[:0]
-	for i := range decls {
-		if fn(i) {
-			continue
+func formatGenDecl(ctx *formatCtx, v *ast.GenDecl) {
+	switch v.Tok {
+	case token.VAR, token.CONST:
+		for _, item := range v.Specs {
+			spec := item.(*ast.ValueSpec)
+			formatType(ctx, spec.Type, &spec.Type)
+			formatExprs(ctx, spec.Values)
+		}
+	case token.TYPE:
+		for _, item := range v.Specs {
+			spec := item.(*ast.TypeSpec)
+			formatType(ctx, spec.Type, &spec.Type)
 		}
-		ret = append(ret, decls[i])
 	}
-	return ret
 }
 
-func removeSpecsIf(specs []ast.Spec, fn func(i int) bool) []ast.Spec {
-	ret := specs[:0]
-	for i := range specs {
-		if fn(i) {
-			continue
-		}
-		ret = append(ret, specs[i])
-	}
-	return ret
+func formatFuncDecl(ctx *formatCtx, v *ast.FuncDecl) {
+	formatFuncType(ctx, v.Type)
+	formatBlockStmt(ctx, v.Body)
 }
+
+// -----------------------------------------------------------------------------
diff --git a/x/format/stmt_expr_or_type.go b/x/format/stmt_expr_or_type.go
new file mode 100644
index 00000000..50d7f83b
--- /dev/null
+++ b/x/format/stmt_expr_or_type.go
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package format
+
+import (
+	"github.com/goplus/gop/ast"
+)
+
+// -----------------------------------------------------------------------------
+
+func formatType(ctx *formatCtx, typ ast.Expr, ref *ast.Expr) {
+	switch t := typ.(type) {
+	case *ast.SelectorExpr:
+		formatSelectorExpr(ctx, t, ref)
+	case *ast.StructType:
+		formatStructType(ctx, t)
+	case *ast.FuncType:
+		formatFuncType(ctx, t)
+	}
+}
+
+func formatFuncType(ctx *formatCtx, t *ast.FuncType) {
+	formatFields(ctx, t.Params)
+	formatFields(ctx, t.Results)
+}
+
+func formatStructType(ctx *formatCtx, t *ast.StructType) {
+	formatFields(ctx, t.Fields)
+}
+
+func formatFields(ctx *formatCtx, flds *ast.FieldList) {
+	if flds != nil {
+		for _, fld := range flds.List {
+			formatField(ctx, fld)
+		}
+	}
+}
+
+func formatField(ctx *formatCtx, fld *ast.Field) {
+	formatType(ctx, fld.Type, &fld.Type)
+}
+
+// -----------------------------------------------------------------------------
+
+func formatExprs(ctx *formatCtx, exprs []ast.Expr) {
+	for i, expr := range exprs {
+		formatExpr(ctx, expr, &exprs[i])
+	}
+}
+
+func formatExpr(ctx *formatCtx, expr ast.Expr, ref *ast.Expr) {
+	switch v := expr.(type) {
+	case *ast.CallExpr:
+		formatCallExpr(ctx, v)
+	case *ast.SelectorExpr:
+		formatSelectorExpr(ctx, v, ref)
+	}
+}
+
+func formatCallExpr(ctx *formatCtx, v *ast.CallExpr) {
+	formatExpr(ctx, v.Fun, &v.Fun)
+	fncallStartingLowerCase(v)
+	formatExprs(ctx, v.Args)
+}
+
+func formatSelectorExpr(ctx *formatCtx, v *ast.SelectorExpr, ref *ast.Expr) {
+	switch x := v.X.(type) {
+	case *ast.Ident:
+		// TODO: maybe have bugs: `x.Name` may be a variable, not a import.
+		if imp, ok := ctx.imports[x.Name]; ok {
+			if !fmtToBuiltin(imp, v.Sel, ref) {
+				imp.isUsed = true
+			}
+		}
+	default:
+		formatExpr(ctx, x, &v.X)
+	}
+}
+
+// -----------------------------------------------------------------------------
+
+func formatBlockStmt(ctx *formatCtx, stmt *ast.BlockStmt) {
+	if stmt != nil {
+		formatStmts(ctx, stmt.List)
+	}
+}
+
+func formatStmts(ctx *formatCtx, stmts []ast.Stmt) {
+	for _, stmt := range stmts {
+		formatStmt(ctx, stmt)
+	}
+}
+
+func formatStmt(ctx *formatCtx, stmt ast.Stmt) {
+	switch v := stmt.(type) {
+	case *ast.ExprStmt:
+		formatExprStmt(ctx, v)
+	case *ast.AssignStmt:
+		formatAssignStmt(ctx, v)
+	case *ast.DeclStmt:
+		formatDeclStmt(ctx, v)
+	}
+}
+
+func formatExprStmt(ctx *formatCtx, v *ast.ExprStmt) {
+	switch x := v.X.(type) {
+	case *ast.CallExpr:
+		commandStyleFirst(x)
+	}
+	formatExpr(ctx, v.X, &v.X)
+}
+
+func formatAssignStmt(ctx *formatCtx, v *ast.AssignStmt) {
+	formatExprs(ctx, v.Lhs)
+	formatExprs(ctx, v.Rhs)
+}
+
+func formatDeclStmt(ctx *formatCtx, v *ast.DeclStmt) {
+	if decl, ok := v.Decl.(*ast.GenDecl); ok {
+		formatGenDecl(ctx, decl)
+	}
+}
+
+// -----------------------------------------------------------------------------


Test patch:
diff --git a/x/format/gopstyle_test.go b/x/format/gopstyle_test.go
index accc1e6f..42883c5a 100644
--- a/x/format/gopstyle_test.go
+++ b/x/format/gopstyle_test.go
@@ -1,11 +1,25 @@
+/*
+ * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package format
 
 import (
 	"testing"
 )
 
-// -----------------------------------------------------------------------------
-
 func testFormat(t *testing.T, name string, src, expect string) {
 	t.Run(name, func(t *testing.T) {
 		result, err := GopstyleSource([]byte(src), name)
@@ -18,8 +32,10 @@ func testFormat(t *testing.T, name string, src, expect string) {
 	})
 }
 
-func TestBasic1(t *testing.T) {
-	testFormat(t, "hello world", `package main
+// -----------------------------------------------------------------------------
+
+func TestMain(t *testing.T) {
+	testFormat(t, "hello world 1", `package main
 
 import "fmt"
 
@@ -31,12 +47,9 @@ func main() {
 `, `// this is main
 
 // say hello
-println("Hello world")
+println "Hello world"
 `)
-}
-
-func TestBasic2(t *testing.T) {
-	testFormat(t, "hello world", `package main
+	testFormat(t, "hello world 2", `package main
 
 import "fmt"
 
@@ -51,16 +64,13 @@ func f() {
 `, `// this is main
 func main() {
 	// say hello
-	println("Hello world")
+	println "Hello world"
 }
 
 func f() {
 }
 `)
-}
-
-func TestBasic3(t *testing.T) {
-	testFormat(t, "hello world", `package main
+	testFormat(t, "hello world 3", `package main
 
 import "fmt"
 
@@ -82,7 +92,7 @@ func f() {
 	fmt.Print("hello")
 }
 `, `func f() {
-	print("hello")
+	print "hello"
 }
 `)
 }
@@ -96,7 +106,7 @@ func f() {
 	fmt.Printf("hello")
 }
 `, `func f() {
-	printf("hello")
+	printf "hello"
 }
 `)
 }
@@ -110,7 +120,7 @@ func f() {
 	fmt.Println("hello")
 }
 `, `func f() {
-	println("hello")
+	println "hello"
 }
 `)
 }
@@ -126,7 +136,7 @@ func f() {
 	fmt.Println("hello")
 }
 `, `func f() {
-	println("hello")
+	println "hello"
 }
 `)
 }
@@ -134,18 +144,18 @@ func f() {
 func TestPrintlnWithOtherFmtCalls(t *testing.T) {
 	testFormat(t, "print", `package main
 
-import "errors"
+import . "errors"
 import "fmt"
 
 func f() {
-	fmt.Errorf("%w", errors.New("hello"))
+	fmt.Errorf("%w", New("hello"))
 	fmt.Println("hello")
 }
-`, `import "errors"
+`, `import . "errors"
 
 func f() {
-	errorf("%w", errors.New("hello"))
-	println("hello")
+	errorf "%w", new("hello")
+	println "hello"
 }
 `)
 }
@@ -167,8 +177,8 @@ func f() {
 )
 
 func f() {
-	errorf("%w", errors.New("hello"))
-	println("hello")
+	errorf "%w", errors.new("hello")
+	println "hello"
 }
 `)
 }
@@ -186,8 +196,8 @@ func f() {
 `, `import "errors"
 
 func f() {
-	_ = errorf("%w", errors.New("hello"))
-	println("hello")
+	_ = errorf("%w", errors.new("hello"))
+	println "hello"
 }
 `)
 }
@@ -209,8 +219,8 @@ func f() {
 )
 
 func f() {
-	_ = errorf("%w", errors.New("hello"))
-	println("hello")
+	_ = errorf("%w", errors.new("hello"))
+	println "hello"
 }
 `)
 }
@@ -228,7 +238,7 @@ func f() {
 
 func f() {
 	_ = fmt.Stringer
-	println("hello")
+	println "hello"
 }
 `)
 }
@@ -246,7 +256,31 @@ func f() {
 
 func f() {
 	var _ fmt.Stringer
-	println("hello")
+	println "hello"
+}
+`)
+}
+
+func TestPrintlnWithOtherFmtType(t *testing.T) {
+	testFormat(t, "print", `package main
+
+import "fmt"
+
+func f() {
+	var _ struct {
+		fmt.Stringer
+		fn func()
+	}
+	fmt.Println("hello")
+}
+`, `import "fmt"
+
+func f() {
+	var _ struct {
+		fmt.Stringer
+		fn func()
+	}
+	println "hello"
 }
 `)
 }
@@ -260,7 +294,7 @@ func f() {
 	fmt1.Println("hello")
 }
 `, `func f() {
-	println("hello")
+	println "hello"
 }
 `)
 }
@@ -278,8 +312,8 @@ func f() {
 	fmt2.Println(2)
 }
 `, `func f() {
-	println(1)
-	println(2)
+	println 1
+	println 2
 }
 `)
 }
@@ -303,8 +337,8 @@ func f() {
 
 func f() {
 	var _ fmt.Stringer
-	println(1)
-	println(2)
+	println 1
+	println 2
 }
 `)
 }