Repository: goplus/gop
Pull request #1027 (2021-12-05 05:41:20)

Release v1.0.33
new features:
- gop/x/format
- build multi platform targets

changes:
- for range `start:end:step` optimization (#875)
- mv cmd/install.go => cmd/make.go
- fix the problem that the path to get the class file gop.mod is wrong



Patch:
diff --git a/cmd/gopfmt/gopfmt.go b/cmd/gopfmt/gopfmt.go
index afadf841..e29bcb13 100644
--- a/cmd/gopfmt/gopfmt.go
+++ b/cmd/gopfmt/gopfmt.go
@@ -69,7 +69,7 @@ func processFile(filename string, in io.Reader, out io.Writer) error {
 		return err
 	}
 
-	res, err := format.Source(src)
+	res, err := format.Source(src, filename)
 	if err != nil {
 		return err
 	}
@@ -111,7 +111,9 @@ func walk(path string, d fs.DirEntry, err error) error {
 		ext := filepath.Ext(path)
 		if _, ok := extGops[ext]; ok {
 			procCnt++
-			err = processFile(path, nil, os.Stdout)
+			if err = processFile(path, nil, os.Stdout); err != nil {
+				report(err)
+			}
 		}
 	}
 	return err
diff --git a/cmd/internal/gopfmt/fmt.go b/cmd/internal/gopfmt/fmt.go
index ae362467..11b1f150 100644
--- a/cmd/internal/gopfmt/fmt.go
+++ b/cmd/internal/gopfmt/fmt.go
@@ -70,9 +70,9 @@ func gopfmt(path string, smart, mvgo bool) (err error) {
 	}
 	var target []byte
 	if smart {
-		target, err = xformat.Source(src)
+		target, err = xformat.GopstyleSource(src, path)
 	} else {
-		target, err = format.Source(src)
+		target, err = format.Source(src, path)
 	}
 	if err != nil {
 		return
@@ -127,12 +127,20 @@ func walk(path string, d fs.DirEntry, err error) error {
 				smart := *flagSmart
 				mvgo := smart && *flagMoveGo
 				err = gopfmt(path, smart && (mvgo || ext != ".go"), mvgo)
+				if err != nil {
+					report(err)
+				}
 			}
 		}
 	}
 	return err
 }
 
