nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: goplus/gop
Pull request #1495 (2023-10-26 11:50:22)

update gox; TestGenericTypeCompositeLit


Patch:
diff --git a/go.mod b/go.mod
index 9f5c3012..c860cb1b 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.16
-	github.com/goplus/gox v1.12.2-0.20231024165412-08fb2524d4a0
+	github.com/goplus/gox v1.12.2-0.20231026084726-48d24f42e91f
 	github.com/goplus/mod v0.11.8-0.20231019172744-da5848421263
 	github.com/qiniu/x v1.13.1
 	golang.org/x/tools v0.14.0
diff --git a/go.sum b/go.sum
index f4e77783..51af496d 100644
--- a/go.sum
+++ b/go.sum
@@ -7,8 +7,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
 github.com/goplus/c2go v0.7.16 h1:B9jRNNytoq7yDBQOZSm2qENQhRQMfNhgOea5XHWNUnI=
 github.com/goplus/c2go v0.7.16/go.mod h1:XODEFX2PeEEJXNLLdykWeZgMSaKJ51fVm+C9IM3FxNQ=
 github.com/goplus/gox v1.12.1/go.mod h1:wymoQJ7ydd42cTlaXb4wNbvn4LlKjR+j8PZehI7v1zQ=
-github.com/goplus/gox v1.12.2-0.20231024165412-08fb2524d4a0 h1:60n144rwLnIapa5Vs9LIhh6QeaKrI26eWh0eJLVL4eM=
-github.com/goplus/gox v1.12.2-0.20231024165412-08fb2524d4a0/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ=
+github.com/goplus/gox v1.12.2-0.20231026084726-48d24f42e91f h1:WGAwExBl2dwEopwlAdnnfbTRiStvTUasONduDWxirlU=
+github.com/goplus/gox v1.12.2-0.20231026084726-48d24f42e91f/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ=
 github.com/goplus/mod v0.11.5/go.mod h1:NDC5E+XOT8vcJCMjqKhLDJHTHX7lyVN4Vbfi2U7dBhs=
 github.com/goplus/mod v0.11.8-0.20231019172744-da5848421263 h1:PE0HveOss5mai9pa52L4/ZvVqZtltogJ9rIUIsdlG/I=
 github.com/goplus/mod v0.11.8-0.20231019172744-da5848421263/go.mod h1:yl2QncBKTdXk+8UaNsdo4u2zSpGEJYA5JKjgD3K2h00=


