161 строка
		
	
	
	
		
			2,6 КиБ
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			161 строка
		
	
	
	
		
			2,6 КиБ
		
	
	
	
		
			Go
		
	
	
	
	
	
package service
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"go/ast"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	inFunctionDepth = 0
 | 
						|
)
 | 
						|
 | 
						|
func incInFunctionDepth() {
 | 
						|
	inFunctionDepth++
 | 
						|
}
 | 
						|
func decInFunctionDepth() {
 | 
						|
	inFunctionDepth--
 | 
						|
	if inFunctionDepth < 0 {
 | 
						|
		panic(fmt.Sprintf("inFunctionDepth: %v", inFunctionDepth))
 | 
						|
	}
 | 
						|
}
 | 
						|
func IsInFunction() bool {
 | 
						|
	return inFunctionDepth > 0
 | 
						|
}
 | 
						|
 | 
						|
func handleFuncDecl(decl ast.Decl) string {
 | 
						|
	incInFunctionDepth()
 | 
						|
	defer decInFunctionDepth()
 | 
						|
 | 
						|
	fd := decl.(*ast.FuncDecl)
 | 
						|
	if fd.Recv != nil {
 | 
						|
		return handleMethodDeclaration(fd)
 | 
						|
	}
 | 
						|
	return handleFunctionDeclaration(fd)
 | 
						|
}
 | 
						|
func handleFunctionDeclaration(fd *ast.FuncDecl) string {
 | 
						|
	if shouldSkipFunction(fd.Type) {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
	code := ""
 | 
						|
	name := ""
 | 
						|
	ft := handleFuncDeclType(fd.Type)
 | 
						|
	code += ft
 | 
						|
	code += " "
 | 
						|
	name = handleFuncDeclName(fd.Name)
 | 
						|
	if name == "NewController" {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
	code += name
 | 
						|
	code += "("
 | 
						|
	fp := handleFuncDeclParams(fd.Type)
 | 
						|
	code += fp
 | 
						|
 | 
						|
	addFunctionDeclaration(ft + " " + name + "(" + fp + ");")
 | 
						|
 | 
						|
	code += ") {\n"
 | 
						|
	code += handleBlockStmt(fd.Body)
 | 
						|
	code += "}\n"
 | 
						|
	return code
 | 
						|
}
 | 
						|
func shouldSkipFunction(t *ast.FuncType) (res bool) {
 | 
						|
	r := t.Results
 | 
						|
	if r == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	l := r.List
 | 
						|
	if len(l) != 1 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	p := l[0]
 | 
						|
	if p == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	pt := p.Type
 | 
						|
	if pt == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	i, ok := pt.(*ast.Ident)
 | 
						|
	if !ok {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if i.Name == "ShouldBeSkipped" {
 | 
						|
		return true
 | 
						|
	}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
func handleFuncDeclType(t *ast.FuncType) string {
 | 
						|
	code := ""
 | 
						|
	if t.Results == nil {
 | 
						|
		return "void"
 | 
						|
	}
 | 
						|
 | 
						|
	fl := t.Results
 | 
						|
	if fl.NumFields() == 0 {
 | 
						|
		panic("handleFuncDeclType: fl.NumFields() == 0")
 | 
						|
	}
 | 
						|
 | 
						|
	switch ft := fl.List[0].Type.(type) {
 | 
						|
	case *ast.Ident:
 | 
						|
		code += handleIdentExpr(ft)
 | 
						|
	case *ast.StarExpr:
 | 
						|
		code += handleStarExpr(ft)
 | 
						|
		code += "*"
 | 
						|
	}
 | 
						|
 | 
						|
	return code
 | 
						|
}
 | 
						|
 | 
						|
func handleFuncDeclName(ident *ast.Ident) (code string) {
 | 
						|
	if ident == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	code += ident.Name
 | 
						|
	if val, ok := mapping[code]; ok {
 | 
						|
		code = val
 | 
						|
	}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
func handleFuncDeclParams(t *ast.FuncType) string {
 | 
						|
	code := ""
 | 
						|
	if t.Params == nil || t.Params.List == nil {
 | 
						|
		return code
 | 
						|
	}
 | 
						|
	values := make([]string, 0)
 | 
						|
	for _, field := range t.Params.List {
 | 
						|
		ftype := ""
 | 
						|
		star := false
 | 
						|
		switch ft := field.Type.(type) {
 | 
						|
		case *ast.Ident:
 | 
						|
			ftype = handleIdentExpr(ft)
 | 
						|
		case *ast.StarExpr:
 | 
						|
			ftype = handleStarExpr(ft)
 | 
						|
			star = true
 | 
						|
		}
 | 
						|
		for _, names := range field.Names {
 | 
						|
			n := ftype
 | 
						|
			if star {
 | 
						|
				n += "*"
 | 
						|
			}
 | 
						|
			n += " "
 | 
						|
			n += names.Name
 | 
						|
			values = append(values, n)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	code += strings.Join(values, ",")
 | 
						|
	return code
 | 
						|
}
 | 
						|
 | 
						|
func addFunctionDeclaration(f string) {
 | 
						|
	dlock.Lock()
 | 
						|
	defer dlock.Unlock()
 | 
						|
 | 
						|
	funcDeclarations = append(funcDeclarations, f)
 | 
						|
}
 |