Repository: goplus/gop
Pull request #920 (2021-11-22 00:24:26)

cl: fix getTypeLoader redefine
fix  getTypeLoader  panic("TODO: redefine")


Patch:
diff --git a/cl/compile.go b/cl/compile.go
index b49bb941..67ae7f88 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -232,11 +232,19 @@ type typeLoader struct {
 	start        token.Pos
 }
 
-func getTypeLoader(syms map[string]loader, start token.Pos, name string) *typeLoader {
+func getTypeLoader(ctx *pkgCtx, syms map[string]loader, start token.Pos, name string) *typeLoader {
 	t, ok := syms[name]
 	if ok {
 		if start != token.NoPos {
-			panic("TODO: redefine")
+			ld := t.(*typeLoader)
+			if ld.start == token.NoPos {
+				ld.start = start
+			} else {
+				pos := ctx.Position(start)
+				ctx.handleCodeErrorf(&pos, "%s redeclared in this block\n\tprevious declaration at %v",
+					name, ctx.Position(ld.start))
+			}
+			return ld
 		}
 	} else {
 		t = &typeLoader{start: start}
@@ -479,7 +487,7 @@ func loadFile(ctx *pkgCtx, f *ast.File) {
 				}
 			} else {
 				if name, ok := getRecvTypeName(ctx, d.Recv, false); ok {
-					getTypeLoader(ctx.syms, token.NoPos, name).load()
+					getTypeLoader(ctx, ctx.syms, token.NoPos, name).load()
 				}
 			}
 		case *ast.GenDecl:
@@ -536,7 +544,7 @@ func preloadFile(p *gox.Package, parent *pkgCtx, file string, f *ast.File, targe
 		}
 		pos := f.Pos()
 		specs := getFields(ctx, f)
-		ld := getTypeLoader(syms, pos, classType)
+		ld := getTypeLoader(parent, syms, pos, classType)
 		ld.typ = func() {
 			if debugLoad {
 				log.Println("==> Load > NewType", classType)
@@ -608,7 +616,7 @@ func preloadFile(p *gox.Package, parent *pkgCtx, file string, f *ast.File, targe
 					if debugLoad {
 						log.Printf("==> Preload method %s.%s\n", name, d.Name.Name)
 					}
-					ld := getTypeLoader(syms, token.NoPos, name)
+					ld := getTypeLoader(parent, syms, token.NoPos, name)
 					ld.methods = append(ld.methods, func() {
 						old := p.SetInTestingFile(testingFile)
 						defer p.SetInTestingFile(old)
@@ -632,7 +640,7 @@ func preloadFile(p *gox.Package, parent *pkgCtx, file string, f *ast.File, targe
 					if debugLoad {
 						log.Println("==> Preload type", name)
 					}
-					ld := getTypeLoader(syms, t.Name.Pos(), name)
+					ld := getTypeLoader(parent, syms, t.Name.Pos(), name)
 					ld.typ = func() {
 						old := p.SetInTestingFile(testingFile)
 						defer p.SetInTestingFile(old)


Test patch:
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 27b6c631..8e9f35d5 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -3268,3 +3268,29 @@ func main() {
 }
 `)
 }
+
+func TestTypeLoader(t *testing.T) {
+	gopClTest(t, `import "fmt"
+
+func (p *Point) String() string {
+	return fmt.Sprintf("%v-%v",p.X,p.Y)
+}
+
+type Point struct {
+	X int
+	Y int
+}
+`, `package main
+
+import fmt "fmt"
+
+type Point struct {
+	X int
+	Y int
+}
+
+func (p *Point) String() string {
+	return fmt.Sprintf("%v-%v", p.X, p.Y)
+}
+`)
+}
diff --git a/cl/error_msg_test.go b/cl/error_msg_test.go
index a8595c50..95cc9310 100644
--- a/cl/error_msg_test.go
+++ b/cl/error_msg_test.go
@@ -609,3 +609,21 @@ func TestErrNoEntrypoint(t *testing.T) {
 println abc
 `)
 }
+
+func TestErrTypeRedefine(t *testing.T) {
+	codeErrorTest(t,
+		"./bar.gop:9:6: Point redeclared in this block\n\tprevious declaration at ./bar.gop:5:6",
+		`import "fmt"
+func (p *Point) String() string {
+	return fmt.Sprintf("%v-%v",p.X,p.Y)
+}
+type Point struct {
+	X int
+	Y int
+}
+type Point struct {
+	X int
+	Y int
+}
+`)
+}