cl: process llgo:skip on const, type declaration, deprecate llgo:skip on import

This commit is contained in:
Li Jie
2025-01-17 10:55:41 +08:00
parent d5d2d6826f
commit 623b5a511a
9 changed files with 162 additions and 15 deletions

View File

@@ -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)

View File

@@ -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
}
}
}
}

View File

@@ -16,7 +16,9 @@
package subtle
// llgo:skip XORBytes
import (
_ "unsafe"
)
// llgo:skip XORBytes
type _xor struct{}

View File

@@ -16,7 +16,9 @@
package fmt
// llgo:skipall
import (
_ "unsafe"
)
// // llgo:skipall
type _fmt struct{}

View File

@@ -16,7 +16,9 @@
package reflectlite
// llgo:skipall
import (
_ "unsafe"
)
// llgo:skipall
type _reflectlite struct{}

View File

@@ -16,7 +16,9 @@
package unix
// llgo:skipall
import (
_ "unsafe"
)
// llgo:skipall
type _unix struct{}

View File

@@ -16,7 +16,9 @@
package reflect
// llgo:skipall
import (
_ "unsafe"
)
// llgo:skipall
type _reflect struct{}

View File

@@ -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

View File

@@ -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.