Test patch:
diff --git a/cl/typeparams_test.go b/cl/typeparams_test.go
index c700ce1d..a3b71457 100644
--- a/cl/typeparams_test.go
+++ b/cl/typeparams_test.go
@@ -591,3 +591,38 @@ func test(v1 int, v2 *Data) {
 }
 `)
 }
+
+func TestGenericTypeCompositeLit(t *testing.T) {
+	gopMixedClTest(t, "main", `package main
+type A[T any] struct {
+	m T
+}
+
+type B[T any] struct {
+	n A[T]
+}
+
+`, `
+var a [2]int
+if 0 == a[1] {
+	println "world"
+}
+println B[int]{}.n
+if 0 < (B[int]{}).n.m {
+}
+`, `package main
+
+import "fmt"
+
+var a [2]int
+
+func main() {
+	if 0 == a[1] {
+		fmt.Println("world")
+	}
+	fmt.Println(B[int]{}.n)
+	if 0 < (B[int]{}).n.m {
+	}
+}
+`)
+}
Repository: goplus/gop
Pull request #1557 (2023-11-25 06:33:26)

cl: offsetFileLine use slash


Patch:
diff --git a/cl/stmt.go b/cl/stmt.go
index 805646b5..3998dbb1 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -47,7 +47,7 @@ func offsetFileLine(ctx *blockCtx, file string) string {
 		file = filepath.Join(ctx.fileLineWorkingDir, file)
 	}
 	if ret, err := filepath.Rel(ctx.fileLineRoot, file); err == nil {
-		return ret
+		return filepath.ToSlash(ret)
 	}
 	return file
 }


Test patch:
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 52022aeb..3f91ef2c 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -4710,7 +4710,7 @@ func main() {
 }
 `
 	if runtime.GOOS == "windows" {
-		expected = strings.Replace(expected, "../", `..\foo\`, -1)
+		expected = strings.Replace(expected, "../", `../foo/`, -1)
 	}
 	gopClTestEx(t, &conf, "main", src, expected)
 }
Repository: goplus/gop
Pull request #1569 (2023-12-10 04:09:04)

cl: record compileRangeStmt defined


Patch:
diff --git a/cl/stmt.go b/cl/stmt.go
index 3998dbb1..cda0a97d 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -327,15 +327,20 @@ func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) {
 	}
 	cb := ctx.cb
 	comments, once := cb.BackupComments()
+	var defineNames []*ast.Ident
 	if v.Tok == token.DEFINE {
 		names := make([]string, 1, 2)
 		if v.Key == nil {
 			names[0] = "_"
 		} else {
-			names[0] = v.Key.(*ast.Ident).Name
+			key := v.Key.(*ast.Ident)
+			names[0] = key.Name
+			defineNames = append(defineNames, key)
 		}
 		if v.Value != nil {
-			names = append(names, v.Value.(*ast.Ident).Name)
+			value := v.Value.(*ast.Ident)
+			names = append(names, value.Name)
+			defineNames = append(defineNames, value)
 		}
 		cb.ForRangeEx(names, v)
 		compileExpr(ctx, v.X)
@@ -362,6 +367,9 @@ func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) {
 		pos = v.For
 	}
 	cb.RangeAssignThen(pos) // TODO: need NewScope for body
+	if len(defineNames) > 0 {
+		defNames(ctx, defineNames, cb.Scope())
+	}
 	compileStmts(ctx, v.Body.List)
 	cb.SetComments(comments, once)
 	setBodyHandler(ctx)


Test patch:
diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go
index 61304e96..91c7c0df 100644
--- a/x/typesutil/info_test.go
+++ b/x/typesutil/info_test.go
@@ -405,3 +405,23 @@ func test() {
 }
 `)
 }
+
+func TestRange(t *testing.T) {
+	testInfo(t, `package main
+func test() {
+	a := []int{100,200}
+	for k, v := range a {
+		_ = k
+		_ = v
+	}
+	var m map[int]string
+	for k, v := range m {
+		_ = k
+		_ = v
+	}
+	for v := range m {
+		_ = v
+	}
+}
+`)
+}
Repository: goplus/gop
Pull request #1571 (2023-12-10 12:02:00)

cl: types record funlit


