mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 17:50:58 +00:00
beego:AST code
This commit is contained in:
parent
6c8a7f1382
commit
21cb8ea4a3
@ -34,8 +34,8 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// custom error when user stop request handler manually.
|
// custom error when user stop request handler manually.
|
||||||
USERSTOPRUN = errors.New("User stop run")
|
USERSTOPRUN = errors.New("User stop run")
|
||||||
GlobalControllerRouter map[string]*ControllerComments //pkgpath+controller:comments
|
GlobalControllerRouter map[string][]ControllerComments = make(map[string][]ControllerComments) //pkgpath+controller:comments
|
||||||
)
|
)
|
||||||
|
|
||||||
// store the comment for the controller method
|
// store the comment for the controller method
|
||||||
@ -43,6 +43,7 @@ type ControllerComments struct {
|
|||||||
method string
|
method string
|
||||||
router string
|
router string
|
||||||
allowHTTPMethods []string
|
allowHTTPMethods []string
|
||||||
|
params []map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controller defines some basic http request handler operations, such as
|
// Controller defines some basic http request handler operations, such as
|
||||||
|
132
parser.go
132
parser.go
@ -6,11 +6,17 @@
|
|||||||
package beego
|
package beego
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var globalControllerRouter = `package routers
|
var globalRouterTemplate = `package routers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
@ -21,26 +27,106 @@ func init() {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
func parserPkg(pkgpath string) error {
|
var genInfoList map[string][]ControllerComments
|
||||||
err := filepath.Walk(pkgpath, func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
Error("error scan app Controller source:", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
//if is normal file or name is temp skip
|
|
||||||
//directory is needed
|
|
||||||
if !info.IsDir() || info.Name() == "tmp" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//fileSet := token.NewFileSet()
|
func init() {
|
||||||
//astPkgs, err := parser.ParseDir(fileSet, path, func(info os.FileInfo) bool {
|
genInfoList = make(map[string][]ControllerComments)
|
||||||
// name := info.Name()
|
}
|
||||||
// return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
|
||||||
//}, parser.ParseComments)
|
func parserPkg(pkgRealpath, pkgpath string) error {
|
||||||
|
fileSet := token.NewFileSet()
|
||||||
return nil
|
astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool {
|
||||||
})
|
name := info.Name()
|
||||||
|
return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
||||||
return err
|
}, parser.ParseComments)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, pkg := range astPkgs {
|
||||||
|
for _, fl := range pkg.Files {
|
||||||
|
for _, d := range fl.Decls {
|
||||||
|
switch specDecl := d.(type) {
|
||||||
|
case *ast.FuncDecl:
|
||||||
|
parserComments(specDecl.Doc, specDecl.Name.String(), fmt.Sprint(specDecl.Recv.List[0].Type.(*ast.StarExpr).X), pkgpath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genRouterCode()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpath string) error {
|
||||||
|
if comments != nil && comments.List != nil {
|
||||||
|
for _, c := range comments.List {
|
||||||
|
t := strings.TrimSpace(strings.TrimLeft(c.Text, "//"))
|
||||||
|
if strings.HasPrefix(t, "@router") {
|
||||||
|
elements := strings.TrimLeft(t, "@router ")
|
||||||
|
e1 := strings.SplitN(elements, " ", 2)
|
||||||
|
if len(e1) < 1 {
|
||||||
|
return errors.New("you should has router infomation")
|
||||||
|
}
|
||||||
|
key := pkgpath + ":" + controllerName
|
||||||
|
cc := ControllerComments{}
|
||||||
|
cc.method = funcName
|
||||||
|
cc.router = e1[0]
|
||||||
|
if len(e1) == 2 && e1[1] != "" {
|
||||||
|
e1 = strings.SplitN(e1[1], " ", 2)
|
||||||
|
if len(e1) >= 1 {
|
||||||
|
cc.allowHTTPMethods = strings.Split(strings.Trim(e1[0], "[]"), ",")
|
||||||
|
} else {
|
||||||
|
cc.allowHTTPMethods = append(cc.allowHTTPMethods, "get")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cc.allowHTTPMethods = append(cc.allowHTTPMethods, "get")
|
||||||
|
}
|
||||||
|
if len(e1) == 2 && e1[1] != "" {
|
||||||
|
keyval := strings.Split(strings.Trim(e1[1], "[]"), " ")
|
||||||
|
for _, kv := range keyval {
|
||||||
|
kk := strings.Split(kv, ":")
|
||||||
|
cc.params = append(cc.params, map[string]string{strings.Join(kk[:len(kk)-1], ":"): kk[len(kk)-1]})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genInfoList[key] = append(genInfoList[key], cc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func genRouterCode() {
|
||||||
|
os.Mkdir(path.Join(AppPath, "routers"), 0755)
|
||||||
|
Info("generate router from comments")
|
||||||
|
f, err := os.Create(path.Join(AppPath, "routers", "commentsRouter.go"))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
var globalinfo string
|
||||||
|
for k, cList := range genInfoList {
|
||||||
|
for _, c := range cList {
|
||||||
|
allmethod := "nil"
|
||||||
|
if len(c.allowHTTPMethods) > 0 {
|
||||||
|
allmethod = "[]string{"
|
||||||
|
for _, m := range c.allowHTTPMethods {
|
||||||
|
allmethod += `"` + m + `",`
|
||||||
|
}
|
||||||
|
allmethod = strings.TrimRight(allmethod, ",") + "}"
|
||||||
|
}
|
||||||
|
params := "nil"
|
||||||
|
if len(c.params) > 0 {
|
||||||
|
params = "[]map[string]string{"
|
||||||
|
for _, p := range c.params {
|
||||||
|
for k, v := range p {
|
||||||
|
params = params + `map[string]string{` + k + `:"` + v + `"},`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params = strings.TrimRight(params, ",") + "}"
|
||||||
|
}
|
||||||
|
globalinfo = globalinfo + fmt.Sprintln(`beego.GlobalControllerRouter["`+k+`"] = &ControllerComments{"`+
|
||||||
|
strings.TrimSpace(c.method)+`", "`+c.router+`", `+allmethod+", "+params+"}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.WriteString(strings.Replace(globalRouterTemplate, "{{.globalinfo}}", globalinfo, -1))
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ func (p *ControllerRegistor) Include(cList ...ControllerInterface) {
|
|||||||
if pkgpath != "" {
|
if pkgpath != "" {
|
||||||
if _, ok := skip[pkgpath]; !ok {
|
if _, ok := skip[pkgpath]; !ok {
|
||||||
skip[pkgpath] = true
|
skip[pkgpath] = true
|
||||||
parserPkg(pkgpath)
|
parserPkg(pkgpath, t.PkgPath())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,7 +184,9 @@ func (p *ControllerRegistor) Include(cList ...ControllerInterface) {
|
|||||||
t := reflect.Indirect(reflectVal).Type()
|
t := reflect.Indirect(reflectVal).Type()
|
||||||
key := t.PkgPath() + ":" + t.Name()
|
key := t.PkgPath() + ":" + t.Name()
|
||||||
if comm, ok := GlobalControllerRouter[key]; ok {
|
if comm, ok := GlobalControllerRouter[key]; ok {
|
||||||
p.Add(comm.router, c, strings.Join(comm.allowHTTPMethods, ",")+":"+comm.method)
|
for _, a := range comm {
|
||||||
|
p.Add(a.router, c, strings.Join(a.allowHTTPMethods, ",")+":"+a.method)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user