Repository: goplus/gop
Pull request #1595 (2024-01-06 07:53:03)

add conf.RelativeBase and rm conf.WorkingDir/TargetDir/FileLineRoot


Patch:
diff --git a/cl/compile.go b/cl/compile.go
index fc8ffc07..32adce82 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -22,8 +22,6 @@ import (
 	"go/constant"
 	"go/types"
 	"log"
-	"os"
-	"path/filepath"
 	"reflect"
 	"sort"
 	"strings"
@@ -174,13 +172,8 @@ type Config struct {
 	// Fset provides source position information for syntax trees and types (required).
 	Fset *token.FileSet
 
-	// WorkingDir is the directory in which to run gop compiler (optional).
-	// If WorkingDir is not set, os.Getwd() is used.
-	WorkingDir string
-
-	// TargetDir is the directory in which to generate Go files (optional).
-	// If TargetDir is not set, it is same as WorkingDir.
-	TargetDir string
+	// RelativeBase is the root directory of relative path.
+	RelativeBase string
 
 	// C2goBase specifies base of standard c2go packages (optional).
 	// Default is github.com/goplus/.
@@ -204,12 +197,6 @@ type Config struct {
 	// NoFileLine = true means not to generate file line comments.
 	NoFileLine bool
 
-	// RelativePath = true means to generate file line comments with relative file path.
-	RelativePath bool
-
-	// FileLineRoot set means generate file line comments start with root path.
-	FileLineRoot string
-
 	// NoAutoGenMain = true means not to auto generate main func is no entry.
 	NoAutoGenMain bool
 
@@ -223,13 +210,13 @@ type Config struct {
 type nodeInterp struct {
 	fset       *token.FileSet
 	files      map[string]*ast.File
-	workingDir string
+	relBaseDir string
 }
 
-func (p *nodeInterp) Position(start token.Pos) token.Position {
-	pos := p.fset.Position(start)
-	pos.Filename = relFile(p.workingDir, pos.Filename)
-	return pos
+func (p *nodeInterp) Position(start token.Pos) (pos token.Position) {
+	pos = p.fset.Position(start)
+	pos.Filename = relFile(p.relBaseDir, pos.Filename)
+	return
 }
 
 func (p *nodeInterp) Caller(node ast.Node) string {
@@ -354,9 +341,6 @@ type pkgCtx struct {
 	generics map[string]bool // generic type record
 	idents   []*ast.Ident    // toType ident recored
 	inInst   int             // toType in generic instance
-
-	fileLineRoot       string // comment file line start root
-	fileLineWorkingDir string // comment file line working dir
 }
 
 type pkgImp struct {
@@ -366,21 +350,20 @@ type pkgImp struct {
 
 type blockCtx struct {
 	*pkgCtx
-	pkg          *gox.Package
-	cb           *gox.CodeBuilder
-	imports      map[string]pkgImp
-	lookups      []*gox.PkgRef
-	clookups     []*cpackages.PkgRef
-	tlookup      *typeParamLookup
-	c2goBase     string // default is `github.com/goplus/`
-	targetDir    string
-	classRecv    *ast.FieldList // available when gmxSettings != nil
-	fileScope    *types.Scope   // only valid when isGopFile
-	rec          *typesRecorder
-	fileLine     bool
-	relativePath bool
-	isClass      bool
-	isGopFile    bool // is Go+ file or not
+	pkg        *gox.Package
+	cb         *gox.CodeBuilder
+	imports    map[string]pkgImp
+	lookups    []*gox.PkgRef
+	clookups   []*cpackages.PkgRef
+	tlookup    *typeParamLookup
+	c2goBase   string // default is `github.com/goplus/`
+	relBaseDir string
+	classRecv  *ast.FieldList // available when gmxSettings != nil
+	fileScope  *types.Scope   // only valid when isGopFile
+	rec        *typesRecorder
+	fileLine   bool
+	isClass    bool
+	isGopFile  bool // is Go+ file or not
 }
 
 func (bc *blockCtx) recorder() *typesRecorder {
@@ -480,27 +463,16 @@ const (
 
 // NewPackage creates a Go+ package instance.
 func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, err error) {
-	workingDir := conf.WorkingDir
-	if workingDir == "" {
-		workingDir, _ = os.Getwd()
-	}
-	targetDir := conf.TargetDir
-	if targetDir == "" {
-		targetDir = workingDir
-	}
+	relBaseDir := conf.RelativeBase
 	fset := conf.Fset
 	files := pkg.Files
 	interp := &nodeInterp{
-		fset: fset, files: files, workingDir: workingDir,
+		fset: fset, files: files, relBaseDir: relBaseDir,
 	}
 	ctx := &pkgCtx{
 		fset: fset,
 		syms: make(map[string]loader), nodeInterp: interp, generics: make(map[string]bool),
 	}
-	if conf.FileLineRoot != "" {
-		ctx.fileLineRoot, _ = filepath.Abs(conf.FileLineRoot)
-		ctx.fileLineWorkingDir, _ = filepath.Abs(workingDir)
-	}
 	confGox := &gox.Config{
 		Types:           conf.Types,
 		Fset:            fset,
@@ -551,7 +523,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 		f := fromgo.ASTFile(gof, 0)
 		gofiles = append(gofiles, f)
 		ctx := &blockCtx{
-			pkg: p, pkgCtx: ctx, cb: p.CB(), targetDir: targetDir,
+			pkg: p, pkgCtx: ctx, cb: p.CB(), relBaseDir: relBaseDir,
 			imports: make(map[string]pkgImp),
 		}
 		preloadFile(p, ctx, fpath, f, false, false)
@@ -563,8 +535,8 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
 		fileLine := !conf.NoFileLine
 		fileScope := types.NewScope(p.Types.Scope(), f.Pos(), f.End(), fpath)
 		ctx := &blockCtx{
-			pkg: p, pkgCtx: ctx, cb: p.CB(), targetDir: targetDir, fileScope: fileScope,
-			fileLine: fileLine, relativePath: conf.RelativePath, isClass: f.IsClass, rec: rec,
+			pkg: p, pkgCtx: ctx, cb: p.CB(), relBaseDir: relBaseDir, fileScope: fileScope,
+			fileLine: fileLine, isClass: f.IsClass, rec: rec,
 			c2goBase: c2goBase(conf.C2goBase), imports: make(map[string]pkgImp), isGopFile: true,
 		}
 		if rec := ctx.rec; rec != nil {
diff --git a/cl/expr.go b/cl/expr.go
index fc9698ee..f25564ce 100644
--- a/cl/expr.go
+++ b/cl/expr.go
@@ -1164,7 +1164,7 @@ func compileErrWrapExpr(ctx *blockCtx, v *ast.ErrWrapExpr, inFlags int) {
 			Val(pkg.Import(errorPkgPath).Ref("NewFrame")).
 			Val(err).
 			Val(sprintAst(pkg.Fset, v.X)).
-			Val(pos.Filename).
+			Val(relFile(ctx.relBaseDir, pos.Filename)).
 			Val(pos.Line).
 			Val(currentFuncName).
 			Call(newFrameArgs).
diff --git a/cl/outline/outline.go b/cl/outline/outline.go
index 3d7e438e..7adab5ac 100644
--- a/cl/outline/outline.go
+++ b/cl/outline/outline.go
@@ -37,9 +37,6 @@ type Config struct {
 	// If Fset is nil, Load will use a new fileset, but preserve Fset's value.
 	Fset *token.FileSet
 
-	// WorkingDir is the directory in which to run gop compiler.
-	WorkingDir string
-
 	// C2goBase specifies base of standard c2go packages.
 	// Default is github.com/goplus/.
 	C2goBase string
@@ -63,7 +60,6 @@ type Package struct {
 func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (_ Package, err error) {
 	ret, err := cl.NewPackage(pkgPath, pkg, &cl.Config{
 		Fset:           conf.Fset,
-		WorkingDir:     conf.WorkingDir,
 		C2goBase:       conf.C2goBase,
 		LookupPub:      conf.LookupPub,
 		LookupClass:    conf.LookupClass,
diff --git a/cl/stmt.go b/cl/stmt.go
index 62136acc..37a14685 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -32,34 +32,26 @@ import (
 	"github.com/goplus/gox"
 )
 
-func relFile(dir string, file string) string {
-	if rel, err := filepath.Rel(dir, file); err == nil {
-		if rel[0] == '.' {
-			return rel
-		}
-		return "./" + rel
+func fileLineFile(relBaseDir, absFile string) string {
+	if ret, err := filepath.Rel(relBaseDir, absFile); err == nil {
+		return filepath.ToSlash(ret)
 	}
-	return file
+	return absFile
 }
 
-func offsetFileLine(ctx *blockCtx, file string) string {
-	if !filepath.IsAbs(file) {
-		file = filepath.Join(ctx.fileLineWorkingDir, file)
-	}
-	if ret, err := filepath.Rel(ctx.fileLineRoot, file); err == nil {
-		return filepath.ToSlash(ret)
+func relFile(dir string, absFile string) string {
+	if dir != "" {
+		return fileLineFile(dir, absFile)
 	}
-	return file
+	return absFile
 }
 
 func commentStmt(ctx *blockCtx, stmt ast.Stmt) {
 	if ctx.fileLine {
 		start := stmt.Pos()
 		pos := ctx.fset.Position(start)
-		if ctx.fileLineRoot != "" {
-			pos.Filename = offsetFileLine(ctx, pos.Filename)
-		} else if ctx.relativePath {
-			pos.Filename = relFile(ctx.targetDir, pos.Filename)
+		if ctx.relBaseDir != "" {
+			pos.Filename = fileLineFile(ctx.relBaseDir, pos.Filename)
 		}
 		line := fmt.Sprintf("\n//line %s:%d:1", pos.Filename, pos.Line)
 		comments := &goast.CommentGroup{
@@ -73,10 +65,8 @@ func commentFunc(ctx *blockCtx, fn *gox.Func, decl *ast.FuncDecl) {
 	start := decl.Name.Pos()
 	if ctx.fileLine && start != token.NoPos {
 		pos := ctx.fset.Position(start)
-		if ctx.fileLineRoot != "" {
-			pos.Filename = offsetFileLine(ctx, pos.Filename)
-		} else if ctx.relativePath {
-			pos.Filename = relFile(ctx.targetDir, pos.Filename)
+		if ctx.relBaseDir != "" {
+			pos.Filename = fileLineFile(ctx.relBaseDir, pos.Filename)
 		}
 		var line string
 		if decl.Shadow {
diff --git a/load.go b/load.go
index e6063126..6e363ffc 100644
--- a/load.go
+++ b/load.go
@@ -187,14 +187,13 @@ func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (ou
 
 	var pkgTest *ast.Package
 	var clConf = &cl.Config{
-		WorkingDir:  dir,
 		Fset:        fset,
 		Importer:    imp,
 		LookupClass: mod.LookupClass,
 		LookupPub:   c2go.LookupPub(mod),
 	}
 	if mod.IsValid() {
-		clConf.FileLineRoot = mod.Root()
+		clConf.RelativeBase = mod.Root()
 	}
 
 	for name, pkg := range pkgs {
diff --git a/outline.go b/outline.go
index a24fd1b4..11c355cd 100644
--- a/outline.go
+++ b/outline.go
@@ -96,7 +96,6 @@ func Outline(dir string, conf *Config) (out outline.Package, err error) {
 		pkgPath := path.Join(mod.Path(), filepath.ToSlash(relPart))
 		out, err = outline.NewPackage(pkgPath, pkg, &outline.Config{
 			Fset:        fset,
-			WorkingDir:  dir,
 			Importer:    imp,
 			LookupClass: mod.LookupClass,
 			LookupPub:   c2go.LookupPub(mod),
diff --git a/x/build/build.go b/x/build/build.go
index 980e6064..0b99626e 100644
--- a/x/build/build.go
+++ b/x/build/build.go
@@ -157,8 +157,7 @@ func (c *Context) loadPackage(srcDir string, pkgs map[string]*ast.Package) (*Pac
 			break
 		}
 	}
-	conf := &cl.Config{
-		WorkingDir: srcDir, TargetDir: srcDir, Fset: c.fset}
+	conf := &cl.Config{Fset: c.fset}
 	conf.Importer = c
 	conf.LookupClass = func(ext string) (c *cl.Project, ok bool) {
 		c, ok = projects[ext]
diff --git a/x/typesutil/check.go b/x/typesutil/check.go
index 882e907f..88673790 100644
--- a/x/typesutil/check.go
+++ b/x/typesutil/check.go
@@ -138,7 +138,6 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
 	_, err = cl.NewPackage(pkgTypes.Path(), pkg, &cl.Config{
 		Types:          pkgTypes,
 		Fset:           fset,
-		WorkingDir:     opts.WorkingDir,
 		C2goBase:       opts.C2goBase,
 		LookupPub:      c2go.LookupPub(mod),
 		LookupClass:    mod.LookupClass,


Test patch:
diff --git a/cl/builtin_test.go b/cl/builtin_test.go
index ac3e0707..db438e40 100644
--- a/cl/builtin_test.go
+++ b/cl/builtin_test.go
@@ -291,7 +291,7 @@ func TestErrNewType(t *testing.T) {
 }
 
 func TestErrLoadImport(t *testing.T) {
-	testPanic(t, ".: unknownpkg not found or not a valid C package (c2go.a.pub file not found).\n", func() {
+	testPanic(t, "-: unknownpkg not found or not a valid C package (c2go.a.pub file not found).\n", func() {
 		pkg := &pkgCtx{
 			nodeInterp: &nodeInterp{
 				fset: token.NewFileSet(),
diff --git a/cl/compile_c2go_test.go b/cl/compile_c2go_test.go
index 8bf5199c..786397b8 100644
--- a/cl/compile_c2go_test.go
+++ b/cl/compile_c2go_test.go
@@ -82,7 +82,7 @@ func main() {
 }
 
 func TestErrHelloC2go(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:7:3: confliction: printf declared both in "github.com/goplus/gop/cl/internal/libc" and "github.com/goplus/gop/cl/internal/libc"`, `
+	codeErrorTest(t, `bar.gop:7:3: confliction: printf declared both in "github.com/goplus/gop/cl/internal/libc" and "github.com/goplus/gop/cl/internal/libc"`, `
 import (
 	"C"
 	"C/libc"
diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go
index 4817c105..e2fbc587 100644
--- a/cl/compile_spx_test.go
+++ b/cl/compile_spx_test.go
@@ -108,10 +108,9 @@ func gopSpxErrorTestEx(t *testing.T, msg, gmx, spxcode, gmxfile, spxfile string)
 		t.Fatal("ParseFSDir:", err)
 	}
 	conf := *gblConf
+	conf.RelativeBase = "/foo"
 	conf.Recorder = nil
 	conf.NoFileLine = false
-	conf.WorkingDir = "/foo"
-	conf.TargetDir = "/foo"
 	bar := pkgs["main"]
 	_, err = cl.NewPackage("", bar, &conf)
 	if err == nil {
@@ -123,8 +122,8 @@ func gopSpxErrorTestEx(t *testing.T, msg, gmx, spxcode, gmxfile, spxfile string)
 }
 
 func TestSpxError(t *testing.T) {
-	gopSpxErrorTestEx(t, `./Game.tgmx:6:2: userScore redeclared
-	./Game.tgmx:5:2 other declaration of userScore`, `
+	gopSpxErrorTestEx(t, `Game.tgmx:6:2: userScore redeclared
+	Game.tgmx:5:2 other declaration of userScore`, `
 import "bytes"
 var (
 	Kai Kai
@@ -135,8 +134,8 @@ var (
 println "hi"
 `, "Game.tgmx", "Kai.tspx")
 
-	gopSpxErrorTestEx(t, `./Kai.tspx:4:2: id redeclared
-	./Kai.tspx:3:2 other declaration of id`, `
+	gopSpxErrorTestEx(t, `Kai.tspx:4:2: id redeclared
+	Kai.tspx:3:2 other declaration of id`, `
 var (
 	Kai Kai
 	userScore int
@@ -658,7 +657,7 @@ func (this *Kai) onCloned() {
 }
 
 func TestSpxErrorSel(t *testing.T) {
-	gopSpxErrorTestEx(t, `./Kai.tspx:2:9: this.pos undefined (type *Kai has no field or method pos)`, `
+	gopSpxErrorTestEx(t, `Kai.tspx:2:9: this.pos undefined (type *Kai has no field or method pos)`, `
 println "hi"
 `, `
 println this.pos
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 952b57ee..8220c126 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -19,7 +19,6 @@ package cl_test
 import (
 	"bytes"
 	"os"
-	"runtime"
 	"strings"
 	"sync"
 	"testing"
@@ -68,8 +67,6 @@ func init() {
 		C2goBase:      "github.com/goplus/gop/cl/internal",
 		NoFileLine:    false,
 		NoAutoGenMain: true,
-		RelativePath:  true,
-		TargetDir:     ".",
 	}
 }
 
@@ -4662,9 +4659,7 @@ func main() {
 func TestCommentLineRoot(t *testing.T) {
 	conf := *gblConf
 	conf.NoFileLine = false
-	conf.FileLineRoot = "/foo/root"
-	conf.WorkingDir = "/foo"
-	conf.TargetDir = "/foo"
+	conf.RelativeBase = "/foo/root"
 	var src = `
 type Point struct {
 	x int
@@ -4714,9 +4709,6 @@ func main() {
 	testPoint()
 }
 `
-	if runtime.GOOS == "windows" {
-		expected = strings.Replace(expected, "../", `../foo/`, -1)
-	}
 	gopClTestEx(t, &conf, "main", src, expected)
 }
 
diff --git a/cl/error_msg_test.go b/cl/error_msg_test.go
index 6ac17953..fe2bf1df 100644
--- a/cl/error_msg_test.go
+++ b/cl/error_msg_test.go
@@ -42,8 +42,7 @@ func codeErrorTestEx(t *testing.T, pkgname, filename, msg, src string) {
 	}
 	conf := *gblConf
 	conf.NoFileLine = false
-	conf.WorkingDir = "/foo"
-	conf.TargetDir = "/foo"
+	conf.RelativeBase = "/foo"
 	bar := pkgs[pkgname]
 	_, err = cl.NewPackage("", bar, &conf)
 	if err == nil {
@@ -56,7 +55,7 @@ func codeErrorTestEx(t *testing.T, pkgname, filename, msg, src string) {
 
 func TestErrLambdaExpr(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:7:6: too few arguments in lambda expression\n\thave ()\n\twant (int, int)", `
+		"bar.gop:7:6: too few arguments in lambda expression\n\thave ()\n\twant (int, int)", `
 
 func foo(func(int, int)) {
 }
@@ -66,7 +65,7 @@ func main() {
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:7:6: too many arguments in lambda expression\n\thave (x, y, z)\n\twant (int, int)", `
+		"bar.gop:7:6: too many arguments in lambda expression\n\thave (x, y, z)\n\twant (int, int)", `
 
 func foo(func(int, int)) {
 }
@@ -75,7 +74,7 @@ func main() {
 	foo((x, y, z) => {})
 }
 `)
-	codeErrorTest(t, "./bar.gop:6:8: cannot use lambda literal as type int in field value to Plot", `
+	codeErrorTest(t, "bar.gop:6:8: cannot use lambda literal as type int in field value to Plot", `
 type Foo struct {
 	Plot int
 }
@@ -83,7 +82,7 @@ foo := &Foo{
 	Plot: x => (x * 2, x * x),
 }
 `)
-	codeErrorTest(t, "./bar.gop:6:8: cannot use lambda literal as type int in field value to Plot", `
+	codeErrorTest(t, "bar.gop:6:8: cannot use lambda literal as type int in field value to Plot", `
 type Foo struct {
 	Plot int
 }
@@ -94,19 +93,19 @@ foo := &Foo{
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:4:5: cannot use lambda literal as type int in argument to foo", `
+		"bar.gop:4:5: cannot use lambda literal as type int in argument to foo", `
 func foo(int) {
 }
 foo(=> {})
 `)
 	codeErrorTest(t,
-		"./bar.gop:4:5: cannot use lambda literal as type func() in argument to foo", `
+		"bar.gop:4:5: cannot use lambda literal as type func() in argument to foo", `
 func foo(func()) {
 }
 foo => (100)
 `)
 	codeErrorTest(t,
-		"./bar.gop:6:8: cannot use lambda literal as type func() int in field value to Plot", `
+		"bar.gop:6:8: cannot use lambda literal as type func() int in field value to Plot", `
 type Foo struct {
 	Plot func() int
 }
@@ -116,25 +115,25 @@ foo := &Foo{
 `)
 
 	codeErrorTest(t,
-		"./bar.gop:2:18: cannot use lambda literal as type func() in assignment to foo", `
+		"bar.gop:2:18: cannot use lambda literal as type func() in assignment to foo", `
 var foo func() = => (100)
 `)
 	codeErrorTest(t,
-		"./bar.gop:3:7: cannot use lambda literal as type func() in assignment to foo", `
+		"bar.gop:3:7: cannot use lambda literal as type func() in assignment to foo", `
 var foo func()
 foo = => (100)
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:29: lambda unsupport multiple assignment", `
+		"bar.gop:2:29: lambda unsupport multiple assignment", `
 var foo, foo1 func() = nil, => {}
 `)
 	codeErrorTest(t,
-		"./bar.gop:3:15: lambda unsupport multiple assignment", `
+		"bar.gop:3:15: lambda unsupport multiple assignment", `
 var foo func()
 _, foo = nil, => {}
 `)
 	codeErrorTest(t,
-		"./bar.gop:4:9: cannot use lambda expression as type int in return statement", `
+		"bar.gop:4:9: cannot use lambda expression as type int in return statement", `
 func intSeq() int {
 	i := 0
 	return => {
@@ -144,7 +143,7 @@ func intSeq() int {
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:6:10: cannot use i (type int) as type string in return argument", `
+		"bar.gop:6:10: cannot use i (type int) as type string in return argument", `
 func intSeq() func() string {
 	i := 0
 	return => {
@@ -157,7 +156,7 @@ func intSeq() func() string {
 
 func TestErrErrWrap(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:2:2: undefined: a", `func main() {
+		"bar.gop:2:2: undefined: a", `func main() {
 	a!
 }
 `)
@@ -165,7 +164,7 @@ func TestErrErrWrap(t *testing.T) {
 
 func TestErrVar(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:6:5: assignment mismatch: 1 variables but fmt.Println returns 2 values", `import "fmt"
+		"bar.gop:6:5: assignment mismatch: 1 variables but fmt.Println returns 2 values", `import "fmt"
 
 func main() {
 }
@@ -173,44 +172,44 @@ func main() {
 var a = fmt.Println(1)
 `)
 	codeErrorTest(t,
-		"./bar.gop:4:5: assignment mismatch: 1 variables but 2 values", `func main() {
+		"bar.gop:4:5: assignment mismatch: 1 variables but 2 values", `func main() {
 }
 
 var a = 1, 2
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:2: undefined: foo", `func main() {
+		"bar.gop:2:2: undefined: foo", `func main() {
 	foo.x = 1
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:2: use of builtin len not in function call", `func main() {
+		"bar.gop:2:2: use of builtin len not in function call", `func main() {
 	len.x = 1
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:10: undefined: foo", `func main() {
+		"bar.gop:2:10: undefined: foo", `func main() {
 	println(foo.x)
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:10: use of builtin len not in function call", `func main() {
+		"bar.gop:2:10: use of builtin len not in function call", `func main() {
 	println(len.x)
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:10: undefined: foo", `func main() {
+		"bar.gop:2:10: undefined: foo", `func main() {
 	println(foo)
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:3:20: use of builtin len not in function call", `package main
+		"bar.gop:3:20: use of builtin len not in function call", `package main
 
 func foo(v map[int]len) {
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:5:20: bar is not a type", `package main
+		"bar.gop:5:20: bar is not a type", `package main
 
 var bar = 1
 
@@ -218,27 +217,27 @@ func foo(v map[int]bar) {
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:6: use of builtin len not in function call", `func main() {
+		"bar.gop:2:6: use of builtin len not in function call", `func main() {
 	new(len)
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:2: undefined: foo", `func main() {
+		"bar.gop:2:2: undefined: foo", `func main() {
 	foo = 1
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:9: cannot use _ as value", `func main() {
+		"bar.gop:2:9: cannot use _ as value", `func main() {
 	foo := _
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:9: use of builtin len not in function call", `func main() {
+		"bar.gop:2:9: use of builtin len not in function call", `func main() {
 	foo := len
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:2: println is not a variable", `func main() {
+		"bar.gop:2:2: println is not a variable", `func main() {
 	println = "hello"
 }
 `)
@@ -246,7 +245,7 @@ func foo(v map[int]bar) {
 
 func TestErrImport(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:8:2: confliction: NewEncoding declared both in "encoding/base64" and "encoding/base32"`, `
+		`bar.gop:8:2: confliction: NewEncoding declared both in "encoding/base64" and "encoding/base32"`, `
 import (
 	. "encoding/base32"
 	. "encoding/base64"
@@ -256,25 +255,25 @@ func foo() {
 	NewEncoding("Hi")
 }`)
 	codeErrorTest(t,
-		"./bar.gop:5:2: cannot refer to unexported name os.undefined", `
+		"bar.gop:5:2: cannot refer to unexported name os.undefined", `
 import "os"
 
 func foo() {
 	os.undefined
 }`)
 	codeErrorTest(t,
-		"./bar.gop:5:2: undefined: os.UndefinedObject", `
+		"bar.gop:5:2: undefined: os.UndefinedObject", `
 import "os"
 
 func foo() {
 	os.UndefinedObject
 }`)
 	codeErrorTest(t,
-		"./bar.gop:2:13: undefined: testing", `
+		"bar.gop:2:13: undefined: testing", `
 func foo(t *testing.T) {
 }`)
 	codeErrorTest(t,
-		"./bar.gop:4:12: testing.Verbose is not a type", `
+		"bar.gop:4:12: testing.Verbose is not a type", `
 import "testing"
 
 func foo(t testing.Verbose) {
@@ -283,12 +282,12 @@ func foo(t testing.Verbose) {
 
 func TestErrConst(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:3:7: a redeclared in this block\n\tprevious declaration at ./bar.gop:2:5", `
+		"bar.gop:3:7: a redeclared in this block\n\tprevious declaration at bar.gop:2:5", `
 var a int
 const a = 1
 `)
 	codeErrorTest(t,
-		"./bar.gop:4:2: missing value in const declaration", `
+		"bar.gop:4:2: missing value in const declaration", `
 const (
 	a = iota
 	b, c
@@ -298,15 +297,15 @@ const (
 
 func TestErrNewVar(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:3:5: a redeclared in this block\n\tprevious declaration at ./bar.gop:2:5", `
+		"bar.gop:3:5: a redeclared in this block\n\tprevious declaration at bar.gop:2:5", `
 var a int
 var a string
 `)
 }
 
 func TestErrDefineVar(t *testing.T) {
-	codeErrorTest(t, "./bar.gop:3:1: no new variables on left side of :=\n"+
-		"./bar.gop:3:6: cannot use \"Hi\" (type untyped string) as type int in assignment", `
+	codeErrorTest(t, "bar.gop:3:1: no new variables on left side of :=\n"+
+		"bar.gop:3:6: cannot use \"Hi\" (type untyped string) as type int in assignment", `
 a := 1
 a := "Hi"
 `)
@@ -314,31 +313,31 @@ a := "Hi"
 
 func TestErrAssignMismatchT(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:2:16: cannot use []string{} (type []string) as type string in assignment`, `
+		`bar.gop:2:16: cannot use []string{} (type []string) as type string in assignment`, `
 var a string = []string{}
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:16: cannot use [2]string{} (type [2]string) as type string in assignment`, `
+		`bar.gop:2:16: cannot use [2]string{} (type [2]string) as type string in assignment`, `
 var a string = [2]string{}
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:16: cannot use map[int]string{} (type map[int]string) as type string in assignment`, `
+		`bar.gop:2:16: cannot use map[int]string{} (type map[int]string) as type string in assignment`, `
 var a string = map[int]string{}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:16: cannot use T{} (type T) as type string in assignment`, `
+		`bar.gop:3:16: cannot use T{} (type T) as type string in assignment`, `
 type T struct{}
 var a string = T{}
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:16: cannot use func(){} (type func()) as type string in assignment`, `
+		`bar.gop:2:16: cannot use func(){} (type func()) as type string in assignment`, `
 var a string = func(){}
 `)
 }
 
 func TestErrAssign(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:8:1: assignment mismatch: 1 variables but bar returns 2 values`, `
+		`bar.gop:8:1: assignment mismatch: 1 variables but bar returns 2 values`, `
 
 func bar() (n int, err error) {
 	return
@@ -348,7 +347,7 @@ x := 1
 x = bar()
 `)
 	codeErrorTest(t,
-		`./bar.gop:4:1: assignment mismatch: 1 variables but 2 values`, `
+		`bar.gop:4:1: assignment mismatch: 1 variables but 2 values`, `
 
 x := 1
 x = 1, "Hi"
@@ -357,28 +356,28 @@ x = 1, "Hi"
 
 func TestErrReturn(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:4:2: too few arguments to return\n\thave (untyped int)\n\twant (int, error)", `
+		"bar.gop:4:2: too few arguments to return\n\thave (untyped int)\n\twant (int, error)", `
 
 func foo() (int, error) {
 	return 1
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:4:2: too many arguments to return\n\thave (untyped int, untyped int, untyped string)\n\twant (int, error)", `
+		"bar.gop:4:2: too many arguments to return\n\thave (untyped int, untyped int, untyped string)\n\twant (int, error)", `
 
 func foo() (int, error) {
 	return 1, 2, "Hi"
 }
 `)
 	codeErrorTest(t,
-		`./bar.gop:4:12: cannot use "Hi" (type untyped string) as type error in return argument`, `
+		`bar.gop:4:12: cannot use "Hi" (type untyped string) as type error in return argument`, `
 
 func foo() (int, error) {
 	return 1, "Hi"
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:8:2: too few arguments to return\n\thave (byte)\n\twant (int, error)", `
+		"bar.gop:8:2: too few arguments to return\n\thave (byte)\n\twant (int, error)", `
 
 func bar() (v byte) {
 	return
@@ -389,7 +388,7 @@ func foo() (int, error) {
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:8:2: too many arguments to return\n\thave (n int, err error)\n\twant (v byte)", `
+		"bar.gop:8:2: too many arguments to return\n\thave (n int, err error)\n\twant (v byte)", `
 
 func bar() (n int, err error) {
 	return
@@ -400,7 +399,7 @@ func foo() (v byte) {
 }
 `)
 	codeErrorTest(t,
-		`./bar.gop:8:2: cannot use byte value as type error in return argument`, `
+		`bar.gop:8:2: cannot use byte value as type error in return argument`, `
 
 func bar() (n int, v byte) {
 	return
@@ -411,7 +410,7 @@ func foo() (int, error) {
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:4:2: not enough arguments to return\n\thave ()\n\twant (byte)", `
+		"bar.gop:4:2: not enough arguments to return\n\thave ()\n\twant (byte)", `
 
 func foo() byte {
 	return
@@ -421,7 +420,7 @@ func foo() byte {
 
 func TestErrForRange(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:4:8: cannot assign type string to a (type int) in range`, `
+		`bar.gop:4:8: cannot assign type string to a (type int) in range`, `
 a := 1
 var b []string
 for _, a = range b {
@@ -431,7 +430,7 @@ for _, a = range b {
 
 func TestErrInitFunc(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:2:6: func init must have no arguments and no return values`, `
+		`bar.gop:2:6: func init must have no arguments and no return values`, `
 func init(v byte) {
 }
 `)
@@ -439,7 +438,7 @@ func init(v byte) {
 
 func TestErrRecv(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:5:9: invalid receiver type a (a is a pointer type)`, `
+		`bar.gop:5:9: invalid receiver type a (a is a pointer type)`, `
 
 type a *int
 
@@ -447,17 +446,17 @@ func (p a) foo() {
 }
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:9: invalid receiver type error (error is an interface type)`, `
+		`bar.gop:2:9: invalid receiver type error (error is an interface type)`, `
 func (p error) foo() {
 }
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:9: invalid receiver type []byte ([]byte is not a defined type)`, `
+		`bar.gop:2:9: invalid receiver type []byte ([]byte is not a defined type)`, `
 func (p []byte) foo() {
 }
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:10: invalid receiver type []byte ([]byte is not a defined type)`, `
+		`bar.gop:2:10: invalid receiver type []byte ([]byte is not a defined type)`, `
 func (p *[]byte) foo() {
 }
 `)
@@ -465,29 +464,29 @@ func (p *[]byte) foo() {
 
 func TestErrStructLit(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:39: too many values in struct{x int; y string}{...}`, `
+		`bar.gop:3:39: too many values in struct{x int; y string}{...}`, `
 x := 1
 a := struct{x int; y string}{1, "Hi", 2}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:30: too few values in struct{x int; y string}{...}`, `
+		`bar.gop:3:30: too few values in struct{x int; y string}{...}`, `
 x := 1
 a := struct{x int; y string}{1}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:33: cannot use x (type int) as type string in value of field y`, `
+		`bar.gop:3:33: cannot use x (type int) as type string in value of field y`, `
 x := 1
 a := struct{x int; y string}{1, x}
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:30: z undefined (type struct{x int; y string} has no field or method z)`, `
+		`bar.gop:2:30: z undefined (type struct{x int; y string} has no field or method z)`, `
 a := struct{x int; y string}{z: 1}
 `)
 }
 
 func TestErrArray(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:8: non-constant array bound n`, `
+		`bar.gop:3:8: non-constant array bound n`, `
 var n int
 var a [n]int
 `)
@@ -495,37 +494,37 @@ var a [n]int
 
 func TestErrArrayLit(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:14: cannot use a as index which must be non-negative integer constant`,
+		`bar.gop:3:14: cannot use a as index which must be non-negative integer constant`,
 		`
 a := "Hi"
 b := [10]int{a: 1}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:20: array index 10 out of bounds [0:10]`,
+		`bar.gop:3:20: array index 10 out of bounds [0:10]`,
 		`
 a := "Hi"
 b := [10]int{9: 1, 3}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:16: array index 1 out of bounds [0:1]`,
+		`bar.gop:3:16: array index 1 out of bounds [0:1]`,
 		`
 a := "Hi"
 b := [1]int{1, 2}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:14: array index 12 (value 12) out of bounds [0:10]`,
+		`bar.gop:3:14: array index 12 (value 12) out of bounds [0:10]`,
 		`
 a := "Hi"
 b := [10]int{12: 2}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:14: cannot use a+"!" (type string) as type int in array literal`,
+		`bar.gop:3:14: cannot use a+"!" (type string) as type int in array literal`,
 		`
 a := "Hi"
 b := [10]int{a+"!"}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:17: cannot use a (type string) as type int in array literal`,
+		`bar.gop:3:17: cannot use a (type string) as type int in array literal`,
 		`
 a := "Hi"
 b := [10]int{2: a}
@@ -534,19 +533,19 @@ b := [10]int{2: a}
 
 func TestErrSliceLit(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:12: cannot use a as index which must be non-negative integer constant`,
+		`bar.gop:3:12: cannot use a as index which must be non-negative integer constant`,
 		`
 a := "Hi"
 b := []int{a: 1}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:12: cannot use a (type string) as type int in slice literal`,
+		`bar.gop:3:12: cannot use a (type string) as type int in slice literal`,
 		`
 a := "Hi"
 b := []int{a}
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:15: cannot use a (type string) as type int in slice literal`,
+		`bar.gop:3:15: cannot use a (type string) as type int in slice literal`,
 		`
 a := "Hi"
 b := []int{2: a}
@@ -554,8 +553,8 @@ b := []int{2: a}
 }
 
 func TestErrMapLit(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:2:21: cannot use 1+2 (type untyped int) as type string in map key
-./bar.gop:3:27: cannot use "Go" + "+" (type untyped string) as type int in map value`,
+	codeErrorTest(t, `bar.gop:2:21: cannot use 1+2 (type untyped int) as type string in map key
+bar.gop:3:27: cannot use "Go" + "+" (type untyped string) as type int in map value`,
 		`
 a := map[string]int{1+2: 2}
 b := map[string]int{"Hi": "Go" + "+"}
@@ -564,20 +563,20 @@ b := map[string]int{"Hi": "Go" + "+"}
 
 func TestErrSlice(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:4:6: cannot slice a (type *byte)`,
+		`bar.gop:4:6: cannot slice a (type *byte)`,
 		`
 var a *byte
 x := 1
 b := a[x:2]
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:6: cannot slice a (type bool)`,
+		`bar.gop:3:6: cannot slice a (type bool)`,
 		`
 a := true
 b := a[1:2]
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:6: invalid operation a[1:2:5] (3-index slice of string)`,
+		`bar.gop:3:6: invalid operation a[1:2:5] (3-index slice of string)`,
 		`
 a := "Hi"
 b := a[1:2:5]
@@ -586,13 +585,13 @@ b := a[1:2:5]
 
 func TestErrIndex(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:10: assignment mismatch: 2 variables but 1 values`,
+		`bar.gop:3:10: assignment mismatch: 2 variables but 1 values`,
 		`
 a := "Hi"
 b, ok := a[1]
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:6: invalid operation: a[1] (type bool does not support indexing)`,
+		`bar.gop:3:6: invalid operation: a[1] (type bool does not support indexing)`,
 		`
 a := true
 b := a[1]
@@ -601,7 +600,7 @@ b := a[1]
 
 func TestErrIndexRef(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:1: cannot assign to a[1] (strings are immutable)`,
+		`bar.gop:3:1: cannot assign to a[1] (strings are immutable)`,
 		`
 a := "Hi"
 a[1] = 'e'
@@ -610,13 +609,13 @@ a[1] = 'e'
 
 func TestErrStar(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:2: invalid indirect of a (type string)`,
+		`bar.gop:3:2: invalid indirect of a (type string)`,
 		`
 a := "Hi"
 *a = 'e'
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:7: invalid indirect of a (type string)`,
+		`bar.gop:3:7: invalid indirect of a (type string)`,
 		`
 a := "Hi"
 b := *a
@@ -625,7 +624,7 @@ b := *a
 
 func TestErrMember(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:6: a.x undefined (type string has no field or method x)`,
+		`bar.gop:3:6: a.x undefined (type string has no field or method x)`,
 		`
 a := "Hello"
 b := a.x
@@ -634,13 +633,13 @@ b := a.x
 
 func TestErrMemberRef(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:3:1: a.x undefined (type string has no field or method x)`,
+		`bar.gop:3:1: a.x undefined (type string has no field or method x)`,
 		`
 a := "Hello"
 a.x = 1
 `)
 	codeErrorTest(t,
-		`./bar.gop:5:1: a.x undefined (type aaa has no field or method x)`,
+		`bar.gop:5:1: a.x undefined (type aaa has no field or method x)`,
 		`
 type aaa byte
 
@@ -648,7 +647,7 @@ a := aaa(0)
 a.x = 1
 `)
 	codeErrorTest(t,
-		`./bar.gop:5:1: a.z undefined (type aaa has no field or method z)`,
+		`bar.gop:5:1: a.z undefined (type aaa has no field or method z)`,
 		`
 type aaa struct {x int; y string}
 
@@ -656,7 +655,7 @@ a := aaa{}
 a.z = 1
 `)
 	codeErrorTest(t,
-		`./bar.gop:3:1: a.z undefined (type struct{x int; y string} has no field or method z)`,
+		`bar.gop:3:1: a.z undefined (type struct{x int; y string} has no field or method z)`,
 		`
 a := struct{x int; y string}{}
 a.z = 1
@@ -665,8 +664,8 @@ a.z = 1
 
 func TestErrLabel(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:4:1: label foo already defined at ./bar.gop:2:1
-./bar.gop:2:1: label foo defined and not used`,
+		`bar.gop:4:1: label foo already defined at bar.gop:2:1
+bar.gop:2:1: label foo defined and not used`,
 		`x := 1
 foo:
 	i := 1
@@ -674,18 +673,18 @@ foo:
 	i++
 `)
 	codeErrorTest(t,
-		`./bar.gop:2:6: label foo is not defined`,
+		`bar.gop:2:6: label foo is not defined`,
 		`x := 1
 goto foo`)
 	codeErrorTest(t,
-		`./bar.gop:2:7: label foo is not defined`,
+		`bar.gop:2:7: label foo is not defined`,
 		`x := 1
 break foo`)
 }
 
 func TestErrBranchStmt(t *testing.T) {
 	codeErrorTest(t,
-		`./bar.gop:2:2: fallthrough statement out of place`,
+		`bar.gop:2:2: fallthrough statement out of place`,
 		`func foo() {
 	fallthrough
 }`)
@@ -693,27 +692,27 @@ func TestErrBranchStmt(t *testing.T) {
 
 func TestErrNoEntrypoint(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:2:2: undefined: println1", `func main() {
+		"bar.gop:2:2: undefined: println1", `func main() {
 	println1 "hello"
 }
 `)
 	codeErrorTest(t,
-		"./bar.gop:1:1: undefined: println1", `println1 "hello"`)
+		"bar.gop:1:1: undefined: println1", `println1 "hello"`)
 
 	codeErrorTest(t,
-		"./bar.gop:2:2: undefined: println1", `
+		"bar.gop:2:2: undefined: println1", `
 	println1 "hello"
 `)
 	codeErrorTest(t,
-		"./bar.gop:2:2: undefined: println1", `package main
+		"bar.gop:2:2: undefined: println1", `package main
 	println1 "hello"
 `)
 	codeErrorTest(t,
-		`./bar.gop:1:9: undefined: abc`,
+		`bar.gop:1:9: undefined: abc`,
 		`println abc
 `)
 	codeErrorTestEx(t, "bar", "bar.gop",
-		`./bar.gop:2:9: undefined: abc`,
+		`bar.gop:2:9: undefined: abc`,
 		`package bar
 println abc
 `)
@@ -721,7 +720,7 @@ 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",
+		"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)
@@ -739,28 +738,28 @@ type Point struct {
 
 func TestErrSwitchDuplicate(t *testing.T) {
 	codeErrorTest(t,
-		"./bar.gop:4:7: duplicate case 100 in switch\n\tprevious case at ./bar.gop:3:7",
+		"bar.gop:4:7: duplicate case 100 in switch\n\tprevious case at bar.gop:3:7",
 		`var n int
 switch n {
 	case 100:
 	case 100:
 }`)
 	codeErrorTest(t,
-		"./bar.gop:4:7: duplicate case int(100) (value 100) in switch\n\tprevious case at ./bar.gop:3:7",
+		"bar.gop:4:7: duplicate case int(100) (value 100) in switch\n\tprevious case at bar.gop:3:7",
 		`var n int
 switch n {
 	case 100:
 	case int(100):
 }`)
 	codeErrorTest(t,
-		"./bar.gop:4:7: duplicate case 50 + 50 (value 100) in switch\n\tprevious case at ./bar.gop:3:7",
+		"bar.gop:4:7: duplicate case 50 + 50 (value 100) in switch\n\tprevious case at bar.gop:3:7",
 		`var n int
 switch n {
 	case 100:
 	case 50 + 50:
 }`)
 	codeErrorTest(t,
-		"./bar.gop:5:7: duplicate case int(100) (value 100) in switch\n\tprevious case at ./bar.gop:3:7",
+		"bar.gop:5:7: duplicate case int(100) (value 100) in switch\n\tprevious case at bar.gop:3:7",
 		`var n interface{}
 switch n {
 	case 100:
@@ -768,14 +767,14 @@ switch n {
 	case int(100):
 }`)
 	codeErrorTest(t,
-		"./bar.gop:4:7: duplicate case 100.0 in switch\n\tprevious case at ./bar.gop:3:7",
+		"bar.gop:4:7: duplicate case 100.0 in switch\n\tprevious case at bar.gop:3:7",
 		`var n interface{}
 switch n {
 	case 100.0:
 	case 100.0:
 }`)
 	codeErrorTest(t,
-		"./bar.gop:5:7: duplicate case v (value 100) in switch\n\tprevious case at ./bar.gop:4:7",
+		"bar.gop:5:7: duplicate case v (value 100) in switch\n\tprevious case at bar.gop:4:7",
 		`var n interface{}
 const v = 100.0
 switch n {
@@ -783,7 +782,7 @@ switch n {
 	case v:
 }`)
 	codeErrorTest(t,
-		"./bar.gop:5:7: duplicate case v (value \"hello\") in switch\n\tprevious case at ./bar.gop:4:7",
+		"bar.gop:5:7: duplicate case v (value \"hello\") in switch\n\tprevious case at bar.gop:4:7",
 		`var n interface{}
 const v = "hello"
 switch n {
@@ -791,10 +790,10 @@ switch n {
 	case v:
 }`)
 	codeErrorTest(t,
-		`./bar.gop:4:7: duplicate case 100 in switch
-	previous case at ./bar.gop:3:7
-./bar.gop:5:7: duplicate case 50 + 50 (value 100) in switch
-	previous case at ./bar.gop:3:7`,
+		`bar.gop:4:7: duplicate case 100 in switch
+	previous case at bar.gop:3:7
+bar.gop:5:7: duplicate case 50 + 50 (value 100) in switch
+	previous case at bar.gop:3:7`,
 		`var n int
 switch n {
 	case 100:
@@ -802,14 +801,14 @@ switch n {
 	case 50 + 50:
 }`)
 	codeErrorTest(t,
-		"./bar.gop:4:2: multiple defaults in switch (first at ./bar.gop:3:2)",
+		"bar.gop:4:2: multiple defaults in switch (first at bar.gop:3:2)",
 		`var n interface{}
 switch n {
 	default:
 	default:
 }`)
-	codeErrorTest(t, `./bar.gop:4:2: multiple defaults in switch (first at ./bar.gop:3:2)
-./bar.gop:5:2: multiple defaults in switch (first at ./bar.gop:3:2)`,
+	codeErrorTest(t, `bar.gop:4:2: multiple defaults in switch (first at bar.gop:3:2)
+bar.gop:5:2: multiple defaults in switch (first at bar.gop:3:2)`,
 		`var n interface{}
 switch n {
 	default:
@@ -819,10 +818,10 @@ switch n {
 }
 
 func TestErrTypeSwitchDuplicate(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:4:7: duplicate case int in type switch
-	previous case at ./bar.gop:3:7
-./bar.gop:5:7: duplicate case int in type switch
-	previous case at ./bar.gop:3:7`,
+	codeErrorTest(t, `bar.gop:4:7: duplicate case int in type switch
+	previous case at bar.gop:3:7
+bar.gop:5:7: duplicate case int in type switch
+	previous case at bar.gop:3:7`,
 		`var n interface{} = 100
 switch n.(type) {
 	case int:
@@ -830,8 +829,8 @@ switch n.(type) {
 	case int:
 }
 `)
-	codeErrorTest(t, `./bar.gop:4:7: multiple nil cases in type switch (first at ./bar.gop:3:7)
-./bar.gop:5:7: multiple nil cases in type switch (first at ./bar.gop:3:7)`,
+	codeErrorTest(t, `bar.gop:4:7: multiple nil cases in type switch (first at bar.gop:3:7)
+bar.gop:5:7: multiple nil cases in type switch (first at bar.gop:3:7)`,
 		`var n interface{} = 100
 switch n.(type) {
 	case nil:
@@ -839,8 +838,8 @@ switch n.(type) {
 	case nil:
 }
 `)
-	codeErrorTest(t, `./bar.gop:4:2: multiple defaults in type switch (first at ./bar.gop:3:2)
-./bar.gop:5:2: multiple defaults in type switch (first at ./bar.gop:3:2)`,
+	codeErrorTest(t, `bar.gop:4:2: multiple defaults in type switch (first at bar.gop:3:2)
+bar.gop:5:2: multiple defaults in type switch (first at bar.gop:3:2)`,
 		`var n interface{} = 100
 switch n.(type) {
 	default:
@@ -851,7 +850,7 @@ switch n.(type) {
 }
 
 func TestErrAutoProperty(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:4:11: cannot refer to unexported name fmt.println`, `
+	codeErrorTest(t, `bar.gop:4:11: cannot refer to unexported name fmt.println`, `
 import "fmt"
 
 n, err := fmt.println
@@ -859,12 +858,12 @@ n, err := fmt.println
 }
 
 func TestFiledsNameRedecl(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:6:2: Id redeclared
-	./bar.gop:5:2 other declaration of Id
-./bar.gop:7:2: Id redeclared
-	./bar.gop:5:2 other declaration of Id
-./bar.gop:9:2: name redeclared
-	./bar.gop:8:2 other declaration of name`, `
+	codeErrorTest(t, `bar.gop:6:2: Id redeclared
+	bar.gop:5:2 other declaration of Id
+bar.gop:7:2: Id redeclared
+	bar.gop:5:2 other declaration of Id
+bar.gop:9:2: name redeclared
+	bar.gop:8:2 other declaration of name`, `
 type Id struct {
 }
 type A struct {
@@ -885,14 +884,14 @@ func TestErrImportPkg(t *testing.T) {
 		where = "std"
 	}
 	codeErrorTest(t,
-		fmt.Sprintf(`./bar.gop:3:2: package fmt2 is not in `+where+` (%v)
+		fmt.Sprintf(`bar.gop:3:2: package fmt2 is not in `+where+` (%v)
 `, root), `
 import (
 	"fmt2"
 )
 `)
 
-	codeErrorTest(t, `./bar.gop:3:2: no required module provides package github.com/goplus/gop/fmt2; to add it:
+	codeErrorTest(t, `bar.gop:3:2: no required module provides package github.com/goplus/gop/fmt2; to add it:
 	go get github.com/goplus/gop/fmt2
 `, `
 import (
@@ -903,8 +902,8 @@ import (
 
 func TestErrClassFileGopx(t *testing.T) {
 	codeErrorTestEx(t, "main", "Rect.gox",
-		`./Rect.gox:5:2: A redeclared
-	./Rect.gox:3:2 other declaration of A`, `
+		`Rect.gox:5:2: A redeclared
+	Rect.gox:3:2 other declaration of A`, `
 var (
 	A
 	i int
@@ -916,10 +915,10 @@ println "hello"
 }
 
 func TestErrVarInFunc(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:6:10: not enough arguments in call to set
+	codeErrorTest(t, `bar.gop:6:10: not enough arguments in call to set
 	have (untyped string)
 	want (name string, v int)
-./bar.gop:7:10: undefined: a`, `
+bar.gop:7:10: undefined: a`, `
 func set(name string, v int) string {
 	return name
 }
@@ -931,42 +930,42 @@ func test() {
 }
 
 func TestErrInt128(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:2:16: cannot use 1<<127 (type untyped int) as type github.com/goplus/gop/builtin/ng.Int128 in assignment`, `
+	codeErrorTest(t, `bar.gop:2:16: cannot use 1<<127 (type untyped int) as type github.com/goplus/gop/builtin/ng.Int128 in assignment`, `
 var a int128 = 1<<127
 `)
-	codeErrorTest(t, `./bar.gop:2:13: cannot convert 1<<127 (untyped int constant 170141183460469231731687303715884105728) to type Int128`, `
+	codeErrorTest(t, `bar.gop:2:13: cannot convert 1<<127 (untyped int constant 170141183460469231731687303715884105728) to type Int128`, `
 a := int128(1<<127)
 `)
-	codeErrorTest(t, `./bar.gop:2:13: cannot convert -1<<127-1 (untyped int constant -170141183460469231731687303715884105729) to type Int128`, `
+	codeErrorTest(t, `bar.gop:2:13: cannot convert -1<<127-1 (untyped int constant -170141183460469231731687303715884105729) to type Int128`, `
 a := int128(-1<<127-1)
 `)
-	codeErrorTest(t, `./bar.gop:3:13: cannot convert b (untyped int constant -170141183460469231731687303715884105729) to type Int128`, `
+	codeErrorTest(t, `bar.gop:3:13: cannot convert b (untyped int constant -170141183460469231731687303715884105729) to type Int128`, `
 const b = -1<<127-1
 a := int128(b)
 `)
 }
 
 func TestErrUint128(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:2:17: cannot use 1<<128 (type untyped int) as type github.com/goplus/gop/builtin/ng.Uint128 in assignment`, `
+	codeErrorTest(t, `bar.gop:2:17: cannot use 1<<128 (type untyped int) as type github.com/goplus/gop/builtin/ng.Uint128 in assignment`, `
 var a uint128 = 1<<128
 `)
-	codeErrorTest(t, `./bar.gop:2:14: cannot convert 1<<128 (untyped int constant 340282366920938463463374607431768211456) to type Uint128`, `
+	codeErrorTest(t, `bar.gop:2:14: cannot convert 1<<128 (untyped int constant 340282366920938463463374607431768211456) to type Uint128`, `
 a := uint128(1<<128)
 `)
-	codeErrorTest(t, `./bar.gop:2:17: cannot use -1 (type untyped int) as type github.com/goplus/gop/builtin/ng.Uint128 in assignment`, `
+	codeErrorTest(t, `bar.gop:2:17: cannot use -1 (type untyped int) as type github.com/goplus/gop/builtin/ng.Uint128 in assignment`, `
 var a uint128 = -1
 `)
-	codeErrorTest(t, `./bar.gop:2:14: cannot convert -1 (untyped int constant -1) to type Uint128`, `
+	codeErrorTest(t, `bar.gop:2:14: cannot convert -1 (untyped int constant -1) to type Uint128`, `
 a := uint128(-1)
 `)
-	codeErrorTest(t, `./bar.gop:3:14: cannot convert b (untyped int constant -1) to type Uint128`, `
+	codeErrorTest(t, `bar.gop:3:14: cannot convert b (untyped int constant -1) to type Uint128`, `
 const b = -1
 a := uint128(b)
 `)
 }
 
 func TestErrCompileFunc(t *testing.T) {
-	codeErrorTest(t, `./bar.gop:2:1: compile func printf("%+v\n", int32) error: unreachable`, `
+	codeErrorTest(t, `bar.gop:2:1: compile func printf("%+v\n", int32) error: unreachable`, `
 printf("%+v\n", int32)
 `)
 }
diff --git a/cl/typeparams_test.go b/cl/typeparams_test.go
index a3b71457..014d36b3 100644
--- a/cl/typeparams_test.go
+++ b/cl/typeparams_test.go
@@ -233,8 +233,7 @@ func mixedErrorTestEx(t *testing.T, pkgname, msg, gocode, gopcode string) {
 	}
 	conf := *gblConf
 	conf.NoFileLine = false
-	conf.WorkingDir = "/foo"
-	conf.TargetDir = "/foo"
+	conf.RelativeBase = "/foo"
 	bar := pkgs[pkgname]
 	_, err = cl.NewPackage("", bar, &conf)
 	if err == nil {
@@ -249,11 +248,11 @@ func TestTypeParamsErrorInstantiate(t *testing.T) {
 	var msg string
 	switch runtime.Version()[:6] {
 	case "go1.18":
-		msg = `./b.gop:2:1: uint does not implement Number`
+		msg = `b.gop:2:1: uint does not implement Number`
 	case "go1.19":
-		msg = `./b.gop:2:1: uint does not implement Number (uint missing in ~int | float64)`
+		msg = `b.gop:2:1: uint does not implement Number (uint missing in ~int | float64)`
 	default:
-		msg = `./b.gop:2:1: uint does not satisfy Number (uint missing in ~int | float64)`
+		msg = `b.gop:2:1: uint does not satisfy Number (uint missing in ~int | float64)`
 	}
 
 	mixedErrorTest(t, msg, `
@@ -281,11 +280,11 @@ func TestTypeParamsErrorMatch(t *testing.T) {
 	var msg string
 	switch runtime.Version()[:6] {
 	case "go1.18", "go1.19":
-		msg = `./b.gop:2:5: T does not match ~[]E`
+		msg = `b.gop:2:5: T does not match ~[]E`
 	case "go1.20":
-		msg = `./b.gop:2:5: int does not match ~[]E`
+		msg = `b.gop:2:5: int does not match ~[]E`
 	default:
-		msg = `./b.gop:2:5: T (type int) does not satisfy interface{interface{~[]E}}`
+		msg = `b.gop:2:5: T (type int) does not satisfy interface{interface{~[]E}}`
 	}
 	mixedErrorTest(t, msg, `
 package main
@@ -301,7 +300,7 @@ _ = At[int]
 }
 
 func TestTypeParamsErrInferFunc(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:5: cannot infer T2 (/foo/a.go:4:21)`, `
+	mixedErrorTest(t, `b.gop:2:5: cannot infer T2 (/foo/a.go:4:21)`, `
 package main
 
 func Loader[T1 any, T2 any](p1 T1, p2 T2) T1 {
@@ -313,7 +312,7 @@ _ = Loader[int]
 }
 
 func TestTypeParamsErrArgumentsParameters1(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:7: got 1 type arguments but Data[T1, T2 interface{}] has 2 type parameters`, `
+	mixedErrorTest(t, `b.gop:2:7: got 1 type arguments but Data[T1, T2 interface{}] has 2 type parameters`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -326,7 +325,7 @@ var v Data[int]
 }
 
 func TestTypeParamsErrArgumentsParameters2(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:7: got 3 type arguments but Data[T1, T2 interface{}] has 2 type parameters`, `
+	mixedErrorTest(t, `b.gop:2:7: got 3 type arguments but Data[T1, T2 interface{}] has 2 type parameters`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -339,7 +338,7 @@ var v Data[int,int,int]
 }
 
 func TestTypeParamsErrArgumentsParameters3(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:1: got 3 type arguments but func[T1, T2 interface{}](t1 T1, t2 T2) has 2 type parameters`, `
+	mixedErrorTest(t, `b.gop:2:1: got 3 type arguments but func[T1, T2 interface{}](t1 T1, t2 T2) has 2 type parameters`, `
 package main
 
 func Test[T1 any, T2 any](t1 T1, t2 T2) {
@@ -351,7 +350,7 @@ Test[int,int,int](1,2)
 }
 
 func TestTypeParamsErrCallArguments1(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:1: not enough arguments in call to Test
+	mixedErrorTest(t, `b.gop:2:1: not enough arguments in call to Test
 	have (untyped int)
 	want (T1, T2)`, `
 package main
@@ -365,7 +364,7 @@ Test(1)
 }
 
 func TestTypeParamsErrCallArguments2(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:1: too many arguments in call to Test
+	mixedErrorTest(t, `b.gop:2:1: too many arguments in call to Test
 	have (untyped int, untyped int, untyped int)
 	want (T1, T2)`, `
 package main
@@ -379,7 +378,7 @@ Test(1,2,3)
 }
 
 func TestTypeParamsErrCallArguments3(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:1: too many arguments in call to Test
+	mixedErrorTest(t, `b.gop:2:1: too many arguments in call to Test
 	have (untyped int, untyped int)
 	want ()`, `
 package main
@@ -395,7 +394,7 @@ Test(1,2)
 }
 
 func TestTypeParamsErrCallVariadicArguments1(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:1: not enough arguments in call to Add
+	mixedErrorTest(t, `b.gop:2:1: not enough arguments in call to Add
 	have ()
 	want (T1, ...T2)`, `
 package main
@@ -413,7 +412,7 @@ Add()
 }
 
 func TestTypeParamsErrCallVariadicArguments2(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:1: cannot infer T2 (./a.go:4:18)`, `
+	mixedErrorTest(t, `b.gop:2:1: cannot infer T2 (a.go:4:18)`, `
 package main
 
 func Add[T1 any, T2 ~int|~uint](v1 T1, v2 ...T2) (sum T2) {
@@ -429,7 +428,7 @@ Add(1)
 }
 
 func TestTypeParamsRecvTypeError1(t *testing.T) {
-	mixedErrorTest(t, `./a.go:7:9: cannot use generic type Data[T interface{}] without instantiation`, `
+	mixedErrorTest(t, `a.go:7:9: cannot use generic type Data[T interface{}] without instantiation`, `
 package main
 
 type Data[T any] struct {
@@ -443,7 +442,7 @@ Data[int]{}.Test()
 }
 
 func TestTypeParamsRecvTypeError2(t *testing.T) {
-	mixedErrorTest(t, `./a.go:7:9: got 2 arguments but 1 type parameters`, `
+	mixedErrorTest(t, `a.go:7:9: got 2 arguments but 1 type parameters`, `
 package main
 
 type Data[T any] struct {
@@ -457,7 +456,7 @@ Data[int]{}.Test()
 }
 
 func TestTypeParamsRecvTypeError3(t *testing.T) {
-	mixedErrorTest(t, `./a.go:8:9: got 1 type parameter, but receiver base type declares 2`, `
+	mixedErrorTest(t, `a.go:8:9: got 1 type parameter, but receiver base type declares 2`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -472,7 +471,7 @@ Data[int,int]{}.Test()
 }
 
 func TestGenericTypeWithoutInst1(t *testing.T) {
-	mixedErrorTest(t, `./a.go:8:9: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `a.go:8:9: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -487,7 +486,7 @@ var v Data[int,int]
 }
 
 func TestGenericTypeWithoutInst2(t *testing.T) {
-	mixedErrorTest(t, `./a.go:10:2: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `a.go:10:2: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -504,7 +503,7 @@ var v My[int]
 }
 
 func TestGenericTypeWithoutInst3(t *testing.T) {
-	mixedErrorTest(t, `./a.go:10:2: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `a.go:10:2: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -521,7 +520,7 @@ var v My
 }
 
 func TestGenericTypeWithoutInst4(t *testing.T) {
-	mixedErrorTest(t, `./a.go:10:15: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `a.go:10:15: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -538,7 +537,7 @@ var v My
 }
 
 func TestGenericTypeWithoutInst5(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:7: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `b.gop:2:7: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -551,7 +550,7 @@ var v Data
 }
 
 func TestGenericTypeWithoutInst6(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:8: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `b.gop:2:8: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -564,7 +563,7 @@ type T Data
 }
 
 func TestGenericTypeWithoutInst7(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:3:2: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `b.gop:3:2: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {
@@ -579,7 +578,7 @@ type My struct {
 }
 
 func TestGenericTypeWithoutInst8(t *testing.T) {
-	mixedErrorTest(t, `./b.gop:2:23: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
+	mixedErrorTest(t, `b.gop:2:23: cannot use generic type Data[T1, T2 interface{}] without instantiation`, `
 package main
 
 type Data[T1 any, T2 any] struct {