compiler: add go test command
This commit is contained in:
5
_demo/runtest/bar/bar.go
Normal file
5
_demo/runtest/bar/bar.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package bar
|
||||||
|
|
||||||
|
func Bar() int {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
9
_demo/runtest/bar/bar_test.go
Normal file
9
_demo/runtest/bar/bar_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package bar
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestBar(t *testing.T) {
|
||||||
|
if Bar() != 2 {
|
||||||
|
t.Fatal("Bar() != 2")
|
||||||
|
}
|
||||||
|
}
|
||||||
5
_demo/runtest/foo/foo.go
Normal file
5
_demo/runtest/foo/foo.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func Foo() int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
9
_demo/runtest/foo/foo_test.go
Normal file
9
_demo/runtest/foo/foo_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestFoo(t *testing.T) {
|
||||||
|
if Foo() != 1 {
|
||||||
|
t.Fatal("Foo() != 1")
|
||||||
|
}
|
||||||
|
}
|
||||||
16
_demo/runtest/main.go
Normal file
16
_demo/runtest/main.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/_demo/runtest/bar"
|
||||||
|
"github.com/goplus/llgo/_demo/runtest/foo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Zoo() int {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("foo.Foo()", foo.Foo())
|
||||||
|
println("bar.Bar()", bar.Bar())
|
||||||
|
println("Zoo()", Zoo())
|
||||||
|
}
|
||||||
9
_demo/runtest/main_test.go
Normal file
9
_demo/runtest/main_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestZoo(t *testing.T) {
|
||||||
|
if Zoo() != 3 {
|
||||||
|
t.Fatal("Zoo() != 3")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -148,7 +148,7 @@ func doMain() error {
|
|||||||
|
|
||||||
for i, p := range pkgs {
|
for i, p := range pkgs {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return fmt.Errorf("cannot build SSA for package %s", initial[i])
|
return fmt.Errorf("cannot build SSA for package %s", initial[i].ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
33
compiler/cmd/internal/test/test.go
Normal file
33
compiler/cmd/internal/test/test.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/compiler/cmd/internal/base"
|
||||||
|
"github.com/goplus/llgo/compiler/internal/build"
|
||||||
|
)
|
||||||
|
|
||||||
|
// llgo test
|
||||||
|
var Cmd = &base.Command{
|
||||||
|
UsageLine: "llgo test [build flags] package [arguments...]",
|
||||||
|
Short: "Compile and run Go test",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Cmd.Run = runCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCmd(cmd *base.Command, args []string) {
|
||||||
|
runCmdEx(cmd, args, build.ModeRun)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCmdEx(_ *base.Command, args []string, mode build.Mode) {
|
||||||
|
conf := build.NewDefaultConf(mode)
|
||||||
|
conf.Mode = build.ModeTest
|
||||||
|
_, err := build.Do(args, conf)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ import (
|
|||||||
"github.com/goplus/llgo/compiler/cmd/internal/help"
|
"github.com/goplus/llgo/compiler/cmd/internal/help"
|
||||||
"github.com/goplus/llgo/compiler/cmd/internal/install"
|
"github.com/goplus/llgo/compiler/cmd/internal/install"
|
||||||
"github.com/goplus/llgo/compiler/cmd/internal/run"
|
"github.com/goplus/llgo/compiler/cmd/internal/run"
|
||||||
|
"github.com/goplus/llgo/compiler/cmd/internal/test"
|
||||||
"github.com/goplus/llgo/compiler/cmd/internal/version"
|
"github.com/goplus/llgo/compiler/cmd/internal/version"
|
||||||
"github.com/goplus/llgo/compiler/internal/mockable"
|
"github.com/goplus/llgo/compiler/internal/mockable"
|
||||||
)
|
)
|
||||||
@@ -47,6 +48,7 @@ func init() {
|
|||||||
get.Cmd,
|
get.Cmd,
|
||||||
run.Cmd,
|
run.Cmd,
|
||||||
run.CmpTestCmd,
|
run.CmpTestCmd,
|
||||||
|
test.Cmd,
|
||||||
clean.Cmd,
|
clean.Cmd,
|
||||||
version.Cmd,
|
version.Cmd,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module github.com/goplus/llgo/compiler
|
module github.com/goplus/llgo/compiler
|
||||||
|
|
||||||
go 1.22.0
|
go 1.22.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/goplus/gogen v1.16.6
|
github.com/goplus/gogen v1.16.6
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ const (
|
|||||||
ModeBuild Mode = iota
|
ModeBuild Mode = iota
|
||||||
ModeInstall
|
ModeInstall
|
||||||
ModeRun
|
ModeRun
|
||||||
|
ModeTest
|
||||||
ModeCmpTest
|
ModeCmpTest
|
||||||
ModeGen
|
ModeGen
|
||||||
)
|
)
|
||||||
@@ -130,6 +131,10 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
|||||||
Mode: loadSyntax | packages.NeedDeps | packages.NeedModule | packages.NeedExportFile,
|
Mode: loadSyntax | packages.NeedDeps | packages.NeedModule | packages.NeedExportFile,
|
||||||
BuildFlags: flags,
|
BuildFlags: flags,
|
||||||
Fset: token.NewFileSet(),
|
Fset: token.NewFileSet(),
|
||||||
|
Tests: conf.Mode == ModeTest,
|
||||||
|
}
|
||||||
|
if conf.Mode == ModeTest {
|
||||||
|
cfg.Mode |= packages.NeedForTest
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(overlayFiles) > 0 {
|
if len(overlayFiles) > 0 {
|
||||||
@@ -164,15 +169,14 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
|||||||
initial, err := packages.LoadEx(dedup, sizes, cfg, patterns...)
|
initial, err := packages.LoadEx(dedup, sizes, cfg, patterns...)
|
||||||
check(err)
|
check(err)
|
||||||
mode := conf.Mode
|
mode := conf.Mode
|
||||||
|
switch mode {
|
||||||
|
case ModeBuild:
|
||||||
if len(initial) == 1 && len(initial[0].CompiledGoFiles) > 0 {
|
if len(initial) == 1 && len(initial[0].CompiledGoFiles) > 0 {
|
||||||
if mode == ModeBuild {
|
|
||||||
mode = ModeInstall
|
mode = ModeInstall
|
||||||
}
|
}
|
||||||
} else if mode == ModeRun {
|
case ModeRun:
|
||||||
if len(initial) > 1 {
|
if len(initial) > 1 {
|
||||||
return nil, fmt.Errorf("cannot run multiple packages")
|
return nil, fmt.Errorf("cannot run multiple packages")
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("no Go files in matched packages")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +209,8 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
|||||||
os.Setenv("PATH", env.BinDir()+":"+os.Getenv("PATH")) // TODO(xsw): check windows
|
os.Setenv("PATH", env.BinDir()+":"+os.Getenv("PATH")) // TODO(xsw): check windows
|
||||||
|
|
||||||
ctx := &context{env, cfg, progSSA, prog, dedup, patches, make(map[string]none), initial, mode, 0}
|
ctx := &context{env, cfg, progSSA, prog, dedup, patches, make(map[string]none), initial, mode, 0}
|
||||||
pkgs := buildAllPkgs(ctx, initial, verbose)
|
pkgs, err := buildAllPkgs(ctx, initial, verbose)
|
||||||
|
check(err)
|
||||||
if mode == ModeGen {
|
if mode == ModeGen {
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
if pkg.Package == initial[0] {
|
if pkg.Package == initial[0] {
|
||||||
@@ -215,7 +220,8 @@ func Do(args []string, conf *Config) ([]Package, error) {
|
|||||||
return nil, fmt.Errorf("initial package not found")
|
return nil, fmt.Errorf("initial package not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
dpkg := buildAllPkgs(ctx, altPkgs[noRt:], verbose)
|
dpkg, err := buildAllPkgs(ctx, altPkgs[noRt:], verbose)
|
||||||
|
check(err)
|
||||||
var linkArgs []string
|
var linkArgs []string
|
||||||
for _, pkg := range dpkg {
|
for _, pkg := range dpkg {
|
||||||
linkArgs = append(linkArgs, pkg.LinkArgs...)
|
linkArgs = append(linkArgs, pkg.LinkArgs...)
|
||||||
@@ -266,7 +272,7 @@ type context struct {
|
|||||||
nLibdir int
|
nLibdir int
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs []*aPackage) {
|
func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs []*aPackage, err error) {
|
||||||
prog := ctx.prog
|
prog := ctx.prog
|
||||||
pkgs, errPkgs := allPkgs(ctx, initial, verbose)
|
pkgs, errPkgs := allPkgs(ctx, initial, verbose)
|
||||||
for _, errPkg := range errPkgs {
|
for _, errPkg := range errPkgs {
|
||||||
@@ -276,7 +282,7 @@ func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs
|
|||||||
fmt.Fprintln(os.Stderr, "cannot build SSA for package", errPkg)
|
fmt.Fprintln(os.Stderr, "cannot build SSA for package", errPkg)
|
||||||
}
|
}
|
||||||
if len(errPkgs) > 0 {
|
if len(errPkgs) > 0 {
|
||||||
mockable.Exit(1)
|
return nil, fmt.Errorf("cannot build SSA for packages")
|
||||||
}
|
}
|
||||||
built := ctx.built
|
built := ctx.built
|
||||||
for _, aPkg := range pkgs {
|
for _, aPkg := range pkgs {
|
||||||
@@ -862,6 +868,7 @@ var hasAltPkg = map[string]none{
|
|||||||
"crypto/sha512": {},
|
"crypto/sha512": {},
|
||||||
"crypto/subtle": {},
|
"crypto/subtle": {},
|
||||||
"fmt": {},
|
"fmt": {},
|
||||||
|
"go/parser": {},
|
||||||
"hash/crc32": {},
|
"hash/crc32": {},
|
||||||
"internal/abi": {},
|
"internal/abi": {},
|
||||||
"internal/bytealg": {},
|
"internal/bytealg": {},
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ const (
|
|||||||
NeedTypesSizes = packages.NeedTypesSizes
|
NeedTypesSizes = packages.NeedTypesSizes
|
||||||
NeedTypesInfo = packages.NeedTypesInfo
|
NeedTypesInfo = packages.NeedTypesInfo
|
||||||
|
|
||||||
|
NeedForTest = packages.NeedForTest
|
||||||
|
|
||||||
typecheckCgo = NeedModule - 1 // TODO(xsw): how to check
|
typecheckCgo = NeedModule - 1 // TODO(xsw): how to check
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -129,18 +131,18 @@ func (p Deduper) SetPkgPath(fn func(path, name string) string) {
|
|||||||
p.setpath = fn
|
p.setpath = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Deduper) Check(pkgPath string) *Cached {
|
func (p Deduper) Check(id string) *Cached {
|
||||||
if v, ok := p.cache.Load(pkgPath); ok {
|
if v, ok := p.cache.Load(id); ok {
|
||||||
return v.(*Cached)
|
return v.(*Cached)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Deduper) set(pkgPath string, cp *Cached) {
|
func (p Deduper) set(id string, cp *Cached) {
|
||||||
if DebugPackagesLoad {
|
if DebugPackagesLoad {
|
||||||
log.Println("==> Import", pkgPath)
|
log.Println("==> Import", id)
|
||||||
}
|
}
|
||||||
p.cache.Store(pkgPath, cp)
|
p.cache.Store(id, cp)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname defaultDriver golang.org/x/tools/go/packages.defaultDriver
|
//go:linkname defaultDriver golang.org/x/tools/go/packages.defaultDriver
|
||||||
@@ -176,7 +178,7 @@ func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if dedup != nil {
|
if dedup != nil {
|
||||||
if cp := dedup.Check(lpkg.PkgPath); cp != nil {
|
if cp := dedup.Check(lpkg.ID); cp != nil {
|
||||||
lpkg.Types = cp.Types
|
lpkg.Types = cp.Types
|
||||||
lpkg.Fset = ld.Fset
|
lpkg.Fset = ld.Fset
|
||||||
lpkg.TypesInfo = cp.TypesInfo
|
lpkg.TypesInfo = cp.TypesInfo
|
||||||
|
|||||||
13
runtime/internal/lib/go/parser/parser.go
Normal file
13
runtime/internal/lib/go/parser/parser.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package parser
|
||||||
|
|
||||||
|
import "go/ast"
|
||||||
|
|
||||||
|
func unparen(e ast.Expr) ast.Expr {
|
||||||
|
for {
|
||||||
|
paren, ok := e.(*ast.ParenExpr)
|
||||||
|
if !ok {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e = paren.X
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user