Patch:
diff --git a/cl/expr.go b/cl/expr.go
index 6f7c9b46..a6191d3e 100644
--- a/cl/expr.go
+++ b/cl/expr.go
@@ -708,6 +708,9 @@ func compileFuncLit(ctx *blockCtx, v *ast.FuncLit) {
 	cb := ctx.cb
 	comments, once := cb.BackupComments()
 	sig := toFuncType(ctx, v.Type, nil, nil)
+	if rec := ctx.recorder(); rec != nil {
+		rec.recordFuncLit(ctx, v, sig)
+	}
 	fn := cb.NewClosureWith(sig)
 	if body := v.Body; body != nil {
 		loadFuncBody(ctx, fn, body, v)
diff --git a/cl/recorder.go b/cl/recorder.go
index 385a7b50..e4820274 100644
--- a/cl/recorder.go
+++ b/cl/recorder.go
@@ -108,6 +108,11 @@ func (rec *typesRecorder) recordCompositeLit(ctx *blockCtx, v *ast.CompositeLit,
 	rec.Type(v, typesutil.NewTypeAndValueForValue(typ, nil, typesutil.Value))
 }
 
+func (rec *typesRecorder) recordFuncLit(ctx *blockCtx, v *ast.FuncLit, typ types.Type) {
+	rec.Type(v.Type, typesutil.NewTypeAndValueForType(typ))
+	rec.Type(v, typesutil.NewTypeAndValueForValue(typ, nil, typesutil.Value))
+}
+
 func (rec *typesRecorder) recordType(ctx *blockCtx, typ ast.Expr, t types.Type) {
 	rec.Type(typ, typesutil.NewTypeAndValueForType(t))
 }


Test patch:
diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go
index 91c7c0df..f69f6ddf 100644
--- a/x/typesutil/info_test.go
+++ b/x/typesutil/info_test.go
@@ -425,3 +425,18 @@ func test() {
 }
 `)
 }
+
+func TestFuncLit(t *testing.T) {
+	testInfo(t, `package main
+func test() {
+	add := func(n1 int, n2 int) int {
+		return n1+n2
+	}
+	_ = add(1,2)
+
+	go func(n int) {
+		_ = n+100
+	}(100)
+}
+`)
+}
Repository: goplus/gop
Pull request #1573 (2023-12-12 02:01:39)

rollbak mv cmd/make.go


Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 1fa5d407..8970d496 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -25,7 +25,7 @@ jobs:
       run: |
         git config --global user.email "build-robot@goplus.org"
         git config --global user.name "build robot"
-        go test -v cmd/make/make_test.go
+        go test -v cmd/make_test.go
 
     - name: Compile gop and related tools
       run: go install ./...
diff --git a/Makefile b/Makefile
index 05ef5e31..bddf0767 100644
--- a/Makefile
+++ b/Makefile
@@ -10,12 +10,12 @@ clean:
 	rm -f bin/*
 
 build:
-	go run cmd/make/make.go -build
+	go run cmd/make.go -build
 
 dist:
 	$(MAKE) clean
 	mkdir -p bin/
-	go build -o $(BUILD_ROOT_DIR)/make cmd/make/make.go
+	go build -o $(BUILD_ROOT_DIR)/make cmd/make.go
 	$(MAKE) build-all
 
 build-all: darwin-amd64.zip darwin-arm64.zip linux-386.zip linux-amd64.zip \
diff --git a/all.bash b/all.bash
index b7887680..8fe94a61 100755
--- a/all.bash
+++ b/all.bash
@@ -18,4 +18,4 @@
 
 set -ex
 
-go run cmd/make/make.go --install --autoproxy
+go run cmd/make.go --install --autoproxy
diff --git a/all.bat b/all.bat
index f8689047..5395a855 100644
--- a/all.bat
+++ b/all.bat
@@ -1,1 +1,1 @@
-go run cmd/make/make.go --install --autoproxy
+go run cmd/make.go --install --autoproxy
diff --git a/make.bash b/make.bash
index b7887680..8fe94a61 100755
--- a/make.bash
+++ b/make.bash
@@ -18,4 +18,4 @@
 
 set -ex
 
-go run cmd/make/make.go --install --autoproxy
+go run cmd/make.go --install --autoproxy
diff --git a/make.bat b/make.bat
index f8689047..5395a855 100644
--- a/make.bat
+++ b/make.bat
@@ -1,1 +1,1 @@
-go run cmd/make/make.go --install --autoproxy
+go run cmd/make.go --install --autoproxy


Test patch:
diff --git a/cmd/make/make.go b/cmd/make.go
similarity index 100%
rename from cmd/make/make.go
rename to cmd/make.go
diff --git a/cmd/make/make_test.go b/cmd/make_test.go
similarity index 99%
rename from cmd/make/make_test.go
rename to cmd/make_test.go
index a5556e7c..e1ae186d 100644
--- a/cmd/make/make_test.go
+++ b/cmd/make_test.go
@@ -21,7 +21,7 @@ const (
 var script = "all.bash"
 var gopRoot = ""
 var gopBinFiles = []string{"gop", "gopfmt"}
-var installer = "cmd/make/make.go"
+var installer = "cmd/make.go"
 var versionFile = "VERSION"
 var mainVersionFile = "env/version.go"
 
@@ -79,7 +79,7 @@ func detectGoBinPath() string {
 
 func init() {
 	pwd, _ := os.Getwd()
-	gopRoot = filepath.Join(pwd, "../..")
+	gopRoot = filepath.Join(pwd, "..")
 	installer = filepath.Join(gopRoot, installer)
 	versionFile = filepath.Join(gopRoot, versionFile)
 	mainVersionFile = filepath.Join(gopRoot, mainVersionFile)
Repository: goplus/gop
Pull request #1610 (2024-01-07 23:41:53)

newGmx bugfix: use classNameAndExt


Patch:
diff --git a/cl/classfile.go b/cl/classfile.go
index e3490163..f7f90b36 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -70,20 +70,16 @@ func classNameAndExt(file string) (name, ext string) {
 }
 
 func newGmx(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Config) *gmxSettings {
-	fname := filepath.Base(file)
-	ext := modfile.ClassExt(fname)
+	tname, ext := classNameAndExt(file)
 	gt, ok := conf.LookupClass(ext)
 	if !ok {
 		panic("TODO: class not found")
 	}
 	var name string
 	if f.IsProj {
-		_, name = filepath.Split(file)
-		if idx := strings.Index(name, "."); idx > 0 {
-			name = name[:idx]
-			if name == "main" {
-				name = gt.Class
-			}
+		name = tname
+		if name == "main" {
+			name = gt.Class
 		}
 	}
 	pkgPaths := gt.PkgPaths


Test patch:
diff --git a/cl/builtin_test.go b/cl/builtin_test.go
index 759150d7..899c5895 100644
--- a/cl/builtin_test.go
+++ b/cl/builtin_test.go
@@ -225,6 +225,15 @@ func TestGmxSettings(t *testing.T) {
 	if e := err.Error(); e != `github.com/goplus/gop/cl/internal/libc.Game not found` {
 		t.Fatal("newGmx:", e)
 	}
+
+	defer func() {
+		if e := recover(); e == nil {
+			t.Fatal("TestGmxSettings failed: no error?")
+		}
+	}()
+	newGmx(nil, pkg, "main.abcx", &ast.File{IsProj: true}, &Config{
+		LookupClass: lookupClass,
+	})
 }
 
 func TestSpxLookup(t *testing.T) {
Repository: goplus/gop
Pull request #1612 (2024-01-10 07:49:26)

cl: export classNameAndExt


Patch:
diff --git a/cl/classfile.go b/cl/classfile.go
index f7f90b36..72777289 100644
--- a/cl/classfile.go
+++ b/cl/classfile.go
@@ -60,7 +60,7 @@ func (p *gmxSettings) getScheds(cb *gox.CodeBuilder) []goast.Stmt {
 	return p.schedStmts
 }
 
-func classNameAndExt(file string) (name, ext string) {
+func ClassNameAndExt(file string) (name, ext string) {
 	fname := filepath.Base(file)
 	name, ext = modfile.SplitFname(fname)
 	if idx := strings.Index(name, "."); idx > 0 {
@@ -70,7 +70,7 @@ func classNameAndExt(file string) (name, ext string) {
 }
 
 func newGmx(ctx *pkgCtx, pkg *gox.Package, file string, f *ast.File, conf *Config) *gmxSettings {
-	tname, ext := classNameAndExt(file)
+	tname, ext := ClassNameAndExt(file)
 	gt, ok := conf.LookupClass(ext)
 	if !ok {
 		panic("TODO: class not found")
diff --git a/cl/compile.go b/cl/compile.go
index d1193145..696be932 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -696,7 +696,7 @@ func preloadGopFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, con
 		}
 	case f.IsClass:
 		var classExt string
-		classType, classExt = classNameAndExt(file)
+		classType, classExt = ClassNameAndExt(file)
 		if parent.gmxSettings != nil {
 			o, ok := parent.sprite[classExt]
 			if ok {


Test patch:
diff --git a/cl/builtin_test.go b/cl/builtin_test.go
index 899c5895..5df2153d 100644
--- a/cl/builtin_test.go
+++ b/cl/builtin_test.go
@@ -40,7 +40,7 @@ func getGoxConf() *gox.Config {
 }
 
 func TestClassNameAndExt(t *testing.T) {
-	name, ext := classNameAndExt("/foo/bar.abc_yap.gox")
+	name, ext := ClassNameAndExt("/foo/bar.abc_yap.gox")
 	if name != "bar" || ext != "_yap.gox" {
 		t.Fatal("classNameAndExt:", name, ext)
 	}
Repository: goplus/gop
Pull request #1618 (2024-01-11 01:33:17)

parser: fix ParseFSEntry for new class mode


Patch:
diff --git a/parser/parser_gop.go b/parser/parser_gop.go
index 77cf548c..d2befd9d 100644
--- a/parser/parser_gop.go
+++ b/parser/parser_gop.go
@@ -190,32 +190,23 @@ func ParseFSDir(fset *token.FileSet, fs FileSystem, dir string, conf Config) (pk
 // Compared to ParseFSFile, ParseFSEntry detects fileKind by its filename.
 func ParseFSEntry(fset *token.FileSet, fs FileSystem, filename string, src interface{}, conf Config) (f *ast.File, err error) {
 	fname := fs.Base(filename)
-	fnameRmGox := fname
 	ext := path.Ext(fname)
-	var isProj, isClass, isNormalGox, rmGox bool
+	var isProj, isClass, isNormalGox bool
 	switch ext {
 	case ".gop", ".go":
 	case ".gox":
-		isClass = true
-		t := fname[:len(fname)-4]
-		if c := path.Ext(t); c != "" {
-			fnameRmGox, rmGox = t, true
-		} else {
-			isNormalGox = true
-		}
+		isNormalGox = true
 		fallthrough
 	default:
-		if !isNormalGox {
-			if conf.ClassKind == nil {
-				conf.ClassKind = defaultClassKind
-			}
-			if isProj, isClass = conf.ClassKind(fnameRmGox); !isClass {
-				if !rmGox {
-					return nil, ErrUnknownFileKind
-				}
-				// not found Go+ class by ext, but is a .gox file
-				isClass, isNormalGox = true, true
-			}
+		if conf.ClassKind == nil {
+			conf.ClassKind = defaultClassKind
+		}
+		if isProj, isClass = conf.ClassKind(fname); isClass {
+			isNormalGox = false
+		} else if isNormalGox { // not found Go+ class by ext, but is a .gox file
+			isClass = true
+		} else {
+			return nil, ErrUnknownFileKind
 		}
 	}
 	mode := conf.Mode


Test patch:
diff --git a/parser/parserdir_test.go b/parser/parserdir_test.go
index ff925701..ca6686dc 100644
--- a/parser/parserdir_test.go
+++ b/parser/parserdir_test.go
@@ -194,6 +194,30 @@ func TestParseEntry(t *testing.T) {
 	})
 }
 
+func TestParseEntry2(t *testing.T) {
+	fset := token.NewFileSet()
+	src, err := os.ReadFile("./_testdata/functype/functype.go")
+	if err != nil {
+		t.Fatal("os.ReadFile:", err)
+	}
+	conf := Config{}
+	conf.ClassKind = func(fname string) (isProj bool, ok bool) {
+		if strings.HasSuffix(fname, "_yap.gox") {
+			return true, true
+		}
+		return defaultClassKind(fname)
+	}
+	t.Run("_yap.gox file", func(t *testing.T) {
+		f, err := ParseEntry(fset, "./functype_yap.gox", src, conf)
+		if err != nil {
+			t.Fatal("ParseEntry failed:", err)
+		}
+		if !f.IsClass || !f.IsProj || f.IsNormalGox {
+			t.Fatal("ParseEntry functype_yap.gox:", f.IsClass, f.IsProj, f.IsNormalGox)
+		}
+	})
+}
+
 func TestSaveAbsFile(t *testing.T) {
 	fset := token.NewFileSet()
 	src, err := os.ReadFile("./_testdata/functype/functype.go")
Repository: goplus/gop
Pull request #1623 (2024-01-12 12:08:42)

x/typesutil: fix checker.Files skip bad file


Patch:
diff --git a/x/typesutil/check.go b/x/typesutil/check.go
index f9165056..dad82567 100644
--- a/x/typesutil/check.go
+++ b/x/typesutil/check.go
@@ -111,6 +111,9 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 	gopfs := make(map[string]*ast.File)
 	for _, goFile := range goFiles {
 		f := fset.File(goFile.Pos())
+		if f == nil {
+			continue
+		}
 		file := f.Name()
 		fname := filepath.Base(file)
 		if strings.HasPrefix(fname, "gop_autogen") {
@@ -121,6 +124,9 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 	}
 	for _, gopFile := range gopFiles {
 		f := fset.File(gopFile.Pos())
+		if f == nil {
+			continue
+		}
 		gopfs[f.Name()] = gopFile
 	}
 	if debugVerbose {


Test patch:
diff --git a/x/typesutil/check_test.go b/x/typesutil/check_test.go
index fbbbe0ac..703118c1 100644
--- a/x/typesutil/check_test.go
+++ b/x/typesutil/check_test.go
@@ -185,3 +185,13 @@ var i int = "hello"
 		t.Fatal("no error")
 	}
 }
+
+func TestBadFile(t *testing.T) {
+	conf := &types.Config{}
+	opt := &typesutil.Config{}
+	opt.Fset = token.NewFileSet()
+	opt.Types = types.NewPackage("", "main")
+	checker := typesutil.NewChecker(conf, opt, nil, nil)
+	_ = checker.Files([]*goast.File{&goast.File{Name: goast.NewIdent("main")}},
+		[]*ast.File{&ast.File{Name: ast.NewIdent("main")}})
+}
Repository: goplus/gop
Pull request #1628 (2024-01-13 07:53:12)

cl: toType error return types.Invalid


Patch:
diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go
index ca8a37f1..6d195d2a 100644
--- a/cl/func_type_and_var.go
+++ b/cl/func_type_and_var.go
@@ -21,7 +21,6 @@ import (
 	"go/types"
 	"log"
 	"math/big"
-	"reflect"
 	"strconv"
 
 	"github.com/goplus/gop/ast"
@@ -179,9 +178,10 @@ func toType(ctx *blockCtx, typ ast.Expr) (t types.Type) {
 		return toIndexType(ctx, v)
 	case *ast.IndexListExpr:
 		return toIndexListType(ctx, v)
+	default:
+		ctx.handleErrorf(v.Pos(), "toType unexpected: %T", v)
+		return types.Typ[types.Invalid]
 	}
-	log.Panicln("toType: unknown -", reflect.TypeOf(typ))
-	return nil
 }
 
 var (


Test patch:
diff --git a/cl/error_msg_test.go b/cl/error_msg_test.go
index fe2bf1df..4a4e1a58 100644
--- a/cl/error_msg_test.go
+++ b/cl/error_msg_test.go
@@ -23,6 +23,7 @@ import (
 	"runtime"
 	"testing"
 
+	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/cl"
 	"github.com/goplus/gop/parser"
 	"github.com/goplus/gop/parser/fsx/memfs"
@@ -53,6 +54,24 @@ func codeErrorTestEx(t *testing.T, pkgname, filename, msg, src string) {
 	}
 }
 
+func codeErrorTestAst(t *testing.T, pkgname, filename, msg, src string) {
+	f, _ := parser.ParseFile(gblFset, filename, src, parser.AllErrors)
+	pkg := &ast.Package{
+		Name:  pkgname,
+		Files: map[string]*ast.File{filename: f},
+	}
+	conf := *gblConf
+	conf.NoFileLine = false
+	conf.RelativeBase = "/foo"
+	_, err := cl.NewPackage("", pkg, &conf)
+	if err == nil {
+		t.Fatal("no error?")
+	}
+	if ret := err.Error(); ret != msg {
+		t.Fatalf("\nError: \"%s\"\nExpected: \"%s\"\n", ret, msg)
+	}
+}
+
 func TestErrLambdaExpr(t *testing.T) {
 	codeErrorTest(t,
 		"bar.gop:7:6: too few arguments in lambda expression\n\thave ()\n\twant (int, int)", `
@@ -969,3 +988,10 @@ func TestErrCompileFunc(t *testing.T) {
 printf("%+v\n", int32)
 `)
 }
+
+func TestToTypeError(t *testing.T) {
+	codeErrorTestAst(t, "main", "bar.gop", `bar.gop:3:3: toType unexpected: *ast.BadExpr`, `
+type
+a := 1
+`)
+}
Repository: goplus/gop
Pull request #1643 (2024-01-18 22:47:56)

gop fmt .gox bugfix


Patch:
diff --git a/printer/nodes.go b/printer/nodes.go
index b4b0851b..4bbf900a 100644
--- a/printer/nodes.go
+++ b/printer/nodes.go
@@ -1705,7 +1705,9 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
 		p.setComment(s.Doc)
 		p.identList(s.Names, doIndent) // always present
 		if s.Type != nil {
-			p.print(blank)
+			if len(s.Names) > 0 {
+				p.print(blank)
+			}
 			p.expr(s.Type)
 		}
 		if s.Values != nil {


Test patch:
diff --git a/parser/_testdata/goxtest/bar.gox b/parser/_testdata/goxtest1/bar.gox
similarity index 100%
rename from parser/_testdata/goxtest/bar.gox
rename to parser/_testdata/goxtest1/bar.gox
diff --git a/parser/_testdata/goxtest/parser.expect b/parser/_testdata/goxtest1/parser.expect
similarity index 100%
rename from parser/_testdata/goxtest/parser.expect
rename to parser/_testdata/goxtest1/parser.expect
diff --git a/parser/_testdata/goxtest2/bar.gox b/parser/_testdata/goxtest2/bar.gox
new file mode 100644
index 00000000..954f1881
--- /dev/null
+++ b/parser/_testdata/goxtest2/bar.gox
@@ -0,0 +1,3 @@
+var (
+	x.App
+)
diff --git a/parser/_testdata/goxtest2/parser.expect b/parser/_testdata/goxtest2/parser.expect
new file mode 100644
index 00000000..43479424
--- /dev/null
+++ b/parser/_testdata/goxtest2/parser.expect
@@ -0,0 +1,15 @@
+package main
+
+file bar.gox
+ast.GenDecl:
+  Tok: var
+  Specs:
+    ast.ValueSpec:
+      Type:
+        ast.SelectorExpr:
+          X:
+            ast.Ident:
+              Name: x
+          Sel:
+            ast.Ident:
+              Name: App
diff --git a/printer/gop_test.go b/printer/gop_test.go
index 30bd7aba..8aadd297 100644
--- a/printer/gop_test.go
+++ b/printer/gop_test.go
@@ -19,7 +19,6 @@ package printer_test
 import (
 	"bytes"
 	"io/fs"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -114,7 +113,7 @@ func testFrom(t *testing.T, fpath, sel string, mode int) {
 	if sel != "" && !strings.Contains(fpath, sel) {
 		return
 	}
-	src, err := ioutil.ReadFile(fpath)
+	src, err := os.ReadFile(fpath)
 	if err != nil {
 		t.Fatal(err)
 	}
Repository: goplus/gop
Pull request #1646 (2024-01-20 05:44:34)

stringLitEx bugfix: stringex3


Patch:
diff --git a/parser/parser.go b/parser/parser.go
index cab4ab32..83d27eb5 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -1635,7 +1635,7 @@ loop:
 		}
 		to := pos + token.Pos(from+end)
 		parts = p.stringLitExpr(parts, pos+token.Pos(from), to)
-		pos = to
+		pos = to + 1
 		text = left[end+1:]
 	case '$': // $$
 		parts = append(parts, text[:at+2])
@@ -1674,7 +1674,8 @@ func hasExtra(text string) bool {
 func (p *parser) stringLitExpr(parts []any, off, end token.Pos) []any {
 	file := p.file
 	base := file.Base()
-	expr, err := parseExprEx(p.file, p.scanner.CodeTo(int(end)-base), int(off)-base, 0)
+	src := p.scanner.CodeTo(int(end) - base)
+	expr, err := parseExprEx(p.file, src, int(off)-base, 0)
 	if err != nil {
 		p.errors = append(p.errors, err...)
 		expr = &ast.BadExpr{From: off, To: end}


Test patch:
diff --git a/parser/_testdata/stringex3/parser.expect b/parser/_testdata/stringex3/parser.expect
new file mode 100644
index 00000000..320578eb
--- /dev/null
+++ b/parser/_testdata/stringex3/parser.expect
@@ -0,0 +1,38 @@
+package main
+
+file string_lit.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.BasicLit:
+                  Kind: STRING
+                  Value: "file:${args[0]}?${query}"
+                    Extra:
+                      file:
+                      ast.IndexExpr:
+                        X:
+                          ast.Ident:
+                            Name: args
+                        Index:
+                          ast.BasicLit:
+                            Kind: INT
+                            Value: 0
+                      ?
+                      ast.Ident:
+                        Name: query
diff --git a/parser/_testdata/stringex3/string_lit.gop b/parser/_testdata/stringex3/string_lit.gop
new file mode 100644
index 00000000..fdb21995
--- /dev/null
+++ b/parser/_testdata/stringex3/string_lit.gop
@@ -0,0 +1,1 @@
+println "file:${args[0]}?${query}"