From 623b5a511aebd7ed200ebaf31287984ab3fcdf10 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Fri, 17 Jan 2025 10:55:41 +0800 Subject: [PATCH] cl: process llgo:skip on const, type declaration, deprecate llgo:skip on import --- compiler/cl/builtin_test.go | 101 ++++++++++++++++++ compiler/cl/import.go | 48 +++++++-- runtime/internal/lib/crypto/subtle/xor.go | 4 +- runtime/internal/lib/fmt/fmt.go | 4 +- .../lib/internal/reflectlite/reflectlite.go | 4 +- .../lib/internal/syscall/unix/unix.go | 4 +- runtime/internal/lib/reflect/reflect.go | 4 +- runtime/internal/lib/syscall/syscall.go | 4 +- runtime/internal/lib/time/time.go | 4 +- 9 files changed, 162 insertions(+), 15 deletions(-) diff --git a/compiler/cl/builtin_test.go b/compiler/cl/builtin_test.go index d52ed6d0..43660fb4 100644 --- a/compiler/cl/builtin_test.go +++ b/compiler/cl/builtin_test.go @@ -20,6 +20,7 @@ import ( "go/ast" "go/constant" "go/types" + "strings" "testing" "unsafe" @@ -46,6 +47,106 @@ func TestCollectSkipNames(t *testing.T) { ctx.collectSkipNames("//llgo:skip abs") } +func TestCollectSkipNamesByDoc(t *testing.T) { + ftest := func(comments string, wantSkips []string, wantAll bool) { + t.Helper() + ctx := &context{skips: make(map[string]none)} + doc := parseComments(t, comments) + ctx.collectSkipNamesByDoc(doc) + + // Check skipall + if wantAll != ctx.skipall { + t.Errorf("skipall = %v, want %v", ctx.skipall, wantAll) + } + + // Check collected symbols + var gotSkips []string + for sym := range ctx.skips { + gotSkips = append(gotSkips, sym) + } + if len(gotSkips) != len(wantSkips) { + t.Errorf("got %d skips %v, want %d skips %v", len(gotSkips), gotSkips, len(wantSkips), wantSkips) + return + } + // Check each expected symbol exists + for _, want := range wantSkips { + if _, ok := ctx.skips[want]; !ok { + t.Errorf("missing expected symbol %q", want) + } + } + } + + // Multiple llgo:skip mixed - stops at first non-directive + ftest(` + //llgo:skip sym1 sym2 + //llgo:skip sym3 + //llgo:skipall + // normal comment + // llgo:skip sym4 + //llgo:skip sym5 + `, + []string{"sym4", "sym5"}, + false, + ) + + // llgo:skip and go: mixed - processes until non-directive + ftest(` + //llgo:skip sym1 + //llgo:skipall + //go:generate + // normal comment + //go:build linux + //llgo:skip sym2 + `, + []string{"sym2"}, + false, + ) + + // Only directives - processes all + ftest(` + // llgo:skip sym1 + //go:generate + // llgo:skip sym2 sym3 + // llgo:skipall + `, + []string{"sym1", "sym2", "sym3"}, + true, + ) + + // Starts with non-directive - stops immediately + ftest(` + //llgo:skip sym1 + // normal comment + //llgo:skip sym2 + //llgo:skipall + `, + []string{"sym2"}, + true, + ) + + // Only normal comments + ftest(` + // normal comment 1 + // normal comment 2 + `, + []string{}, + false, + ) +} + +func parseComments(t *testing.T, text string) *ast.CommentGroup { + t.Helper() + var comments []*ast.Comment + for _, line := range strings.Split(text, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + comments = append(comments, &ast.Comment{Text: line}) + } + return &ast.CommentGroup{List: comments} +} + func TestReplaceGoName(t *testing.T) { if ret := replaceGoName("foo", 0); ret != "foo" { t.Fatal("replaceGoName:", ret) diff --git a/compiler/cl/import.go b/compiler/cl/import.go index 3c40bb9e..179a0de1 100644 --- a/compiler/cl/import.go +++ b/compiler/cl/import.go @@ -190,11 +190,18 @@ func (p *context) initFiles(pkgPath string, files []*ast.File) { p.initLinknameByDoc(decl.Doc, pkgPath+"."+inPkgName, inPkgName, true) } } + case token.CONST: + fallthrough + case token.TYPE: + p.collectSkipNamesByDoc(decl.Doc) case token.IMPORT: if doc := decl.Doc; doc != nil { if n := len(doc.List); n > 0 { line := doc.List[n-1].Text - p.collectSkipNames(line) + if p.collectSkipNames(line) { + // Deprecate on import since conflict with cgo + fmt.Fprintf(os.Stderr, "DEPRECATED: llgo:skip on import is deprecated %v\n", line) + } } } } @@ -203,17 +210,42 @@ func (p *context) initFiles(pkgPath string, files []*ast.File) { } } +// Collect skip names and skip other annotations, such as go: and llgo: // llgo:skip symbol1 symbol2 ... // llgo:skipall -func (p *context) collectSkipNames(line string) { +func (p *context) collectSkipNames(line string) bool { const ( - skip = "//llgo:skip" - skip2 = "// llgo:skip" + llgo1 = "//llgo:" + llgo2 = "// llgo:" + go1 = "//go:" + skip = "skip" + skipAll = "skipall" ) - if strings.HasPrefix(line, skip2) { - p.collectSkip(line, len(skip2)) - } else if strings.HasPrefix(line, skip) { - p.collectSkip(line, len(skip)) + if strings.HasPrefix(line, go1) { + return true + } + var skipLine string + if strings.HasPrefix(line, llgo1) { + skipLine = line[len(llgo1):] + } else if strings.HasPrefix(line, llgo2) { + skipLine = line[len(llgo2):] + } else { + return false + } + if strings.HasPrefix(skipLine, skip) { + p.collectSkip(skipLine, len(skip)) + } + return true +} + +func (p *context) collectSkipNamesByDoc(doc *ast.CommentGroup) { + if doc != nil { + for n := len(doc.List) - 1; n >= 0; n-- { + line := doc.List[n].Text + if !p.collectSkipNames(line) { + break + } + } } } diff --git a/runtime/internal/lib/crypto/subtle/xor.go b/runtime/internal/lib/crypto/subtle/xor.go index 0fdeab90..7d03bbca 100644 --- a/runtime/internal/lib/crypto/subtle/xor.go +++ b/runtime/internal/lib/crypto/subtle/xor.go @@ -16,7 +16,9 @@ package subtle -// llgo:skip XORBytes import ( _ "unsafe" ) + +// llgo:skip XORBytes +type _xor struct{} diff --git a/runtime/internal/lib/fmt/fmt.go b/runtime/internal/lib/fmt/fmt.go index 46413808..6d97abca 100644 --- a/runtime/internal/lib/fmt/fmt.go +++ b/runtime/internal/lib/fmt/fmt.go @@ -16,7 +16,9 @@ package fmt -// llgo:skipall import ( _ "unsafe" ) + +// // llgo:skipall +type _fmt struct{} diff --git a/runtime/internal/lib/internal/reflectlite/reflectlite.go b/runtime/internal/lib/internal/reflectlite/reflectlite.go index 354ac4da..044d4848 100644 --- a/runtime/internal/lib/internal/reflectlite/reflectlite.go +++ b/runtime/internal/lib/internal/reflectlite/reflectlite.go @@ -16,7 +16,9 @@ package reflectlite -// llgo:skipall import ( _ "unsafe" ) + +// llgo:skipall +type _reflectlite struct{} diff --git a/runtime/internal/lib/internal/syscall/unix/unix.go b/runtime/internal/lib/internal/syscall/unix/unix.go index 8b0cffd8..1ee23aeb 100644 --- a/runtime/internal/lib/internal/syscall/unix/unix.go +++ b/runtime/internal/lib/internal/syscall/unix/unix.go @@ -16,7 +16,9 @@ package unix -// llgo:skipall import ( _ "unsafe" ) + +// llgo:skipall +type _unix struct{} diff --git a/runtime/internal/lib/reflect/reflect.go b/runtime/internal/lib/reflect/reflect.go index 1cbda820..103972a3 100644 --- a/runtime/internal/lib/reflect/reflect.go +++ b/runtime/internal/lib/reflect/reflect.go @@ -16,7 +16,9 @@ package reflect -// llgo:skipall import ( _ "unsafe" ) + +// llgo:skipall +type _reflect struct{} diff --git a/runtime/internal/lib/syscall/syscall.go b/runtime/internal/lib/syscall/syscall.go index f6645f17..c87cff44 100644 --- a/runtime/internal/lib/syscall/syscall.go +++ b/runtime/internal/lib/syscall/syscall.go @@ -16,7 +16,6 @@ package syscall -// llgo:skipall import ( "unsafe" @@ -25,6 +24,9 @@ import ( "github.com/goplus/llgo/runtime/internal/clite/syscall" ) +// llgo:skipall +type _syscall struct{} + type Timespec syscall.Timespec type Timeval syscall.Timeval diff --git a/runtime/internal/lib/time/time.go b/runtime/internal/lib/time/time.go index 7f6b3a59..d7db0d46 100644 --- a/runtime/internal/lib/time/time.go +++ b/runtime/internal/lib/time/time.go @@ -16,7 +16,6 @@ package time -// llgo:skipall import ( "unsafe" @@ -24,6 +23,9 @@ import ( "github.com/goplus/llgo/runtime/internal/clite/time" ) +// llgo:skipall +type _time struct{} + type Time struct { // wall and ext encode the wall time seconds, wall time nanoseconds, // and optional monotonic clock reading in nanoseconds.