From e941bda34d1b8caff62dff1fd55b40bd9184e67e Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 12 Oct 2023 14:56:04 +0800 Subject: [PATCH 01/64] go.mod: update gox --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 95c7ec3fd..9ae30e0db 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.17 require ( github.com/fsnotify/fsnotify v1.6.0 github.com/goplus/c2go v0.7.16 - github.com/goplus/gox v1.12.5 + github.com/goplus/gox v1.12.2-0.20231012035644-c3bf89ec9e2b github.com/goplus/mod v0.11.7 github.com/qiniu/x v1.13.1 golang.org/x/tools v0.14.0 diff --git a/go.sum b/go.sum index 50d77c9b7..80ab5bf22 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.5 h1:YkdsZDIOW3DZLJctWYKVzdsqMeuCYNn7J4BsFi6B058= -github.com/goplus/gox v1.12.5/go.mod h1:ferIrvJSoXae8gABk5Z4olEzfAxZpUy4hD91Vm5E/qs= +github.com/goplus/gox v1.12.2-0.20231012035644-c3bf89ec9e2b h1:5jCLZcnLj2jOTOw5j979XMoqeWI1ghZVnfuwmKbe5Eo= +github.com/goplus/gox v1.12.2-0.20231012035644-c3bf89ec9e2b/go.mod h1:ferIrvJSoXae8gABk5Z4olEzfAxZpUy4hD91Vm5E/qs= github.com/goplus/mod v0.11.5/go.mod h1:NDC5E+XOT8vcJCMjqKhLDJHTHX7lyVN4Vbfi2U7dBhs= github.com/goplus/mod v0.11.7 h1:OTGFi/Jk0qmTy3ih8u3BQ6CbtcaPlTrJBlTacnge0jE= github.com/goplus/mod v0.11.7/go.mod h1:yl2QncBKTdXk+8UaNsdo4u2zSpGEJYA5JKjgD3K2h00= From 4f52124569b6a3c9e37a1ca510cf1ede275abdb9 Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 12 Oct 2023 15:23:56 +0800 Subject: [PATCH 02/64] cl: add TestSpxErrorSel/TestSpxMethodSel/TestSpxPkgOverload --- cl/compile_spx_test.go | 75 +++++++++++++++++++++++++++++++ cl/internal/spx/game.go | 7 +++ cl/internal/spx/pkg/pkg.go | 23 ++++++++++ cl/internal/spx/sprite.go | 9 ++++ cl/outline/cl/compile_spx_test.go | 71 +++++++++++++++++++++++++++++ 5 files changed, 185 insertions(+) create mode 100644 cl/internal/spx/pkg/pkg.go diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go index 0451c3016..9786376e7 100644 --- a/cl/compile_spx_test.go +++ b/cl/compile_spx_test.go @@ -654,3 +654,78 @@ func (this *Kai) onCloned() { } `, "Game.tgmx", "Kai.tspx") } + +func TestSpxErrorSel(t *testing.T) { + gopSpxErrorTestEx(t, `./Kai.tspx:2:9: this.pos undefined (type *Kai has no field or method pos)`, ` +println "hi" +`, ` +println this.pos +`, "Game.tgmx", "Kai.tspx") +} + +func TestSpxMethodSel(t *testing.T) { + gopSpxTestEx(t, ` +sendMessage "Hi" +`, ` +func onMsg(msg string) { +} +`, `package main + +import spx "github.com/goplus/gop/cl/internal/spx" + +type Game struct { + *spx.MyGame +} + +func (this *Game) MainEntry() { + this.SendMessage("Hi") +} +func main() { + spx.Gopt_MyGame_Main(new(Game)) +} + +type Kai struct { + spx.Sprite + *Game +} + +func (this *Kai) onMsg(msg string) { +} +`, "Game.tgmx", "Kai.tspx") +} + +func TestSpxPkgOverload(t *testing.T) { + gopSpxTestEx(t, ` +println "Hi" +`, ` +func onMsg(msg string) { + this.position.add 100,200 +} +`, `package main + +import ( + fmt "fmt" + spx "github.com/goplus/gop/cl/internal/spx" +) + +type Game struct { + *spx.MyGame +} + +func (this *Game) MainEntry() { + fmt.Println("Hi") +} +func main() { + spx.Gopt_MyGame_Main(new(Game)) +} + +type Kai struct { + spx.Sprite + *Game +} + +func (this *Kai) onMsg(msg string) { + this.Position().Add__0(100, 200) +} +`, "Game.tgmx", "Kai.tspx") +} diff --git a/cl/internal/spx/game.go b/cl/internal/spx/game.go index a201d0897..9367eae70 100644 --- a/cl/internal/spx/game.go +++ b/cl/internal/spx/game.go @@ -41,6 +41,13 @@ func (p *MyGame) Broadcast__2(msg string, data interface{}, wait bool) { func (p *MyGame) Play(media string, wait ...bool) { } +func (p *MyGame) sendMessage(data interface{}) { +} + +func (p *MyGame) SendMessage(data interface{}) { + p.sendMessage(data) +} + func Gopt_MyGame_Run(game interface{}, resource string) error { return nil } diff --git a/cl/internal/spx/pkg/pkg.go b/cl/internal/spx/pkg/pkg.go new file mode 100644 index 000000000..649406b52 --- /dev/null +++ b/cl/internal/spx/pkg/pkg.go @@ -0,0 +1,23 @@ +package pkg + +var ( + GopPackage = true +) + +type Vector struct { + x int + y int +} + +func NewVector(x, y int) *Vector { + return &Vector{x, y} +} + +func (v *Vector) Add__0(x int, y int) { + v.x += x + v.y += y +} + +func (v *Vector) Add__1(o *Vector) { + v.Add__0(o.x, o.y) +} diff --git a/cl/internal/spx/sprite.go b/cl/internal/spx/sprite.go index 9bbd27fdc..00963bb87 100644 --- a/cl/internal/spx/sprite.go +++ b/cl/internal/spx/sprite.go @@ -16,7 +16,12 @@ package spx +import ( + "github.com/goplus/gop/cl/internal/spx/pkg" +) + type Sprite struct { + pos pkg.Vector } func (p *Sprite) SetCostume(costume interface{}) { @@ -25,6 +30,10 @@ func (p *Sprite) SetCostume(costume interface{}) { func (p *Sprite) Say(msg string, secs ...float64) { } +func (p *Sprite) Position() *pkg.Vector { + return &p.pos +} + func Gopt_Sprite_Clone__0(sprite interface{}) { } diff --git a/cl/outline/cl/compile_spx_test.go b/cl/outline/cl/compile_spx_test.go index e730234f8..583afaf9f 100644 --- a/cl/outline/cl/compile_spx_test.go +++ b/cl/outline/cl/compile_spx_test.go @@ -650,3 +650,74 @@ func (this *Kai) onCloned() { } `, "Game.tgmx", "Kai.tspx") } + +func TestSpxErrorSel(t *testing.T) { + gopSpxErrorTestEx(t, `./Kai.tspx:2:9: this.pos undefined (type *Kai has no field or method pos)`, ` +println "hi" +`, ` +println this.pos +`, "Game.tgmx", "Kai.tspx") +} + +func TestSpxMethodSel(t *testing.T) { + gopSpxTestEx(t, ` +sendMessage "Hi" +`, ` +func onMsg(msg string) { +} +`, `package main + +import spx "github.com/goplus/gop/cl/internal/spx" + +type Game struct { + *spx.MyGame +} +type Kai struct { + spx.Sprite + *Game +} + +func (this *Game) MainEntry() { + this.SendMessage("Hi") +} +func (this *Kai) onMsg(msg string) { +} +func main() { + spx.Gopt_MyGame_Main(new(Game)) +} +`, "Game.tgmx", "Kai.tspx") +} + +func TestSpxPkgOverload(t *testing.T) { + gopSpxTestEx(t, ` +println "Hi" +`, ` +func onMsg(msg string) { + this.position.add 100,200 +} +`, `package main + +import ( + fmt "fmt" + spx "github.com/goplus/gop/cl/internal/spx" +) + +type Game struct { + *spx.MyGame +} +type Kai struct { + spx.Sprite + *Game +} + +func (this *Game) MainEntry() { + fmt.Println("Hi") +} +func (this *Kai) onMsg(msg string) { + this.Position().Add__0(100, 200) +} +func main() { + spx.Gopt_MyGame_Main(new(Game)) +} +`, "Game.tgmx", "Kai.tspx") +} From e1370eb256f1d1d2a7bbea149b4693b2bf325099 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 18 Oct 2023 16:08:51 +0800 Subject: [PATCH 03/64] gop/env.Installed(); gop/ast.File.Pos() --- ast/ast.go | 9 +++++++-- env/version.go | 23 ++++++++++++++++++++++- parser/parser.go | 2 +- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index 57f498d71..2a8ae5474 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -1123,7 +1123,7 @@ type FileType = int16 // are "free-floating" (see also issues #18593, #20744). type File struct { Doc *CommentGroup // associated documentation; or nil - Package token.Pos // position of "package" keyword + Package token.Pos // position of "package" keyword; or NoPos Name *Ident // package name Decls []Decl // top-level declarations; or nil @@ -1145,7 +1145,12 @@ func (f *File) NoEntrypoint() bool { } // Pos returns position of first character belonging to the node. -func (f *File) Pos() token.Pos { return f.Package } +func (f *File) Pos() token.Pos { + if f.Package != token.NoPos { + return f.Package + } + return f.Name.NamePos +} // End returns position of first character immediately after the node. func (f *File) End() token.Pos { diff --git a/env/version.go b/env/version.go index 5ce9b61ed..af9c33eb9 100644 --- a/env/version.go +++ b/env/version.go @@ -17,6 +17,8 @@ package env import ( + "bytes" + "os/exec" "strings" ) @@ -31,11 +33,30 @@ var ( ) func init() { - if buildVersion != "" && !strings.HasPrefix(buildVersion, "v"+MainVersion+".") { + if buildVersion == "" { + var b bytes.Buffer + cmd := exec.Command("gop", "env", "GOPVERSION", "BUILDDATE", "GOPROOT") + cmd.Stdout = &b + err := cmd.Run() + if err == nil { + parts := strings.SplitN(strings.TrimRight(b.String(), "\n"), "\n", 3) + if len(parts) == 3 { + buildVersion, buildDate, defaultGopRoot = parts[0], parts[1], parts[2] + } + } + return + } + if !strings.HasPrefix(buildVersion, "v"+MainVersion+".") { panic("Invalid buildVersion: " + buildVersion) } } +// Installed checks is `gop` installed or not. +// If returns false, it means `gop` is not installed or not in PATH. +func Installed() bool { + return buildVersion != "" +} + // Version returns the GoPlus tree's version string. // It is either the commit hash and date at the time of the build or, // when possible, a release tag like "v1.0.0-rc1". diff --git a/parser/parser.go b/parser/parser.go index b89ec37ae..5de4dc461 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -3709,7 +3709,7 @@ func (p *parser) parseFile() *ast.File { } else { noPkgDecl = true pos = token.NoPos - ident = ast.NewIdent("main") + ident = &ast.Ident{NamePos: p.file.Pos(0), Name: "main"} } p.openScope() From d17024ea956fc44d7e115ed151e8afd7bfd65c86 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 18 Oct 2023 19:07:55 +0800 Subject: [PATCH 04/64] gop/env: initEnvByGop --- env/build.go | 1 + env/path.go | 2 ++ env/path_test.go | 20 ++++++++--------- env/sys_others.go | 1 + env/sys_plan9.go | 1 + env/sys_windows.go | 1 + env/version.go | 36 ++++++++++++++++++++++--------- env/version_test.go | 52 ++++++++++++++++++++++++++++++++++++--------- 8 files changed, 84 insertions(+), 30 deletions(-) diff --git a/env/build.go b/env/build.go index b7325414a..1405cabf3 100644 --- a/env/build.go +++ b/env/build.go @@ -22,6 +22,7 @@ var ( buildDate string ) +// BuildDate returns build date of the `gop` command. func BuildDate() string { return buildDate } diff --git a/env/path.go b/env/path.go index d52cf90aa..1f071efa8 100644 --- a/env/path.go +++ b/env/path.go @@ -28,6 +28,8 @@ var ( defaultGopRoot string ) +// GOPROOT returns the root of the Go+ tree. It uses the GOPROOT environment variable, +// if set at process start, or else the root used during the Go+ build. func GOPROOT() string { gopRoot, err := findGopRoot() if err != nil { diff --git a/env/path_test.go b/env/path_test.go index a38dc6546..834235b3e 100644 --- a/env/path_test.go +++ b/env/path_test.go @@ -17,7 +17,6 @@ package env import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -39,12 +38,13 @@ func findGoModFile(dir string) (modfile string, noCacheFile bool, err error) { // Common testing directory structure: // testing_root/ -// src/ -// subdir/ -// valid_goproot/ -// go.mod -// go.sum -// cmd/gop/ +// +// src/ +// subdir/ +// valid_goproot/ +// go.mod +// go.sum +// cmd/gop/ func makeTestDir(t *testing.T) (root string, src string, gopRoot string) { root, _ = filepath.EvalSymlinks(t.TempDir()) src = filepath.Join(root, "src") @@ -57,12 +57,12 @@ func makeTestDir(t *testing.T) (root string, src string, gopRoot string) { func makeValidGopRoot(root string) { os.Mkdir(root, 0755) os.MkdirAll(filepath.Join(root, "cmd/gop"), 0755) - ioutil.WriteFile(filepath.Join(root, "go.mod"), []byte(""), 0644) - ioutil.WriteFile(filepath.Join(root, "go.sum"), []byte(""), 0644) + os.WriteFile(filepath.Join(root, "go.mod"), []byte(""), 0644) + os.WriteFile(filepath.Join(root, "go.sum"), []byte(""), 0644) } func writeDummyFile(path string) { - ioutil.WriteFile(path, []byte(""), 0644) + os.WriteFile(path, []byte(""), 0644) } func cleanup() { diff --git a/env/sys_others.go b/env/sys_others.go index 305816f3f..9ec00c659 100644 --- a/env/sys_others.go +++ b/env/sys_others.go @@ -21,4 +21,5 @@ package env const ( envHOME = "HOME" + appEXT = "" ) diff --git a/env/sys_plan9.go b/env/sys_plan9.go index 11a567f5c..4c274e847 100644 --- a/env/sys_plan9.go +++ b/env/sys_plan9.go @@ -18,4 +18,5 @@ package env const ( envHOME = "home" + appEXT = "" ) diff --git a/env/sys_windows.go b/env/sys_windows.go index 401494900..5c8a9329c 100644 --- a/env/sys_windows.go +++ b/env/sys_windows.go @@ -18,4 +18,5 @@ package env const ( envHOME = "USERPROFILE" + appEXT = ".exe" ) diff --git a/env/version.go b/env/version.go index af9c33eb9..9b0666094 100644 --- a/env/version.go +++ b/env/version.go @@ -18,7 +18,9 @@ package env import ( "bytes" + "os" "os/exec" + "path/filepath" "strings" ) @@ -33,24 +35,38 @@ var ( ) func init() { + initEnv() +} + +func initEnv() { if buildVersion == "" { - var b bytes.Buffer - cmd := exec.Command("gop", "env", "GOPVERSION", "BUILDDATE", "GOPROOT") - cmd.Stdout = &b - err := cmd.Run() - if err == nil { - parts := strings.SplitN(strings.TrimRight(b.String(), "\n"), "\n", 3) + initEnvByGop() + return + } + if !strings.HasPrefix(buildVersion, "v"+MainVersion+".") { + panic("gop/env: [FATAL] Invalid buildVersion: " + buildVersion) + } +} + +func initEnvByGop() { + if fname := filepath.Base(os.Args[0]); fname != "gop"+appEXT { + if ret, err := gopEnv(); err == nil { + parts := strings.SplitN(strings.TrimRight(ret, "\n"), "\n", 3) if len(parts) == 3 { buildVersion, buildDate, defaultGopRoot = parts[0], parts[1], parts[2] } } - return - } - if !strings.HasPrefix(buildVersion, "v"+MainVersion+".") { - panic("Invalid buildVersion: " + buildVersion) } } +var gopEnv = func() (string, error) { + var b bytes.Buffer + cmd := exec.Command("gop", "env", "GOPVERSION", "BUILDDATE", "GOPROOT") + cmd.Stdout = &b + err := cmd.Run() + return b.String(), err +} + // Installed checks is `gop` installed or not. // If returns false, it means `gop` is not installed or not in PATH. func Installed() bool { diff --git a/env/version_test.go b/env/version_test.go index 5b51422d7..7beb6b9f4 100644 --- a/env/version_test.go +++ b/env/version_test.go @@ -16,21 +16,53 @@ package env -import "testing" +import ( + "os" + "path/filepath" + "testing" +) -func TestVersion(t *testing.T) { - if Version() != "v"+MainVersion+".x" { - t.Fatal("TestVersion failed:", Version()) +func TestPanic(t *testing.T) { + t.Run("initEnvPanic", func(t *testing.T) { + defer func() { + if e := recover(); e == nil { + t.Fatal("initEnvPanic: no panic?") + } + }() + buildVersion = "v1.2" + initEnv() + }) + t.Run("GOPROOT panic", func(t *testing.T) { + defer func() { + if e := recover(); e == nil { + t.Fatal("GOPROOT: no panic?") + } + }() + defaultGopRoot = "" + os.Setenv(envGOPROOT, "") + GOPROOT() + }) +} + +func TestEnv(t *testing.T) { + gopEnv = func() (string, error) { + wd, _ := os.Getwd() + root := filepath.Dir(wd) + return "v1.0.0-beta1\n2023-10-18_17-45-50\n" + root + "\n", nil + } + buildVersion = "" + initEnv() + if !Installed() { + t.Fatal("not Installed") } - buildVersion = "v1.0.0-beta1" - if Version() != buildVersion { + if Version() != "v1.0.0-beta1" { t.Fatal("TestVersion failed:", Version()) } buildVersion = "" -} - -func TestBuild(t *testing.T) { - if BuildDate() != "" { + if Version() != "v"+MainVersion+".x" { + t.Fatal("TestVersion failed:", Version()) + } + if BuildDate() != "2023-10-18_17-45-50" { t.Fatal("BuildInfo failed:", BuildDate()) } } From 7aba2e946a7b0395bc92c7a22f71816f87d96b68 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 18 Oct 2023 19:53:40 +0800 Subject: [PATCH 05/64] gop/env --- env/gop_nonwindows.go | 24 ++++++++++++++++++++++++ env/sys_others.go | 1 - env/sys_plan9.go | 1 - env/sys_windows.go | 5 ++++- env/version.go | 2 +- 5 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 env/gop_nonwindows.go diff --git a/env/gop_nonwindows.go b/env/gop_nonwindows.go new file mode 100644 index 000000000..482e829f9 --- /dev/null +++ b/env/gop_nonwindows.go @@ -0,0 +1,24 @@ +//go:build !windows +// +build !windows + +/* + * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package env + +func isGopCmd(fname string) bool { + return fname == "gop" +} diff --git a/env/sys_others.go b/env/sys_others.go index 9ec00c659..305816f3f 100644 --- a/env/sys_others.go +++ b/env/sys_others.go @@ -21,5 +21,4 @@ package env const ( envHOME = "HOME" - appEXT = "" ) diff --git a/env/sys_plan9.go b/env/sys_plan9.go index 4c274e847..11a567f5c 100644 --- a/env/sys_plan9.go +++ b/env/sys_plan9.go @@ -18,5 +18,4 @@ package env const ( envHOME = "home" - appEXT = "" ) diff --git a/env/sys_windows.go b/env/sys_windows.go index 5c8a9329c..1975f0cd0 100644 --- a/env/sys_windows.go +++ b/env/sys_windows.go @@ -18,5 +18,8 @@ package env const ( envHOME = "USERPROFILE" - appEXT = ".exe" ) + +func isGopCmd(fname string) bool { + return fname == "gop.exe" || fname == "gop" +} diff --git a/env/version.go b/env/version.go index 9b0666094..e70a940d8 100644 --- a/env/version.go +++ b/env/version.go @@ -49,7 +49,7 @@ func initEnv() { } func initEnvByGop() { - if fname := filepath.Base(os.Args[0]); fname != "gop"+appEXT { + if fname := filepath.Base(os.Args[0]); !isGopCmd(fname) { if ret, err := gopEnv(); err == nil { parts := strings.SplitN(strings.TrimRight(ret, "\n"), "\n", 3) if len(parts) == 3 { From 4a859b3a253b262a5888d311115f56c59e303b3f Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 19 Oct 2023 14:40:41 +0800 Subject: [PATCH 06/64] gop/x/typesutil --- x/typesutil/check.go | 49 ++++++++++++ x/typesutil/eval.go | 46 ++++++++++++ x/typesutil/typesutil.go | 156 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 x/typesutil/check.go create mode 100644 x/typesutil/eval.go create mode 100644 x/typesutil/typesutil.go diff --git a/x/typesutil/check.go b/x/typesutil/check.go new file mode 100644 index 000000000..00642d34d --- /dev/null +++ b/x/typesutil/check.go @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package typesutil + +import ( + goast "go/ast" + "go/types" + + "github.com/goplus/gop/ast" + "github.com/goplus/gop/token" +) + +// A Checker maintains the state of the type checker. +// It must be created with NewChecker. +type Checker struct { + c *types.Checker +} + +// NewChecker returns a new Checker instance for a given package. +// Package files may be added incrementally via checker.Files. +func NewChecker( + conf *types.Config, fset *token.FileSet, pkg *types.Package, + goInfo *types.Info, gopInfo *Info) *Checker { + check := types.NewChecker(conf, fset, pkg, goInfo) + return &Checker{check} +} + +// Files checks the provided files as part of the checker's package. +func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { + if len(gopFiles) == 0 { + return p.c.Files(goFiles) + } + // goxls: todo + return nil +} diff --git a/x/typesutil/eval.go b/x/typesutil/eval.go new file mode 100644 index 000000000..779ad5e78 --- /dev/null +++ b/x/typesutil/eval.go @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package typesutil + +import ( + "go/types" + + "github.com/goplus/gop/ast" + "github.com/goplus/gop/token" +) + +// CheckExpr type checks the expression expr as if it had appeared at position +// pos of package pkg. Type information about the expression is recorded in +// info. The expression may be an identifier denoting an uninstantiated generic +// function or type. +// +// If pkg == nil, the Universe scope is used and the provided +// position pos is ignored. If pkg != nil, and pos is invalid, +// the package scope is used. Otherwise, pos must belong to the +// package. +// +// An error is returned if pos is not within the package or +// if the node cannot be type-checked. +// +// Note: Eval and CheckExpr should not be used instead of running Check +// to compute types and values, but in addition to Check, as these +// functions ignore the context in which an expression is used (e.g., an +// assignment). Thus, top-level untyped constants will return an +// untyped type rather than the respective context-specific type. +func CheckExpr(fset *token.FileSet, pkg *types.Package, pos token.Pos, expr ast.Expr, info *Info) (err error) { + panic("todo") +} diff --git a/x/typesutil/typesutil.go b/x/typesutil/typesutil.go new file mode 100644 index 000000000..6ded02979 --- /dev/null +++ b/x/typesutil/typesutil.go @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package typesutil + +import ( + "go/types" + + "github.com/goplus/gop/ast" +) + +// Info holds result type information for a type-checked package. +// Only the information for which a map is provided is collected. +// If the package has type errors, the collected information may +// be incomplete. +type Info struct { + // Types maps expressions to their types, and for constant + // expressions, also their values. Invalid expressions are + // omitted. + // + // For (possibly parenthesized) identifiers denoting built-in + // functions, the recorded signatures are call-site specific: + // if the call result is not a constant, the recorded type is + // an argument-specific signature. Otherwise, the recorded type + // is invalid. + // + // The Types map does not record the type of every identifier, + // only those that appear where an arbitrary expression is + // permitted. For instance, the identifier f in a selector + // expression x.f is found only in the Selections map, the + // identifier z in a variable declaration 'var z int' is found + // only in the Defs map, and identifiers denoting packages in + // qualified identifiers are collected in the Uses map. + Types map[ast.Expr]types.TypeAndValue + + // Instances maps identifiers denoting generic types or functions to their + // type arguments and instantiated type. + // + // For example, Instances will map the identifier for 'T' in the type + // instantiation T[int, string] to the type arguments [int, string] and + // resulting instantiated *Named type. Given a generic function + // func F[A any](A), Instances will map the identifier for 'F' in the call + // expression F(int(1)) to the inferred type arguments [int], and resulting + // instantiated *Signature. + // + // Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs + // results in an equivalent of Instances[id].Type. + Instances map[*ast.Ident]types.Instance + + // Defs maps identifiers to the objects they define (including + // package names, dots "." of dot-imports, and blank "_" identifiers). + // For identifiers that do not denote objects (e.g., the package name + // in package clauses, or symbolic variables t in t := x.(type) of + // type switch headers), the corresponding objects are nil. + // + // For an embedded field, Defs returns the field *Var it defines. + // + // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() + Defs map[*ast.Ident]types.Object + + // Uses maps identifiers to the objects they denote. + // + // For an embedded field, Uses returns the *TypeName it denotes. + // + // Invariant: Uses[id].Pos() != id.Pos() + Uses map[*ast.Ident]types.Object + + // Implicits maps nodes to their implicitly declared objects, if any. + // The following node and object types may appear: + // + // node declared object + // + // *ast.ImportSpec *PkgName for imports without renames + // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default) + // *ast.Field anonymous parameter *Var (incl. unnamed results) + // + Implicits map[ast.Node]types.Object + + // Selections maps selector expressions (excluding qualified identifiers) + // to their corresponding selections. + Selections map[*ast.SelectorExpr]*types.Selection + + // Scopes maps ast.Nodes to the scopes they define. Package scopes are not + // associated with a specific node but with all files belonging to a package. + // Thus, the package scope can be found in the type-checked Package object. + // Scopes nest, with the Universe scope being the outermost scope, enclosing + // the package scope, which contains (one or more) files scopes, which enclose + // function scopes which in turn enclose statement and function literal scopes. + // Note that even though package-level functions are declared in the package + // scope, the function scopes are embedded in the file scope of the file + // containing the function declaration. + // + // The following node types may appear in Scopes: + // + // *ast.File + // *ast.FuncType + // *ast.TypeSpec + // *ast.BlockStmt + // *ast.IfStmt + // *ast.SwitchStmt + // *ast.TypeSwitchStmt + // *ast.CaseClause + // *ast.CommClause + // *ast.ForStmt + // *ast.RangeStmt + // + Scopes map[ast.Node]*types.Scope + + // InitOrder is the list of package-level initializers in the order in which + // they must be executed. Initializers referring to variables related by an + // initialization dependency appear in topological order, the others appear + // in source order. Variables without an initialization expression do not + // appear in this list. + // InitOrder []*Initializer +} + +// ObjectOf returns the object denoted by the specified id, +// or nil if not found. +// +// If id is an embedded struct field, ObjectOf returns the field (*Var) +// it defines, not the type (*TypeName) it uses. +// +// Precondition: the Uses and Defs maps are populated. +func (info *Info) ObjectOf(id *ast.Ident) types.Object { + if obj := info.Defs[id]; obj != nil { + return obj + } + return info.Uses[id] +} + +// TypeOf returns the type of expression e, or nil if not found. +// Precondition: the Types, Uses and Defs maps are populated. +func (info *Info) TypeOf(e ast.Expr) types.Type { + if t, ok := info.Types[e]; ok { + return t.Type + } + if id, _ := e.(*ast.Ident); id != nil { + if obj := info.ObjectOf(id); obj != nil { + return obj.Type() + } + } + return nil +} From cc4b8585b5877b886c133f8b97f348c4c6c21137 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 19 Oct 2023 20:14:16 +0800 Subject: [PATCH 07/64] gop/x/typesutil --- cl/compile.go | 170 ++++++++++++++++++++++++++++++++++++--- cl/stmt.go | 11 +++ go.mod | 2 +- load.go | 19 +---- outline.go | 3 +- x/c2go/c2go.go | 42 ++++++++++ x/typesutil/check.go | 75 ++++++++++++++--- x/typesutil/typesutil.go | 114 ++++++++++++++++++++++++++ 8 files changed, 399 insertions(+), 37 deletions(-) create mode 100644 x/c2go/c2go.go diff --git a/cl/compile.go b/cl/compile.go index edbf9b481..1ce820856 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -62,34 +62,141 @@ func SetDebug(flags int) { // ----------------------------------------------------------------------------- +type Recorder interface { + // Type maps expressions to their types, and for constant + // expressions, also their values. Invalid expressions are + // omitted. + // + // For (possibly parenthesized) identifiers denoting built-in + // functions, the recorded signatures are call-site specific: + // if the call result is not a constant, the recorded type is + // an argument-specific signature. Otherwise, the recorded type + // is invalid. + // + // The Types map does not record the type of every identifier, + // only those that appear where an arbitrary expression is + // permitted. For instance, the identifier f in a selector + // expression x.f is found only in the Selections map, the + // identifier z in a variable declaration 'var z int' is found + // only in the Defs map, and identifiers denoting packages in + // qualified identifiers are collected in the Uses map. + Type(ast.Expr, types.TypeAndValue) + + // Instantiate maps identifiers denoting generic types or functions to their + // type arguments and instantiated type. + // + // For example, Instantiate will map the identifier for 'T' in the type + // instantiation T[int, string] to the type arguments [int, string] and + // resulting instantiated *Named type. Given a generic function + // func F[A any](A), Instances will map the identifier for 'F' in the call + // expression F(int(1)) to the inferred type arguments [int], and resulting + // instantiated *Signature. + // + // Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs + // results in an equivalent of Instances[id].Type. + Instantiate(*ast.Ident, types.Instance) + + // Def maps identifiers to the objects they define (including + // package names, dots "." of dot-imports, and blank "_" identifiers). + // For identifiers that do not denote objects (e.g., the package name + // in package clauses, or symbolic variables t in t := x.(type) of + // type switch headers), the corresponding objects are nil. + // + // For an embedded field, Def maps the field *Var it defines. + // + // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() + Def(id *ast.Ident, obj types.Object) + + // Use maps identifiers to the objects they denote. + // + // For an embedded field, Use maps the *TypeName it denotes. + // + // Invariant: Uses[id].Pos() != id.Pos() + Use(id *ast.Ident, obj types.Object) + + // Implicit maps nodes to their implicitly declared objects, if any. + // The following node and object types may appear: + // + // node declared object + // + // *ast.ImportSpec *PkgName for imports without renames + // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default) + // *ast.Field anonymous parameter *Var (incl. unnamed results) + // + Implicit(node ast.Node, obj types.Object) + + // Select maps selector expressions (excluding qualified identifiers) + // to their corresponding selections. + Select(*ast.SelectorExpr, *types.Selection) + + // Scope maps ast.Nodes to the scopes they define. Package scopes are not + // associated with a specific node but with all files belonging to a package. + // Thus, the package scope can be found in the type-checked Package object. + // Scopes nest, with the Universe scope being the outermost scope, enclosing + // the package scope, which contains (one or more) files scopes, which enclose + // function scopes which in turn enclose statement and function literal scopes. + // Note that even though package-level functions are declared in the package + // scope, the function scopes are embedded in the file scope of the file + // containing the function declaration. + // + // The following node types may appear in Scopes: + // + // *ast.File + // *ast.FuncType + // *ast.TypeSpec + // *ast.BlockStmt + // *ast.IfStmt + // *ast.SwitchStmt + // *ast.TypeSwitchStmt + // *ast.CaseClause + // *ast.CommClause + // *ast.ForStmt + // *ast.RangeStmt + // + Scope(ast.Node, *types.Scope) +} + +// ----------------------------------------------------------------------------- + type Project = modfile.Project type Class = modfile.Class // Config of loading Go+ packages. type Config struct { - // Fset provides source position information for syntax trees and types. + // Types provides type information for the package (optional). + Types *types.Package + + // Fset provides source position information for syntax trees and types (required). // 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 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. + // TargetDir is the directory in which to generate Go files (optional). + // If TargetDir is not set, it is same as WorkingDir. TargetDir string - // C2goBase specifies base of standard c2go packages. + // C2goBase specifies base of standard c2go packages (optional). // Default is github.com/goplus/. C2goBase string - // LookupPub lookups the c2go package pubfile (named c2go.a.pub). + // LookupPub lookups the c2go package pubfile named c2go.a.pub (required). + // See gop/x/c2go.LookupPub. LookupPub func(pkgPath string) (pubfile string, err error) - // LookupClass lookups a class by specified file extension. + // LookupClass lookups a class by specified file extension (required). + // See (*github.com/goplus/mod/gopmod.Module).LookupClass. LookupClass func(ext string) (c *Project, ok bool) - // An Importer resolves import paths to Packages. + // An Importer resolves import paths to Packages (optional). Importer types.Importer + // A Recorder records existing objects including constants, variables and + // types etc (optional). + Recorder Recorder + // NoFileLine = true means not to generate file line comments. NoFileLine bool @@ -270,9 +377,18 @@ type blockCtx struct { c2goBase string // default is `github.com/goplus/` targetDir string classRecv *ast.FieldList // available when gmxSettings != nil + rec Recorder fileLine bool relativePath bool isClass bool + isGopFile bool // is Go+ file or not +} + +func (bc *blockCtx) recorder() Recorder { + if bc.isGopFile { + return bc.rec + } + return nil } func (bc *blockCtx) findImport(name string) (pr *gox.PkgRef, ok bool) { @@ -382,6 +498,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, syms: make(map[string]loader), nodeInterp: interp, generics: make(map[string]bool), } confGox := &gox.Config{ + Types: conf.Types, Fset: fset, Importer: conf.Importer, LoadNamed: ctx.loadNamed, @@ -422,8 +539,8 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, fileLine := !conf.NoFileLine ctx := &blockCtx{ pkg: p, pkgCtx: ctx, cb: p.CB(), fset: p.Fset, targetDir: targetDir, - fileLine: fileLine, relativePath: conf.RelativePath, isClass: f.IsClass, - c2goBase: c2goBase(conf.C2goBase), imports: make(map[string]*gox.PkgRef), + fileLine: fileLine, relativePath: conf.RelativePath, isClass: f.IsClass, rec: conf.Recorder, + c2goBase: c2goBase(conf.C2goBase), imports: make(map[string]*gox.PkgRef), isGopFile: true, } preloadGopFile(p, ctx, fpath, f, conf) } @@ -774,6 +891,9 @@ func preloadFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, gopFil } else if d.Doc != nil { defs.SetComments(d.Doc) } + if rec := ctx.recorder(); rec != nil { + rec.Def(t.Name, decl.Type().Obj()) + } ld.typInit = func() { // decycle if debugLoad { log.Println("==> Load > InitType", name) @@ -899,6 +1019,9 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { if d.Doc != nil { fn.SetComments(d.Doc) } + if rec := ctx.recorder(); rec != nil { + rec.Def(d.Name, fn.Obj()) + } if genBody { if body := d.Body; body != nil { if recv != nil { @@ -996,6 +1119,16 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) { pkg = ctx.pkg.Import(simplifyGopPackage(pkgPath), spec) } var name string + if rec := ctx.recorder(); rec != nil { + defer func() { + pkgName := types.NewPkgName(token.NoPos, ctx.pkg.Types, name, pkg.Types) + if spec.Name != nil { + rec.Def(spec.Name, pkgName) + } else { + rec.Implicit(spec, pkgName) + } + }() + } if spec.Name != nil { name = spec.Name.Name if name == "." { @@ -1020,12 +1153,14 @@ func loadConstSpecs(ctx *blockCtx, cdecl *gox.ConstDefs, specs []ast.Spec) { } func loadConsts(ctx *blockCtx, cdecl *gox.ConstDefs, v *ast.ValueSpec, iotav int) { - names := makeNames(v.Names) + vNames := v.Names + names := makeNames(vNames) if v.Values == nil { if debugLoad { log.Println("==> Load const", names) } cdecl.Next(iotav, v.Pos(), names...) + defNames(ctx, vNames, nil) return } var typ types.Type @@ -1042,6 +1177,7 @@ func loadConsts(ctx *blockCtx, cdecl *gox.ConstDefs, v *ast.ValueSpec, iotav int return len(v.Values) } cdecl.New(fn, iotav, v.Pos(), typ, names...) + defNames(ctx, v.Names, nil) } func loadVars(ctx *blockCtx, v *ast.ValueSpec, global bool) { @@ -1093,6 +1229,20 @@ func loadVars(ctx *blockCtx, v *ast.ValueSpec, global bool) { } cb.EndInit(nv) } + defNames(ctx, v.Names, scope) +} + +func defNames(ctx *blockCtx, names []*ast.Ident, scope *types.Scope) { + if rec := ctx.recorder(); rec != nil { + if scope == nil { + scope = ctx.cb.Scope() + } + for _, name := range names { + if o := scope.Lookup(name.Name); o != nil { + rec.Def(name, o) + } + } + } } func makeNames(vals []*ast.Ident) []string { diff --git a/cl/stmt.go b/cl/stmt.go index acef23b7d..77183fc49 100644 --- a/cl/stmt.go +++ b/cl/stmt.go @@ -213,6 +213,17 @@ func compileAssignStmt(ctx *blockCtx, expr *ast.AssignStmt) { log.Panicln("TODO: non-name $v on left side of :=") } } + if rec := ctx.recorder(); rec != nil { + newNames := make([]*ast.Ident, 0, len(names)) + scope := ctx.cb.Scope() + for _, lhs := range expr.Lhs { + v := lhs.(*ast.Ident) + if scope.Lookup(v.Name) == nil { + newNames = append(newNames, v) + } + } + defer defNames(ctx, newNames, scope) + } ctx.cb.DefineVarStart(expr.Pos(), names...) if enableRecover { defer func() { diff --git a/go.mod b/go.mod index 9ae30e0db..5e7e64fdf 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/goplus/gop -go 1.17 +go 1.18 require ( github.com/fsnotify/fsnotify v1.6.0 diff --git a/load.go b/load.go index 52b9cc512..a7bafa714 100644 --- a/load.go +++ b/load.go @@ -21,13 +21,13 @@ import ( "go/token" "go/types" "io/fs" - "path/filepath" "strings" "syscall" "github.com/goplus/gop/ast" "github.com/goplus/gop/cl" "github.com/goplus/gop/parser" + "github.com/goplus/gop/x/c2go" "github.com/goplus/gop/x/gopenv" "github.com/goplus/gox" "github.com/goplus/mod/env" @@ -79,19 +79,6 @@ func LoadMod(dir string, gop *env.Gop, conf *Config) (mod *gopmod.Module, err er return new(gopmod.Module), nil } -func lookupPub(mod *gopmod.Module) func(pkgPath string) (pubfile string, err error) { - return func(pkgPath string) (pubfile string, err error) { - if mod.File == nil { // no go.mod/gop.mod file - return "", syscall.ENOENT - } - pkg, err := mod.Lookup(pkgPath) - if err == nil { - pubfile = filepath.Join(pkg.Dir, "c2go.a.pub") - } - return - } -} - // ----------------------------------------------------------------------------- func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (out, test *gox.Package, err error) { @@ -134,7 +121,7 @@ func LoadDir(dir string, conf *Config, genTestPkg bool, promptGenGo ...bool) (ou Fset: fset, Importer: imp, LookupClass: mod.LookupClass, - LookupPub: lookupPub(mod), + LookupPub: c2go.LookupPub(mod), } for name, pkg := range pkgs { if strings.HasSuffix(name, "_test") { @@ -205,7 +192,7 @@ func LoadFiles(files []string, conf *Config) (out *gox.Package, err error) { Fset: fset, Importer: imp, LookupClass: mod.LookupClass, - LookupPub: lookupPub(mod), + LookupPub: c2go.LookupPub(mod), } out, err = cl.NewPackage("", pkg, clConf) if err != nil { diff --git a/outline.go b/outline.go index e718e4d77..9ddcb354f 100644 --- a/outline.go +++ b/outline.go @@ -28,6 +28,7 @@ import ( "github.com/goplus/gop/cl/outline" "github.com/goplus/gop/parser" + "github.com/goplus/gop/x/c2go" "github.com/goplus/gop/x/gopenv" "github.com/goplus/mod/gopmod" ) @@ -99,7 +100,7 @@ func Outline(dir string, conf *Config) (out outline.Package, err error) { WorkingDir: dir, Importer: imp, LookupClass: mod.LookupClass, - LookupPub: lookupPub(mod), + LookupPub: c2go.LookupPub(mod), }) if err != nil { return diff --git a/x/c2go/c2go.go b/x/c2go/c2go.go new file mode 100644 index 000000000..d2240f117 --- /dev/null +++ b/x/c2go/c2go.go @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package c2go + +import ( + "path/filepath" + "syscall" + + "github.com/goplus/mod/gopmod" +) + +// ----------------------------------------------------------------------------- + +// LookupPub returns a anonymous function required by cl.NewPackage. +func LookupPub(mod *gopmod.Module) func(pkgPath string) (pubfile string, err error) { + return func(pkgPath string) (pubfile string, err error) { + if mod.File == nil { // no go.mod/gop.mod file + return "", syscall.ENOENT + } + pkg, err := mod.Lookup(pkgPath) + if err == nil { + pubfile = filepath.Join(pkg.Dir, "c2go.a.pub") + } + return + } +} + +// ----------------------------------------------------------------------------- diff --git a/x/typesutil/check.go b/x/typesutil/check.go index 00642d34d..09db392ba 100644 --- a/x/typesutil/check.go +++ b/x/typesutil/check.go @@ -21,29 +21,86 @@ import ( "go/types" "github.com/goplus/gop/ast" + "github.com/goplus/gop/cl" "github.com/goplus/gop/token" ) +type Project = cl.Project + +type Config struct { + // Types provides type information for the package. + Types *types.Package + + // Fset provides source position information for syntax trees and types. + // 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 + + // LookupPub lookups the c2go package pubfile (named c2go.a.pub). + LookupPub func(pkgPath string) (pubfile string, err error) + + // LookupClass lookups a class by specified file extension. + LookupClass func(ext string) (c *Project, ok bool) +} + // A Checker maintains the state of the type checker. // It must be created with NewChecker. type Checker struct { - c *types.Checker + conf *types.Config + opts *Config + goInfo *types.Info + gopInfo *Info } // NewChecker returns a new Checker instance for a given package. // Package files may be added incrementally via checker.Files. -func NewChecker( - conf *types.Config, fset *token.FileSet, pkg *types.Package, - goInfo *types.Info, gopInfo *Info) *Checker { - check := types.NewChecker(conf, fset, pkg, goInfo) - return &Checker{check} +func NewChecker(conf *types.Config, opts *Config, goInfo *types.Info, gopInfo *Info) *Checker { + return &Checker{conf, opts, goInfo, gopInfo} } // Files checks the provided files as part of the checker's package. func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { + opts := p.opts + pkgTypes := opts.Types + fset := opts.Fset + conf := p.conf if len(gopFiles) == 0 { - return p.c.Files(goFiles) + checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo) + return checker.Files(goFiles) + } + gofs := make(map[string]*goast.File) + gopfs := make(map[string]*ast.File) + for _, goFile := range goFiles { + f := fset.File(goFile.Pos()) + gofs[f.Name()] = goFile + } + for _, gopFile := range gopFiles { + f := fset.File(gopFile.Pos()) + gopfs[f.Name()] = gopFile + } + pkg := &ast.Package{ + Name: pkgTypes.Name(), + Files: gopfs, + GoFiles: gofs, } - // goxls: todo - return nil + _, err := cl.NewPackage(pkgTypes.Path(), pkg, &cl.Config{ + Types: pkgTypes, + Fset: fset, + WorkingDir: opts.WorkingDir, + C2goBase: opts.C2goBase, + LookupPub: opts.LookupPub, + LookupClass: opts.LookupClass, + Importer: conf.Importer, + Recorder: gopRecorder{p.gopInfo}, + NoFileLine: true, + NoAutoGenMain: true, + NoSkipConstant: true, + }) + return err } diff --git a/x/typesutil/typesutil.go b/x/typesutil/typesutil.go index 6ded02979..4f3575616 100644 --- a/x/typesutil/typesutil.go +++ b/x/typesutil/typesutil.go @@ -22,6 +22,8 @@ import ( "github.com/goplus/gop/ast" ) +// ----------------------------------------------------------------------------- + // Info holds result type information for a type-checked package. // Only the information for which a map is provided is collected. // If the package has type errors, the collected information may @@ -154,3 +156,115 @@ func (info *Info) TypeOf(e ast.Expr) types.Type { } return nil } + +// ----------------------------------------------------------------------------- + +type gopRecorder struct { + *Info +} + +// Type maps expressions to their types, and for constant +// expressions, also their values. Invalid expressions are +// omitted. +// +// For (possibly parenthesized) identifiers denoting built-in +// functions, the recorded signatures are call-site specific: +// if the call result is not a constant, the recorded type is +// an argument-specific signature. Otherwise, the recorded type +// is invalid. +// +// The Types map does not record the type of every identifier, +// only those that appear where an arbitrary expression is +// permitted. For instance, the identifier f in a selector +// expression x.f is found only in the Selections map, the +// identifier z in a variable declaration 'var z int' is found +// only in the Defs map, and identifiers denoting packages in +// qualified identifiers are collected in the Uses map. +func (info gopRecorder) Type(e ast.Expr, tv types.TypeAndValue) { + info.Types[e] = tv +} + +// Instantiate maps identifiers denoting generic types or functions to their +// type arguments and instantiated type. +// +// For example, Instantiate will map the identifier for 'T' in the type +// instantiation T[int, string] to the type arguments [int, string] and +// resulting instantiated *Named type. Given a generic function +// func F[A any](A), Instances will map the identifier for 'F' in the call +// expression F(int(1)) to the inferred type arguments [int], and resulting +// instantiated *Signature. +// +// Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs +// results in an equivalent of Instances[id].Type. +func (info gopRecorder) Instantiate(id *ast.Ident, inst types.Instance) { + info.Instances[id] = inst +} + +// Def maps identifiers to the objects they define (including +// package names, dots "." of dot-imports, and blank "_" identifiers). +// For identifiers that do not denote objects (e.g., the package name +// in package clauses, or symbolic variables t in t := x.(type) of +// type switch headers), the corresponding objects are nil. +// +// For an embedded field, Def maps the field *Var it defines. +// +// Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() +func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { + info.Defs[id] = obj +} + +// Use maps identifiers to the objects they denote. +// +// For an embedded field, Use maps the *TypeName it denotes. +// +// Invariant: Uses[id].Pos() != id.Pos() +func (info gopRecorder) Use(id *ast.Ident, obj types.Object) { + info.Uses[id] = obj +} + +// Implicit maps nodes to their implicitly declared objects, if any. +// The following node and object types may appear: +// +// node declared object +// +// *ast.ImportSpec *PkgName for imports without renames +// *ast.CaseClause type-specific *Var for each type switch case clause (incl. default) +// *ast.Field anonymous parameter *Var (incl. unnamed results) +func (info gopRecorder) Implicit(node ast.Node, obj types.Object) { + info.Implicits[node] = obj +} + +// Select maps selector expressions (excluding qualified identifiers) +// to their corresponding selections. +func (info gopRecorder) Select(e *ast.SelectorExpr, sel *types.Selection) { + info.Selections[e] = sel +} + +// Scope maps ast.Nodes to the scopes they define. Package scopes are not +// associated with a specific node but with all files belonging to a package. +// Thus, the package scope can be found in the type-checked Package object. +// Scopes nest, with the Universe scope being the outermost scope, enclosing +// the package scope, which contains (one or more) files scopes, which enclose +// function scopes which in turn enclose statement and function literal scopes. +// Note that even though package-level functions are declared in the package +// scope, the function scopes are embedded in the file scope of the file +// containing the function declaration. +// +// The following node types may appear in Scopes: +// +// *ast.File +// *ast.FuncType +// *ast.TypeSpec +// *ast.BlockStmt +// *ast.IfStmt +// *ast.SwitchStmt +// *ast.TypeSwitchStmt +// *ast.CaseClause +// *ast.CommClause +// *ast.ForStmt +// *ast.RangeStmt +func (info gopRecorder) Scope(n ast.Node, scope *types.Scope) { + info.Scopes[n] = scope +} + +// ----------------------------------------------------------------------------- From d3e1fa373884f8828b8268b65bcaca0c610bbe50 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 19 Oct 2023 20:15:57 +0800 Subject: [PATCH 08/64] github.com/goplus/gox@main --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5e7e64fdf..68c56342d 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/fsnotify/fsnotify v1.6.0 github.com/goplus/c2go v0.7.16 - github.com/goplus/gox v1.12.2-0.20231012035644-c3bf89ec9e2b + github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c github.com/goplus/mod v0.11.7 github.com/qiniu/x v1.13.1 golang.org/x/tools v0.14.0 diff --git a/go.sum b/go.sum index 80ab5bf22..7f5d25df6 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.20231012035644-c3bf89ec9e2b h1:5jCLZcnLj2jOTOw5j979XMoqeWI1ghZVnfuwmKbe5Eo= -github.com/goplus/gox v1.12.2-0.20231012035644-c3bf89ec9e2b/go.mod h1:ferIrvJSoXae8gABk5Z4olEzfAxZpUy4hD91Vm5E/qs= +github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c h1:ejOhMNclo9/kzkI31k1IMCjUAUZ0Ore5+CXJZQgxBOQ= +github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c/go.mod h1:ferIrvJSoXae8gABk5Z4olEzfAxZpUy4hD91Vm5E/qs= github.com/goplus/mod v0.11.5/go.mod h1:NDC5E+XOT8vcJCMjqKhLDJHTHX7lyVN4Vbfi2U7dBhs= github.com/goplus/mod v0.11.7 h1:OTGFi/Jk0qmTy3ih8u3BQ6CbtcaPlTrJBlTacnge0jE= github.com/goplus/mod v0.11.7/go.mod h1:yl2QncBKTdXk+8UaNsdo4u2zSpGEJYA5JKjgD3K2h00= From 8ee9016f6e964ff870bd3d864b7d797981ef160f Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 19 Oct 2023 20:26:58 +0800 Subject: [PATCH 09/64] go1.18 --- .github/workflows/go.yml | 2 +- README.md | 2 +- doc/docs.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 193276de0..8970d496f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -10,7 +10,7 @@ jobs: Test: strategy: matrix: - go-version: [1.17.x, 1.18.x, 1.19.x, 1.20.x] + go-version: [1.18.x, 1.19.x, 1.20.x, 1.21.x] os: [ubuntu-latest, windows-latest, macos-11] runs-on: ${{ matrix.os }} steps: diff --git a/README.md b/README.md index 3912c3aad..70e944cac 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ For more details, see [Quick Start](doc/docs.md). For now, we suggest you install Go+ from source code. -Note: Requires go1.17 or later +Note: Requires go1.18 or later ```bash git clone https://github.com/goplus/gop.git diff --git a/doc/docs.md b/doc/docs.md index 784e128bc..f2434cf9c 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -11,7 +11,7 @@ The Go+ programming language is designed for engineering, STEM education, and da For now, we suggest you install Go+ from source code. -Note: Requires go1.17 or later +Note: Requires go1.18 or later ```bash git clone https://github.com/goplus/gop.git From f56162eef2afa5bfc3b297e0e8ed2d17495082d9 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 19 Oct 2023 20:47:58 +0800 Subject: [PATCH 10/64] cl/recorder_test --- cl/compile_spx_test.go | 1 + cl/compile_test.go | 1 + cl/recorder_test.go | 107 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 cl/recorder_test.go diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go index 9786376e7..1fe31d875 100644 --- a/cl/compile_spx_test.go +++ b/cl/compile_spx_test.go @@ -108,6 +108,7 @@ func gopSpxErrorTestEx(t *testing.T, msg, gmx, spxcode, gmxfile, spxfile string) t.Fatal("ParseFSDir:", err) } conf := *gblConf + conf.Recorder = nil conf.NoFileLine = false conf.WorkingDir = "/foo" conf.TargetDir = "/foo" diff --git a/cl/compile_test.go b/cl/compile_test.go index e870aed3d..37cf5786b 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -50,6 +50,7 @@ func init() { gblConf = &cl.Config{ Fset: gblFset, Importer: imp, + Recorder: gopRecorder{}, LookupClass: lookupClass, LookupPub: lookupPub, C2goBase: "github.com/goplus/gop/cl/internal", diff --git a/cl/recorder_test.go b/cl/recorder_test.go new file mode 100644 index 000000000..1e85a573b --- /dev/null +++ b/cl/recorder_test.go @@ -0,0 +1,107 @@ +package cl_test + +import ( + "go/types" + + "github.com/goplus/gop/ast" +) + +type gopRecorder struct { +} + +// Type maps expressions to their types, and for constant +// expressions, also their values. Invalid expressions are +// omitted. +// +// For (possibly parenthesized) identifiers denoting built-in +// functions, the recorded signatures are call-site specific: +// if the call result is not a constant, the recorded type is +// an argument-specific signature. Otherwise, the recorded type +// is invalid. +// +// The Types map does not record the type of every identifier, +// only those that appear where an arbitrary expression is +// permitted. For instance, the identifier f in a selector +// expression x.f is found only in the Selections map, the +// identifier z in a variable declaration 'var z int' is found +// only in the Defs map, and identifiers denoting packages in +// qualified identifiers are collected in the Uses map. +func (info gopRecorder) Type(e ast.Expr, tv types.TypeAndValue) { +} + +// Instantiate maps identifiers denoting generic types or functions to their +// type arguments and instantiated type. +// +// For example, Instantiate will map the identifier for 'T' in the type +// instantiation T[int, string] to the type arguments [int, string] and +// resulting instantiated *Named type. Given a generic function +// func F[A any](A), Instances will map the identifier for 'F' in the call +// expression F(int(1)) to the inferred type arguments [int], and resulting +// instantiated *Signature. +// +// Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs +// results in an equivalent of Instances[id].Type. +func (info gopRecorder) Instantiate(id *ast.Ident, inst types.Instance) { +} + +// Def maps identifiers to the objects they define (including +// package names, dots "." of dot-imports, and blank "_" identifiers). +// For identifiers that do not denote objects (e.g., the package name +// in package clauses, or symbolic variables t in t := x.(type) of +// type switch headers), the corresponding objects are nil. +// +// For an embedded field, Def maps the field *Var it defines. +// +// Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() +func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { +} + +// Use maps identifiers to the objects they denote. +// +// For an embedded field, Use maps the *TypeName it denotes. +// +// Invariant: Uses[id].Pos() != id.Pos() +func (info gopRecorder) Use(id *ast.Ident, obj types.Object) { +} + +// Implicit maps nodes to their implicitly declared objects, if any. +// The following node and object types may appear: +// +// node declared object +// +// *ast.ImportSpec *PkgName for imports without renames +// *ast.CaseClause type-specific *Var for each type switch case clause (incl. default) +// *ast.Field anonymous parameter *Var (incl. unnamed results) +func (info gopRecorder) Implicit(node ast.Node, obj types.Object) { +} + +// Select maps selector expressions (excluding qualified identifiers) +// to their corresponding selections. +func (info gopRecorder) Select(e *ast.SelectorExpr, sel *types.Selection) { +} + +// Scope maps ast.Nodes to the scopes they define. Package scopes are not +// associated with a specific node but with all files belonging to a package. +// Thus, the package scope can be found in the type-checked Package object. +// Scopes nest, with the Universe scope being the outermost scope, enclosing +// the package scope, which contains (one or more) files scopes, which enclose +// function scopes which in turn enclose statement and function literal scopes. +// Note that even though package-level functions are declared in the package +// scope, the function scopes are embedded in the file scope of the file +// containing the function declaration. +// +// The following node types may appear in Scopes: +// +// *ast.File +// *ast.FuncType +// *ast.TypeSpec +// *ast.BlockStmt +// *ast.IfStmt +// *ast.SwitchStmt +// *ast.TypeSwitchStmt +// *ast.CaseClause +// *ast.CommClause +// *ast.ForStmt +// *ast.RangeStmt +func (info gopRecorder) Scope(n ast.Node, scope *types.Scope) { +} From 8aaba9d80c8cccdde00541cdfda8cd6660f9f568 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 19 Oct 2023 20:52:34 +0800 Subject: [PATCH 11/64] go1.18 --- cl/func_type_and_var.go | 14 +++-- cl/{types_go118.go => typeparams.go} | 5 -- cl/types_go117.go | 81 ---------------------------- 3 files changed, 6 insertions(+), 94 deletions(-) rename cl/{types_go118.go => typeparams.go} (99%) delete mode 100644 cl/types_go117.go diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index 7fe59d7f2..52b69f943 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -100,14 +100,12 @@ func toParam(ctx *blockCtx, fld *ast.Field, args []*gox.Param) []*gox.Param { func toType(ctx *blockCtx, typ ast.Expr) types.Type { switch v := typ.(type) { case *ast.Ident: - if enableTypeParams { - ctx.idents = append(ctx.idents, v) - defer func() { - ctx.idents = ctx.idents[:len(ctx.idents)-1] - }() - } + ctx.idents = append(ctx.idents, v) + defer func() { + ctx.idents = ctx.idents[:len(ctx.idents)-1] + }() typ := toIdentType(ctx, v) - if enableTypeParams && ctx.inInst == 0 { + if ctx.inInst == 0 { if t, ok := typ.(*types.Named); ok { if namedIsTypeParams(ctx, t) { pos := ctx.idents[0].Pos() @@ -142,7 +140,7 @@ func toType(ctx *blockCtx, typ ast.Expr) types.Type { return toFuncType(ctx, v, nil, nil) case *ast.SelectorExpr: typ := toExternalType(ctx, v) - if enableTypeParams && ctx.inInst == 0 { + if ctx.inInst == 0 { if t, ok := typ.(*types.Named); ok { if namedIsTypeParams(ctx, t) { panic(ctx.newCodeErrorf(v.Pos(), "cannot use generic type %v without instantiation", t.Obj().Type())) diff --git a/cl/types_go118.go b/cl/typeparams.go similarity index 99% rename from cl/types_go118.go rename to cl/typeparams.go index 52b2ea4b0..5a1e9d323 100644 --- a/cl/types_go118.go +++ b/cl/typeparams.go @@ -1,6 +1,3 @@ -//go:build go1.18 -// +build go1.18 - /* * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved. * @@ -26,8 +23,6 @@ import ( "github.com/goplus/gop/token" ) -const enableTypeParams = true - func toTermList(ctx *blockCtx, expr ast.Expr) []*types.Term { retry: switch v := expr.(type) { diff --git a/cl/types_go117.go b/cl/types_go117.go deleted file mode 100644 index 2f32f9164..000000000 --- a/cl/types_go117.go +++ /dev/null @@ -1,81 +0,0 @@ -//go:build !go1.18 -// +build !go1.18 - -/* - * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package cl - -import ( - "go/types" - - "github.com/goplus/gop/ast" -) - -const enableTypeParams = false - -func toBinaryExprType(ctx *blockCtx, v *ast.BinaryExpr) types.Type { - panic("type parameters are unsupported at this go version") -} - -func toUnaryExprType(ctx *blockCtx, v *ast.UnaryExpr) types.Type { - panic("type parameters are unsupported at this go version") -} - -type typeParamLookup struct { -} - -func (p *typeParamLookup) Lookup(name string) types.Type { - return nil -} - -func toFuncType(ctx *blockCtx, typ *ast.FuncType, recv *types.Var, d *ast.FuncDecl) *types.Signature { - params, variadic := toParams(ctx, typ.Params.List) - results := toResults(ctx, typ.Results) - return types.NewSignature(recv, params, results, variadic) -} - -func initType(ctx *blockCtx, named *types.Named, spec *ast.TypeSpec) { - typ := toType(ctx, spec.Type) - if named, ok := typ.(*types.Named); ok { - typ = getUnderlying(ctx, named) - } - named.SetUnderlying(typ) -} - -func getRecvType(typ ast.Expr) (ast.Expr, bool) { - var ptr bool -L: - for { - switch t := typ.(type) { - case *ast.ParenExpr: - typ = t.X - case *ast.StarExpr: - ptr = true - typ = t.X - default: - break L - } - } - return typ, ptr -} - -func sliceHasTypeParam(ctx *blockCtx, typ types.Type) bool { - return false -} - -func namedIsTypeParams(ctx *blockCtx, t *types.Named) bool { - return false -} From 613a552c43b6306cc4f57d8fc2ec7019de4194c8 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 20 Oct 2023 01:30:26 +0800 Subject: [PATCH 12/64] github.com/goplus/mod@main --- go.mod | 2 +- x/typesutil/check.go | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 68c56342d..bfc984aec 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/goplus/c2go v0.7.16 github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c - github.com/goplus/mod v0.11.7 + 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/x/typesutil/check.go b/x/typesutil/check.go index 09db392ba..6b6e2eb1b 100644 --- a/x/typesutil/check.go +++ b/x/typesutil/check.go @@ -28,24 +28,27 @@ import ( type Project = cl.Project type Config struct { - // Types provides type information for the package. + // Types provides type information for the package (optional). Types *types.Package - // Fset provides source position information for syntax trees and types. + // Fset provides source position information for syntax trees and types (required). // 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 is the directory in which to run gop compiler (optional). + // If WorkingDir is not set, os.Getwd() is used. WorkingDir string - // C2goBase specifies base of standard c2go packages. + // C2goBase specifies base of standard c2go packages (optional). // Default is github.com/goplus/. C2goBase string - // LookupPub lookups the c2go package pubfile (named c2go.a.pub). + // LookupPub lookups the c2go package pubfile named c2go.a.pub (required). + // See gop/x/c2go.LookupPub. LookupPub func(pkgPath string) (pubfile string, err error) - // LookupClass lookups a class by specified file extension. + // LookupClass lookups a class by specified file extension (required). + // See (*github.com/goplus/mod/gopmod.Module).LookupClass. LookupClass func(ext string) (c *Project, ok bool) } From d3e28deae8b0ae9fb1eb979d5f09c2ee9c1883f1 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 20 Oct 2023 01:30:56 +0800 Subject: [PATCH 13/64] github.com/goplus/mod@main --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 7f5d25df6..20e5090f8 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/goplus/gox v1.12.1/go.mod h1:wymoQJ7ydd42cTlaXb4wNbvn4LlKjR+j8PZehI7v github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c h1:ejOhMNclo9/kzkI31k1IMCjUAUZ0Ore5+CXJZQgxBOQ= github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c/go.mod h1:ferIrvJSoXae8gABk5Z4olEzfAxZpUy4hD91Vm5E/qs= github.com/goplus/mod v0.11.5/go.mod h1:NDC5E+XOT8vcJCMjqKhLDJHTHX7lyVN4Vbfi2U7dBhs= -github.com/goplus/mod v0.11.7 h1:OTGFi/Jk0qmTy3ih8u3BQ6CbtcaPlTrJBlTacnge0jE= -github.com/goplus/mod v0.11.7/go.mod h1:yl2QncBKTdXk+8UaNsdo4u2zSpGEJYA5JKjgD3K2h00= +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= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= From aba7fd72ee369333a99ca6f29b7ee9aaf64e3226 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 20 Oct 2023 01:32:35 +0800 Subject: [PATCH 14/64] gop.LoadMod: fix std package --- load.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/load.go b/load.go index a7bafa714..9d2065af4 100644 --- a/load.go +++ b/load.go @@ -58,11 +58,6 @@ func LoadMod(dir string, gop *env.Gop, conf *Config) (mod *gopmod.Module, err er return } if mod != nil { - if mod.Path() == "std" { // a Go std package - // TODO: should do this at github.com/goplus/mod - mod.Module.Module.Mod.Path = "" - return - } err = mod.ImportClasses() if err != nil { err = errors.NewWith(err, `mod.RegisterClasses()`, -2, "(*gopmod.Module).RegisterClasses", mod) From 588a70b3da0cc8c65a3411499b4effc52d0a64a9 Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 20 Oct 2023 15:12:41 +0800 Subject: [PATCH 15/64] update gox version --- cl/error_msg_test.go | 2 +- cl/outline/cl/error_msg_test.go | 2 +- go.mod | 2 +- go.sum | 8 ++------ 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/cl/error_msg_test.go b/cl/error_msg_test.go index 1bd50affd..7bd7d1b18 100644 --- a/cl/error_msg_test.go +++ b/cl/error_msg_test.go @@ -916,7 +916,7 @@ println "hello" } func TestErrVarInFunc(t *testing.T) { - codeErrorTest(t, `./bar.gop:6:10: too few arguments in call to set("box") + 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`, ` diff --git a/cl/outline/cl/error_msg_test.go b/cl/outline/cl/error_msg_test.go index 3a5f43eef..a07c414c6 100644 --- a/cl/outline/cl/error_msg_test.go +++ b/cl/outline/cl/error_msg_test.go @@ -916,7 +916,7 @@ println "hello" } func TestErrVarInFunc(t *testing.T) { - codeErrorTest(t, `./bar.gop:6:10: too few arguments in call to set("box") + 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`, ` diff --git a/go.mod b/go.mod index 68c56342d..9fdaa3b8f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/fsnotify/fsnotify v1.6.0 github.com/goplus/c2go v0.7.16 - github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c + github.com/goplus/gox v1.12.2-0.20231020050546-7a7af254a518 github.com/goplus/mod v0.11.7 github.com/qiniu/x v1.13.1 golang.org/x/tools v0.14.0 diff --git a/go.sum b/go.sum index 7f5d25df6..64cc6d31b 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.20231019103849-a9127073096c h1:ejOhMNclo9/kzkI31k1IMCjUAUZ0Ore5+CXJZQgxBOQ= -github.com/goplus/gox v1.12.2-0.20231019103849-a9127073096c/go.mod h1:ferIrvJSoXae8gABk5Z4olEzfAxZpUy4hD91Vm5E/qs= +github.com/goplus/gox v1.12.2-0.20231020050546-7a7af254a518 h1:s9CsA13IvxuCkOLrJkPmbS+Tilof5i2zIdQtyL5+USw= +github.com/goplus/gox v1.12.2-0.20231020050546-7a7af254a518/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ= github.com/goplus/mod v0.11.5/go.mod h1:NDC5E+XOT8vcJCMjqKhLDJHTHX7lyVN4Vbfi2U7dBhs= github.com/goplus/mod v0.11.7 h1:OTGFi/Jk0qmTy3ih8u3BQ6CbtcaPlTrJBlTacnge0jE= github.com/goplus/mod v0.11.7/go.mod h1:yl2QncBKTdXk+8UaNsdo4u2zSpGEJYA5JKjgD3K2h00= @@ -30,7 +30,6 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -42,13 +41,11 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -65,7 +62,6 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= From bd43aa404c990a70b65000d818ac0f208ee2e901 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 20 Oct 2023 17:51:14 +0800 Subject: [PATCH 16/64] gox: pkg.TryImport; typesutil.SetDebug --- cl/builtin.go | 66 ++++++++++++++---------- cl/c.go | 3 +- cl/compile.go | 23 +++++---- cl/func_type_and_var.go | 19 ++++--- cl/stmt.go | 22 ++++---- x/typesutil/check.go | 46 ++++++++++++++++- x/typesutil/{typesutil.go => gopinfo.go} | 13 +++++ 7 files changed, 134 insertions(+), 58 deletions(-) rename x/typesutil/{typesutil.go => gopinfo.go} (97%) diff --git a/cl/builtin.go b/cl/builtin.go index a97ecf343..3058e246e 100644 --- a/cl/builtin.go +++ b/cl/builtin.go @@ -41,39 +41,51 @@ func initBuiltinFns(builtin *types.Package, scope *types.Scope, pkg *gox.PkgRef, func initBuiltin(pkg *gox.Package, builtin *types.Package, os, fmt, ng, iox, buil *gox.PkgRef) { scope := builtin.Scope() - typs := []string{"bigint", "bigrat", "bigfloat"} - for _, typ := range typs { - name := string(typ[0]-('a'-'A')) + typ[1:] - scope.Insert(types.NewTypeName(token.NoPos, builtin, typ, ng.Ref(name).Type())) + if ng != nil { + typs := []string{"bigint", "bigrat", "bigfloat"} + for _, typ := range typs { + name := string(typ[0]-('a'-'A')) + typ[1:] + scope.Insert(types.NewTypeName(token.NoPos, builtin, typ, ng.Ref(name).Type())) + } + scope.Insert(types.NewTypeName(token.NoPos, builtin, "uint128", ng.Ref("Uint128").Type())) + scope.Insert(types.NewTypeName(token.NoPos, builtin, "int128", ng.Ref("Int128").Type())) + } + if fmt != nil { + initBuiltinFns(builtin, scope, fmt, []string{ + "print", "println", "printf", "errorf", + "fprint", "fprintln", "fprintf", + "sprint", "sprintln", "sprintf", + }) + } + if os != nil { + initBuiltinFns(builtin, scope, os, []string{ + "open", "create", + }) + } + if iox != nil { + initBuiltinFns(builtin, scope, iox, []string{ + "lines", + }) + scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "blines", iox.Ref("BLines"))) + } + if buil != nil { + scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "newRange", buil.Ref("NewRange__0"))) } - initBuiltinFns(builtin, scope, fmt, []string{ - "print", "println", "printf", "errorf", - "fprint", "fprintln", "fprintf", - "sprint", "sprintln", "sprintf", - }) - initBuiltinFns(builtin, scope, os, []string{ - "open", "create", - }) - initBuiltinFns(builtin, scope, iox, []string{ - "lines", - }) - scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "blines", iox.Ref("BLines"))) - scope.Insert(gox.NewOverloadFunc(token.NoPos, builtin, "newRange", buil.Ref("NewRange__0"))) - scope.Insert(types.NewTypeName(token.NoPos, builtin, "uint128", ng.Ref("Uint128").Type())) - scope.Insert(types.NewTypeName(token.NoPos, builtin, "int128", ng.Ref("Int128").Type())) scope.Insert(types.NewTypeName(token.NoPos, builtin, "any", gox.TyEmptyInterface)) } func newBuiltinDefault(pkg *gox.Package, conf *gox.Config) *types.Package { builtin := types.NewPackage("", "") - fmt := pkg.Import("fmt") - os := pkg.Import("os") - buil := pkg.Import("github.com/goplus/gop/builtin") - ng := pkg.Import("github.com/goplus/gop/builtin/ng") - iox := pkg.Import("github.com/goplus/gop/builtin/iox") - pkg.Import("strconv") - pkg.Import("strings") - initMathBig(pkg, conf, ng) + fmt := pkg.TryImport("fmt") + os := pkg.TryImport("os") + buil := pkg.TryImport("github.com/goplus/gop/builtin") + ng := pkg.TryImport("github.com/goplus/gop/builtin/ng") + iox := pkg.TryImport("github.com/goplus/gop/builtin/iox") + pkg.TryImport("strconv") + pkg.TryImport("strings") + if ng != nil { + initMathBig(pkg, conf, ng) + } initBuiltin(pkg, builtin, os, fmt, ng, iox, buil) gox.InitBuiltin(pkg, builtin, conf) return builtin diff --git a/cl/c.go b/cl/c.go index 39b4c9899..b203bbb21 100644 --- a/cl/c.go +++ b/cl/c.go @@ -60,8 +60,7 @@ func c2goBase(base string) string { func loadC2goPkg(ctx *blockCtx, realPath string, src *ast.BasicLit) *gox.PkgRef { cpkg, err := ctx.cpkgs.Import(realPath) if err != nil { - pos := ctx.Position(src.Pos()) - ctx.handleCodeErrorf(&pos, + ctx.handleErrorf(src.Pos(), "%v not found or not a valid C package (c2go.a.pub file not found).\n", realPath) return nil } diff --git a/cl/compile.go b/cl/compile.go index 1ce820856..f4f359689 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -36,8 +36,10 @@ import ( "github.com/qiniu/x/errors" ) +type dbgFlags int + const ( - DbgFlagLoad = 1 << iota + DbgFlagLoad dbgFlags = 1 << iota DbgFlagLookup DbgFlagAll = DbgFlagLoad | DbgFlagLookup ) @@ -55,7 +57,7 @@ func SetDisableRecover(disableRecover bool) { enableRecover = !disableRecover } -func SetDebug(flags int) { +func SetDebug(flags dbgFlags) { debugLoad = (flags & DbgFlagLoad) != 0 debugLookup = (flags & DbgFlagLookup) != 0 } @@ -271,13 +273,9 @@ func initLoader(ctx *pkgCtx, syms map[string]loader, start token.Pos, name strin return } if old, ok := syms[name]; ok { - var pos token.Position - if start != token.NoPos { - pos = ctx.Position(start) - } oldpos := ctx.Position(old.pos()) - ctx.handleCodeErrorf( - &pos, "%s redeclared in this block\n\tprevious declaration at %v", name, oldpos) + ctx.handleErrorf( + start, "%s redeclared in this block\n\tprevious declaration at %v", name, oldpos) return } syms[name] = &baseLoader{start: start, fn: fn} @@ -305,8 +303,8 @@ func getTypeLoader(ctx *pkgCtx, syms map[string]loader, start token.Pos, name st 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", + ctx.handleErrorf( + start, "%s redeclared in this block\n\tprevious declaration at %v", name, ctx.Position(ld.start)) } return ld @@ -414,6 +412,11 @@ func (p *pkgCtx) handleCodeErrorf(pos *token.Position, format string, args ...in p.handleErr(newCodeErrorf(pos, format, args...)) } +func (p *pkgCtx) handleErrorf(start token.Pos, format string, args ...interface{}) { + pos := p.Position(start) + p.handleErr(newCodeErrorf(&pos, format, args...)) +} + func (p *pkgCtx) handleErr(err error) { p.errs = append(p.errs, err) } diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index 52b69f943..321913486 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -115,7 +115,8 @@ func toType(ctx *blockCtx, typ ast.Expr) types.Type { break } } - panic(ctx.newCodeErrorf(pos, "cannot use generic type %v without instantiation", t.Obj().Type())) + ctx.handleErrorf(pos, "cannot use generic type %v without instantiation", t.Obj().Type()) + return types.Typ[types.Invalid] } } } @@ -182,9 +183,11 @@ func toExternalType(ctx *blockCtx, v *ast.SelectorExpr) types.Type { if t, ok := o.(*types.TypeName); ok { return t.Type() } - panic(ctx.newCodeErrorf(v.Pos(), "%s.%s is not a type", name, v.Sel.Name)) + ctx.handleErrorf(v.Pos(), "%s.%s is not a type", name, v.Sel.Name) + } else { + ctx.handleErrorf(v.Pos(), "undefined: %s", name) } - panic(ctx.newCodeErrorf(v.Pos(), "undefined: %s", name)) + return types.Typ[types.Invalid] } /*----------------------------------------------------------------------------- @@ -204,7 +207,8 @@ func toIdentType(ctx *blockCtx, ident *ast.Ident) types.Type { } v, builtin := lookupType(ctx, ident.Name) if isBuiltin(builtin) { - panic(ctx.newCodeErrorf(ident.Pos(), "use of builtin %s not in function call", ident.Name)) + ctx.handleErrorf(ident.Pos(), "use of builtin %s not in function call", ident.Name) + return types.Typ[types.Invalid] } if t, ok := v.(*types.TypeName); ok { return t.Type() @@ -214,7 +218,8 @@ func toIdentType(ctx *blockCtx, ident *ast.Ident) types.Type { return t.Type() } } - panic(ctx.newCodeErrorf(ident.Pos(), "%s is not a type", ident.Name)) + ctx.handleErrorf(ident.Pos(), "%s is not a type", ident.Name) + return types.Typ[types.Invalid] } // TODO: optimization @@ -255,8 +260,8 @@ func (p *checkRedecl) chkRedecl(ctx *blockCtx, name string, pos token.Pos) bool return false } if opos, ok := p.names[name]; ok { - npos := ctx.Position(pos) - ctx.handleCodeErrorf(&npos, "%v redeclared\n\t%v other declaration of %v", + ctx.handleErrorf( + pos, "%v redeclared\n\t%v other declaration of %v", name, ctx.Position(opos), name) return true } diff --git a/cl/stmt.go b/cl/stmt.go index 77183fc49..121c28983 100644 --- a/cl/stmt.go +++ b/cl/stmt.go @@ -559,11 +559,15 @@ func compileTypeSwitchStmt(ctx *blockCtx, v *ast.TypeSwitchStmt) { for t, other := range seen { if T == nil && t == nil || T != nil && t != nil && types.Identical(T, t) { haserr = true - pos := ctx.Position(citem.Pos()) + pos := citem.Pos() if T == types.Typ[types.UntypedNil] { - ctx.handleCodeErrorf(&pos, "multiple nil cases in type switch (first at %v)", ctx.Position(other.Pos())) + ctx.handleErrorf( + pos, "multiple nil cases in type switch (first at %v)", + ctx.Position(other.Pos())) } else { - ctx.handleCodeErrorf(&pos, "duplicate case %s in type switch\n\tprevious case at %v", T, ctx.Position(other.Pos())) + ctx.handleErrorf( + pos, "duplicate case %s in type switch\n\tprevious case at %v", + T, ctx.Position(other.Pos())) } } } @@ -573,8 +577,7 @@ func compileTypeSwitchStmt(ctx *blockCtx, v *ast.TypeSwitchStmt) { } if c.List == nil { if firstDefault != nil { - pos := ctx.Position(c.Pos()) - ctx.handleCodeErrorf(&pos, "multiple defaults in type switch (first at %v)", ctx.Position(firstDefault.Pos())) + ctx.handleErrorf(c.Pos(), "multiple defaults in type switch (first at %v)", ctx.Position(firstDefault.Pos())) } else { firstDefault = c } @@ -648,8 +651,7 @@ func compileSwitchStmt(ctx *blockCtx, v *ast.SwitchStmt) { } if c.List == nil { if firstDefault != nil { - pos := ctx.Position(c.Pos()) - ctx.handleCodeErrorf(&pos, "multiple defaults in switch (first at %v)", ctx.Position(firstDefault.Pos())) + ctx.handleErrorf(c.Pos(), "multiple defaults in switch (first at %v)", ctx.Position(firstDefault.Pos())) } else { firstDefault = c } @@ -735,8 +737,7 @@ func compileBranchStmt(ctx *blockCtx, v *ast.BranchStmt) { case token.CONTINUE: ctx.cb.Continue(getLabel(ctx, label)) case token.FALLTHROUGH: - pos := ctx.Position(v.Pos()) - ctx.handleCodeErrorf(&pos, "fallthrough statement out of place") + ctx.handleErrorf(v.Pos(), "fallthrough statement out of place") default: panic("unknown branch statement") } @@ -747,8 +748,7 @@ func getLabel(ctx *blockCtx, label *ast.Ident) *gox.Label { if l, ok := ctx.cb.LookupLabel(label.Name); ok { return l } - pos := ctx.Position(label.Pos()) - ctx.handleCodeErrorf(&pos, "label %v is not defined", label.Name) + ctx.handleErrorf(label.Pos(), "label %v is not defined", label.Name) } return nil } diff --git a/x/typesutil/check.go b/x/typesutil/check.go index 6b6e2eb1b..8febfaf8a 100644 --- a/x/typesutil/check.go +++ b/x/typesutil/check.go @@ -19,12 +19,42 @@ package typesutil import ( goast "go/ast" "go/types" + "path/filepath" + "strings" "github.com/goplus/gop/ast" "github.com/goplus/gop/cl" "github.com/goplus/gop/token" + "github.com/qiniu/x/log" ) +// ----------------------------------------------------------------------------- + +type dbgFlags int + +const ( + DbgFlagVerbose dbgFlags = 1 << iota + DbgFlagPrintError + DbgFlagDisableRecover + DbgFlagDefault = DbgFlagVerbose | DbgFlagPrintError + DbgFlagAll = DbgFlagDefault | DbgFlagDisableRecover +) + +var ( + debugVerbose bool + debugPrintErr bool +) + +func SetDebug(flags dbgFlags) { + debugVerbose = (flags & DbgFlagVerbose) != 0 + debugPrintErr = (flags & DbgFlagPrintError) != 0 + if (flags & DbgFlagDisableRecover) != 0 { + cl.SetDisableRecover(true) + } +} + +// ----------------------------------------------------------------------------- + type Project = cl.Project type Config struct { @@ -81,12 +111,20 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { gopfs := make(map[string]*ast.File) for _, goFile := range goFiles { f := fset.File(goFile.Pos()) - gofs[f.Name()] = goFile + file := f.Name() + fname := filepath.Base(file) + if strings.HasPrefix(fname, "gop_autogen") { + continue + } + gofs[file] = goFile } for _, gopFile := range gopFiles { f := fset.File(gopFile.Pos()) gopfs[f.Name()] = gopFile } + if debugVerbose { + log.Println("typesutil.Check:", pkgTypes.Path(), "gopFiles =", len(gopfs), "goFiles =", len(gofs)) + } pkg := &ast.Package{ Name: pkgTypes.Name(), Files: gopfs, @@ -105,5 +143,11 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { NoAutoGenMain: true, NoSkipConstant: true, }) + if debugPrintErr { + if err != nil { + log.Println("typesutil.Check err:", err) + log.SingleStack() + } + } return err } diff --git a/x/typesutil/typesutil.go b/x/typesutil/gopinfo.go similarity index 97% rename from x/typesutil/typesutil.go rename to x/typesutil/gopinfo.go index 4f3575616..0648ec4d8 100644 --- a/x/typesutil/typesutil.go +++ b/x/typesutil/gopinfo.go @@ -20,6 +20,7 @@ import ( "go/types" "github.com/goplus/gop/ast" + "github.com/qiniu/x/log" ) // ----------------------------------------------------------------------------- @@ -210,6 +211,9 @@ func (info gopRecorder) Instantiate(id *ast.Ident, inst types.Instance) { // // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { + if debugVerbose { + log.Println("==> Def:", id, obj.Type()) + } info.Defs[id] = obj } @@ -219,6 +223,9 @@ func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { // // Invariant: Uses[id].Pos() != id.Pos() func (info gopRecorder) Use(id *ast.Ident, obj types.Object) { + if debugVerbose { + log.Println("==> Use:", id, obj.Type()) + } info.Uses[id] = obj } @@ -231,6 +238,9 @@ func (info gopRecorder) Use(id *ast.Ident, obj types.Object) { // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default) // *ast.Field anonymous parameter *Var (incl. unnamed results) func (info gopRecorder) Implicit(node ast.Node, obj types.Object) { + if debugVerbose { + log.Println("==> Implicit:", obj) + } info.Implicits[node] = obj } @@ -264,6 +274,9 @@ func (info gopRecorder) Select(e *ast.SelectorExpr, sel *types.Selection) { // *ast.ForStmt // *ast.RangeStmt func (info gopRecorder) Scope(n ast.Node, scope *types.Scope) { + if debugVerbose { + log.Println("==> Scope:", scope) + } info.Scopes[n] = scope } From 0ef3e73f4ce8a17ebb005b0c9ef2e1c1c444b4b0 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 20 Oct 2023 18:02:53 +0800 Subject: [PATCH 17/64] x/build: TestContext --- x/build/build.go | 4 ++-- x/build/build_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/build/build.go b/x/build/build.go index 9373c6162..980e6064d 100644 --- a/x/build/build.go +++ b/x/build/build.go @@ -65,14 +65,14 @@ type Package struct { func (p *Package) ToSource() ([]byte, error) { var buf bytes.Buffer - if err := gox.WriteTo(&buf, p.Pkg); err != nil { + if err := p.Pkg.WriteTo(&buf); err != nil { return nil, err } return buf.Bytes(), nil } func (p *Package) ToAst() *goast.File { - return gox.ASTFile(p.Pkg) + return p.Pkg.ASTFile() } func ClassKind(fname string) (isProj, ok bool) { diff --git a/x/build/build_test.go b/x/build/build_test.go index 72e46f14b..a677214ee 100644 --- a/x/build/build_test.go +++ b/x/build/build_test.go @@ -515,7 +515,7 @@ func (i *emptyImporter) Import(path string) (*types.Package, error) { func TestContext(t *testing.T) { ctx := build.NewContext(&emptyImporter{}, nil) - _, err := ctx.BuildFile("main.gop", `println "Go+"`) + _, err := ctx.BuildFile("main.gop", `import "fmt"; fmt.Println "Go+"`) if err == nil { t.Fatal("BuildFile: no error?") } From 49a91fa8e1dfba89127cd146084acb5c3e076ca4 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 20 Oct 2023 18:27:33 +0800 Subject: [PATCH 18/64] gop fmt -t: test if Go+ files are formatted or not --- cmd/internal/gopfmt/fmt.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cmd/internal/gopfmt/fmt.go b/cmd/internal/gopfmt/fmt.go index d03045d04..40efc8a58 100644 --- a/cmd/internal/gopfmt/fmt.go +++ b/cmd/internal/gopfmt/fmt.go @@ -38,14 +38,15 @@ import ( xformat "github.com/goplus/gop/x/format" ) -// Cmd - gop go +// Cmd - gop fmt var Cmd = &base.Command{ - UsageLine: "gop fmt [-n --smart --mvgo] path ...", + UsageLine: "gop fmt [flags] path ...", Short: "Format Go+ packages", } var ( flag = &Cmd.Flag + flagTest = flag.Bool("t", false, "test if Go+ files are formatted or not.") flagNotExec = flag.Bool("n", false, "prints commands that would be executed.") flagMoveGo = flag.Bool("mvgo", false, "move .go files to .gop files (only available in `--smart` mode).") flagSmart = flag.Bool("smart", false, "convert Go code style into Go+ style.") @@ -56,6 +57,7 @@ func init() { } var ( + testErrCnt = 0 procCnt = 0 walkSubDir = false rootDir = "" @@ -93,6 +95,10 @@ func gopfmt(path string, class, smart, mvgo bool) (err error) { return } fmt.Println(path) + if *flagTest { + testErrCnt++ + return nil + } if mvgo { newPath := strings.TrimSuffix(path, ".go") + ".gop" if err = os.WriteFile(newPath, target, 0666); err != nil { @@ -199,6 +205,14 @@ func runCmd(cmd *base.Command, args []string) { if narg < 1 { cmd.Usage(os.Stderr) } + if *flagTest { + defer func() { + if testErrCnt > 0 { + fmt.Printf("total %d files are not formatted.\n", testErrCnt) + os.Exit(1) + } + }() + } walker := newWalker() for i := 0; i < narg; i++ { path := flag.Arg(i) From 5a4bb59bda6c06a3657fabcc545e2279f20f1e5e Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 00:27:18 +0800 Subject: [PATCH 19/64] typesutil: def func --- cl/compile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/compile.go b/cl/compile.go index 1ce820856..f08cc1fc5 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -1020,7 +1020,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { fn.SetComments(d.Doc) } if rec := ctx.recorder(); rec != nil { - rec.Def(d.Name, fn.Obj()) + rec.Def(d.Name, &fn.Func) } if genBody { if body := d.Body; body != nil { From 3de5907fed4b2169daa3b570bba4024c43d32606 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 04:28:44 +0800 Subject: [PATCH 20/64] typesutil: rec.Use; gox.Recorder --- ast/fromgo/gopast.go | 11 +++++++++++ cl/builtin_test.go | 34 ++++++++++++++++++++++++++++++++++ cl/compile.go | 22 ++++++++++++++++++++++ cl/expr.go | 10 ++++++++++ cl/func_type_and_var.go | 21 ++++++++++++++++++--- cl/typeparams.go | 3 +++ go.mod | 2 +- go.sum | 4 ++-- x/typesutil/gopinfo.go | 4 ++-- 9 files changed, 103 insertions(+), 8 deletions(-) diff --git a/ast/fromgo/gopast.go b/ast/fromgo/gopast.go index 02220fb2a..9ec50a0dd 100644 --- a/ast/fromgo/gopast.go +++ b/ast/fromgo/gopast.go @@ -211,9 +211,19 @@ func gopIdent(v *ast.Ident) *gopast.Ident { return &gopast.Ident{ NamePos: v.NamePos, Name: v.Name, + Obj: &gopast.Object{Data: v}, } } +// CheckIdent checks if a Go+ ast.Ident is converted from a Go ast.Ident or not. +// If it is, CheckIdent returns the original Go ast.Ident object. +func CheckIdent(v *gopast.Ident) (id *ast.Ident, ok bool) { + if o := v.Obj; o != nil && o.Kind == 0 && o.Data != nil { + id, ok = o.Data.(*ast.Ident) + } + return +} + func gopIdents(names []*ast.Ident) []*gopast.Ident { ret := make([]*gopast.Ident, len(names)) for i, v := range names { @@ -332,6 +342,7 @@ const ( KeepCgo ) +// ASTFile converts a Go ast.File into a Go+ ast.File object. func ASTFile(f *ast.File, mode int) *gopast.File { if (mode & KeepFuncBody) != 0 { log.Panicln("ASTFile: doesn't support keeping func body now") diff --git a/cl/builtin_test.go b/cl/builtin_test.go index b20381db8..bc15a433e 100644 --- a/cl/builtin_test.go +++ b/cl/builtin_test.go @@ -39,6 +39,40 @@ func getGoxConf() *gox.Config { return &gox.Config{Fset: fset, Importer: imp} } +func TestErrMultiStarRecv(t *testing.T) { + defer func() { + if e := recover(); e == nil { + t.Fatal("TestErrMultiStarRecv: no panic?") + } + }() + getRecvType(&ast.StarExpr{ + X: &ast.StarExpr{}, + }) +} + +func TestErrPanicToRecv(t *testing.T) { + ctx := &blockCtx{ + tlookup: &typeParamLookup{ + []*types.TypeParam{ + types.NewTypeParam(types.NewTypeName(0, nil, "t", nil), nil), + }, + }, + } + recv := &ast.FieldList{ + List: []*ast.Field{ + {Type: &ast.SelectorExpr{}}, + }, + } + func() { + defer func() { + if e := recover(); e == nil { + t.Fatal("TestErrPanicToRecv: no panic?") + } + }() + toRecv(ctx, recv) + }() +} + func TestCompileErrWrapExpr(t *testing.T) { defer func() { if e := recover(); e != "TODO: can't use expr? in global" { diff --git a/cl/compile.go b/cl/compile.go index 29400d252..c7fb665b8 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -64,6 +64,7 @@ func SetDebug(flags dbgFlags) { // ----------------------------------------------------------------------------- +// Recorder represents a compiling event recorder. type Recorder interface { // Type maps expressions to their types, and for constant // expressions, also their values. Invalid expressions are @@ -215,6 +216,24 @@ type Config struct { Outline bool } +type goxRecorder struct { + rec Recorder +} + +// Member maps identifiers to the objects they denote. +func (p *goxRecorder) Member(id ast.Node, obj types.Object) { + switch v := id.(type) { + case *ast.SelectorExpr: + sel := v.Sel + // TODO: record event for a Go ident + if _, ok := fromgo.CheckIdent(sel); !ok { + p.rec.Use(sel, obj) + } + case *ast.Ident: // it's impossible converted from Go + p.rec.Use(v, obj) + } +} + type nodeInterp struct { fset *token.FileSet files map[string]*ast.File @@ -512,6 +531,9 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, NoSkipConstant: conf.NoSkipConstant, PkgPathIox: ioxPkgPath, } + if conf.Recorder != nil { + confGox.Recorder = &goxRecorder{rec: conf.Recorder} + } if enableRecover { defer func() { if e := recover(); e != nil { diff --git a/cl/expr.go b/cl/expr.go index cf2f8c1ea..c23d4c9a9 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -120,6 +120,10 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (obj *gox.PkgRef, return nil, objCPkgRef } if pr, ok := ctx.findImport(name); ok { + if rec := ctx.recorder(); rec != nil { + pkgName := types.NewPkgName(token.NoPos, ctx.pkg.Types, name, pr.Types) + rec.Use(ident, pkgName) + } return pr, objPkgRef } } @@ -149,6 +153,9 @@ find: } else { ctx.cb.VarRef(o, ident) } + if rec := ctx.recorder(); rec != nil { + rec.Use(ident, o) + } return } @@ -424,6 +431,9 @@ func compilePkgRef(ctx *blockCtx, at *gox.PkgRef, x *ast.Ident, flags, pkgKind i cb.Call(0) } } + if rec := ctx.recorder(); rec != nil { + rec.Use(x, v) + } return true } return false diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index 321913486..1d3c0b8a5 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -38,11 +38,22 @@ func toRecv(ctx *blockCtx, recv *ast.FieldList) *types.Var { name = v.Names[0].Name } typ, star := getRecvType(v.Type) - t := toType(ctx, typ) + id, ok := typ.(*ast.Ident) + if !ok { + panic("TODO: getRecvType") + } + t := toIdentType(ctx, id) if star { t = types.NewPointer(t) } - return ctx.pkg.NewParam(v.Pos(), name, t) + ret := ctx.pkg.NewParam(v.Pos(), name, t) + if rec := ctx.recorder(); rec != nil { + dRecv := recv.List[0] + if names := dRecv.Names; len(names) == 1 { + rec.Def(names[0], ret) + } + } + return ret } func getRecvTypeName(ctx *pkgCtx, recv *ast.FieldList, handleErr bool) (string, bool) { @@ -90,7 +101,11 @@ func toParam(ctx *blockCtx, fld *ast.Field, args []*gox.Param) []*gox.Param { return append(args, pkg.NewParam(fld.Pos(), "", typ)) } for _, name := range fld.Names { - args = append(args, pkg.NewParam(name.Pos(), name.Name, typ)) + param := pkg.NewParam(name.Pos(), name.Name, typ) + args = append(args, param) + if rec := ctx.recorder(); rec != nil { + rec.Def(name, param) + } } return args } diff --git a/cl/typeparams.go b/cl/typeparams.go index 5a1e9d323..a26b57b81 100644 --- a/cl/typeparams.go +++ b/cl/typeparams.go @@ -169,6 +169,9 @@ L: case *ast.ParenExpr: typ = t.X case *ast.StarExpr: + if ptr { + panic("TODO: getRecvType") + } ptr = true typ = t.X default: diff --git a/go.mod b/go.mod index 978219585..446d101b3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/fsnotify/fsnotify v1.6.0 github.com/goplus/c2go v0.7.16 - github.com/goplus/gox v1.12.2-0.20231020050546-7a7af254a518 + github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754 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 64d2450a2..d808e9459 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.20231020050546-7a7af254a518 h1:s9CsA13IvxuCkOLrJkPmbS+Tilof5i2zIdQtyL5+USw= -github.com/goplus/gox v1.12.2-0.20231020050546-7a7af254a518/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ= +github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754 h1:uuXDqFfg4RhmHD7slw15hzwVQtJ51CsdcZn6gQtve/E= +github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754/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= diff --git a/x/typesutil/gopinfo.go b/x/typesutil/gopinfo.go index 0648ec4d8..77f777920 100644 --- a/x/typesutil/gopinfo.go +++ b/x/typesutil/gopinfo.go @@ -212,7 +212,7 @@ func (info gopRecorder) Instantiate(id *ast.Ident, inst types.Instance) { // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos() func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { if debugVerbose { - log.Println("==> Def:", id, obj.Type()) + log.Println("==> Def:", id, obj) } info.Defs[id] = obj } @@ -224,7 +224,7 @@ func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { // Invariant: Uses[id].Pos() != id.Pos() func (info gopRecorder) Use(id *ast.Ident, obj types.Object) { if debugVerbose { - log.Println("==> Use:", id, obj.Type()) + log.Println("==> Use:", id, obj) } info.Uses[id] = obj } From 887576497acbca96606780f0eb0dfb9385b6ca83 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 04:40:08 +0800 Subject: [PATCH 21/64] fromgo: TestCheckIdent --- ast/fromgo/gopast_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ast/fromgo/gopast_test.go b/ast/fromgo/gopast_test.go index 5f748acf0..46d51d70f 100644 --- a/ast/fromgo/gopast_test.go +++ b/ast/fromgo/gopast_test.go @@ -23,6 +23,7 @@ import ( "go/token" "testing" + gopast "github.com/goplus/gop/ast" "github.com/goplus/gop/format" ) @@ -125,3 +126,14 @@ type foo int func (a foo) Str() (string) {} `) } + +func TestCheckIdent(t *testing.T) { + if _, ok := CheckIdent(&gopast.Ident{}); ok { + t.Fatal("CheckIdent: found?") + } + if _, ok := CheckIdent(&gopast.Ident{Obj: &gopast.Object{ + Data: &ast.Ident{}, + }}); !ok { + t.Fatal("CheckIdent: not found?") + } +} From c93d72444b51ba9f8d721b3ef977d1373fe73755 Mon Sep 17 00:00:00 2001 From: visualfc Date: Sat, 21 Oct 2023 10:33:14 +0800 Subject: [PATCH 22/64] ast: walk add Go+ expr and stmt --- ast/walk.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/ast/walk.go b/ast/walk.go index e77558d13..dac33e1bf 100644 --- a/ast/walk.go +++ b/ast/walk.go @@ -59,7 +59,6 @@ func walkDeclList(v Visitor, list []Decl) { // v.Visit(node) is not nil, Walk is invoked recursively with visitor // w for each of the non-nil children of node, followed by a call of // w.Visit(nil). -// func Walk(v Visitor, node Node) { if v = v.Visit(node); v == nil { return @@ -372,6 +371,62 @@ func Walk(v Visitor, node Node) { Walk(v, f) } + // Go+ expr and stmt + case *SliceLit: + walkExprList(v, n.Elts) + + case *ErrWrapExpr: + Walk(v, n.X) + if n.Default != nil { + Walk(v, n.Default) + } + + case *LambdaExpr: + walkIdentList(v, n.Lhs) + walkExprList(v, n.Rhs) + + case *LambdaExpr2: + walkIdentList(v, n.Lhs) + Walk(v, n.Body) + + case *ForPhrase: + if n.Key != nil { + Walk(v, n.Key) + } + if n.Value != nil { + Walk(v, n.Value) + } + if n.Init != nil { + Walk(v, n.Init) + } + if n.Cond != nil { + Walk(v, n.Cond) + } + Walk(v, n.X) + + case *ComprehensionExpr: + if n.Elt != nil { + Walk(v, n.Elt) + } + for _, x := range n.Fors { + Walk(v, x) + } + + case *ForPhraseStmt: + Walk(v, n.ForPhrase) + Walk(v, n.Body) + + case *RangeExpr: + if n.First != nil { + Walk(v, n.First) + } + if n.Last != nil { + Walk(v, n.Last) + } + if n.Expr3 != nil { + Walk(v, n.Expr3) + } + default: panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n)) } @@ -392,7 +447,6 @@ func (f inspector) Visit(node Node) Visitor { // f(node); node must not be nil. If f returns true, Inspect invokes f // recursively for each of the non-nil children of node, followed by a // call of f(nil). -// func Inspect(node Node, f func(Node) bool) { Walk(inspector(f), node) } From b8e59aaf70fd3ade32dceae1a59599e1808e88b0 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 20:46:57 +0800 Subject: [PATCH 23/64] typeDecl: rec.Def --- ast/walk.go | 16 +++++++++------- cl/compile.go | 6 +++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ast/walk.go b/ast/walk.go index dac33e1bf..ba6f4ff18 100644 --- a/ast/walk.go +++ b/ast/walk.go @@ -16,7 +16,9 @@ package ast -import "fmt" +import ( + "fmt" +) // Visitor - A Visitor's Visit method is invoked for each node encountered by Walk. // If the result visitor w is not nil, Walk visits each of the children @@ -375,12 +377,6 @@ func Walk(v Visitor, node Node) { case *SliceLit: walkExprList(v, n.Elts) - case *ErrWrapExpr: - Walk(v, n.X) - if n.Default != nil { - Walk(v, n.Default) - } - case *LambdaExpr: walkIdentList(v, n.Lhs) walkExprList(v, n.Rhs) @@ -427,6 +423,12 @@ func Walk(v Visitor, node Node) { Walk(v, n.Expr3) } + case *ErrWrapExpr: + Walk(v, n.X) + if n.Default != nil { + Walk(v, n.Default) + } + default: panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n)) } diff --git a/cl/compile.go b/cl/compile.go index c7fb665b8..3e73ff714 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -916,14 +916,14 @@ func preloadFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, gopFil } else if d.Doc != nil { defs.SetComments(d.Doc) } - if rec := ctx.recorder(); rec != nil { - rec.Def(t.Name, decl.Type().Obj()) - } ld.typInit = func() { // decycle if debugLoad { log.Println("==> Load > InitType", name) } decl.InitType(ctx.pkg, toType(ctx, t.Type)) + if rec := ctx.recorder(); rec != nil { + rec.Def(t.Name, decl.Type().Obj()) + } } } } else { From d6f7c4ca9e640aa23e43f75c016db40d770e5899 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 21:22:03 +0800 Subject: [PATCH 24/64] Use: fix *gox.Func --- x/typesutil/gopinfo.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/typesutil/gopinfo.go b/x/typesutil/gopinfo.go index 77f777920..2550b2763 100644 --- a/x/typesutil/gopinfo.go +++ b/x/typesutil/gopinfo.go @@ -20,6 +20,7 @@ import ( "go/types" "github.com/goplus/gop/ast" + "github.com/goplus/gox" "github.com/qiniu/x/log" ) @@ -223,6 +224,9 @@ func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { // // Invariant: Uses[id].Pos() != id.Pos() func (info gopRecorder) Use(id *ast.Ident, obj types.Object) { + if f, ok := obj.(*gox.Func); ok { + obj = &f.Func + } if debugVerbose { log.Println("==> Use:", id, obj) } From 3faae921f795742c65bcfa5a17f724250ca6de35 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 21:52:10 +0800 Subject: [PATCH 25/64] typeDecl: rec.Use --- cl/compile.go | 5 +++-- cl/func_type_and_var.go | 11 ++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 3e73ff714..2adcfc07f 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -894,7 +894,8 @@ func preloadFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, gopFil if debugLoad { log.Println("==> Preload type", name) } - ld := getTypeLoader(parent, syms, t.Name.Pos(), name) + pos := t.Name.Pos() + ld := getTypeLoader(parent, syms, pos, name) defs := ctx.pkg.NewTypeDefs() if gopFile { ld.typ = func() { @@ -910,7 +911,7 @@ func preloadFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, gopFil if debugLoad { log.Println("==> Load > NewType", name) } - decl := defs.NewType(name) + decl := defs.NewType(name, pos) if t.Doc != nil { defs.SetComments(t.Doc) } else if d.Doc != nil { diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index 1d3c0b8a5..232ffe084 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -214,7 +214,16 @@ Name context: // ---------------------------------------------------------------------------*/ -func toIdentType(ctx *blockCtx, ident *ast.Ident) types.Type { +func toIdentType(ctx *blockCtx, ident *ast.Ident) (ret types.Type) { + if rec := ctx.recorder(); rec != nil { + defer func() { + if n, ok := ret.(interface { + Obj() *types.TypeName + }); ok { + rec.Use(ident, n.Obj()) + } + }() + } if ctx.tlookup != nil { if typ := ctx.tlookup.Lookup(ident.Name); typ != nil { return typ From f2ac2be17bf74d6039c824c358b2f163f1376df2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 22:08:39 +0800 Subject: [PATCH 26/64] gox: defs.AliasType --- cl/compile.go | 4 ++-- cl/compile_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 2adcfc07f..3c634e2bb 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -324,7 +324,7 @@ func getTypeLoader(ctx *pkgCtx, syms map[string]loader, start token.Pos, name st } else { ctx.handleErrorf( start, "%s redeclared in this block\n\tprevious declaration at %v", - name, ctx.Position(ld.start)) + name, ctx.Position(ld.pos())) } return ld } @@ -905,7 +905,7 @@ func preloadFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, gopFil if debugLoad { log.Println("==> Load > AliasType", name) } - ctx.pkg.AliasType(name, toType(ctx, t.Type), t.Pos()) + defs.AliasType(name, toType(ctx, t.Type), t.Pos()) return } if debugLoad { diff --git a/cl/compile_test.go b/cl/compile_test.go index 37cf5786b..eceb1c454 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -2206,12 +2206,12 @@ func main() { } `, `package main +type bar = foo type foo struct { p *foo A int B string `+"`tag1:123`"+` } -type bar = foo func main() { type a struct { From ab4642551ca82d56114e040334048e98f41daea5 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 21 Oct 2023 22:29:42 +0800 Subject: [PATCH 27/64] externType: rec.Use --- cl/compile.go | 14 ++++++++------ cl/expr.go | 2 +- cl/func_type_and_var.go | 11 ++++++++++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 3c634e2bb..38e9aff06 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -1145,18 +1145,20 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) { pkg = ctx.pkg.Import(simplifyGopPackage(pkgPath), spec) } var name string + var pos token.Pos + var specName = spec.Name if rec := ctx.recorder(); rec != nil { defer func() { - pkgName := types.NewPkgName(token.NoPos, ctx.pkg.Types, name, pkg.Types) - if spec.Name != nil { - rec.Def(spec.Name, pkgName) + pkgName := types.NewPkgName(pos, ctx.pkg.Types, name, pkg.Types) + if specName != nil { + rec.Def(specName, pkgName) } else { rec.Implicit(spec, pkgName) } }() } - if spec.Name != nil { - name = spec.Name.Name + if specName != nil { + name, pos = specName.Name, specName.NamePos if name == "." { ctx.lookups = append(ctx.lookups, pkg) return @@ -1166,7 +1168,7 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) { return } } else { - name = pkg.Types.Name() + name, pos = pkg.Types.Name(), spec.Path.Pos() } ctx.imports[name] = pkg } diff --git a/cl/expr.go b/cl/expr.go index c23d4c9a9..4c918fa3a 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -121,7 +121,7 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (obj *gox.PkgRef, } if pr, ok := ctx.findImport(name); ok { if rec := ctx.recorder(); rec != nil { - pkgName := types.NewPkgName(token.NoPos, ctx.pkg.Types, name, pr.Types) + pkgName := types.NewPkgName(ident.NamePos, ctx.pkg.Types, name, pr.Types) rec.Use(ident, pkgName) } return pr, objPkgRef diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index 232ffe084..c81dd25e0 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -192,10 +192,19 @@ func toChanType(ctx *blockCtx, v *ast.ChanType) *types.Chan { } func toExternalType(ctx *blockCtx, v *ast.SelectorExpr) types.Type { - name := v.X.(*ast.Ident).Name + id := v.X.(*ast.Ident) + name := id.Name if pr, ok := ctx.findImport(name); ok { + rec := ctx.recorder() + if rec != nil { + pkgName := types.NewPkgName(id.NamePos, ctx.pkg.Types, name, pr.Types) + rec.Use(id, pkgName) + } o := pr.TryRef(v.Sel.Name) if t, ok := o.(*types.TypeName); ok { + if rec != nil { + rec.Use(v.Sel, t) + } return t.Type() } ctx.handleErrorf(v.Pos(), "%s.%s is not a type", name, v.Sel.Name) From 3707f9b4a442bff0cc7c625b68612feedaa463d0 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 22 Oct 2023 04:42:15 +0800 Subject: [PATCH 28/64] toIdentType: rec.Use --- ast/ast.go | 5 +++++ cl/func_type_and_var.go | 10 ++++++---- cl/typeparams.go | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index 2a8ae5474..dbac1db09 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -1144,6 +1144,11 @@ func (f *File) NoEntrypoint() bool { return f.ShadowEntry != nil } +// HasPkgDecl checks if `package xxx` exists or not. +func (f *File) HasPkgDecl() bool { + return f.Package != token.NoPos +} + // Pos returns position of first character belonging to the node. func (f *File) Pos() token.Pos { if f.Package != token.NoPos { diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index c81dd25e0..053bc1bec 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -224,17 +224,17 @@ Name context: // ---------------------------------------------------------------------------*/ func toIdentType(ctx *blockCtx, ident *ast.Ident) (ret types.Type) { + var obj types.Object if rec := ctx.recorder(); rec != nil { defer func() { - if n, ok := ret.(interface { - Obj() *types.TypeName - }); ok { - rec.Use(ident, n.Obj()) + if obj != nil { + rec.Use(ident, obj) } }() } if ctx.tlookup != nil { if typ := ctx.tlookup.Lookup(ident.Name); typ != nil { + obj = typ.Obj() return typ } } @@ -244,10 +244,12 @@ func toIdentType(ctx *blockCtx, ident *ast.Ident) (ret types.Type) { return types.Typ[types.Invalid] } if t, ok := v.(*types.TypeName); ok { + obj = t return t.Type() } if v, _ := lookupPkgRef(ctx, nil, ident, objPkgRef); v != nil { if t, ok := v.(*types.TypeName); ok { + obj = t return t.Type() } } diff --git a/cl/typeparams.go b/cl/typeparams.go index a26b57b81..aeb82608e 100644 --- a/cl/typeparams.go +++ b/cl/typeparams.go @@ -130,7 +130,7 @@ type typeParamLookup struct { typeParams []*types.TypeParam } -func (p *typeParamLookup) Lookup(name string) types.Type { +func (p *typeParamLookup) Lookup(name string) *types.TypeParam { for _, t := range p.typeParams { tname := t.Obj().Name() if tname != "_" && name == tname { From 9bc730bad569a874e17470c666011c0341cc0ef2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 22 Oct 2023 11:21:47 +0800 Subject: [PATCH 29/64] parser: parseGlobalStmts set main.FuncType.Pos --- parser/parser.go | 1 + 1 file changed, 1 insertion(+) diff --git a/parser/parser.go b/parser/parser.go index 5de4dc461..481f9f3a2 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -3664,6 +3664,7 @@ func (p *parser) parseGlobalStmts(sync map[token.Token]bool, pos token.Pos, stmt Name: &ast.Ident{NamePos: pos, Name: "main"}, Doc: doc, Type: &ast.FuncType{ + Func: pos, Params: &ast.FieldList{}, }, Body: &ast.BlockStmt{List: list}, From 24b2024b7a8adb888768280f7780e7436fb9c8b2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 22 Oct 2023 19:26:04 +0800 Subject: [PATCH 30/64] parser: ParseExprFrom/ParseExpr; readSource --- parser/interface.go | 68 ++++++++++++++++++++++++++++++++++++++-- parser/parser.go | 3 +- parser/parser_gop.go | 44 +++++++++++++------------- parser/parser_test.go | 11 +++++++ parser/parserdir_test.go | 6 ++-- 5 files changed, 105 insertions(+), 27 deletions(-) diff --git a/parser/interface.go b/parser/interface.go index c88c4a431..52929d1aa 100644 --- a/parser/interface.go +++ b/parser/interface.go @@ -49,6 +49,8 @@ const ( ParseGoPlusClass Mode = 1 << 17 ) +// ----------------------------------------------------------------------------- + // ParseFile parses the source code of a single Go source file and returns // the corresponding ast.File node. The source code may be provided via // the filename of the source file, or via the src parameter. @@ -73,9 +75,9 @@ func parseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) } // get source - text, err := readSource(src) + text, err := readSource(filename, src) if err != nil { - return nil, err + return } var p parser @@ -108,3 +110,65 @@ func parseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) return } + +// ----------------------------------------------------------------------------- + +// ParseExprFrom is a convenience function for parsing an expression. +// The arguments have the same meaning as for ParseFile, but the source must +// be a valid Go (type or value) expression. Specifically, fset must not +// be nil. +// +// If the source couldn't be read, the returned AST is nil and the error +// indicates the specific failure. If the source was read but syntax +// errors were found, the result is a partial AST (with ast.Bad* nodes +// representing the fragments of erroneous source code). Multiple errors +// are returned via a scanner.ErrorList which is sorted by source position. +func ParseExprFrom(fset *token.FileSet, filename string, src any, mode Mode) (expr ast.Expr, err error) { + if fset == nil { + panic("parser.ParseExprFrom: no token.FileSet provided (fset == nil)") + } + + // get source + text, err := readSource(filename, src) + if err != nil { + return + } + + var p parser + defer func() { + if e := recover(); e != nil { + // resume same panic if it's not a bailout + if _, ok := e.(bailout); !ok { + panic(e) + } + } + p.errors.Sort() + err = p.errors.Err() + }() + + // parse expr + p.init(fset, filename, text, mode) + expr = p.parseRHS() + + // If a semicolon was inserted, consume it; + // report an error if there's more tokens. + if p.tok == token.SEMICOLON && p.lit == "\n" { + p.next() + } + p.expect(token.EOF) + + return +} + +// ParseExpr is a convenience function for obtaining the AST of an expression x. +// The position information recorded in the AST is undefined. The filename used +// in error messages is the empty string. +// +// If syntax errors were found, the result is a partial AST (with ast.Bad* nodes +// representing the fragments of erroneous source code). Multiple errors are +// returned via a scanner.ErrorList which is sorted by source position. +func ParseExpr(x string) (ast.Expr, error) { + return ParseExprFrom(token.NewFileSet(), "", []byte(x), 0) +} + +// ----------------------------------------------------------------------------- diff --git a/parser/parser.go b/parser/parser.go index 481f9f3a2..43bb6efe8 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -381,7 +381,8 @@ func (p *parser) next() { } // A bailout panic is raised to indicate early termination. -type bailout struct{} +type bailout struct { +} func (p *parser) error(pos token.Pos, msg string) { epos := p.file.Position(pos) diff --git a/parser/parser_gop.go b/parser/parser_gop.go index 372c880ba..efc78310c 100644 --- a/parser/parser_gop.go +++ b/parser/parser_gop.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "io/fs" + "os" "path" "path/filepath" "strings" @@ -164,7 +165,7 @@ func ParseFSDir(fset *token.FileSet, fs FileSystem, path string, conf Config) (p if isClass { mode |= ParseGoPlusClass } - if !strings.HasPrefix(fname, "_") && (conf.Filter == nil || filter(conf.Filter, d)) { + if !strings.HasPrefix(fname, "_") && (conf.Filter == nil || filter(d, conf.Filter)) { filename := fs.Join(path, fname) if useGoParser { if filedata, err := fs.ReadFile(filename); err == nil { @@ -193,7 +194,7 @@ func ParseFSDir(fset *token.FileSet, fs FileSystem, path string, conf Config) (p return } -func filter(fn func(fs.FileInfo) bool, d fs.DirEntry) bool { +func filter(d fs.DirEntry, fn func(fs.FileInfo) bool) bool { fi, err := d.Info() return err != nil || fn(fi) } @@ -254,12 +255,7 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) // ParseFSFile parses the source code of a single Go+ source file and returns the corresponding ast.File node. func ParseFSFile(fset *token.FileSet, fs FileSystem, filename string, src interface{}, mode Mode) (f *ast.File, err error) { - var code []byte - if src == nil { - code, err = fs.ReadFile(filename) - } else { - code, err = readSource(src) - } + code, err := readSource(filename, src) if err != nil { return } @@ -270,21 +266,27 @@ var ( errInvalidSource = errors.New("invalid source") ) -func readSource(src interface{}) ([]byte, error) { - switch s := src.(type) { - case string: - return []byte(s), nil - case []byte: - return s, nil - case *bytes.Buffer: - // is io.Reader, but src is already available in []byte form - if s != nil { - return s.Bytes(), nil +// If src != nil, readSource converts src to a []byte if possible; +// otherwise it returns an error. If src == nil, readSource returns +// the result of reading the file specified by filename. +func readSource(filename string, src any) ([]byte, error) { + if src != nil { + switch s := src.(type) { + case string: + return []byte(s), nil + case []byte: + return s, nil + case *bytes.Buffer: + // is io.Reader, but src is already available in []byte form + if s != nil { + return s.Bytes(), nil + } + case io.Reader: + return io.ReadAll(s) } - case io.Reader: - return io.ReadAll(s) + return nil, errInvalidSource } - return nil, errInvalidSource + return os.ReadFile(filename) } // ----------------------------------------------------------------------------- diff --git a/parser/parser_test.go b/parser/parser_test.go index 1aed0e3f1..81e0c6e1c 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -17,14 +17,25 @@ package parser import ( + "io/fs" "testing" "github.com/goplus/gop/parser/parsertest" "github.com/goplus/gop/token" + fsx "github.com/qiniu/x/http/fs" ) // ----------------------------------------------------------------------------- +func TestFilter(t *testing.T) { + d := fsx.NewFileInfo("foo.go", 10) + if filter(d, func(fi fs.FileInfo) bool { + return false + }) { + t.Fatal("TestFilter failed") + } +} + func TestExt(t *testing.T) { cases := [][2]string{ {"t.spx.gox", ".spx"}, diff --git a/parser/parserdir_test.go b/parser/parserdir_test.go index 10fcc0254..baefcd3c9 100644 --- a/parser/parserdir_test.go +++ b/parser/parserdir_test.go @@ -42,14 +42,14 @@ func init() { func TestReadSource(t *testing.T) { buf := bytes.NewBuffer(nil) - if _, err := readSource(buf); err != nil { + if _, err := readSource("", buf); err != nil { t.Fatal("readSource failed:", err) } sr := strings.NewReader("") - if _, err := readSource(sr); err != nil { + if _, err := readSource("", sr); err != nil { t.Fatal("readSource strings.Reader failed:", err) } - if _, err := readSource(0); err == nil { + if _, err := readSource("", 0); err == nil { t.Fatal("readSource int failed: no error?") } } From 835672a071bc01799ecaedd5f7d1cf293fec84c7 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 22 Oct 2023 19:48:41 +0800 Subject: [PATCH 31/64] readSource: readSourceLocal/readSourceFS --- parser/interface.go | 4 ++-- parser/parser_gop.go | 43 +++++++++++++++++++++++++--------------- parser/parserdir_test.go | 9 ++++++--- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/parser/interface.go b/parser/interface.go index 52929d1aa..48bf231a8 100644 --- a/parser/interface.go +++ b/parser/interface.go @@ -75,7 +75,7 @@ func parseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) } // get source - text, err := readSource(filename, src) + text, err := readSourceLocal(filename, src) if err != nil { return } @@ -129,7 +129,7 @@ func ParseExprFrom(fset *token.FileSet, filename string, src any, mode Mode) (ex } // get source - text, err := readSource(filename, src) + text, err := readSourceLocal(filename, src) if err != nil { return } diff --git a/parser/parser_gop.go b/parser/parser_gop.go index efc78310c..776430833 100644 --- a/parser/parser_gop.go +++ b/parser/parser_gop.go @@ -255,7 +255,7 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) // ParseFSFile parses the source code of a single Go+ source file and returns the corresponding ast.File node. func ParseFSFile(fset *token.FileSet, fs FileSystem, filename string, src interface{}, mode Mode) (f *ast.File, err error) { - code, err := readSource(filename, src) + code, err := readSourceFS(fs, filename, src) if err != nil { return } @@ -266,27 +266,38 @@ var ( errInvalidSource = errors.New("invalid source") ) +func readSource(src interface{}) ([]byte, error) { + switch s := src.(type) { + case string: + return []byte(s), nil + case []byte: + return s, nil + case *bytes.Buffer: + // is io.Reader, but src is already available in []byte form + if s != nil { + return s.Bytes(), nil + } + case io.Reader: + return io.ReadAll(s) + } + return nil, errInvalidSource +} + // If src != nil, readSource converts src to a []byte if possible; // otherwise it returns an error. If src == nil, readSource returns // the result of reading the file specified by filename. -func readSource(filename string, src any) ([]byte, error) { +func readSourceLocal(filename string, src interface{}) ([]byte, error) { if src != nil { - switch s := src.(type) { - case string: - return []byte(s), nil - case []byte: - return s, nil - case *bytes.Buffer: - // is io.Reader, but src is already available in []byte form - if s != nil { - return s.Bytes(), nil - } - case io.Reader: - return io.ReadAll(s) - } - return nil, errInvalidSource + return readSource(src) } return os.ReadFile(filename) } +func readSourceFS(fs FileSystem, filename string, src interface{}) ([]byte, error) { + if src != nil { + return readSource(src) + } + return fs.ReadFile(filename) +} + // ----------------------------------------------------------------------------- diff --git a/parser/parserdir_test.go b/parser/parserdir_test.go index baefcd3c9..d3dc27dca 100644 --- a/parser/parserdir_test.go +++ b/parser/parserdir_test.go @@ -42,16 +42,19 @@ func init() { func TestReadSource(t *testing.T) { buf := bytes.NewBuffer(nil) - if _, err := readSource("", buf); err != nil { + if _, err := readSource(buf); err != nil { t.Fatal("readSource failed:", err) } sr := strings.NewReader("") - if _, err := readSource("", sr); err != nil { + if _, err := readSource(sr); err != nil { t.Fatal("readSource strings.Reader failed:", err) } - if _, err := readSource("", 0); err == nil { + if _, err := readSource(0); err == nil { t.Fatal("readSource int failed: no error?") } + if _, err := readSourceLocal("/foo/bar/not-exists", nil); err == nil { + t.Fatal("readSourceLocal int failed: no error?") + } } func TestParseFiles(t *testing.T) { From 9d593fb34f72c7fbec61c582e0d1426f0d7e0f41 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 22 Oct 2023 20:10:23 +0800 Subject: [PATCH 32/64] TestParseExprFrom --- parser/interface.go | 4 ---- parser/parser_test.go | 33 +++++++++++++++++++++++++++++++++ parser/parserdir_test.go | 10 ++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/parser/interface.go b/parser/interface.go index 48bf231a8..3ed93a1c8 100644 --- a/parser/interface.go +++ b/parser/interface.go @@ -124,10 +124,6 @@ func parseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) // representing the fragments of erroneous source code). Multiple errors // are returned via a scanner.ErrorList which is sorted by source position. func ParseExprFrom(fset *token.FileSet, filename string, src any, mode Mode) (expr ast.Expr, err error) { - if fset == nil { - panic("parser.ParseExprFrom: no token.FileSet provided (fset == nil)") - } - // get source text, err := readSourceLocal(filename, src) if err != nil { diff --git a/parser/parser_test.go b/parser/parser_test.go index 81e0c6e1c..20dcfd7ee 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -75,6 +75,20 @@ func testErrCode(t *testing.T, code string, errExp, panicExp string) { } } +func testErrCodeParseExpr(t *testing.T, code string, errExp, panicExp string) { + defer func() { + if e := recover(); e != nil { + if panicMsg(e) != panicExp { + t.Fatal("testErrCodeParseExpr panic:", e) + } + } + }() + _, err := ParseExpr(code) + if err == nil || err.Error() != errExp { + t.Fatal("testErrCodeParseExpr error:", err) + } +} + func testClassErrCode(t *testing.T, code string, errExp, panicExp string) { defer func() { if e := recover(); e != nil { @@ -131,6 +145,24 @@ test "hello", (x, "y") => { `, `/foo/bar.gop:3:19: expected 'IDENT', found "y"`, ``) } +func TestErrTooManyParseExpr(t *testing.T) { + testErrCodeParseExpr(t, `func() int { + var + var + var + var + var + var + var + var + var + var + var + var +}() +`, `3:3: expected 'IDENT', found 'var' (and 10 more errors)`, ``) +} + func TestErrTooMany(t *testing.T) { testErrCode(t, ` func f() { var } @@ -144,6 +176,7 @@ func h() { var } func h() { var } func h() { var } func h() { var } +func h() { var } `, `/foo/bar.gop:2:16: expected 'IDENT', found '}' (and 10 more errors)`, ``) } diff --git a/parser/parserdir_test.go b/parser/parserdir_test.go index d3dc27dca..a5f398a3d 100644 --- a/parser/parserdir_test.go +++ b/parser/parserdir_test.go @@ -40,6 +40,16 @@ func init() { SetDebug(DbgFlagAll) } +func TestParseExprFrom(t *testing.T) { + fset := token.NewFileSet() + if _, err := ParseExprFrom(fset, "/foo/bar/not-exists", nil, 0); err == nil { + t.Fatal("ParseExprFrom: no error?") + } + if _, err := ParseExpr("1+1\n;"); err == nil || err.Error() != "2:1: expected 'EOF', found ';'" { + t.Fatal("ParseExpr:", err) + } +} + func TestReadSource(t *testing.T) { buf := bytes.NewBuffer(nil) if _, err := readSource(buf); err != nil { From 94efdcd5065381bf254852f36fd473a8ead61da3 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 22 Oct 2023 20:13:16 +0800 Subject: [PATCH 33/64] TestAssert --- parser/parser_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/parser/parser_test.go b/parser/parser_test.go index 20dcfd7ee..76fe912dd 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -36,6 +36,15 @@ func TestFilter(t *testing.T) { } } +func TestAssert(t *testing.T) { + defer func() { + if e := recover(); e != "go/parser internal error: panic msg" { + t.Fatal("TestAssert:", e) + } + }() + assert(false, "panic msg") +} + func TestExt(t *testing.T) { cases := [][2]string{ {"t.spx.gox", ".spx"}, From 2f66dc54d34ddfcb5ae475652a5e6dde91fe3712 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 23 Oct 2023 00:42:11 +0800 Subject: [PATCH 34/64] typesutil.Check: ident/selectorExpr rec.Type --- cl/expr.go | 10 ++++++++++ x/typesutil/gopinfo.go | 3 +++ 2 files changed, 13 insertions(+) diff --git a/cl/expr.go b/cl/expr.go index 4c918fa3a..8e24089ad 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -155,6 +155,12 @@ find: } if rec := ctx.recorder(); rec != nil { rec.Use(ident, o) + e := ctx.cb.Get(-1) + tv := types.TypeAndValue{Type: e.Type, Value: e.CVal} + if !fvalue { + tv.Type = o.Type() + } + rec.Type(ident, tv) } return } @@ -368,6 +374,10 @@ func compileSelectorExpr(ctx *blockCtx, v *ast.SelectorExpr, flags int) { } default: compileExpr(ctx, v.X) + if rec := ctx.recorder(); rec != nil { + e := ctx.cb.Get(-1) + rec.Type(v.X, types.TypeAndValue{Type: e.Type, Value: e.CVal}) + } } if err := compileMember(ctx, v, v.Sel.Name, flags); err != nil { panic(err) diff --git a/x/typesutil/gopinfo.go b/x/typesutil/gopinfo.go index 2550b2763..cf6ed2c45 100644 --- a/x/typesutil/gopinfo.go +++ b/x/typesutil/gopinfo.go @@ -183,6 +183,9 @@ type gopRecorder struct { // only in the Defs map, and identifiers denoting packages in // qualified identifiers are collected in the Uses map. func (info gopRecorder) Type(e ast.Expr, tv types.TypeAndValue) { + if debugVerbose { + log.Println("==> Type:", e, tv.Type) + } info.Types[e] = tv } From 7ef9255b15e09f9b970ecead1dd8069983770473 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 17:04:05 +0000 Subject: [PATCH 35/64] build(deps): bump github.com/fsnotify/fsnotify from 1.6.0 to 1.7.0 Bumps [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify) from 1.6.0 to 1.7.0. - [Release notes](https://github.com/fsnotify/fsnotify/releases) - [Changelog](https://github.com/fsnotify/fsnotify/blob/main/CHANGELOG.md) - [Commits](https://github.com/fsnotify/fsnotify/compare/v1.6.0...v1.7.0) --- updated-dependencies: - dependency-name: github.com/fsnotify/fsnotify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 446d101b3..43f1148f4 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/goplus/gop go 1.18 require ( - github.com/fsnotify/fsnotify v1.6.0 + github.com/fsnotify/fsnotify v1.7.0 github.com/goplus/c2go v0.7.16 github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754 github.com/goplus/mod v0.11.8-0.20231019172744-da5848421263 diff --git a/go.sum b/go.sum index d808e9459..cf76739d6 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/goplus/c2go v0.7.16 h1:B9jRNNytoq7yDBQOZSm2qENQhRQMfNhgOea5XHWNUnI= github.com/goplus/c2go v0.7.16/go.mod h1:XODEFX2PeEEJXNLLdykWeZgMSaKJ51fVm+C9IM3FxNQ= @@ -51,7 +51,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 3edf20bc49e11c0e8ef1715d6b83064e88b99f84 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 24 Oct 2023 06:13:38 +0800 Subject: [PATCH 36/64] cl: rec.Use PkgName --- cl/compile.go | 43 ++++++++++++++++++++++++----------------- cl/expr.go | 7 +++---- cl/func_type_and_var.go | 7 +++---- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 38e9aff06..1b06ed911 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -382,12 +382,17 @@ type pkgCtx struct { inInst int // toType in generic instance } +type pkgImp struct { + *gox.PkgRef + pkgName *types.PkgName +} + type blockCtx struct { *pkgCtx pkg *gox.Package cb *gox.CodeBuilder fset *token.FileSet - imports map[string]*gox.PkgRef + imports map[string]pkgImp lookups []*gox.PkgRef clookups []*cpackages.PkgRef tlookup *typeParamLookup @@ -408,8 +413,8 @@ func (bc *blockCtx) recorder() Recorder { return nil } -func (bc *blockCtx) findImport(name string) (pr *gox.PkgRef, ok bool) { - pr, ok = bc.imports[name] +func (bc *blockCtx) findImport(name string) (pi pkgImp, ok bool) { + pi, ok = bc.imports[name] return } @@ -565,7 +570,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, ctx := &blockCtx{ pkg: p, pkgCtx: ctx, cb: p.CB(), fset: p.Fset, targetDir: targetDir, fileLine: fileLine, relativePath: conf.RelativePath, isClass: f.IsClass, rec: conf.Recorder, - c2goBase: c2goBase(conf.C2goBase), imports: make(map[string]*gox.PkgRef), isGopFile: true, + c2goBase: c2goBase(conf.C2goBase), imports: make(map[string]pkgImp), isGopFile: true, } preloadGopFile(p, ctx, fpath, f, conf) } @@ -576,7 +581,7 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, gofiles = append(gofiles, f) ctx := &blockCtx{ pkg: p, pkgCtx: ctx, cb: p.CB(), fset: p.Fset, targetDir: targetDir, - imports: make(map[string]*gox.PkgRef), + imports: make(map[string]pkgImp), } preloadFile(p, ctx, fpath, f, false, false) } @@ -1144,21 +1149,25 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) { } else { pkg = ctx.pkg.Import(simplifyGopPackage(pkgPath), spec) } - var name string + var pos token.Pos + var name string var specName = spec.Name + if specName != nil { + name, pos = specName.Name, specName.Pos() + } else { + name, pos = pkg.Types.Name(), spec.Path.Pos() + } + pkgName := types.NewPkgName(pos, ctx.pkg.Types, name, pkg.Types) if rec := ctx.recorder(); rec != nil { - defer func() { - pkgName := types.NewPkgName(pos, ctx.pkg.Types, name, pkg.Types) - if specName != nil { - rec.Def(specName, pkgName) - } else { - rec.Implicit(spec, pkgName) - } - }() + if specName != nil { + rec.Def(specName, pkgName) + } else { + rec.Implicit(spec, pkgName) + } } + if specName != nil { - name, pos = specName.Name, specName.NamePos if name == "." { ctx.lookups = append(ctx.lookups, pkg) return @@ -1167,10 +1176,8 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) { pkg.MarkForceUsed() return } - } else { - name, pos = pkg.Types.Name(), spec.Path.Pos() } - ctx.imports[name] = pkg + ctx.imports[name] = pkgImp{pkg, pkgName} } func loadConstSpecs(ctx *blockCtx, cdecl *gox.ConstDefs, specs []ast.Spec) { diff --git a/cl/expr.go b/cl/expr.go index 8e24089ad..83a624478 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -119,12 +119,11 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (obj *gox.PkgRef, if name == "C" && len(ctx.clookups) > 0 { return nil, objCPkgRef } - if pr, ok := ctx.findImport(name); ok { + if pi, ok := ctx.findImport(name); ok { if rec := ctx.recorder(); rec != nil { - pkgName := types.NewPkgName(ident.NamePos, ctx.pkg.Types, name, pr.Types) - rec.Use(ident, pkgName) + rec.Use(ident, pi.pkgName) } - return pr, objPkgRef + return pi.PkgRef, objPkgRef } } diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index 053bc1bec..9a734d471 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -194,13 +194,12 @@ func toChanType(ctx *blockCtx, v *ast.ChanType) *types.Chan { func toExternalType(ctx *blockCtx, v *ast.SelectorExpr) types.Type { id := v.X.(*ast.Ident) name := id.Name - if pr, ok := ctx.findImport(name); ok { + if pi, ok := ctx.findImport(name); ok { rec := ctx.recorder() if rec != nil { - pkgName := types.NewPkgName(id.NamePos, ctx.pkg.Types, name, pr.Types) - rec.Use(id, pkgName) + rec.Use(id, pi.pkgName) } - o := pr.TryRef(v.Sel.Name) + o := pi.TryRef(v.Sel.Name) if t, ok := o.(*types.TypeName); ok { if rec != nil { rec.Use(v.Sel, t) From ac456c8b459cde7e24e3a7752119be6cfd4a2dad Mon Sep 17 00:00:00 2001 From: visualfc Date: Tue, 24 Oct 2023 06:28:40 +0800 Subject: [PATCH 37/64] update gox version --- cl/compile_c2go_test.go | 12 +- cl/compile_spx_test.go | 46 +++--- cl/compile_test.go | 254 +++++++++++++++--------------- cl/outline/cl/compile_spx_test.go | 46 +++--- cl/outline/cl/compile_test.go | 254 +++++++++++++++--------------- cl/outline/cl/typeparams_test.go | 2 +- cl/typeparams_test.go | 2 +- go.mod | 2 +- go.sum | 4 +- 9 files changed, 311 insertions(+), 311 deletions(-) diff --git a/cl/compile_c2go_test.go b/cl/compile_c2go_test.go index c20edcc97..8bf5199cd 100644 --- a/cl/compile_c2go_test.go +++ b/cl/compile_c2go_test.go @@ -35,8 +35,8 @@ C.printf C"Hello, world!\n" `, `package main import ( - libc "github.com/goplus/gop/cl/internal/libc" - unsafe "unsafe" + "github.com/goplus/gop/cl/internal/libc" + "unsafe" ) func main() { @@ -53,8 +53,8 @@ C.printf C"Hello, world!\n" `, `package main import ( - libc "github.com/goplus/gop/cl/internal/libc" - unsafe "unsafe" + "github.com/goplus/gop/cl/internal/libc" + "unsafe" ) func main() { @@ -71,8 +71,8 @@ C.printf C"Hello, world!\n" `, `package main import ( - libc "github.com/goplus/gop/cl/internal/libc" - unsafe "unsafe" + "github.com/goplus/gop/cl/internal/libc" + "unsafe" ) func main() { diff --git a/cl/compile_spx_test.go b/cl/compile_spx_test.go index 1fe31d875..28e0fd718 100644 --- a/cl/compile_spx_test.go +++ b/cl/compile_spx_test.go @@ -164,7 +164,7 @@ func onMsg(msg string) { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -211,8 +211,8 @@ func onInit() { `, ``, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) const Foo = 1 @@ -248,8 +248,8 @@ func onInit() { `, `package main import ( - spx "github.com/goplus/gop/cl/internal/spx" - math "math" + "github.com/goplus/gop/cl/internal/spx" + "math" ) type Game struct { @@ -301,7 +301,7 @@ func onCloned() { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -341,8 +341,8 @@ println "Hi" `, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) var x float64 = spx.Rand__1(1.2) @@ -378,8 +378,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Game struct { @@ -410,8 +410,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Game struct { @@ -442,8 +442,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Dog struct { @@ -472,7 +472,7 @@ func TestSpxMainEntry(t *testing.T) { `, ` `, `package main -import spx2 "github.com/goplus/gop/cl/internal/spx2" +import "github.com/goplus/gop/cl/internal/spx2" type Game struct { spx2.Game @@ -491,7 +491,7 @@ var ( `, ` `, `package main -import spx2 "github.com/goplus/gop/cl/internal/spx2" +import "github.com/goplus/gop/cl/internal/spx2" type Game struct { spx2.Game @@ -525,8 +525,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Game struct { @@ -566,7 +566,7 @@ func onMsg(msg string) { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -624,7 +624,7 @@ func onCloned() { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type info struct { x int @@ -672,7 +672,7 @@ func onMsg(msg string) { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -705,8 +705,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) type Game struct { diff --git a/cl/compile_test.go b/cl/compile_test.go index eceb1c454..3a54eeb86 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -153,10 +153,10 @@ for line <- open("foo.txt")! { `, `package main import ( - fmt "fmt" - os "os" - iox "github.com/goplus/gop/builtin/iox" - errors "github.com/qiniu/x/errors" + "fmt" + "os" + "github.com/goplus/gop/builtin/iox" + "github.com/qiniu/x/errors" ) func main() { @@ -190,9 +190,9 @@ for line <- os.Stdin { `, `package main import ( - fmt "fmt" - os "os" - iox "github.com/goplus/gop/builtin/iox" + "fmt" + "os" + "github.com/goplus/gop/builtin/iox" ) func main() { @@ -220,9 +220,9 @@ for line <- lines(r) { `, `package main import ( - fmt "fmt" - iox "github.com/goplus/gop/builtin/iox" - io "io" + "fmt" + "github.com/goplus/gop/builtin/iox" + "io" ) var r io.Reader @@ -294,7 +294,7 @@ type T struct{} println(&T{},&Point{10,20}) `, `package main -import fmt "fmt" +import "fmt" type T struct { } @@ -311,7 +311,7 @@ for i <- :10, i%3 == 0 { println i }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 0; i < 10; i += 1 { @@ -334,7 +334,7 @@ d := fvec([]) println a, b, c, d `, `package main -import fmt "fmt" +import "fmt" type fvec []float64 type foo float64 @@ -538,8 +538,8 @@ println "The Go+ Language for", fields.join(", ") `, `package main import ( - fmt "fmt" - strings "strings" + "fmt" + "strings" ) func main() { @@ -555,7 +555,7 @@ p := println p "Hello world" `, `package main -import fmt "fmt" +import "fmt" func main() { p := fmt.Println @@ -921,8 +921,8 @@ func main() { }`, `package main import ( - fmt "fmt" - errors "github.com/qiniu/x/errors" + "fmt" + "github.com/qiniu/x/errors" ) func t() (int, int, error) { @@ -955,7 +955,7 @@ func main() { t()! }`, `package main -import errors "github.com/qiniu/x/errors" +import "github.com/qiniu/x/errors" func t() error { return nil @@ -998,7 +998,7 @@ func (a *A) String() string { } `, `package main -import fmt "fmt" +import "fmt" type AA interface { String() string @@ -1043,7 +1043,7 @@ func (a *A) String() string { } `, `package main -import fmt "fmt" +import "fmt" type AA interface { String() string @@ -1084,7 +1084,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" func main() { { @@ -1136,7 +1136,7 @@ func main() { var i int `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println(i) @@ -1179,7 +1179,7 @@ func main() { var i = 100 `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println(i) @@ -1199,7 +1199,7 @@ func main() { println(n) }`, `package main -import fmt "fmt" +import "fmt" func main() { v := []uint64{2, 3, 5} @@ -1224,7 +1224,7 @@ func consume(xchg chan int) { } `, `package main -import fmt "fmt" +import "fmt" func consume(xchg chan int) { select { @@ -1397,7 +1397,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" type Shape interface { Area() float64 @@ -1442,7 +1442,7 @@ type BigInt struct { *big.Int }`, `package main -import big "math/big" +import "math/big" type BigInt struct { *big.Int @@ -1462,10 +1462,10 @@ func foo(script string) { `, `package main import ( - fmt "fmt" - goptest "github.com/goplus/gop/ast/goptest" - errors "github.com/qiniu/x/errors" - gopq "github.com/goplus/gop/ast/gopq" + "fmt" + "github.com/goplus/gop/ast/goptest" + "github.com/qiniu/x/errors" + "github.com/goplus/gop/ast/gopq" ) func foo(script string) { @@ -1496,10 +1496,10 @@ func foo(script string) { `, `package main import ( - fmt "fmt" - goptest "github.com/goplus/gop/ast/goptest" - errors "github.com/qiniu/x/errors" - gopq "github.com/goplus/gop/ast/gopq" + "fmt" + "github.com/goplus/gop/ast/goptest" + "github.com/qiniu/x/errors" + "github.com/goplus/gop/ast/gopq" ) func foo(script string) { @@ -1528,8 +1528,8 @@ func add(x, y string) (int, error) { `, `package main import ( - strconv "strconv" - errors "github.com/qiniu/x/errors" + "strconv" + "github.com/qiniu/x/errors" ) func add(x string, y string) (int, error) { @@ -1569,7 +1569,7 @@ func addSafe(x, y string) int { } `, `package main -import strconv "strconv" +import "strconv" func addSafe(x string, y string) int { return func() (_gop_ret int) { @@ -1597,8 +1597,8 @@ var ret int = println("Hi")! `, `package main import ( - fmt "fmt" - errors "github.com/qiniu/x/errors" + "fmt" + "github.com/qiniu/x/errors" ) var ret int = func() (_gop_ret int) { @@ -1622,7 +1622,7 @@ func mkdir(name string) error { mkdir! "foo" `, `package main -import errors "github.com/qiniu/x/errors" +import "github.com/qiniu/x/errors" func mkdir(name string) error { return nil @@ -1650,7 +1650,7 @@ func foo() (func(), error) { foo()!() `, `package main -import errors "github.com/qiniu/x/errors" +import "github.com/qiniu/x/errors" func foo() (func(), error) { return nil, nil @@ -1699,7 +1699,7 @@ var x, y uint128 var z uint128 = x + y `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x, y ng.Uint128 var z ng.Uint128 = x.Gop_Add__1(y) @@ -1712,7 +1712,7 @@ var x, y int128 var z int128 = x + y `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x, y ng.Int128 var z ng.Int128 = x.Gop_Add__1(y) @@ -1725,7 +1725,7 @@ var x, y bigint var z bigint = x + y `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x, y ng.Bigint var z ng.Bigint = x.Gop_Add(y) @@ -1738,8 +1738,8 @@ var x = 1r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigint_Init__1(big.NewInt(1)) @@ -1751,7 +1751,7 @@ func TestUint128Lit(t *testing.T) { var x uint128 = 1 `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x ng.Uint128 = ng.Uint128_Init__0(1) `) @@ -1762,7 +1762,7 @@ func TestInt128Lit(t *testing.T) { var x int128 = 1 `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x ng.Int128 = ng.Int128_Init__0(1) `) @@ -1774,8 +1774,8 @@ var x = 1/2r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigrat_Init__2(big.NewRat(1, 2)) @@ -1788,8 +1788,8 @@ var x = 3 + 1/2r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigrat_Init__2(big.NewRat(7, 2)) @@ -1805,8 +1805,8 @@ var z = 100 + y `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigrat_Init__2(big.NewRat(7, 2)) @@ -1919,7 +1919,7 @@ var x bigint x += 3 `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x ng.Bigint @@ -1936,8 +1936,8 @@ x *= 2 `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) func main() { @@ -1954,8 +1954,8 @@ x *= 2r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) func main() { @@ -2228,7 +2228,7 @@ go println("Hi") defer println("Go+") `, `package main -import fmt "fmt" +import "fmt" func main() { go fmt.Println("Hi") @@ -2248,7 +2248,7 @@ for { } `, `package main -import fmt "fmt" +import "fmt" func main() { a := []float64{1, 3.4, 5} @@ -2285,7 +2285,7 @@ for range a { } `, `package main -import fmt "fmt" +import "fmt" func main() { a := []float64{1, 3.4, 5} @@ -2323,7 +2323,7 @@ for k, v := range new(foo) { } `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -2351,7 +2351,7 @@ for v <- new(foo) { } `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -2386,7 +2386,7 @@ for k, v <- new(foo) { } `, `package main -import fmt "fmt" +import "fmt" type fooIter struct { } @@ -2422,7 +2422,7 @@ func (p *foo) Gop_Enum(c func(val string)) { println([v for v <- new(foo)]) `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -2473,7 +2473,7 @@ for k, v <- newFoo() { } `, `package main -import fmt "fmt" +import "fmt" type fooIter struct { data *foo @@ -2522,7 +2522,7 @@ for i, x <- [1, 3, 5, 7, 11, 13, 17] { println("sum(5,7,11,13,17):", sum) `, `package main -import fmt "fmt" +import "fmt" func main() { sum := 0 @@ -2693,7 +2693,7 @@ x := [[a, b] for a <- arr, a < b for b <- arr, b > 2] println("x:", x) `, `package main -import fmt "fmt" +import "fmt" func main() { arr := []float64{1, 2, 3, 4.1, 5, 6} @@ -2799,8 +2799,8 @@ println("x:", x) `, `package main import ( - fmt "fmt" - strings "strings" + "fmt" + "strings" ) func main() { @@ -2823,7 +2823,7 @@ func bar(p pfoo) { } `, `package main -import fmt "fmt" +import "fmt" type foo struct { req int @@ -2852,7 +2852,7 @@ a.B = "Hi" flag.Usage = nil `, `package main -import flag "flag" +import "flag" func main() { a := &struct { @@ -2912,7 +2912,7 @@ func (M) Bar() { } `, `package main -import fmt "fmt" +import "fmt" type M int @@ -2959,7 +2959,7 @@ var d = -a // TODO: -a have no return value! var e = a!=b `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -2993,7 +2993,7 @@ var e = a.Gop_NE(b) func TestCmdlineNoEOL(t *testing.T) { gopClTest(t, `println "Hi"`, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hi") @@ -3008,7 +3008,7 @@ func main() { fmt.println "Hi" }`, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hi") @@ -3022,7 +3022,7 @@ func TestDotImport(t *testing.T) { var a = round(1.2) `, `package main -import math "math" +import "math" var a = math.Round(1.2) `) @@ -3034,7 +3034,7 @@ func TestLocalImport(t *testing.T) { var a = spx.TestIntValue `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" var a = spx.TestIntValue `) @@ -3069,7 +3069,7 @@ func TestAnonymousImport(t *testing.T) { printf("Hello Go+\n") `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hello") @@ -3108,7 +3108,7 @@ func main() { fmt.Println("Hi") }`, `package main -import fmt "fmt" +import "fmt" func main() { const ( @@ -3133,7 +3133,7 @@ if t := false; t { println("x:", x) `, `package main -import fmt "fmt" +import "fmt" func main() { x := 0 @@ -3173,7 +3173,7 @@ default: println("x:", x) `, `package main -import fmt "fmt" +import "fmt" func main() { x := 0 @@ -3214,7 +3214,7 @@ default: } `, `package main -import fmt "fmt" +import "fmt" func main() { v := "Hello" @@ -3246,7 +3246,7 @@ label: } `, `package main -import fmt "fmt" +import "fmt" func main() { a := []float64{1, 3.4, 5} @@ -3273,7 +3273,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" func foo(format string, args ...interface { }) (int, error) { @@ -3311,7 +3311,7 @@ func(v string) { }("Hello") `, `package main -import fmt "fmt" +import "fmt" func main() { func(v string) { @@ -3452,7 +3452,7 @@ Do => { } `, `package main -import fmt "fmt" +import "fmt" func Do(func()) { } @@ -3621,7 +3621,7 @@ func bar(foo func(string, ...interface{}) (int, error)) { bar(fmt.Printf) `, `package main -import fmt "fmt" +import "fmt" func bar(foo func(string, ...interface { }) (int, error)) { @@ -3658,8 +3658,8 @@ fmt.Println(printf("Hello, %v\n", "Go+")) `, `package main import ( - fmt "fmt" - strings "strings" + "fmt" + "strings" ) func foo(x string) string { @@ -3687,7 +3687,7 @@ func TestFuncCall(t *testing.T) { fmt.Println("Hello")`, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hello") @@ -3705,7 +3705,7 @@ func foo(args ...interface{}) { func main() { }`, `package main -import fmt "fmt" +import "fmt" func foo(args ...interface { }) { @@ -3728,7 +3728,7 @@ func foo(args ...interface{}) { } `, `package main -import fmt "fmt" +import "fmt" func main() { foo("Hello", 123) @@ -3764,7 +3764,7 @@ func TestAssignUnderscore(t *testing.T) { _, err := log.Println("Hello") `, `package main -import fmt "fmt" +import "fmt" func main() { _, err := fmt.Println("Hello") @@ -3811,8 +3811,8 @@ println(rmap) `, `package main import ( - fmt "fmt" - foo "github.com/goplus/gop/cl/internal/gop-in-go/foo" + "fmt" + "github.com/goplus/gop/cl/internal/gop-in-go/foo" ) func main() { @@ -3857,8 +3857,8 @@ func New() Result { `, `package main import ( - reflect "reflect" - testing "testing" + "reflect" + "testing" ) type Repo struct { @@ -3902,7 +3902,7 @@ for i $ :10 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 0; i < 10; i += 1 { @@ -3915,7 +3915,7 @@ for i $ 1:10:3 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 1; i < 10; i += 3 { @@ -3931,7 +3931,7 @@ for i $ 1:10:2 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 1; i < 10; i += 2 { @@ -3947,7 +3947,7 @@ for i $ 1:10 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 1; i < 10; i += 1 { @@ -3963,7 +3963,7 @@ for i $ :10:2 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 0; i < 10; i += 2 { @@ -3979,7 +3979,7 @@ for range :10 { println("Hi") }`, `package main -import fmt "fmt" +import "fmt" func main() { for _gop_k := 0; _gop_k < 10; _gop_k += 1 { @@ -3995,7 +3995,7 @@ for _ <- :10 { println("Hi") }`, `package main -import fmt "fmt" +import "fmt" func main() { for _gop_k := 0; _gop_k < 10; _gop_k += 1 { @@ -4011,8 +4011,8 @@ println [x for x <- 0:3:1] `, `package main import ( - fmt "fmt" - builtin "github.com/goplus/gop/builtin" + "fmt" + "github.com/goplus/gop/builtin" ) func main() { @@ -4058,7 +4058,7 @@ func TestRangeExpr8(t *testing.T) { } `, `package main -import fmt "fmt" +import "fmt" type T struct { } @@ -4102,7 +4102,7 @@ func TestRangeExpr9(t *testing.T) { } `, `package main -import fmt "fmt" +import "fmt" type T struct { } @@ -4158,7 +4158,7 @@ func TestNoEntrypoint(t *testing.T) { gopClTest(t, `println("init") `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("init") @@ -4168,7 +4168,7 @@ func main() { println("init") `, `package bar -import fmt "fmt" +import "fmt" func init() { fmt.Println("init") @@ -4192,7 +4192,7 @@ println [] println {} `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println([]interface { @@ -4216,7 +4216,7 @@ type Point struct { } `, `package main -import fmt "fmt" +import "fmt" type Point struct { X int @@ -4239,7 +4239,7 @@ println "hello" println("hello") `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Print() @@ -4258,7 +4258,7 @@ var a any = 100 println(a) `, `package main -import fmt "fmt" +import "fmt" var a interface { } = 100 @@ -4285,7 +4285,7 @@ func test() { } `, `package main -import fmt "fmt" +import "fmt" func test() { fmt.Println("hello") @@ -4300,7 +4300,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("hello") @@ -4313,7 +4313,7 @@ func TestCommandNotExpr(t *testing.T) { println !true `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println(false) @@ -4324,7 +4324,7 @@ a := true println !a `, `package main -import fmt "fmt" +import "fmt" func main() { a := true @@ -4335,7 +4335,7 @@ func main() { println !func() bool { return true }() `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println(!func() bool { @@ -4389,7 +4389,7 @@ var ( func test(){} `, `package main -import bytes "bytes" +import "bytes" type Rect struct { bytes.Buffer @@ -4406,7 +4406,7 @@ var ( func test(){} `, `package main -import bytes "bytes" +import "bytes" type Rect struct { *bytes.Buffer @@ -4425,7 +4425,7 @@ var ( func test(){} `, `package main -import bytes "bytes" +import "bytes" type Rect struct { *bytes.Buffer `+"`spec:\"buffer\"`"+` @@ -4493,7 +4493,7 @@ n.onKey ["a"],nil,key => { } `, `package main -import foo "github.com/goplus/gop/cl/internal/overload/foo" +import "github.com/goplus/gop/cl/internal/overload/foo" type Mesh struct { } diff --git a/cl/outline/cl/compile_spx_test.go b/cl/outline/cl/compile_spx_test.go index 583afaf9f..a4d381b15 100644 --- a/cl/outline/cl/compile_spx_test.go +++ b/cl/outline/cl/compile_spx_test.go @@ -163,7 +163,7 @@ func onMsg(msg string) { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -208,8 +208,8 @@ func onInit() { `, ``, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) type bar struct { @@ -249,8 +249,8 @@ func onInit() { `, `package main import ( - spx "github.com/goplus/gop/cl/internal/spx" - math "math" + "github.com/goplus/gop/cl/internal/spx" + "math" ) type Game struct { @@ -300,7 +300,7 @@ func onCloned() { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -340,8 +340,8 @@ println "Hi" `, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) type Kai struct { @@ -377,8 +377,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Game struct { @@ -407,8 +407,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Game struct { @@ -437,8 +437,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Dog struct { @@ -465,7 +465,7 @@ func TestSpxMainEntry(t *testing.T) { `, ` `, `package main -import spx2 "github.com/goplus/gop/cl/internal/spx2" +import "github.com/goplus/gop/cl/internal/spx2" type Game struct { spx2.Game @@ -488,7 +488,7 @@ var ( `, ` `, `package main -import spx2 "github.com/goplus/gop/cl/internal/spx2" +import "github.com/goplus/gop/cl/internal/spx2" type Game struct { spx2.Game @@ -522,8 +522,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx2 "github.com/goplus/gop/cl/internal/spx2" + "fmt" + "github.com/goplus/gop/cl/internal/spx2" ) type Game struct { @@ -563,7 +563,7 @@ func onMsg(msg string) { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -619,7 +619,7 @@ func onCloned() { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -667,7 +667,7 @@ func onMsg(msg string) { } `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" type Game struct { *spx.MyGame @@ -698,8 +698,8 @@ func onMsg(msg string) { `, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) type Game struct { diff --git a/cl/outline/cl/compile_test.go b/cl/outline/cl/compile_test.go index 87dd7447d..52fd5dc4b 100644 --- a/cl/outline/cl/compile_test.go +++ b/cl/outline/cl/compile_test.go @@ -157,10 +157,10 @@ for line <- open("foo.txt")! { `, `package main import ( - fmt "fmt" - os "os" - iox "github.com/goplus/gop/builtin/iox" - errors "github.com/qiniu/x/errors" + "fmt" + "os" + "github.com/goplus/gop/builtin/iox" + "github.com/qiniu/x/errors" ) func main() { @@ -194,9 +194,9 @@ for line <- os.Stdin { `, `package main import ( - fmt "fmt" - os "os" - iox "github.com/goplus/gop/builtin/iox" + "fmt" + "os" + "github.com/goplus/gop/builtin/iox" ) func main() { @@ -224,9 +224,9 @@ for line <- lines(r) { `, `package main import ( - fmt "fmt" - iox "github.com/goplus/gop/builtin/iox" - io "io" + "fmt" + "github.com/goplus/gop/builtin/iox" + "io" ) var r io.Reader @@ -298,7 +298,7 @@ type T struct{} println(&T{},&Point{10,20}) `, `package main -import fmt "fmt" +import "fmt" type T struct { } @@ -315,7 +315,7 @@ for i <- :10, i%3 == 0 { println i }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 0; i < 10; i += 1 { @@ -338,7 +338,7 @@ d := fvec([]) println a, b, c, d `, `package main -import fmt "fmt" +import "fmt" type fvec []float64 type foo float64 @@ -542,8 +542,8 @@ println "The Go+ Language for", fields.join(", ") `, `package main import ( - fmt "fmt" - strings "strings" + "fmt" + "strings" ) func main() { @@ -559,7 +559,7 @@ p := println p "Hello world" `, `package main -import fmt "fmt" +import "fmt" func main() { p := fmt.Println @@ -927,8 +927,8 @@ func main() { }`, `package main import ( - fmt "fmt" - errors "github.com/qiniu/x/errors" + "fmt" + "github.com/qiniu/x/errors" ) func t() (int, int, error) { @@ -961,7 +961,7 @@ func main() { t()! }`, `package main -import errors "github.com/qiniu/x/errors" +import "github.com/qiniu/x/errors" func t() error { return nil @@ -1004,7 +1004,7 @@ func (a *A) String() string { } `, `package main -import fmt "fmt" +import "fmt" type AA interface { String() string @@ -1049,7 +1049,7 @@ func (a *A) String() string { } `, `package main -import fmt "fmt" +import "fmt" type AA interface { String() string @@ -1090,7 +1090,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" func main() { { @@ -1159,7 +1159,7 @@ func main() { var i int `, `package main -import fmt "fmt" +import "fmt" var i int @@ -1202,7 +1202,7 @@ func main() { var i = 100 `, `package main -import fmt "fmt" +import "fmt" var i = 100 @@ -1222,7 +1222,7 @@ func main() { println(n) }`, `package main -import fmt "fmt" +import "fmt" func main() { v := []uint64{2, 3, 5} @@ -1247,7 +1247,7 @@ func consume(xchg chan int) { } `, `package main -import fmt "fmt" +import "fmt" func consume(xchg chan int) { select { @@ -1420,7 +1420,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" type Shape interface { Area() float64 @@ -1465,7 +1465,7 @@ type BigInt struct { *big.Int }`, `package main -import big "math/big" +import "math/big" type BigInt struct { *big.Int @@ -1485,10 +1485,10 @@ func foo(script string) { `, `package main import ( - fmt "fmt" - goptest "github.com/goplus/gop/ast/goptest" - errors "github.com/qiniu/x/errors" - gopq "github.com/goplus/gop/ast/gopq" + "fmt" + "github.com/goplus/gop/ast/goptest" + "github.com/qiniu/x/errors" + "github.com/goplus/gop/ast/gopq" ) func foo(script string) { @@ -1519,10 +1519,10 @@ func foo(script string) { `, `package main import ( - fmt "fmt" - goptest "github.com/goplus/gop/ast/goptest" - errors "github.com/qiniu/x/errors" - gopq "github.com/goplus/gop/ast/gopq" + "fmt" + "github.com/goplus/gop/ast/goptest" + "github.com/qiniu/x/errors" + "github.com/goplus/gop/ast/gopq" ) func foo(script string) { @@ -1551,8 +1551,8 @@ func add(x, y string) (int, error) { `, `package main import ( - strconv "strconv" - errors "github.com/qiniu/x/errors" + "strconv" + "github.com/qiniu/x/errors" ) func add(x string, y string) (int, error) { @@ -1592,7 +1592,7 @@ func addSafe(x, y string) int { } `, `package main -import strconv "strconv" +import "strconv" func addSafe(x string, y string) int { return func() (_gop_ret int) { @@ -1620,8 +1620,8 @@ var ret int = println("Hi")! `, `package main import ( - fmt "fmt" - errors "github.com/qiniu/x/errors" + "fmt" + "github.com/qiniu/x/errors" ) var ret int = func() (_gop_ret int) { @@ -1645,7 +1645,7 @@ func mkdir(name string) error { mkdir! "foo" `, `package main -import errors "github.com/qiniu/x/errors" +import "github.com/qiniu/x/errors" func mkdir(name string) error { return nil @@ -1673,7 +1673,7 @@ func foo() (func(), error) { foo()!() `, `package main -import errors "github.com/qiniu/x/errors" +import "github.com/qiniu/x/errors" func foo() (func(), error) { return nil, nil @@ -1722,7 +1722,7 @@ var x, y uint128 var z uint128 = x + y `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x, y ng.Uint128 var z ng.Uint128 = x.Gop_Add__1(y) @@ -1735,7 +1735,7 @@ var x, y int128 var z int128 = x + y `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x, y ng.Int128 var z ng.Int128 = x.Gop_Add__1(y) @@ -1748,7 +1748,7 @@ var x, y bigint var z bigint = x + y `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x, y ng.Bigint var z ng.Bigint = x.Gop_Add(y) @@ -1761,8 +1761,8 @@ var x = 1r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigint_Init__1(big.NewInt(1)) @@ -1774,7 +1774,7 @@ func TestUint128Lit(t *testing.T) { var x uint128 = 1 `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x ng.Uint128 = ng.Uint128_Init__0(1) `) @@ -1785,7 +1785,7 @@ func TestInt128Lit(t *testing.T) { var x int128 = 1 `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x ng.Int128 = ng.Int128_Init__0(1) `) @@ -1797,8 +1797,8 @@ var x = 1/2r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigrat_Init__2(big.NewRat(1, 2)) @@ -1811,8 +1811,8 @@ var x = 3 + 1/2r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigrat_Init__2(big.NewRat(7, 2)) @@ -1828,8 +1828,8 @@ var z = 100 + y `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) var x = ng.Bigrat_Init__2(big.NewRat(7, 2)) @@ -1942,7 +1942,7 @@ var x bigint x += 3 `, `package main -import ng "github.com/goplus/gop/builtin/ng" +import "github.com/goplus/gop/builtin/ng" var x ng.Bigint @@ -1959,8 +1959,8 @@ x *= 2 `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) func main() { @@ -1977,8 +1977,8 @@ x *= 2r `, `package main import ( - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "github.com/goplus/gop/builtin/ng" + "math/big" ) func main() { @@ -2251,7 +2251,7 @@ go println("Hi") defer println("Go+") `, `package main -import fmt "fmt" +import "fmt" func main() { go fmt.Println("Hi") @@ -2271,7 +2271,7 @@ for { } `, `package main -import fmt "fmt" +import "fmt" func main() { a := []float64{1, 3.4, 5} @@ -2308,7 +2308,7 @@ for range a { } `, `package main -import fmt "fmt" +import "fmt" func main() { a := []float64{1, 3.4, 5} @@ -2346,7 +2346,7 @@ for k, v := range new(foo) { } `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -2374,7 +2374,7 @@ for v <- new(foo) { } `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -2409,7 +2409,7 @@ for k, v <- new(foo) { } `, `package main -import fmt "fmt" +import "fmt" type fooIter struct { } @@ -2445,7 +2445,7 @@ func (p *foo) Gop_Enum(c func(val string)) { println([v for v <- new(foo)]) `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -2496,7 +2496,7 @@ for k, v <- newFoo() { } `, `package main -import fmt "fmt" +import "fmt" type fooIter struct { data *foo @@ -2545,7 +2545,7 @@ for i, x <- [1, 3, 5, 7, 11, 13, 17] { println("sum(5,7,11,13,17):", sum) `, `package main -import fmt "fmt" +import "fmt" func main() { sum := 0 @@ -2716,7 +2716,7 @@ x := [[a, b] for a <- arr, a < b for b <- arr, b > 2] println("x:", x) `, `package main -import fmt "fmt" +import "fmt" func main() { arr := []float64{1, 2, 3, 4.1, 5, 6} @@ -2822,8 +2822,8 @@ println("x:", x) `, `package main import ( - fmt "fmt" - strings "strings" + "fmt" + "strings" ) func main() { @@ -2846,7 +2846,7 @@ func bar(p pfoo) { } `, `package main -import fmt "fmt" +import "fmt" type foo struct { req int @@ -2875,7 +2875,7 @@ a.B = "Hi" flag.Usage = nil `, `package main -import flag "flag" +import "flag" func main() { a := &struct { @@ -2935,7 +2935,7 @@ func (M) Bar() { } `, `package main -import fmt "fmt" +import "fmt" type M int @@ -2982,7 +2982,7 @@ var d = -a // TODO: -a have no return value! var e = a!=b `, `package main -import fmt "fmt" +import "fmt" type foo struct { } @@ -3016,7 +3016,7 @@ func (a foo) Gop_NE(b foo) bool { func TestCmdlineNoEOL(t *testing.T) { gopClTest(t, `println "Hi"`, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hi") @@ -3031,7 +3031,7 @@ func main() { fmt.println "Hi" }`, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hi") @@ -3045,7 +3045,7 @@ func TestDotImport(t *testing.T) { var a = round(1.2) `, `package main -import math "math" +import "math" var a = math.Round(1.2) `) @@ -3057,7 +3057,7 @@ func TestLocalImport(t *testing.T) { var a = spx.TestIntValue `, `package main -import spx "github.com/goplus/gop/cl/internal/spx" +import "github.com/goplus/gop/cl/internal/spx" var a = spx.TestIntValue `) @@ -3092,7 +3092,7 @@ func TestAnonymousImport(t *testing.T) { printf("Hello Go+\n") `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hello") @@ -3131,7 +3131,7 @@ func main() { fmt.Println("Hi") }`, `package main -import fmt "fmt" +import "fmt" func main() { const ( @@ -3156,7 +3156,7 @@ if t := false; t { println("x:", x) `, `package main -import fmt "fmt" +import "fmt" func main() { x := 0 @@ -3196,7 +3196,7 @@ default: println("x:", x) `, `package main -import fmt "fmt" +import "fmt" func main() { x := 0 @@ -3237,7 +3237,7 @@ default: } `, `package main -import fmt "fmt" +import "fmt" func main() { v := "Hello" @@ -3269,7 +3269,7 @@ label: } `, `package main -import fmt "fmt" +import "fmt" func main() { a := []float64{1, 3.4, 5} @@ -3296,7 +3296,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" func foo(format string, args ...interface { }) (int, error) { @@ -3334,7 +3334,7 @@ func(v string) { }("Hello") `, `package main -import fmt "fmt" +import "fmt" func main() { func(v string) { @@ -3475,7 +3475,7 @@ Do => { } `, `package main -import fmt "fmt" +import "fmt" func Do(func()) { } @@ -3644,7 +3644,7 @@ func bar(foo func(string, ...interface{}) (int, error)) { bar(fmt.Printf) `, `package main -import fmt "fmt" +import "fmt" func bar(foo func(string, ...interface { }) (int, error)) { @@ -3681,8 +3681,8 @@ fmt.Println(printf("Hello, %v\n", "Go+")) `, `package main import ( - fmt "fmt" - strings "strings" + "fmt" + "strings" ) func foo(x string) string { @@ -3710,7 +3710,7 @@ func TestFuncCall(t *testing.T) { fmt.Println("Hello")`, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Hello") @@ -3728,7 +3728,7 @@ func foo(args ...interface{}) { func main() { }`, `package main -import fmt "fmt" +import "fmt" func foo(args ...interface { }) { @@ -3751,7 +3751,7 @@ func foo(args ...interface{}) { } `, `package main -import fmt "fmt" +import "fmt" func main() { foo("Hello", 123) @@ -3787,7 +3787,7 @@ func TestAssignUnderscore(t *testing.T) { _, err := log.Println("Hello") `, `package main -import fmt "fmt" +import "fmt" func main() { _, err := fmt.Println("Hello") @@ -3838,8 +3838,8 @@ println(rmap) `, `package main import ( - fmt "fmt" - foo "github.com/goplus/gop/cl/internal/gop-in-go/foo" + "fmt" + "github.com/goplus/gop/cl/internal/gop-in-go/foo" ) func main() { @@ -3884,8 +3884,8 @@ func New() Result { `, `package main import ( - reflect "reflect" - testing "testing" + "reflect" + "testing" ) type Repo struct { @@ -3929,7 +3929,7 @@ for i $ :10 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 0; i < 10; i += 1 { @@ -3942,7 +3942,7 @@ for i $ 1:10:3 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 1; i < 10; i += 3 { @@ -3958,7 +3958,7 @@ for i $ 1:10:2 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 1; i < 10; i += 2 { @@ -3974,7 +3974,7 @@ for i $ 1:10 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 1; i < 10; i += 1 { @@ -3990,7 +3990,7 @@ for i $ :10:2 { println(i) }`, `package main -import fmt "fmt" +import "fmt" func main() { for i := 0; i < 10; i += 2 { @@ -4006,7 +4006,7 @@ for range :10 { println("Hi") }`, `package main -import fmt "fmt" +import "fmt" func main() { for _gop_k := 0; _gop_k < 10; _gop_k += 1 { @@ -4022,7 +4022,7 @@ for _ <- :10 { println("Hi") }`, `package main -import fmt "fmt" +import "fmt" func main() { for _gop_k := 0; _gop_k < 10; _gop_k += 1 { @@ -4038,8 +4038,8 @@ println [x for x <- 0:3:1] `, `package main import ( - fmt "fmt" - builtin "github.com/goplus/gop/builtin" + "fmt" + "github.com/goplus/gop/builtin" ) func main() { @@ -4085,7 +4085,7 @@ func TestRangeExpr8(t *testing.T) { } `, `package main -import fmt "fmt" +import "fmt" type T struct { } @@ -4129,7 +4129,7 @@ func TestRangeExpr9(t *testing.T) { } `, `package main -import fmt "fmt" +import "fmt" type T struct { } @@ -4185,7 +4185,7 @@ func TestNoEntrypoint(t *testing.T) { gopClTest(t, `println("init") `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("init") @@ -4195,7 +4195,7 @@ func main() { println("init") `, `package bar -import fmt "fmt" +import "fmt" func init() { fmt.Println("init") @@ -4219,7 +4219,7 @@ println [] println {} `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println([]interface { @@ -4243,7 +4243,7 @@ type Point struct { } `, `package main -import fmt "fmt" +import "fmt" type Point struct { X int @@ -4266,7 +4266,7 @@ println "hello" println("hello") `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Print() @@ -4285,7 +4285,7 @@ var a any = 100 println(a) `, `package main -import fmt "fmt" +import "fmt" var a interface { } = 100 @@ -4312,7 +4312,7 @@ func test() { } `, `package main -import fmt "fmt" +import "fmt" func test() { fmt.Println("hello") @@ -4327,7 +4327,7 @@ func main() { } `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("hello") @@ -4340,7 +4340,7 @@ func TestCommandNotExpr(t *testing.T) { println !true `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println(false) @@ -4351,7 +4351,7 @@ a := true println !a `, `package main -import fmt "fmt" +import "fmt" func main() { a := true @@ -4362,7 +4362,7 @@ func main() { println !func() bool { return true }() `, `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println(!func() bool { @@ -4416,7 +4416,7 @@ var ( func test(){} `, `package main -import bytes "bytes" +import "bytes" type Rect struct { bytes.Buffer @@ -4433,7 +4433,7 @@ var ( func test(){} `, `package main -import bytes "bytes" +import "bytes" type Rect struct { *bytes.Buffer @@ -4452,7 +4452,7 @@ var ( func test(){} `, `package main -import bytes "bytes" +import "bytes" type Rect struct { *bytes.Buffer `+"`spec:\"buffer\"`"+` @@ -4520,7 +4520,7 @@ n.onKey ["a"],nil,key => { } `, `package main -import foo "github.com/goplus/gop/cl/internal/overload/foo" +import "github.com/goplus/gop/cl/internal/overload/foo" type Mesh struct { } diff --git a/cl/outline/cl/typeparams_test.go b/cl/outline/cl/typeparams_test.go index bb0a47f04..644e084fa 100644 --- a/cl/outline/cl/typeparams_test.go +++ b/cl/outline/cl/typeparams_test.go @@ -161,7 +161,7 @@ v3.Append([1,2,3,4]...) v3.Append2([1,2,3,4]...) `, `package main -import fmt "fmt" +import "fmt" type DataString = Data[string] type SliceString = Slice[[]string, string] diff --git a/cl/typeparams_test.go b/cl/typeparams_test.go index a35f93694..c700ce1d5 100644 --- a/cl/typeparams_test.go +++ b/cl/typeparams_test.go @@ -166,7 +166,7 @@ v3.Append([1,2,3,4]...) v3.Append2([1,2,3,4]...) `, `package main -import fmt "fmt" +import "fmt" type DataString = Data[string] type SliceString = Slice[[]string, string] diff --git a/go.mod b/go.mod index 446d101b3..6ef782d6b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/fsnotify/fsnotify v1.6.0 github.com/goplus/c2go v0.7.16 - github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754 + github.com/goplus/gox v1.12.2-0.20231023222557-3d1b2e0a7dbf 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 d808e9459..fcaadb346 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.20231020202641-5f657ff4e754 h1:uuXDqFfg4RhmHD7slw15hzwVQtJ51CsdcZn6gQtve/E= -github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ= +github.com/goplus/gox v1.12.2-0.20231023222557-3d1b2e0a7dbf h1:gQNKxSMyYDdOFNpfqZfWjVZE5q/MsZmqn2rJ3U+OvA8= +github.com/goplus/gox v1.12.2-0.20231023222557-3d1b2e0a7dbf/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= From c2f160efd6fc7a1aebac6de336c9f1502bb9116f Mon Sep 17 00:00:00 2001 From: visualfc Date: Tue, 24 Oct 2023 06:39:16 +0800 Subject: [PATCH 38/64] x --- x/build/_testdata/hello/hello.expect | 2 +- x/build/_testdata/multi/multi.expect | 2 +- x/build/_testdata/pkg/pkg.expect | 2 +- x/build/build_test.go | 46 ++++++++++++++-------------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/x/build/_testdata/hello/hello.expect b/x/build/_testdata/hello/hello.expect index e62ecea49..13b98bf6f 100644 --- a/x/build/_testdata/hello/hello.expect +++ b/x/build/_testdata/hello/hello.expect @@ -1,6 +1,6 @@ package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Go+") diff --git a/x/build/_testdata/multi/multi.expect b/x/build/_testdata/multi/multi.expect index 9eb31ec28..e2243eb6e 100644 --- a/x/build/_testdata/multi/multi.expect +++ b/x/build/_testdata/multi/multi.expect @@ -1,6 +1,6 @@ package main -import fmt "fmt" +import "fmt" type BaseClass struct { x int diff --git a/x/build/_testdata/pkg/pkg.expect b/x/build/_testdata/pkg/pkg.expect index e71e8cb88..54ec82421 100644 --- a/x/build/_testdata/pkg/pkg.expect +++ b/x/build/_testdata/pkg/pkg.expect @@ -1,6 +1,6 @@ package pkg -import fmt "fmt" +import "fmt" func Hello() { fmt.Println("Go+") diff --git a/x/build/build_test.go b/x/build/build_test.go index a677214ee..cb867bd22 100644 --- a/x/build/build_test.go +++ b/x/build/build_test.go @@ -84,7 +84,7 @@ println "Go+" ` var expect = `package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Go+") @@ -108,7 +108,7 @@ func TestGox(t *testing.T) { println "Go+" `, `package main -import fmt "fmt" +import "fmt" type Rect struct { } @@ -130,7 +130,7 @@ type Buffer struct { println "Go+" `, `package main -import fmt "fmt" +import "fmt" type Buffer struct { buf []byte @@ -157,7 +157,7 @@ type Buffer struct { println "Go+" `, `package main -import fmt "fmt" +import "fmt" type Buffer struct { buf []byte @@ -183,8 +183,8 @@ println "Go+" `, `package main import ( - fmt "fmt" - bytes "bytes" + "fmt" + "bytes" ) type Rect struct { @@ -208,8 +208,8 @@ println "Go+" `, `package main import ( - fmt "fmt" - bytes "bytes" + "fmt" + "bytes" ) type Rect struct { @@ -232,9 +232,9 @@ println a+1/2r `, `package main import ( - fmt "fmt" - ng "github.com/goplus/gop/builtin/ng" - big "math/big" + "fmt" + "github.com/goplus/gop/builtin/ng" + "math/big" ) func main() { @@ -256,9 +256,9 @@ for line <- lines(r) { `, `package main import ( - fmt "fmt" - iox "github.com/goplus/gop/builtin/iox" - io "io" + "fmt" + "github.com/goplus/gop/builtin/iox" + "io" ) var r io.Reader @@ -299,9 +299,9 @@ println addSafe("10", "abc") `, `package main import ( - fmt "fmt" - strconv "strconv" - errors "github.com/qiniu/x/errors" + "fmt" + "strconv" + "github.com/qiniu/x/errors" ) func add(x string, y string) (int, error) { @@ -367,8 +367,8 @@ func TestSpx(t *testing.T) { gopClTestEx(t, "main.tspx", `println "hi"`, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) type MyGame struct { @@ -385,8 +385,8 @@ func main() { gopClTestEx(t, "Cat.tspx", `println "hi"`, `package main import ( - fmt "fmt" - spx "github.com/goplus/gop/cl/internal/spx" + "fmt" + "github.com/goplus/gop/cl/internal/spx" ) type Cat struct { @@ -441,7 +441,7 @@ func TestFromTestdata(t *testing.T) { func TestFS(t *testing.T) { var expect = []byte(`package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Go+") @@ -459,7 +459,7 @@ func main() { func TestAst(t *testing.T) { var expect = []byte(`package main -import fmt "fmt" +import "fmt" func main() { fmt.Println("Go+") From ad929663a20aba86f58c02d57dc75cf840c50c39 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 24 Oct 2023 11:53:50 +0800 Subject: [PATCH 39/64] ast: FuncDecl.Shadow --- ast/ast.go | 1 + ast/walk.go | 16 +++++++++------- parser/parser.go | 3 ++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index dbac1db09..f0b489532 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -1059,6 +1059,7 @@ type ( Type *FuncType // function signature: parameters, results, and position of "func" keyword Body *BlockStmt // function body; or nil for external (non-Go) function Operator bool // is operator or not + Shadow bool // is a shadow entry } ) diff --git a/ast/walk.go b/ast/walk.go index ba6f4ff18..3cdc64e96 100644 --- a/ast/walk.go +++ b/ast/walk.go @@ -345,14 +345,16 @@ func Walk(v Visitor, node Node) { } case *FuncDecl: - if n.Doc != nil { - Walk(v, n.Doc) - } - if n.Recv != nil { - Walk(v, n.Recv) + if !n.Shadow { // not a shadow entry + if n.Doc != nil { + Walk(v, n.Doc) + } + if n.Recv != nil { + Walk(v, n.Recv) + } + Walk(v, n.Name) + Walk(v, n.Type) } - Walk(v, n.Name) - Walk(v, n.Type) if n.Body != nil { Walk(v, n.Body) } diff --git a/parser/parser.go b/parser/parser.go index 43bb6efe8..6a9100d9d 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -3668,7 +3668,8 @@ func (p *parser) parseGlobalStmts(sync map[token.Token]bool, pos token.Pos, stmt Func: pos, Params: &ast.FieldList{}, }, - Body: &ast.BlockStmt{List: list}, + Body: &ast.BlockStmt{List: list}, + Shadow: true, } p.shadowEntry = f return f From 87266ff47dff9182d963821edec55b73aa98c1c5 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 25 Oct 2023 00:56:26 +0800 Subject: [PATCH 40/64] gox: newScope support start..end --- cl/compile.go | 2 +- cl/stmt.go | 48 ++++++++++++++++++++++++------------------------ go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 1b06ed911..65484b59d 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -1117,7 +1117,7 @@ var unaryGopNames = map[string]string{ } func loadFuncBody(ctx *blockCtx, fn *gox.Func, body *ast.BlockStmt, src ast.Node) { - cb := fn.BodyStart(ctx.pkg) + cb := fn.BodyStart(ctx.pkg, body) compileStmts(ctx, body.List) cb.End(src) } diff --git a/cl/stmt.go b/cl/stmt.go index 121c28983..35847bb4b 100644 --- a/cl/stmt.go +++ b/cl/stmt.go @@ -297,10 +297,10 @@ func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) { if v.Value != nil { names = append(names, v.Value.(*ast.Ident).Name) } - cb.ForRange(names...) + cb.ForRangeEx(names, v) compileExpr(ctx, v.X) } else { - cb.ForRange() + cb.ForRangeEx(nil, v) n := 0 if v.Key == nil { if v.Value != nil { @@ -321,11 +321,11 @@ func compileRangeStmt(ctx *blockCtx, v *ast.RangeStmt) { if pos == 0 { pos = v.For } - cb.RangeAssignThen(pos) + cb.RangeAssignThen(pos) // TODO: need NewScope for body compileStmts(ctx, v.Body.List) cb.SetComments(comments, once) setBodyHandler(ctx) - cb.End() + cb.End(v) } func compileForPhraseStmt(ctx *blockCtx, v *ast.ForPhraseStmt) { @@ -459,7 +459,7 @@ func toForStmt(forPos token.Pos, value ast.Expr, body *ast.BlockStmt, re *ast.Ra func compileForStmt(ctx *blockCtx, v *ast.ForStmt) { cb := ctx.cb comments, once := cb.BackupComments() - cb.For() + cb.For(v) if v.Init != nil { compileStmt(ctx, v.Init) } @@ -468,7 +468,7 @@ func compileForStmt(ctx *blockCtx, v *ast.ForStmt) { } else { cb.None() } - cb.Then() + cb.Then(v.Body) compileStmts(ctx, v.Body.List) if v.Post != nil { cb.Post() @@ -476,7 +476,7 @@ func compileForStmt(ctx *blockCtx, v *ast.ForStmt) { } cb.SetComments(comments, once) setBodyHandler(ctx) - cb.End() + cb.End(v) } // if init; cond then @@ -487,15 +487,15 @@ func compileForStmt(ctx *blockCtx, v *ast.ForStmt) { func compileIfStmt(ctx *blockCtx, v *ast.IfStmt) { cb := ctx.cb comments, once := cb.BackupComments() - cb.If() + cb.If(v) if v.Init != nil { compileStmt(ctx, v.Init) } compileExpr(ctx, v.Cond) - cb.Then() + cb.Then(v.Body) compileStmts(ctx, v.Body.List) if e := v.Else; e != nil { - cb.Else() + cb.Else(e) if stmts, ok := e.(*ast.BlockStmt); ok { compileStmts(ctx, stmts.List) } else { @@ -503,7 +503,7 @@ func compileIfStmt(ctx *blockCtx, v *ast.IfStmt) { } } cb.SetComments(comments, once) - cb.End() + cb.End(v) } // typeSwitch(name) init; expr typeAssertThen() @@ -536,7 +536,7 @@ func compileTypeSwitchStmt(ctx *blockCtx, v *ast.TypeSwitchStmt) { if ta.Type != nil { panic("TODO: type switch syntax error, please use x.(type)") } - cb.TypeSwitch(name) + cb.TypeSwitch(name, v) if v.Init != nil { compileStmt(ctx, v.Init) } @@ -582,13 +582,13 @@ func compileTypeSwitchStmt(ctx *blockCtx, v *ast.TypeSwitchStmt) { firstDefault = c } } - cb.TypeCase(len(c.List)) // TypeCase(0) means default case + cb.TypeCase(len(c.List), c) // TypeCase(0) means default case compileStmts(ctx, c.Body) commentStmt(ctx, stmt) - cb.End() + cb.End(c) } cb.SetComments(comments, once) - cb.End() + cb.End(v) } // switch init; tag then @@ -606,7 +606,7 @@ func compileTypeSwitchStmt(ctx *blockCtx, v *ast.TypeSwitchStmt) { func compileSwitchStmt(ctx *blockCtx, v *ast.SwitchStmt) { cb := ctx.cb comments, once := cb.BackupComments() - cb.Switch() + cb.Switch(v) if v.Init != nil { compileStmt(ctx, v.Init) } @@ -615,7 +615,7 @@ func compileSwitchStmt(ctx *blockCtx, v *ast.SwitchStmt) { } else { cb.None() // switch {...} } - cb.Then() + cb.Then(v.Body) seen := make(valueMap) var firstDefault ast.Stmt for _, stmt := range v.Body.List { @@ -656,17 +656,17 @@ func compileSwitchStmt(ctx *blockCtx, v *ast.SwitchStmt) { firstDefault = c } } - cb.Case(len(c.List)) // Case(0) means default case + cb.Case(len(c.List), c) // Case(0) means default case body, has := hasFallthrough(c.Body) compileStmts(ctx, body) if has { cb.Fallthrough() } commentStmt(ctx, stmt) - cb.End() + cb.End(c) } cb.SetComments(comments, once) - cb.End() + cb.End(v) } func hasFallthrough(body []ast.Stmt) ([]ast.Stmt, bool) { @@ -699,7 +699,7 @@ func hasFallthrough(body []ast.Stmt) ([]ast.Stmt, bool) { func compileSelectStmt(ctx *blockCtx, v *ast.SelectStmt) { cb := ctx.cb comments, once := cb.BackupComments() - cb.Select() + cb.Select(v) for _, stmt := range v.Body.List { c, ok := stmt.(*ast.CommClause) if !ok { @@ -710,13 +710,13 @@ func compileSelectStmt(ctx *blockCtx, v *ast.SelectStmt) { compileStmt(ctx, c.Comm) n = 1 } - cb.CommCase(n) // CommCase(0) means default case + cb.CommCase(n, c) // CommCase(0) means default case compileStmts(ctx, c.Body) commentStmt(ctx, stmt) - cb.End() + cb.End(c) } cb.SetComments(comments, once) - cb.End() + cb.End(v) } func compileBranchStmt(ctx *blockCtx, v *ast.BranchStmt) { diff --git a/go.mod b/go.mod index 446d101b3..1b793b4e1 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/fsnotify/fsnotify v1.6.0 github.com/goplus/c2go v0.7.16 - github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754 + github.com/goplus/gox v1.12.2-0.20231024165412-08fb2524d4a0 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 d808e9459..f7e27234e 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.20231020202641-5f657ff4e754 h1:uuXDqFfg4RhmHD7slw15hzwVQtJ51CsdcZn6gQtve/E= -github.com/goplus/gox v1.12.2-0.20231020202641-5f657ff4e754/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ= +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/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= From df6221ed921293de74d22bd37061f0a9860046da Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 26 Oct 2023 09:39:14 +0800 Subject: [PATCH 41/64] parser: parsePrimaryExpr fix LiteralValue check --- parser/parser.go | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index 6a9100d9d..5914f55bd 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -2068,23 +2068,9 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr { return x } -// isTypeName reports whether x is a (qualified) TypeName. -func isTypeName(x ast.Expr) bool { - switch t := x.(type) { - case *ast.BadExpr: - case *ast.Ident: - case *ast.SelectorExpr: - _, isIdent := t.X.(*ast.Ident) - return isIdent - default: - return false // all other nodes are not type names - } - return true -} - // isLiteralType reports whether x is a legal composite literal type. func isLiteralType(x ast.Expr) bool { - switch t := x.(type) { + switch t := unparen(x).(type) { case *ast.BadExpr: case *ast.Ident: case *ast.IndexExpr: @@ -2188,7 +2174,7 @@ L: case token.LBRACE: // { if allowCmd && p.isCmd(x) { // println {...} x = p.parseCallOrConversion(p.checkExprOrType(x), true) - } else if isLiteralType(x) && (p.exprLev >= 0 || !isTypeName(x)) { + } else if isLiteralType(x) && p.exprLev >= 0 { if lhs { p.resolve(x) } From 3363ba1cc35b08585e2a7bbee25b9c0ecad966a6 Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 26 Oct 2023 09:45:45 +0800 Subject: [PATCH 42/64] parser: add test _instance/instance5 --- parser/_instance/instance5/cmd.gop | 6 ++ parser/_instance/instance5/parser.expect | 115 +++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 parser/_instance/instance5/cmd.gop create mode 100644 parser/_instance/instance5/parser.expect diff --git a/parser/_instance/instance5/cmd.gop b/parser/_instance/instance5/cmd.gop new file mode 100644 index 000000000..b693b560a --- /dev/null +++ b/parser/_instance/instance5/cmd.gop @@ -0,0 +1,6 @@ +var a [2]int +if 0 < a[0] { + println a + 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 new file mode 100644 index 000000000..1dc92068c --- /dev/null +++ b/parser/_instance/instance5/parser.expect @@ -0,0 +1,115 @@ +package main + +file cmd.gop +noEntrypoint +ast.GenDecl: + Tok: var + Specs: + ast.ValueSpec: + Names: + ast.Ident: + Name: a + Type: + ast.ArrayType: + Len: + ast.BasicLit: + Kind: INT + Value: 2 + Elt: + ast.Ident: + Name: int +ast.FuncDecl: + Name: + ast.Ident: + Name: main + Type: + ast.FuncType: + Params: + ast.FieldList: + Body: + ast.BlockStmt: + List: + ast.IfStmt: + Cond: + ast.BinaryExpr: + X: + ast.BasicLit: + Kind: INT + Value: 0 + Op: < + Y: + ast.IndexExpr: + X: + ast.Ident: + Name: a + Index: + ast.BasicLit: + Kind: INT + Value: 0 + Body: + ast.BlockStmt: + List: + ast.ExprStmt: + X: + ast.CallExpr: + Fun: + ast.Ident: + Name: println + Args: + ast.Ident: + Name: a + ast.ExprStmt: + X: + ast.CallExpr: + Fun: + ast.Ident: + Name: println + Args: + ast.CompositeLit: + Type: + ast.IndexExpr: + X: + ast.Ident: + Name: T + Index: + ast.Ident: + Name: int + Elts: + ast.BasicLit: + Kind: INT + Value: 1 + ast.ExprStmt: + X: + ast.CallExpr: + Fun: + ast.Ident: + Name: println + Args: + ast.CompositeLit: + Type: + ast.ParenExpr: + X: + ast.IndexExpr: + X: + ast.Ident: + Name: T + Index: + ast.Ident: + Name: int + Elts: + ast.KeyValueExpr: + Key: + ast.Ident: + Name: a + Value: + ast.BasicLit: + Kind: INT + Value: 1 + ast.KeyValueExpr: + Key: + ast.Ident: + Name: b + Value: + ast.BasicLit: + Kind: INT + Value: 2 From 5c75e59fd732d31f54057e44235687f4ca1222ea Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 26 Oct 2023 17:51:09 +0800 Subject: [PATCH 43/64] typesutil.Check fix: exprLHS --- cl/expr.go | 4 ++++ cl/stmt.go | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cl/expr.go b/cl/expr.go index 83a624478..632308e29 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -355,6 +355,10 @@ func compileSelectorExprLHS(ctx *blockCtx, v *ast.SelectorExpr) { } default: compileExpr(ctx, v.X) + if rec := ctx.recorder(); rec != nil { + e := ctx.cb.Get(-1) + rec.Type(v.X, types.TypeAndValue{Type: e.Type, Value: e.CVal}) + } } ctx.cb.MemberRef(v.Sel.Name, v) } diff --git a/cl/stmt.go b/cl/stmt.go index 35847bb4b..0dd0004c9 100644 --- a/cl/stmt.go +++ b/cl/stmt.go @@ -206,14 +206,16 @@ func compileAssignStmt(ctx *blockCtx, expr *ast.AssignStmt) { } if tok == token.DEFINE { names := make([]string, len(expr.Lhs)) + rec := ctx.recorder() for i, lhs := range expr.Lhs { if v, ok := lhs.(*ast.Ident); ok { names[i] = v.Name } else { + compileExprLHS(ctx, lhs) // only for typesutil.Check log.Panicln("TODO: non-name $v on left side of :=") } } - if rec := ctx.recorder(); rec != nil { + if rec != nil { newNames := make([]*ast.Ident, 0, len(names)) scope := ctx.cb.Scope() for _, lhs := range expr.Lhs { From 6a8bf802166fca6457d29cfbd66652191e51bf6f Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 26 Oct 2023 17:52:45 +0800 Subject: [PATCH 44/64] compileAssignStmt small rollback --- cl/stmt.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cl/stmt.go b/cl/stmt.go index 0dd0004c9..0bb43cf60 100644 --- a/cl/stmt.go +++ b/cl/stmt.go @@ -206,7 +206,6 @@ func compileAssignStmt(ctx *blockCtx, expr *ast.AssignStmt) { } if tok == token.DEFINE { names := make([]string, len(expr.Lhs)) - rec := ctx.recorder() for i, lhs := range expr.Lhs { if v, ok := lhs.(*ast.Ident); ok { names[i] = v.Name @@ -215,7 +214,7 @@ func compileAssignStmt(ctx *blockCtx, expr *ast.AssignStmt) { log.Panicln("TODO: non-name $v on left side of :=") } } - if rec != nil { + if rec := ctx.recorder(); rec != nil { newNames := make([]*ast.Ident, 0, len(names)) scope := ctx.cb.Scope() for _, lhs := range expr.Lhs { From 17c4a9ab87eec6200b8f75f6152b5f4486bb6153 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 26 Oct 2023 18:05:15 +0800 Subject: [PATCH 45/64] TestErrAssign --- cl/builtin_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cl/builtin_test.go b/cl/builtin_test.go index bc15a433e..3f09e167d 100644 --- a/cl/builtin_test.go +++ b/cl/builtin_test.go @@ -50,6 +50,24 @@ func TestErrMultiStarRecv(t *testing.T) { }) } +func TestErrAssign(t *testing.T) { + defer func() { + if e := recover(); e == nil { + t.Fatal("TestErrAssign: no panic?") + } + }() + ctx := &blockCtx{} + compileAssignStmt(ctx, &ast.AssignStmt{ + Tok: token.DEFINE, + Lhs: []ast.Expr{ + &ast.SelectorExpr{ + X: ast.NewIdent("foo"), + Sel: ast.NewIdent("bar"), + }, + }, + }) +} + func TestErrPanicToRecv(t *testing.T) { ctx := &blockCtx{ tlookup: &typeParamLookup{ From 556fc3fca764136d7e0158601f4779ec33970b79 Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 26 Oct 2023 19:49:39 +0800 Subject: [PATCH 46/64] update gox; TestGenericTypeCompositeLit --- cl/typeparams_test.go | 35 +++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/cl/typeparams_test.go b/cl/typeparams_test.go index c700ce1d5..a3b714577 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 { + } +} +`) +} diff --git a/go.mod b/go.mod index 9f5c30127..c860cb1b8 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 f4e77783f..51af496d1 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= From 14856b717f367891c6aca465519ec4fa8376622c Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 27 Oct 2023 08:55:04 +0800 Subject: [PATCH 47/64] toStructType: add field pos --- cl/func_type_and_var.go | 4 ++-- cl/outline/cl/func_type_and_var.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index 9a734d471..a2f3608ca 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -319,7 +319,7 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { if t, ok := typ.(*types.Named); ok { // #1196: embedded type should ensure loaded ctx.loadNamed(ctx.pkg, t) } - fld := types.NewField(token.NoPos, pkg, name, typ, true) + fld := types.NewField(field.Type.Pos(), pkg, name, typ, true) fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) continue @@ -328,7 +328,7 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { if chk.chkRedecl(ctx, name.Name, name.NamePos) { continue } - fld := types.NewField(token.NoPos, pkg, name.Name, typ, false) + fld := types.NewField(name.Pos(), pkg, name.Name, typ, false) fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) } diff --git a/cl/outline/cl/func_type_and_var.go b/cl/outline/cl/func_type_and_var.go index cb52ef9d0..9a412d49e 100644 --- a/cl/outline/cl/func_type_and_var.go +++ b/cl/outline/cl/func_type_and_var.go @@ -285,7 +285,7 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { if chk.chkRedecl(ctx, name, field.Type.Pos()) { continue } - fld := types.NewField(token.NoPos, pkg, name, typ, true) + fld := types.NewField(field.Type.Pos(), pkg, name, typ, true) fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) continue @@ -294,7 +294,7 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { if chk.chkRedecl(ctx, name.Name, name.NamePos) { continue } - fld := types.NewField(token.NoPos, pkg, name.Name, typ, false) + fld := types.NewField(name.Pos(), pkg, name.Name, typ, false) fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) } From 51060d8bb8ad5e1228c374f6569b33a00ee2023c Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 27 Oct 2023 11:18:29 +0800 Subject: [PATCH 48/64] toStructType: record.Def field --- cl/func_type_and_var.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index a2f3608ca..a9f6e12be 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -320,6 +320,11 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { ctx.loadNamed(ctx.pkg, t) } fld := types.NewField(field.Type.Pos(), pkg, name, typ, true) + if rec := ctx.recorder(); rec != nil { + if ident := parseTypeEmbedName(field.Type); ident != nil { + rec.Def(ident, fld) + } + } fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) continue @@ -329,6 +334,9 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { continue } fld := types.NewField(name.Pos(), pkg, name.Name, typ, false) + if rec := ctx.recorder(); rec != nil { + rec.Def(name, fld) + } fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) } From 6d3596d93fb92c3273e94f0d7d65fca39b3340d4 Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 27 Oct 2023 15:21:26 +0800 Subject: [PATCH 49/64] cl: loadFunc fix ctx.pkg.NewFuncWith use name pos --- cl/compile.go | 2 +- cl/outline/cl/compile.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 65484b59d..250ff0e2f 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -1040,7 +1040,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { } } sig := toFuncType(ctx, d.Type, recv, d) - fn, err := ctx.pkg.NewFuncWith(d.Pos(), name, sig, func() token.Pos { + fn, err := ctx.pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos { return d.Recv.List[0].Type.Pos() }) if err != nil { diff --git a/cl/outline/cl/compile.go b/cl/outline/cl/compile.go index fe5e36345..51423513d 100644 --- a/cl/outline/cl/compile.go +++ b/cl/outline/cl/compile.go @@ -750,7 +750,7 @@ func preloadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) } } sig := toFuncType(ctx, d.Type, recv, d) - fn, err := ctx.pkg.NewFuncWith(d.Pos(), name, sig, func() token.Pos { + fn, err := ctx.pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos { return d.Recv.List[0].Type.Pos() }) if err != nil { From de2b8cb317eb1ad29e844d894908f31a056edd64 Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 27 Oct 2023 15:24:46 +0800 Subject: [PATCH 50/64] x --- cl/error_msg_test.go | 2 +- cl/outline/cl/error_msg_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cl/error_msg_test.go b/cl/error_msg_test.go index 7bd7d1b18..6ac179536 100644 --- a/cl/error_msg_test.go +++ b/cl/error_msg_test.go @@ -431,7 +431,7 @@ for _, a = range b { func TestErrInitFunc(t *testing.T) { codeErrorTest(t, - `./bar.gop:2:1: 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) { } `) diff --git a/cl/outline/cl/error_msg_test.go b/cl/outline/cl/error_msg_test.go index a07c414c6..29919464e 100644 --- a/cl/outline/cl/error_msg_test.go +++ b/cl/outline/cl/error_msg_test.go @@ -431,7 +431,7 @@ for _, a = range b { func TestErrInitFunc(t *testing.T) { codeErrorTest(t, - `./bar.gop:2:1: 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) { } `) From 6c796970a3e841c14d91ef6518b0ddf5757eadfe Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 28 Oct 2023 14:11:01 +0800 Subject: [PATCH 51/64] goxRecorder.Member: rec.Type --- cl/compile.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cl/compile.go b/cl/compile.go index 65484b59d..9f0123f90 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -222,15 +222,18 @@ type goxRecorder struct { // Member maps identifiers to the objects they denote. func (p *goxRecorder) Member(id ast.Node, obj types.Object) { + tv := types.TypeAndValue{Type: obj.Type()} switch v := id.(type) { case *ast.SelectorExpr: sel := v.Sel // TODO: record event for a Go ident if _, ok := fromgo.CheckIdent(sel); !ok { p.rec.Use(sel, obj) + p.rec.Type(v, tv) } - case *ast.Ident: // it's impossible converted from Go + case *ast.Ident: // it's in a classfile and impossible converted from Go p.rec.Use(v, obj) + p.rec.Type(v, tv) } } From dff1b75601820beba61d63db384baee0a1b1b8a8 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 28 Oct 2023 15:15:42 +0800 Subject: [PATCH 52/64] cl.compileIdent: rec.Use for builtin objects --- cl/expr.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/cl/expr.go b/cl/expr.go index 632308e29..cd6328ef8 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -74,7 +74,7 @@ const ( const errorPkgPath = "github.com/qiniu/x/errors" -func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (obj *gox.PkgRef, kind int) { +func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg *gox.PkgRef, kind int) { fvalue := (flags&clIdentSelectorExpr) != 0 || (flags&clIdentLHS) == 0 name := ident.Name if name == "_" { @@ -85,6 +85,7 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (obj *gox.PkgRef, return } + var oldo types.Object scope := ctx.pkg.Types.Scope() at, o := ctx.cb.Scope().LookupParent(name, token.NoPos) if o != nil { @@ -137,7 +138,7 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (obj *gox.PkgRef, if (flags&clIdentAllowBuiltin) == 0 && isBuiltin(o) && !strings.HasPrefix(o.Name(), "print") { panic(ctx.newCodeErrorf(ident.Pos(), "use of builtin %s not in function call", name)) } - o = obj + oldo, o = o, obj } else if o == nil { if (clIdentGoto & flags) != 0 { l := ident.Obj.Data.(*ast.Ident) @@ -153,12 +154,14 @@ find: ctx.cb.VarRef(o, ident) } if rec := ctx.recorder(); rec != nil { - rec.Use(ident, o) e := ctx.cb.Get(-1) - tv := types.TypeAndValue{Type: e.Type, Value: e.CVal} - if !fvalue { - tv.Type = o.Type() + if oldo != nil && gox.IsTypeEx(e.Type) { + rec.Use(ident, oldo) + return } + rec.Use(ident, o) + typ, _ := gox.DerefType(e.Type) + tv := types.TypeAndValue{Type: typ, Value: e.CVal} rec.Type(ident, tv) } return From 519478a08f6c82be0f571dfd07c367ed5a2de4c8 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 28 Oct 2023 15:18:10 +0800 Subject: [PATCH 53/64] gox.IsTypeEx --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9f5c30127..9c910ffe1 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.20231028071646-bb6d796d66cf 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 f4e77783f..2489e2909 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.20231028071646-bb6d796d66cf h1:67Lz2V9Nj6pZz+u4d9uq5rCfw2t/zE34Qo6AF5dJN3c= +github.com/goplus/gox v1.12.2-0.20231028071646-bb6d796d66cf/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= From f1b1a104e9bccf55dd039b8374f35b809cb7f684 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 29 Oct 2023 09:55:21 +0800 Subject: [PATCH 54/64] toInterfaceType: rec.Def fields --- cl/func_type_and_var.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index a9f6e12be..d964c3bac 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -309,6 +309,7 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { fields := make([]*types.Var, 0, len(fieldList)) tags := make([]string, 0, len(fieldList)) chk := newCheckRedecl() + rec := ctx.recorder() for _, field := range fieldList { typ := toType(ctx, field.Type) if len(field.Names) == 0 { // embedded @@ -320,13 +321,13 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { ctx.loadNamed(ctx.pkg, t) } fld := types.NewField(field.Type.Pos(), pkg, name, typ, true) - if rec := ctx.recorder(); rec != nil { + fields = append(fields, fld) + tags = append(tags, toFieldTag(field.Tag)) + if rec != nil { if ident := parseTypeEmbedName(field.Type); ident != nil { rec.Def(ident, fld) } } - fields = append(fields, fld) - tags = append(tags, toFieldTag(field.Tag)) continue } for _, name := range field.Names { @@ -334,11 +335,11 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { continue } fld := types.NewField(name.Pos(), pkg, name.Name, typ, false) - if rec := ctx.recorder(); rec != nil { - rec.Def(name, fld) - } fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) + if rec != nil { + rec.Def(name, fld) + } } } return types.NewStruct(fields, tags) @@ -408,6 +409,7 @@ func toInterfaceType(ctx *blockCtx, v *ast.InterfaceType) types.Type { if methodsList == nil { return types.NewInterfaceType(nil, nil) } + var rec = ctx.recorder() var pkg = ctx.pkg.Types var methods []*types.Func var embeddeds []types.Type @@ -420,9 +422,13 @@ func toInterfaceType(ctx *blockCtx, v *ast.InterfaceType) types.Type { embeddeds = append(embeddeds, typ) continue } - name := m.Names[0].Name + name := m.Names[0] sig := toFuncType(ctx, m.Type.(*ast.FuncType), nil, nil) - methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig)) + mthd := types.NewFunc(name.NamePos, pkg, name.Name, sig) + methods = append(methods, mthd) + if rec != nil { + rec.Def(name, mthd) + } } intf := types.NewInterfaceType(methods, embeddeds).Complete() return intf From eef71f9ff4a89baf89444d72b198d61f9dac5a75 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 29 Oct 2023 10:02:50 +0800 Subject: [PATCH 55/64] toStructType: fix fld.pos --- cl/compile.go | 2 +- cl/func_type_and_var.go | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 145b09ebb..c7e73b76a 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -836,7 +836,7 @@ retry: typ = t.X goto retry } - return nil + panic("TODO: parseTypeEmbedName unexpected") } func preloadFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, gopFile, genFnBody bool) { diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go index d964c3bac..ef4d1bbae 100644 --- a/cl/func_type_and_var.go +++ b/cl/func_type_and_var.go @@ -320,13 +320,12 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { if t, ok := typ.(*types.Named); ok { // #1196: embedded type should ensure loaded ctx.loadNamed(ctx.pkg, t) } - fld := types.NewField(field.Type.Pos(), pkg, name, typ, true) + ident := parseTypeEmbedName(field.Type) + fld := types.NewField(ident.NamePos, pkg, name, typ, true) fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) if rec != nil { - if ident := parseTypeEmbedName(field.Type); ident != nil { - rec.Def(ident, fld) - } + rec.Def(ident, fld) } continue } @@ -334,7 +333,7 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct { if chk.chkRedecl(ctx, name.Name, name.NamePos) { continue } - fld := types.NewField(name.Pos(), pkg, name.Name, typ, false) + fld := types.NewField(name.NamePos, pkg, name.Name, typ, false) fields = append(fields, fld) tags = append(tags, toFieldTag(field.Tag)) if rec != nil { From b98468720a4557cd0e36fba63653380994bcce0b Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 29 Oct 2023 16:01:48 +0800 Subject: [PATCH 56/64] typesutil.Check: support Go/Go+ mixed project --- x/types/load.go | 58 ------------------------- x/typesutil/check.go | 41 ++++++++++++++--- x/typesutil/internal/typesutil/types.go | 42 ++++++++++++++++++ 3 files changed, 78 insertions(+), 63 deletions(-) delete mode 100644 x/types/load.go create mode 100644 x/typesutil/internal/typesutil/types.go diff --git a/x/types/load.go b/x/types/load.go deleted file mode 100644 index b62c95409..000000000 --- a/x/types/load.go +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// This package is experimental. Don't use it in production. -package types - -import ( - "go/token" - "go/types" - "strings" - - goast "go/ast" - - "github.com/goplus/gop/ast" - "github.com/goplus/gop/ast/togo" -) - -// A Config specifies the configuration for type checking. -// The zero value for Config is a ready-to-use default configuration. -type Config = types.Config - -// A Package describes a Go/Go+ package. -type Package = types.Package - -// Load loads a package and returns the resulting package object and -// the first error if any. -// -// The package is marked as complete if no errors occurred, otherwise it is -// incomplete. See Config.Error for controlling behavior in the presence of -// errors. -func Load(fset *token.FileSet, in *ast.Package, conf *Config) (pkg *Package, err error) { - n := len(in.Files) + len(in.GoFiles) - files := make([]*goast.File, 0, n) - for filename, f := range in.Files { - if !strings.HasSuffix(filename, "_test.gop") { - files = append(files, togo.ASTFile(f, 0)) - } - } - for filename, f := range in.GoFiles { - if !strings.HasSuffix(filename, "_test.go") { - files = append(files, f) - } - } - return conf.Check(in.Name, fset, files, nil) -} diff --git a/x/typesutil/check.go b/x/typesutil/check.go index 8febfaf8a..2167c8907 100644 --- a/x/typesutil/check.go +++ b/x/typesutil/check.go @@ -25,6 +25,7 @@ import ( "github.com/goplus/gop/ast" "github.com/goplus/gop/cl" "github.com/goplus/gop/token" + "github.com/goplus/gop/x/typesutil/internal/typesutil" "github.com/qiniu/x/log" ) @@ -98,7 +99,7 @@ func NewChecker(conf *types.Config, opts *Config, goInfo *types.Info, gopInfo *I } // Files checks the provided files as part of the checker's package. -func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { +func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error) { opts := p.opts pkgTypes := opts.Types fset := opts.Fset @@ -107,6 +108,7 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo) return checker.Files(goFiles) } + files := make([]*goast.File, 0, len(goFiles)) gofs := make(map[string]*goast.File) gopfs := make(map[string]*ast.File) for _, goFile := range goFiles { @@ -117,6 +119,7 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { continue } gofs[file] = goFile + files = append(files, goFile) } for _, gopFile := range gopFiles { f := fset.File(gopFile.Pos()) @@ -130,7 +133,7 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { Files: gopfs, GoFiles: gofs, } - _, err := cl.NewPackage(pkgTypes.Path(), pkg, &cl.Config{ + _, err = cl.NewPackage(pkgTypes.Path(), pkg, &cl.Config{ Types: pkgTypes, Fset: fset, WorkingDir: opts.WorkingDir, @@ -143,11 +146,39 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) error { NoAutoGenMain: true, NoSkipConstant: true, }) - if debugPrintErr { - if err != nil { + if err != nil { + if debugPrintErr { log.Println("typesutil.Check err:", err) log.SingleStack() } + return } - return err + if len(files) > 0 { + scope := pkgTypes.Scope() + // remove all objects defined by files + for _, f := range files { + for _, decl := range f.Decls { + switch v := decl.(type) { + case *goast.GenDecl: + for _, spec := range v.Specs { + switch v := spec.(type) { + case *goast.ValueSpec: + for _, name := range v.Names { + typesutil.ScopeDelete(scope, name.Name) + } + case *goast.TypeSpec: + typesutil.ScopeDelete(scope, v.Name.Name) + } + } + case *goast.FuncDecl: + if v.Recv == nil { + typesutil.ScopeDelete(scope, v.Name.Name) + } + } + } + } + checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo) + err = checker.Files(files) + } + return } diff --git a/x/typesutil/internal/typesutil/types.go b/x/typesutil/internal/typesutil/types.go new file mode 100644 index 000000000..e10ea76f6 --- /dev/null +++ b/x/typesutil/internal/typesutil/types.go @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package typesutil + +import ( + "go/token" + "go/types" + "unsafe" +) + +// A Scope maintains a set of objects and links to its containing +// (parent) and contained (children) scopes. Objects may be inserted +// and looked up by name. The zero value for Scope is a ready-to-use +// empty scope. +type Scope struct { + parent *Scope + children []*Scope + number int // parent.children[number-1] is this scope; 0 if there is no parent + elems map[string]types.Object // lazily allocated + pos, end token.Pos // scope extent; may be invalid + comment string // for debugging only + isFunc bool // set if this is a function scope (internal use only) +} + +// ScopeDelete deletes an object from specified scope by its name. +func ScopeDelete(s *types.Scope, name string) { + delete((*Scope)(unsafe.Pointer(s)).elems, name) +} From 33c2b21c912a6240c526cc42929f09771eb26124 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 29 Oct 2023 16:08:06 +0800 Subject: [PATCH 57/64] rm gopdecl --- cmd/gopdecl/gopdecl.go | 137 ----------------------------------------- 1 file changed, 137 deletions(-) delete mode 100644 cmd/gopdecl/gopdecl.go diff --git a/cmd/gopdecl/gopdecl.go b/cmd/gopdecl/gopdecl.go deleted file mode 100644 index 7a82918c6..000000000 --- a/cmd/gopdecl/gopdecl.go +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package main - -import ( - "flag" - "fmt" - "go/token" - "log" - "os" - "path/filepath" - "strings" - "unicode" - - goast "go/ast" - goparser "go/parser" - - "github.com/goplus/gop/ast" - "github.com/goplus/gop/parser" - "github.com/goplus/gop/x/types" - "github.com/goplus/gox/packages" -) - -var ( - verboseFlag = flag.Bool("v", false, "print verbose information") - internal = flag.Bool("i", false, "print internal declarations") -) - -func usage() { - fmt.Fprintf(os.Stderr, "Usage: gopdecl [-i] [source.gop ...]\n") - flag.PrintDefaults() -} - -func isDir(name string) bool { - if fi, err := os.Lstat(name); err == nil { - return fi.IsDir() - } - return false -} - -func isPublic(name string) bool { - for _, c := range name { - return unicode.IsUpper(c) - } - return false -} - -func main() { - flag.Parse() - if flag.NArg() < 1 { - usage() - return - } - verbose := *verboseFlag - if verbose { - log.Println("==> Parsing ...") - } - - var fset = token.NewFileSet() - var in *ast.Package - if infile := flag.Arg(0); isDir(infile) { - pkgs, first := parser.ParseDir(fset, infile, nil, 0) - check(first) - for name, pkg := range pkgs { - if !strings.HasSuffix(name, "_test") { - in = pkg - break - } - } - } else { - in = &ast.Package{ - Files: make(map[string]*ast.File), - GoFiles: make(map[string]*goast.File), - } - for i, n := 0, flag.NArg(); i < n; i++ { - infile = flag.Arg(i) - switch filepath.Ext(infile) { - case ".gop": - f, err := parser.ParseFile(fset, infile, nil, 0) - check(err) - in.Files[infile] = f - case ".go": - f, err := goparser.ParseFile(fset, infile, nil, 0) - check(err) - in.GoFiles[infile] = f - default: - log.Panicln("Unknown support file:", infile) - } - } - } - - if verbose { - log.Println("==> Loading ...") - } - conf := &types.Config{ - Importer: packages.NewImporter(fset), - IgnoreFuncBodies: true, - Error: func(err error) { - log.Println(err) - }, - DisableUnusedImportCheck: true, - } - pkg, err := types.Load(fset, in, conf) - check(err) - - if verbose { - log.Println("==> Printing ...") - } - scope := pkg.Scope() - names := scope.Names() - for _, name := range names { - if *internal || isPublic(name) { - fmt.Println(scope.Lookup(name)) - } - } -} - -func check(err error) { - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} From 17741077a08df35ad825e2b8f2ad71908f4475dd Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 30 Oct 2023 09:32:29 +0800 Subject: [PATCH 58/64] use gox.ObjectDocs --- cl/compile.go | 9 +++++---- cl/outline/cl/compile.go | 4 ++-- cl/outline/outline.go | 39 +++++++++++++++++++++------------------ cmd/internal/doc/doc.go | 7 ++++--- x/typesutil/gopinfo.go | 4 ---- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index c7e73b76a..f74e41ee0 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -1026,6 +1026,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { log.Printf("==> Load method %v.%s\n", recv.Type(), name) } } + pkg := ctx.pkg if d.Operator { if recv != nil { // binary op if v, ok := binaryGopNames[name]; ok { @@ -1034,7 +1035,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { } else { // unary op if v, ok := unaryGopNames[name]; ok { name = v - at := ctx.pkg.Types + at := pkg.Types arg1 := d.Type.Params.List[0] typ := toType(ctx, arg1.Type) recv = types.NewParam(arg1.Pos(), at, arg1.Names[0].Name, typ) @@ -1043,7 +1044,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { } } sig := toFuncType(ctx, d.Type, recv, d) - fn, err := ctx.pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos { + fn, err := pkg.NewFuncWith(d.Name.Pos(), name, sig, func() token.Pos { return d.Recv.List[0].Type.Pos() }) if err != nil { @@ -1051,10 +1052,10 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { return } if d.Doc != nil { - fn.SetComments(d.Doc) + fn.SetComments(pkg, d.Doc) } if rec := ctx.recorder(); rec != nil { - rec.Def(d.Name, &fn.Func) + rec.Def(d.Name, fn.Func) } if genBody { if body := d.Body; body != nil { diff --git a/cl/outline/cl/compile.go b/cl/outline/cl/compile.go index 51423513d..6fd2a2ce9 100644 --- a/cl/outline/cl/compile.go +++ b/cl/outline/cl/compile.go @@ -660,7 +660,7 @@ func preloadFile(p *gox.Package, ctx *blockCtx, file string, f *ast.File, gopFil if debugLoad { log.Println("==> Load > NewType", name) } - decl := tdecl.NewType(name, pos).SetComments(t.Doc) + decl := tdecl.NewType(name, pos).SetComments(p, t.Doc) fnInitType := getInitType(ctx, decl, t, gopFile) parent.insertObject(name, pos, lazyInitType, fnInitType) } @@ -758,7 +758,7 @@ func preloadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) return } if d.Doc != nil { - fn.SetComments(d.Doc) + fn.SetComments(ctx.pkg, d.Doc) } if genBody { if body := d.Body; body != nil { diff --git a/cl/outline/outline.go b/cl/outline/outline.go index 9a6535f85..3d7e438ee 100644 --- a/cl/outline/outline.go +++ b/cl/outline/outline.go @@ -55,7 +55,8 @@ type Config struct { } type Package struct { - pkg *gox.Package + pkg *types.Package + docs gox.ObjectDocs } // NewPackage creates a Go/Go+ outline package. @@ -75,11 +76,11 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (_ Package, err if err != nil { return } - return Package{ret}, nil + return Package{ret.Types, ret.Docs}, nil } func (p Package) Pkg() *types.Package { - return p.pkg.Types + return p.pkg } func (p Package) Valid() bool { @@ -94,7 +95,7 @@ type All struct { Funcs []Func Types []*TypeName - pkg *types.Package + Package named map[*types.TypeName]*TypeName } @@ -225,8 +226,8 @@ func (p *All) lookupNamed(pkg *types.Package, name string) (_ *TypeName, ok bool func (p Package) Outline(withUnexported ...bool) (ret *All) { pkg := p.Pkg() ret = &All{ - pkg: pkg, - named: make(map[*types.TypeName]*TypeName), + Package: p, + named: make(map[*types.TypeName]*TypeName), } all := (withUnexported != nil && withUnexported[0]) aliasr := &typeutil.Map{} @@ -248,25 +249,25 @@ func (p Package) Outline(withUnexported ...bool) (ret *All) { continue } switch v := o.(type) { - case *gox.Func: + case *types.Func: sig := v.Type().(*types.Signature) if !all { ret.checkUsedSig(sig) } if name, ok := checkGoptFunc(o.Name()); ok { if named, ok := ret.lookupNamed(pkg, name); ok { - named.GoptFuncs = append(named.GoptFuncs, Func{v}) + named.GoptFuncs = append(named.GoptFuncs, Func{v, p.docs}) continue } } kind, named := ret.sigKind(aliasr, sig) switch kind { case sigNormal: - ret.Funcs = append(ret.Funcs, Func{v}) + ret.Funcs = append(ret.Funcs, Func{v, p.docs}) case sigCreator: - named.Creators = append(named.Creators, Func{v}) + named.Creators = append(named.Creators, Func{v, p.docs}) case sigHelper: - named.Helpers = append(named.Helpers, Func{v}) + named.Helpers = append(named.Helpers, Func{v, p.docs}) } case *types.Const: if name := v.Name(); strings.HasPrefix(name, "Gop") { @@ -364,15 +365,16 @@ func (p Var) Doc() string { } type Func struct { - *gox.Func + *types.Func + docs gox.ObjectDocs } func (p Func) Obj() types.Object { - return &p.Func.Func + return p.Func } func (p Func) Doc() string { - return p.Comments().Text() + return p.docs[p.Func].Text() } func CheckOverload(obj types.Object) (name string, fn *types.Func, ok bool) { @@ -513,10 +515,10 @@ type Type struct { types.Type } -func (p Type) CheckNamed(pkg *types.Package) (_ Named, ok bool) { +func (p Type) CheckNamed(pkg Package) (_ Named, ok bool) { ret, ok := p.Type.(*types.Named) - if ok && ret.Obj().Pkg() == pkg { - return Named{ret}, true + if ok && ret.Obj().Pkg() == pkg.pkg { + return Named{ret, pkg.docs}, true } return } @@ -525,6 +527,7 @@ func (p Type) CheckNamed(pkg *types.Package) (_ Named, ok bool) { type Named struct { *types.Named + docs gox.ObjectDocs } func (p Named) Methods() []Func { @@ -532,7 +535,7 @@ func (p Named) Methods() []Func { ret := make([]Func, n) for i := 0; i < n; i++ { fn := p.Method(i) - ret[i] = Func{gox.MethodFrom(fn)} + ret[i] = Func{fn, p.docs} } return ret } diff --git a/cmd/internal/doc/doc.go b/cmd/internal/doc/doc.go index 84b4900f8..82ca12cf7 100644 --- a/cmd/internal/doc/doc.go +++ b/cmd/internal/doc/doc.go @@ -100,7 +100,7 @@ func outlinePkg(proj gopprojs.Proj, conf *gop.Config) { } else if err != nil { fmt.Fprintln(os.Stderr, err) } else { - outlineDoc(out.Pkg(), out.Outline(*unexp), *unexp, *withDoc) + outlineDoc(out.Outline(*unexp), *unexp, *withDoc) } } @@ -109,7 +109,8 @@ const ( ln = "\n" ) -func outlineDoc(pkg *types.Package, out *outline.All, all, withDoc bool) { +func outlineDoc(out *outline.All, all, withDoc bool) { + pkg := out.Pkg() fmt.Printf("package %s // import %s\n\n", pkg.Name(), strconv.Quote(pkg.Path())) if withDoc && len(out.Consts) > 0 { fmt.Print("CONSTANTS\n\n") @@ -149,7 +150,7 @@ func outlineDoc(pkg *types.Package, out *outline.All, all, withDoc bool) { printFuncsForType(pkg, t.Helpers, withDoc) if !typName.IsAlias() { typ := t.Type() - if named, ok := typ.CheckNamed(pkg); ok { + if named, ok := typ.CheckNamed(out.Package); ok { for _, fn := range named.Methods() { if o := fn.Obj(); all || o.Exported() { if withDoc { diff --git a/x/typesutil/gopinfo.go b/x/typesutil/gopinfo.go index cf6ed2c45..e95f8631c 100644 --- a/x/typesutil/gopinfo.go +++ b/x/typesutil/gopinfo.go @@ -20,7 +20,6 @@ import ( "go/types" "github.com/goplus/gop/ast" - "github.com/goplus/gox" "github.com/qiniu/x/log" ) @@ -227,9 +226,6 @@ func (info gopRecorder) Def(id *ast.Ident, obj types.Object) { // // Invariant: Uses[id].Pos() != id.Pos() func (info gopRecorder) Use(id *ast.Ident, obj types.Object) { - if f, ok := obj.(*gox.Func); ok { - obj = &f.Func - } if debugVerbose { log.Println("==> Use:", id, obj) } From 51cce14e4f6b4c6bb3b6815323b102067ae7ebc7 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 30 Oct 2023 15:05:34 +0800 Subject: [PATCH 59/64] rec.Scope fileScope; gox#298: use gox.ObjectDocs --- cl/compile.go | 10 +++++++++- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index f74e41ee0..f1ff311db 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -402,6 +402,7 @@ type blockCtx struct { c2goBase string // default is `github.com/goplus/` targetDir string classRecv *ast.FieldList // available when gmxSettings != nil + fileScope *types.Scope // only valid when isGopFile rec Recorder fileLine bool relativePath bool @@ -570,11 +571,15 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package, } for fpath, f := range files { fileLine := !conf.NoFileLine + fileScope := types.NewScope(p.Types.Scope(), f.Pos(), f.End(), fpath) ctx := &blockCtx{ - pkg: p, pkgCtx: ctx, cb: p.CB(), fset: p.Fset, targetDir: targetDir, + pkg: p, pkgCtx: ctx, cb: p.CB(), fset: p.Fset, targetDir: targetDir, fileScope: fileScope, fileLine: fileLine, relativePath: conf.RelativePath, isClass: f.IsClass, rec: conf.Recorder, c2goBase: c2goBase(conf.C2goBase), imports: make(map[string]pkgImp), isGopFile: true, } + if rec := ctx.rec; rec != nil { + rec.Scope(f, fileScope) + } preloadGopFile(p, ctx, fpath, f, conf) } @@ -1056,6 +1061,9 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) { } if rec := ctx.recorder(); rec != nil { rec.Def(d.Name, fn.Func) + if recv == nil { + ctx.fileScope.Insert(fn.Func) + } } if genBody { if body := d.Body; body != nil { diff --git a/go.mod b/go.mod index 9c910ffe1..4bea0508f 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.20231028071646-bb6d796d66cf + github.com/goplus/gox v1.12.2-0.20231030070332-723a6b4b6c99 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 2489e2909..585d70cbc 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.20231028071646-bb6d796d66cf h1:67Lz2V9Nj6pZz+u4d9uq5rCfw2t/zE34Qo6AF5dJN3c= -github.com/goplus/gox v1.12.2-0.20231028071646-bb6d796d66cf/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ= +github.com/goplus/gox v1.12.2-0.20231030070332-723a6b4b6c99 h1:2lqPMMQM+F4Cpp/LSkoChGb+nQmpypRzzpNTmXDr0Fc= +github.com/goplus/gox v1.12.2-0.20231030070332-723a6b4b6c99/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= From eec1130b380a1d49f2178e1854c4339c2e15f103 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 30 Oct 2023 20:27:58 +0800 Subject: [PATCH 60/64] gop: fix restore mod --- build_install_run.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/build_install_run.go b/build_install_run.go index 688d2a848..9972ee651 100644 --- a/build_install_run.go +++ b/build_install_run.go @@ -86,8 +86,8 @@ func BuildPkgPath(workDir, pkgPath string, conf *Config, build *gocmd.BuildConfi if err != nil { return errors.NewWith(err, `GenGoPkgPath(workDir, pkgPath, conf, false)`, -2, "gop.GenGoPkgPath", workDir, pkgPath, conf, false) } - old := chdirAndMod(localDir) - defer restoreDirAndMod(old) + old, mod := chdirAndMod(localDir) + defer restoreDirAndMod(old, mod) return gocmd.Build(cwdParam(recursively), build) } @@ -99,13 +99,18 @@ func BuildFiles(files []string, conf *Config, build *gocmd.BuildConfig) (err err return gocmd.BuildFiles(files, build) } -func chdirAndMod(dir string) string { +func chdirAndMod(dir string) (old string, mod os.FileMode) { + mod = 0755 + if info, err := os.Stat(dir); err == nil { + mod = info.Mode().Perm() + } os.Chmod(dir, 0777) - return chdir(dir) + old = chdir(dir) + return } -func restoreDirAndMod(old string) { - os.Chmod(".", 0555) +func restoreDirAndMod(old string, mod os.FileMode) { + os.Chmod(".", mod) os.Chdir(old) } @@ -158,8 +163,8 @@ func TestPkgPath(workDir, pkgPath string, conf *Config, test *gocmd.TestConfig) if err != nil { return errors.NewWith(err, `GenGoPkgPath(workDir, pkgPath, conf, false)`, -2, "gop.GenGoPkgPath", workDir, pkgPath, conf, false) } - old := chdirAndMod(localDir) - defer restoreDirAndMod(old) + old, mod := chdirAndMod(localDir) + defer restoreDirAndMod(old, mod) return gocmd.Test(cwdParam(recursively), test) } From 07b7dec3b3f56456df7f994e4d20c1f170bfdec4 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 31 Oct 2023 12:16:09 +0800 Subject: [PATCH 61/64] typesutil: avoid two instances for same Go object --- x/typesutil/check.go | 25 +++++++++++++++++++++---- x/typesutil/internal/typesutil/types.go | 9 +++++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/x/typesutil/check.go b/x/typesutil/check.go index 2167c8907..b5be474a5 100644 --- a/x/typesutil/check.go +++ b/x/typesutil/check.go @@ -155,7 +155,8 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error) } if len(files) > 0 { scope := pkgTypes.Scope() - // remove all objects defined by files + objMap := make(map[types.Object]types.Object) + // remove all objects defined in Go files for _, f := range files { for _, decl := range f.Decls { switch v := decl.(type) { @@ -164,21 +165,37 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error) switch v := spec.(type) { case *goast.ValueSpec: for _, name := range v.Names { - typesutil.ScopeDelete(scope, name.Name) + scopeDelete(objMap, scope, name.Name) } case *goast.TypeSpec: - typesutil.ScopeDelete(scope, v.Name.Name) + scopeDelete(objMap, scope, v.Name.Name) } } case *goast.FuncDecl: if v.Recv == nil { - typesutil.ScopeDelete(scope, v.Name.Name) + scopeDelete(objMap, scope, v.Name.Name) } } } } checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo) err = checker.Files(files) + for o := range objMap { + objMap[o] = scope.Lookup(o.Name()) + } + // correct Go+ types info to avoid there are two instances for same Go object: + uses := p.gopInfo.Uses + for id, old := range uses { + if new, ok := objMap[old]; ok { + uses[id] = new + } + } } return } + +func scopeDelete(objMap map[types.Object]types.Object, scope *types.Scope, name string) { + if o := typesutil.ScopeDelete(scope, name); o != nil { + objMap[o] = nil + } +} diff --git a/x/typesutil/internal/typesutil/types.go b/x/typesutil/internal/typesutil/types.go index e10ea76f6..2835c3713 100644 --- a/x/typesutil/internal/typesutil/types.go +++ b/x/typesutil/internal/typesutil/types.go @@ -37,6 +37,11 @@ type Scope struct { } // ScopeDelete deletes an object from specified scope by its name. -func ScopeDelete(s *types.Scope, name string) { - delete((*Scope)(unsafe.Pointer(s)).elems, name) +func ScopeDelete(s *types.Scope, name string) types.Object { + elems := (*Scope)(unsafe.Pointer(s)).elems + if o, ok := elems[name]; ok { + delete(elems, name) + return o + } + return nil } From 362ff94e6d1431a9d1d653352719f65db63bae1f Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 31 Oct 2023 12:18:46 +0800 Subject: [PATCH 62/64] objMap[old] maybe nil --- x/typesutil/check.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/typesutil/check.go b/x/typesutil/check.go index b5be474a5..157e77408 100644 --- a/x/typesutil/check.go +++ b/x/typesutil/check.go @@ -186,7 +186,7 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error) // correct Go+ types info to avoid there are two instances for same Go object: uses := p.gopInfo.Uses for id, old := range uses { - if new, ok := objMap[old]; ok { + if new := objMap[old]; new != nil { uses[id] = new } } From 39e344c0a23b64436f9eb3632add0bd75d45ee63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 04:14:40 +0000 Subject: [PATCH 63/64] build(deps): bump github.com/goplus/mod Bumps [github.com/goplus/mod](https://github.com/goplus/mod) from 0.11.8-0.20231019172744-da5848421263 to 0.11.8. - [Release notes](https://github.com/goplus/mod/releases) - [Commits](https://github.com/goplus/mod/commits/v0.11.8) --- updated-dependencies: - dependency-name: github.com/goplus/mod dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4bea0508f..d3fb9e66e 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 github.com/goplus/c2go v0.7.16 github.com/goplus/gox v1.12.2-0.20231030070332-723a6b4b6c99 - github.com/goplus/mod v0.11.8-0.20231019172744-da5848421263 + 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 585d70cbc..d6aafba4f 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/goplus/gox v1.12.1/go.mod h1:wymoQJ7ydd42cTlaXb4wNbvn4LlKjR+j8PZehI7v github.com/goplus/gox v1.12.2-0.20231030070332-723a6b4b6c99 h1:2lqPMMQM+F4Cpp/LSkoChGb+nQmpypRzzpNTmXDr0Fc= github.com/goplus/gox v1.12.2-0.20231030070332-723a6b4b6c99/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= +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= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= From c5f4b15a79919d30afc346ca2f640b82932c7f52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 04:21:32 +0000 Subject: [PATCH 64/64] build(deps): bump github.com/goplus/gox Bumps [github.com/goplus/gox](https://github.com/goplus/gox) from 1.12.2-0.20231030070332-723a6b4b6c99 to 1.12.8. - [Release notes](https://github.com/goplus/gox/releases) - [Commits](https://github.com/goplus/gox/commits/v1.12.8) --- updated-dependencies: - dependency-name: github.com/goplus/gox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d3fb9e66e..73c1f41ae 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.20231030070332-723a6b4b6c99 + github.com/goplus/gox v1.12.8 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 d6aafba4f..dc1bcc5d3 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.20231030070332-723a6b4b6c99 h1:2lqPMMQM+F4Cpp/LSkoChGb+nQmpypRzzpNTmXDr0Fc= -github.com/goplus/gox v1.12.2-0.20231030070332-723a6b4b6c99/go.mod h1:Ek1YIy3wRaZ1i0DD2XG29i3r5AFdhcOradK0/GGs1YQ= +github.com/goplus/gox v1.12.8 h1:xXpsGbNIIDmykOQwI/kDcoA3cOX5ISvLPlU5RiPtyZY= +github.com/goplus/gox v1.12.8/go.mod h1:MOJnwqA8/rSUkn0vsayHFK7TD/3XQrdexMTqdzR70X0= github.com/goplus/mod v0.11.5/go.mod h1:NDC5E+XOT8vcJCMjqKhLDJHTHX7lyVN4Vbfi2U7dBhs= github.com/goplus/mod v0.11.8 h1:90Kbg+MJhrdsonNGXYx3HUcW4IbBlRHYpIMssJaMMxM= github.com/goplus/mod v0.11.8/go.mod h1:yl2QncBKTdXk+8UaNsdo4u2zSpGEJYA5JKjgD3K2h00=