Skip to content

Commit

Permalink
Merge pull request #49 from xushiwei/class
Browse files Browse the repository at this point in the history
modfile: Import => ClassMods
  • Loading branch information
xushiwei committed Jan 31, 2024
2 parents 6475985 + 70b2361 commit e78cc38
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 345 deletions.
4 changes: 2 additions & 2 deletions gopmod/classfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ func (p *Module) ImportClasses(importClass ...func(c *Project)) (err error) {
for _, c := range opt.Projects {
p.importClass(c, impcls)
}
for _, r := range opt.Import {
if err = p.importMod(r.ClassfileMod, impcls); err != nil {
for _, classMod := range opt.ClassMods {
if err = p.importMod(classMod, impcls); err != nil {
return
}
}
Expand Down
54 changes: 0 additions & 54 deletions modfile/gop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,6 @@ func lookupClass(ext string) (c *Project, ok bool) {
return
}

func TestUpdateLine(t *testing.T) {
line := &Line{InBlock: true}
updateLine(line, "foo", "bar")
if len(line.Token) != 1 && line.Token[0] != "bar" {
t.Fatal("updateLine failed:", line.Token)
}
}

func TestGetWeight(t *testing.T) {
if getWeight(&modfile.LineBlock{Token: []string{"gop"}}) != directiveGop {
t.Fatal("getWeight require failed")
}
if getWeight(&modfile.LineBlock{Token: []string{"unknown"}}) != directiveLineBlock {
t.Fatal("getWeight unknown failed")
}
}

// -----------------------------------------------------------------------------

const gopmodSpx1 = `
Expand Down Expand Up @@ -265,34 +248,6 @@ func TestParse2(t *testing.T) {
}
}

const gopmodUserProj = `
gop 1.1
import github.com/goplus/spx
`

func TestParseUser(t *testing.T) {
const (
gopmod = gopmodUserProj
)
f, err := Parse("github.com/goplus/gop/gop.mod", []byte(gopmod), nil)
if err != nil || len(f.Import) != 1 {
t.Fatal("Parse:", f, err)
return
}
if f.Import[0].ClassfileMod != "github.com/goplus/spx" {
t.Fatal("Parse => Register:", f.Import)
}
f.AddImport("github.com/goplus/spx")
if len(f.Import) != 1 {
t.Fatal("AddRegister not exist?")
}
f.AddImport("github.com/xushiwei/foogop")
if len(f.Import) != 2 {
t.Fatal("AddRegister failed")
}
}

func TestParseErr(t *testing.T) {
doTestParseErr(t, `gop.mod:2: unknown directive: module`, `
module foo
Expand All @@ -309,15 +264,6 @@ gop 1.1 1.2
`)
doTestParseErr(t, `gop.mod:2: invalid gop version '1.x': must match format 1.23`, `
gop 1.x
`)
doTestParseErr(t, `gop.mod:2: import directive expects exactly one argument`, `
register 1 2 3
`)
doTestParseErr(t, `gop.mod:2: invalid quoted string: invalid syntax`, `
register "\?"
`)
doTestParseErr(t, `gop.mod:2: malformed module path "-": leading dash`, `
register -
`)
doTestParseErr(t, `gop.mod:2: usage: project [.projExt ProjClass] classFilePkgPath ...`, `
project
Expand Down
8 changes: 0 additions & 8 deletions modfile/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ type Line = modfile.Line
// "x"
// "y"
// )
//
type LineBlock = modfile.LineBlock

// An LParen represents the beginning of a parenthesized line block.
Expand All @@ -59,10 +58,3 @@ type LParen = modfile.LParen
// An RParen represents the end of a parenthesized line block.
// It is a place to store whole-line (before) comments.
type RParen = modfile.RParen

// ModulePath returns the module path from the gopmod file text.
// If it cannot find a module path, it returns an empty string.
// It is tolerant of unrelated problems in the gop.mod file.
func ModulePath(mod []byte) string {
return modfile.ModulePath(mod)
}
64 changes: 0 additions & 64 deletions modfile/read_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion modfile/regtest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ require (
if err != nil {
t.Fatal("LoadFromEx:", err)
}
if n := len(mod.Opt.Import); n != 2 {
if n := len(mod.Opt.ClassMods); n != 2 {
t.Fatal("len(mod.Opt.Import):", n)
}
}
147 changes: 21 additions & 126 deletions modfile/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ import (

"github.com/qiniu/x/errors"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
)

// A File is the parsed, interpreted form of a gop.mod file.
type File struct {
Gop *Gop
Projects []*Project
Import []*Import
Gop *Gop
Projects []*Project
ClassMods []string

Syntax *FileSyntax
}
Expand All @@ -49,14 +48,11 @@ func (p *File) proj() *Project { // current project
return p.Projects[n-1]
}

// A Module is the module statement.
type Module = modfile.Module

// A Gop is the gop statement.
type Gop = modfile.Go

// A Import is the import statement.
type Import struct {
// A Register is the //gop:class statement.
type Register struct {
ClassfileMod string // module path of classfile
Syntax *Line
}
Expand Down Expand Up @@ -90,6 +86,22 @@ type Class struct {
Syntax *Line
}

func New(gopmod, gopVer string) *File {
gop := &Line{
Token: []string{"gop", gopVer},
}
return &File{
Gop: &Gop{
Version: gopVer,
Syntax: gop,
},
Syntax: &FileSyntax{
Name: gopmod,
Stmt: []Expr{gop},
},
}
}

type VersionFixer = modfile.VersionFixer

// Parse parses and returns a gop.mod file.
Expand Down Expand Up @@ -176,25 +188,6 @@ func (f *File) parseVerb(errs *ErrorList, verb string, line *Line, args []string
}
f.Gop = &Gop{Syntax: line}
f.Gop.Version = args[0]
case "import", "register": // register => import
if len(args) != 1 {
errorf("import directive expects exactly one argument")
return
}
s, err := parseString(&args[0])
if err != nil {
errorf("invalid quoted string: %v", err)
return
}
err = module.CheckPath(s)
if err != nil {
wrapError(err)
return
}
f.Import = append(f.Import, &Import{
ClassfileMod: s,
Syntax: line,
})
case "project":
if len(args) < 1 {
errorf("usage: project [.projExt ProjClass] classFilePkgPath ...")
Expand Down Expand Up @@ -382,101 +375,3 @@ func (p *Error) Summary() string {
}

// -----------------------------------------------------------------------------

const (
directiveInvalid = iota
directiveModule
directiveGop
directiveProject
directiveClass
)

const (
directiveLineBlock = 0x80 + iota
directiveImport
)

var directiveWeights = map[string]int{
"module": directiveModule,
"gop": directiveGop,
"import": directiveImport,
"register": directiveImport, // register => import
"project": directiveProject,
"class": directiveClass,
}

func getWeight(e Expr) int {
if line, ok := e.(*Line); ok {
return directiveWeights[line.Token[0]]
}
if w, ok := directiveWeights[e.(*LineBlock).Token[0]]; ok {
return w
}
return directiveLineBlock
}

func updateLine(line *Line, tokens ...string) {
if line.InBlock {
tokens = tokens[1:]
}
line.Token = tokens
}

func addLine(x *FileSyntax, tokens ...string) *Line {
new := &Line{Token: tokens}
w := directiveWeights[tokens[0]]
for i, e := range x.Stmt {
w2 := getWeight(e)
if w <= w2 {
x.Stmt = append(x.Stmt, nil)
copy(x.Stmt[i+1:], x.Stmt[i:])
x.Stmt[i] = new
return new
}
}
x.Stmt = append(x.Stmt, new)
return new
}

func (f *File) AddGopStmt(version string) error {
if !modfile.GoVersionRE.MatchString(version) {
return fmt.Errorf("invalid language version string %q", version)
}
if f.Gop == nil {
if f.Syntax == nil {
f.Syntax = new(FileSyntax)
}
f.Gop = &Gop{
Version: version,
Syntax: addLine(f.Syntax, "gop", version),
}
} else {
f.Gop.Version = version
updateLine(f.Gop.Syntax, "gop", version)
}
return nil
}

func (f *File) AddImport(modPath string) {
for _, r := range f.Import {
if r.ClassfileMod == modPath {
return
}
}
f.AddNewImport(modPath)
}

func (f *File) AddNewImport(modPath string) {
line := addLine(f.Syntax, "import", AutoQuote(modPath))
r := &Import{
ClassfileMod: modPath,
Syntax: line,
}
f.Import = append(f.Import, r)
}

func (f *File) Format() ([]byte, error) {
return modfile.Format(f.Syntax), nil
}

// -----------------------------------------------------------------------------
Loading

0 comments on commit e78cc38

Please sign in to comment.