mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-11 18:54:31 +00:00
102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
package model
|
|
|
|
// TypeExpr provides a type name that may be rewritten to use a package name.
|
|
import (
|
|
"fmt"
|
|
"go/ast"
|
|
)
|
|
|
|
type TypeExpr struct {
|
|
Expr string // The unqualified type expression, e.g. "[]*MyType"
|
|
PkgName string // The default package idenifier
|
|
pkgIndex int // The index where the package identifier should be inserted.
|
|
Valid bool
|
|
}
|
|
|
|
// Returns a new type from the data.
|
|
func NewTypeExprFromData(expr, pkgName string, pkgIndex int, valid bool) TypeExpr {
|
|
return TypeExpr{expr, pkgName, pkgIndex, valid}
|
|
}
|
|
|
|
// NewTypeExpr returns the syntactic expression for referencing this type in Go.
|
|
func NewTypeExprFromAst(pkgName string, expr ast.Expr) TypeExpr {
|
|
error := ""
|
|
switch t := expr.(type) {
|
|
case *ast.Ident:
|
|
if IsBuiltinType(t.Name) {
|
|
pkgName = ""
|
|
}
|
|
return TypeExpr{t.Name, pkgName, 0, true}
|
|
case *ast.SelectorExpr:
|
|
e := NewTypeExprFromAst(pkgName, t.X)
|
|
return NewTypeExprFromData(t.Sel.Name, e.Expr, 0, e.Valid)
|
|
case *ast.StarExpr:
|
|
e := NewTypeExprFromAst(pkgName, t.X)
|
|
return NewTypeExprFromData("*"+e.Expr, e.PkgName, e.pkgIndex+1, e.Valid)
|
|
case *ast.ArrayType:
|
|
e := NewTypeExprFromAst(pkgName, t.Elt)
|
|
return NewTypeExprFromData("[]"+e.Expr, e.PkgName, e.pkgIndex+2, e.Valid)
|
|
case *ast.MapType:
|
|
if identKey, ok := t.Key.(*ast.Ident); ok && IsBuiltinType(identKey.Name) {
|
|
e := NewTypeExprFromAst(pkgName, t.Value)
|
|
return NewTypeExprFromData("map["+identKey.Name+"]"+e.Expr, e.PkgName, e.pkgIndex+len("map["+identKey.Name+"]"), e.Valid)
|
|
}
|
|
error = fmt.Sprintf("Failed to generate name for Map field :%v. Make sure the field name is valid.", t.Key)
|
|
case *ast.Ellipsis:
|
|
e := NewTypeExprFromAst(pkgName, t.Elt)
|
|
return NewTypeExprFromData("[]"+e.Expr, e.PkgName, e.pkgIndex+2, e.Valid)
|
|
default:
|
|
error = fmt.Sprintf("Failed to generate name for field: %v Package: %v. Make sure the field name is valid.", expr, pkgName)
|
|
}
|
|
return NewTypeExprFromData(error, "", 0, false)
|
|
}
|
|
|
|
// TypeName returns the fully-qualified type name for this expression.
|
|
// The caller may optionally specify a package name to override the default.
|
|
func (e TypeExpr) TypeName(pkgOverride string) string {
|
|
pkgName := FirstNonEmpty(pkgOverride, e.PkgName)
|
|
if pkgName == "" {
|
|
return e.Expr
|
|
}
|
|
return e.Expr[:e.pkgIndex] + pkgName + "." + e.Expr[e.pkgIndex:]
|
|
}
|
|
|
|
var builtInTypes = map[string]struct{}{
|
|
"bool": {},
|
|
"byte": {},
|
|
"complex128": {},
|
|
"complex64": {},
|
|
"error": {},
|
|
"float32": {},
|
|
"float64": {},
|
|
"int": {},
|
|
"int16": {},
|
|
"int32": {},
|
|
"int64": {},
|
|
"int8": {},
|
|
"rune": {},
|
|
"string": {},
|
|
"uint": {},
|
|
"uint16": {},
|
|
"uint32": {},
|
|
"uint64": {},
|
|
"uint8": {},
|
|
"uintptr": {},
|
|
}
|
|
|
|
// IsBuiltinType checks the given type is built-in types of Go.
|
|
func IsBuiltinType(name string) bool {
|
|
_, ok := builtInTypes[name]
|
|
return ok
|
|
}
|
|
|
|
// Returns the first non empty string from a list of arguments.
|
|
func FirstNonEmpty(strs ...string) string {
|
|
for _, str := range strs {
|
|
if len(str) > 0 {
|
|
return str
|
|
}
|
|
}
|
|
return ""
|
|
}
|