+func report(err error) {
+	fmt.Println(err)
+	os.Exit(2)
+}
+
 func runCmd(cmd *base.Command, args []string) {
 	err := flag.Parse(args)
 	if err != nil {
diff --git a/cmd/make.go b/cmd/make.go
index 2b767c86..74382d52 100644
--- a/cmd/make.go
+++ b/cmd/make.go
@@ -182,6 +182,11 @@ func runTestcases() {
 
 	coverage := "-coverprofile=coverage.txt"
 	gopCommand := filepath.Join(detectGopBinPath(), "gop")
+	if !checkPathExist(gopCommand, false) {
+		println("Error: Go+ must be installed before running testcases.")
+		os.Exit(1)
+	}
+
 	testOutput, testErr, err := execCommand(gopCommand, "test", coverage, "-covermode=atomic", "./...")
 	println(testOutput)
 	println(testErr)
@@ -239,13 +244,19 @@ func main() {
 		isTest:      runTestcases,
 	}
 
-	for flag, action := range flagActionMap {
+	// Sort flags, for example: install flag should be checked earlier than test flag.
+	flags := []*bool{isInstall, isTest, isUninstall}
+	hasActionDone := false
+
+	for _, flag := range flags {
 		if *flag {
-			action()
-			return
+			flagActionMap[flag]()
+			hasActionDone = true
 		}
 	}
 
-	println("Usage:\n")
-	flag.PrintDefaults()
+	if !hasActionDone {
+		println("Usage:\n")
+		flag.PrintDefaults()
+	}
 }
diff --git a/format/format.go b/format/format.go
index 9e05c16a..3ee26f05 100644
--- a/format/format.go
+++ b/format/format.go
@@ -101,9 +101,13 @@ func Node(dst io.Writer, fset *token.FileSet, node interface{}) error {
 // space as src), and the result is indented by the same amount as the first
 // line of src containing code. Imports are not sorted for partial source files.
 //
-func Source(src []byte) ([]byte, error) {
+func Source(src []byte, filename ...string) ([]byte, error) {
+	var fname string
+	if filename != nil {
+		fname = filename[0]
+	}
 	fset := token.NewFileSet()
-	file, sourceAdj, indentAdj, err := parse(fset, "", src, true)
+	file, sourceAdj, indentAdj, err := parse(fset, fname, src, true)
 	if err != nil {
 		return nil, err
 	}
diff --git a/x/format/gopstyle.go b/x/format/gopstyle.go
index 68d8cf47..66828b29 100644
--- a/x/format/gopstyle.go
+++ b/x/format/gopstyle.go
@@ -11,9 +11,14 @@ import (
 
 // -----------------------------------------------------------------------------
 
-func Source(src []byte) (ret []byte, err error) {
+func GopstyleSource(src []byte, filename ...string) (ret []byte, err error) {
+	var fname string
+	if filename != nil {
+		fname = filename[0]
+	}
 	fset := token.NewFileSet()
-	if f, err := parser.ParseFile(fset, "", src, parser.ParseComments); err == nil {
+	var f *ast.File
+	if f, err = parser.ParseFile(fset, fname, src, parser.ParseComments); err == nil {
 		Gopstyle(f)
 		var buf bytes.Buffer
 		if err = format.Node(&buf, fset, f); err == nil {
@@ -31,12 +36,16 @@ func Gopstyle(file *ast.File) {
 	}
 	if idx := findFuncDecl(file.Decls, "main"); idx >= 0 {
 		last := len(file.Decls) - 1
-		if idx != last { // swap main func to last
-			fn := file.Decls[idx]
-			copy(file.Decls[idx:], file.Decls[idx+1:])
-			file.Decls[last] = fn
+		if idx == last {
+			file.NoEntrypoint = true
+			// TODO: idx != last: swap main func to last
+			// TODO: should also swap file.Comments
+			/*
+				fn := file.Decls[idx]
+				copy(file.Decls[idx:], file.Decls[idx+1:])
+				file.Decls[last] = fn
+			*/
 		}
-		file.NoEntrypoint = true
 	}
 }
 


Test patch:
diff --git a/parser/_testdata/cmdlinestyle3/cmd3.gop b/parser/_testdata/cmdlinestyle3/cmd3.gop
new file mode 100644
index 00000000..b1f81ffd
--- /dev/null
+++ b/parser/_testdata/cmdlinestyle3/cmd3.gop
@@ -0,0 +1,1 @@
+println &x
diff --git a/parser/_testdata/cmdlinestyle3/parser.expect b/parser/_testdata/cmdlinestyle3/parser.expect
new file mode 100644
index 00000000..762e943c
--- /dev/null
+++ b/parser/_testdata/cmdlinestyle3/parser.expect
@@ -0,0 +1,27 @@
+package main
+
+file cmd3.gop
+noEntrypoint
+ast.FuncDecl:
+  Name:
+    ast.Ident:
+      Name: main
+  Type:
+    ast.FuncType:
+      Params:
+        ast.FieldList:
+  Body:
+    ast.BlockStmt:
+      List:
+        ast.ExprStmt:
+          X:
+            ast.CallExpr:
+              Fun:
+                ast.Ident:
+                  Name: println
+              Args:
+                ast.UnaryExpr:
+                  Op: &
+                  X:
+                    ast.Ident:
+                      Name: x
diff --git a/parser/parserdir_test.go b/parser/parserdir_test.go
index 9db148cb..62878a21 100644
--- a/parser/parserdir_test.go
+++ b/parser/parserdir_test.go
@@ -147,7 +147,9 @@ func TestFromTestdata(t *testing.T) {
 		if strings.HasPrefix(name, "_") {
 			continue
 		}
-		testFrom(t, dir+"/"+name, sel, 0)
+		t.Run(name, func(t *testing.T) {
+			testFrom(t, dir+"/"+name, sel, 0)
+		})
 	}
 }
 
diff --git a/printer/gop_test.go b/printer/gop_test.go
index 13cd9703..25517a3c 100644
--- a/printer/gop_test.go
+++ b/printer/gop_test.go
@@ -108,7 +108,7 @@ func testFrom(t *testing.T, fpath string) {
 		t.Fatal(err)
 	}
 
-	res, err := format.Source(src)
+	res, err := format.Source(src, fpath)
 	if err != nil {
 		t.Fatal("Source failed:", err)
 	}
diff --git a/x/format/gopstyle_test.go b/x/format/gopstyle_test.go
index f9f9d7df..b0a0f037 100644
--- a/x/format/gopstyle_test.go
+++ b/x/format/gopstyle_test.go
@@ -8,7 +8,7 @@ import (
 
 func testFormat(t *testing.T, name string, src, expect string) {
 	t.Run(name, func(t *testing.T) {
-		result, err := Source([]byte(src))
+		result, err := GopstyleSource([]byte(src), name)
 		if err != nil {
 			t.Fatal("format.Source failed:", err)
 		}
@@ -23,11 +23,16 @@ func TestBasic1(t *testing.T) {
 
 import "fmt"
 
+// this is main
 func main() {
+	// say hello
 	fmt.Println("Hello world")
 }
 `, `import "fmt"
 
+// this is main
+
+// say hello
 fmt.Println("Hello world")
 `)
 }
@@ -37,7 +42,9 @@ func TestBasic2(t *testing.T) {
 
 import "fmt"
 
+// this is main
 func main() {
+	// say hello
 	fmt.Println("Hello world")
 }
 
@@ -45,10 +52,14 @@ func f() {
 }
 `, `import "fmt"
 
-func f() {
+// this is main
+func main() {
+	// say hello
+	fmt.Println("Hello world")
 }
 
-fmt.Println("Hello world")
+func f() {
+}
 `)
 }