Repository: goplus/gop
Pull request #1514 (2023-11-02 14:36:48)

typesutil: Check support conf.Error


Patch:
diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml
index 21776fd5..2e288a65 100644
--- a/.github/workflows/release-build.yml
+++ b/.github/workflows/release-build.yml
@@ -22,7 +22,7 @@ jobs:
     - name: Set up Go
       uses: actions/setup-go@v4
       with:
-        go-version: 1.18
+        go-version: 1.17
 
     - name: Build
       run: |
diff --git a/go.mod b/go.mod
index 9de7efc3..ec5c16e6 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.18
 require (
 	github.com/fsnotify/fsnotify v1.7.0
 	github.com/goplus/c2go v0.7.17-0.20231102134817-4d12585f3af3
-	github.com/goplus/gox v1.12.2-0.20231102132054-7ebd369dd022
+	github.com/goplus/gox v1.12.2-0.20231102143433-424983d7a5ba
 	github.com/goplus/mod v0.11.8
 	github.com/qiniu/x v1.13.1
 	golang.org/x/tools v0.14.0
diff --git a/go.sum b/go.sum
index 48220eb2..b5329298 100644
--- a/go.sum
+++ b/go.sum
@@ -6,8 +6,9 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/goplus/c2go v0.7.17-0.20231102134817-4d12585f3af3 h1:+/enB6wmQenM2Ihwv/v41lSgdTf3ARPi6A8FB1A/YH4=
 github.com/goplus/c2go v0.7.17-0.20231102134817-4d12585f3af3/go.mod h1:DX0qhR2JSukHgIGMS9f6Vcu0N76LYBQy2tB+UnmIx3U=
-github.com/goplus/gox v1.12.2-0.20231102132054-7ebd369dd022 h1:1g5BzuA9FfZgQwQ4XJXFsNh7KfscSIJfbUp9KkOWY80=
 github.com/goplus/gox v1.12.2-0.20231102132054-7ebd369dd022/go.mod h1:MOJnwqA8/rSUkn0vsayHFK7TD/3XQrdexMTqdzR70X0=
+github.com/goplus/gox v1.12.2-0.20231102143433-424983d7a5ba h1:XPnDAw65OtpBFbR2XQkFz53HXN06ibEHX5xQIDffGXs=
+github.com/goplus/gox v1.12.2-0.20231102143433-424983d7a5ba/go.mod h1:MOJnwqA8/rSUkn0vsayHFK7TD/3XQrdexMTqdzR70X0=
 github.com/goplus/mod v0.11.8 h1:90Kbg+MJhrdsonNGXYx3HUcW4IbBlRHYpIMssJaMMxM=
 github.com/goplus/mod v0.11.8/go.mod h1:yl2QncBKTdXk+8UaNsdo4u2zSpGEJYA5JKjgD3K2h00=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
diff --git a/parser/_instance/instance5/cmd.gop b/parser/_instance/instance5/cmd.gop
index e185d378..b693b560 100644
--- a/parser/_instance/instance5/cmd.gop
+++ b/parser/_instance/instance5/cmd.gop
@@ -1,11 +1,6 @@
 var a [2]int
-
 if 0 < a[0] {
 	println a
-	println M[int]{1}
-	println T[int]{a: 1, b: 2}
-}
-
-for _, i := range []int{7, 42} {
-	println i
+	println T[int]{1}
+	println (T[int]){a:1,b:2}
 }
diff --git a/parser/_instance/instance5/parser.expect b/parser/_instance/instance5/parser.expect
index fb6a2d13..1dc92068 100644
--- a/parser/_instance/instance5/parser.expect
+++ b/parser/_instance/instance5/parser.expect
@@ -70,7 +70,7 @@ ast.FuncDecl:
                             ast.IndexExpr:
                               X:
                                 ast.Ident:
-                                  Name: M
+                                  Name: T
                               Index:
                                 ast.Ident:
                                   Name: int
@@ -87,13 +87,15 @@ ast.FuncDecl:
                       Args:
                         ast.CompositeLit:
                           Type:
-                            ast.IndexExpr:
+                            ast.ParenExpr:
                               X:
-                                ast.Ident:
-                                  Name: T
-                              Index:
-                                ast.Ident:
-                                  Name: int
+                                ast.IndexExpr:
+                                  X:
+                                    ast.Ident:
+                                      Name: T
+                                  Index:
+                                    ast.Ident:
+                                      Name: int
                           Elts:
                             ast.KeyValueExpr:
                               Key:
@@ -111,37 +113,3 @@ ast.FuncDecl:
                                 ast.BasicLit:
                                   Kind: INT
                                   Value: 2
-        ast.RangeStmt:
-          Key:
-            ast.Ident:
-              Name: _
-          Value:
-            ast.Ident:
-              Name: i
-          Tok: :=
-          X:
-            ast.CompositeLit:
-              Type:
-                ast.ArrayType:
-                  Elt:
-                    ast.Ident:
-                      Name: int
-              Elts:
-                ast.BasicLit:
-                  Kind: INT
-                  Value: 7
-                ast.BasicLit:
-                  Kind: INT
-                  Value: 42
-          Body:
-            ast.BlockStmt:
-              List:
-                ast.ExprStmt:
-                  X:
-                    ast.CallExpr:
-                      Fun:
-                        ast.Ident:
-                          Name: println
-                      Args:
-                        ast.Ident:
-                          Name: i
diff --git a/parser/parser.go b/parser/parser.go
index ef1d8a64..5914f55b 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -2068,6 +2068,29 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr {
 	return x
 }
 
+// isLiteralType reports whether x is a legal composite literal type.
+func isLiteralType(x ast.Expr) bool {
+	switch t := unparen(x).(type) {
+	case *ast.BadExpr:
+	case *ast.Ident:
+	case *ast.IndexExpr:
+		_, isIdent := t.X.(*ast.Ident)
+		return isIdent
+	case *ast.IndexListExpr:
+		_, isIdent := t.X.(*ast.Ident)
+		return isIdent
+	case *ast.SelectorExpr:
+		_, isIdent := t.X.(*ast.Ident)
+		return isIdent
+	case *ast.ArrayType:
+	case *ast.StructType:
+	case *ast.MapType:
+	default:
+		return false // all other nodes are not legal composite literal types
+	}
+	return true
+}
+
 /*
 // If x is of the form *T, deref returns T, otherwise it returns x.
 func deref(x ast.Expr) ast.Expr {
@@ -2151,30 +2174,13 @@ L:
 		case token.LBRACE: // {
 			if allowCmd && p.isCmd(x) { // println {...}
 				x = p.parseCallOrConversion(p.checkExprOrType(x), true)
-			} else {
-				t := unparen(x)
-				// determine if '{' belongs to a composite literal or a block statement
-				switch t.(type) {
-				case *ast.BadExpr, *ast.Ident, *ast.SelectorExpr:
-					if p.exprLev < 0 {
-						break L
-					}
-					// x is possibly a composite literal type
-				case *ast.IndexExpr, *ast.IndexListExpr:
-					if p.exprLev < 0 {
-						break L
-					}
-					// x is possibly a composite literal type
-				case *ast.ArrayType, *ast.StructType, *ast.MapType:
-					// x is a composite literal type
-				default:
-					break L
-				}
-				if t != x {
-					p.error(t.Pos(), "cannot parenthesize type in composite literal")
-					// already progressed, no need to advance
+			} else if isLiteralType(x) && p.exprLev >= 0 {
+				if lhs {
+					p.resolve(x)
 				}
 				x = p.parseLiteralValue(x)
+			} else {
+				break L
 			}
 		case token.NOT:
 			if allowCmd && p.isCmd(x) {
@@ -3641,9 +3647,6 @@ func (p *parser) parseGlobalStmts(sync map[token.Token]bool, pos token.Pos, stmt
 	if p.errors.Len() != 0 { // TODO: error
 		p.advance(sync)
 	}
-	if p.tok != token.EOF {
-		p.errorExpected(p.pos, "statement", 2)
-	}
 	f := &ast.FuncDecl{
 		Name: &ast.Ident{NamePos: pos, Name: "main"},
 		Doc:  doc,
diff --git a/x/typesutil/check.go b/x/typesutil/check.go
index 157e7740..71f8ec47 100644
--- a/x/typesutil/check.go
+++ b/x/typesutil/check.go
@@ -26,6 +26,8 @@ import (
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/token"
 	"github.com/goplus/gop/x/typesutil/internal/typesutil"
+	"github.com/goplus/gox"
+	"github.com/qiniu/x/errors"
 	"github.com/qiniu/x/log"
 )
 
@@ -147,6 +149,17 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 		NoSkipConstant: true,
 	})
 	if err != nil {
+		if onErr := conf.Error; onErr != nil {
+			if list, ok := err.(errors.List); ok {
+				for _, e := range list {
+					if ce, ok := convErr(fset, e); ok {
+						onErr(ce)
+					}
+				}
+			} else if ce, ok := convErr(fset, err); ok {
+				onErr(ce)
+			}
+		}
 		if debugPrintErr {
 			log.Println("typesutil.Check err:", err)
 			log.SingleStack()
@@ -194,6 +207,22 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 	return
 }
 
+func convErr(fset *token.FileSet, e error) (*types.Error, bool) {
+	switch v := e.(type) {
+	case *gox.CodeError:
+		return &types.Error{Fset: fset, Pos: v.Pos, Msg: v.Msg}, true
+	case *gox.MatchError:
+		pos := token.NoPos
+		if v.Src != nil {
+			pos = v.Src.Pos()
+		}
+		return &types.Error{Fset: fset, Pos: pos, Msg: v.Message("")}, true
+	case *gox.ImportError:
+		return &types.Error{Fset: fset, Pos: v.Pos, Msg: v.Err.Error()}, true
+	}
+	return nil, false
+}
+
 func scopeDelete(objMap map[types.Object]types.Object, scope *types.Scope, name string) {
 	if o := typesutil.ScopeDelete(scope, name); o != nil {
 		objMap[o] = nil


Test patch:
diff --git a/parser/parser_test.go b/parser/parser_test.go
index a387edc4..76fe912d 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -508,14 +508,4 @@ const d
 `, `/foo/bar.gox:5:7: missing constant value`, ``)
 }
 
-func TestErrGlobal(t *testing.T) {
-	testErrCode(t, `func test() {}
-}`, `/foo/bar.gop:2:1: expected statement, found '}'`, ``)
-}
-
-func TestErrCompositeLiteral(t *testing.T) {
-	testErrCode(t, `println (T[int]){a: 1, b: 2}
-`, `/foo/bar.gop:1:10: cannot parenthesize type in composite literal`, ``)
-}
-
 // -----------------------------------------------------------------------------