代码拉取完成,页面将自动刷新
package codegen
import (
"fmt"
"goa.design/goa/expr"
)
type (
// ImportSpec defines a generated import statement.
ImportSpec struct {
// Name of imported package if needed.
Name string
// Go import path of package.
Path string
}
)
// NewImport creates an import spec.
func NewImport(name, path string) *ImportSpec {
return &ImportSpec{Name: name, Path: path}
}
// SimpleImport creates an import with no explicit path component.
func SimpleImport(path string) *ImportSpec {
return &ImportSpec{Path: path}
}
// Code returns the Go import statement for the ImportSpec.
func (s *ImportSpec) Code() string {
if len(s.Name) > 0 {
return fmt.Sprintf(`%s "%s"`, s.Name, s.Path)
}
return fmt.Sprintf(`"%s"`, s.Path)
}
// GetMetaType retrieves the type and package defined by the struct:field:type
// metadata if any.
func GetMetaType(att *expr.AttributeExpr) (typeName string, importS *ImportSpec) {
if att == nil {
return typeName, importS
}
if args, ok := att.Meta["struct:field:type"]; ok {
if len(args) > 0 {
typeName = args[0]
}
if len(args) > 1 {
importS = &ImportSpec{Path: args[1]}
}
if len(args) > 2 {
importS.Name = args[2]
}
}
return typeName, importS
}
// GetMetaTypeImports parses the attribute for all user defined imports
func GetMetaTypeImports(att *expr.AttributeExpr) []*ImportSpec {
return safelyGetMetaTypeImports(att, nil)
}
// safelyGetMetaTypeImports parses attributes while keeping track of previous usertypes to avoid infinite recursion
func safelyGetMetaTypeImports(att *expr.AttributeExpr, seen map[string]struct{}) []*ImportSpec {
if att == nil {
return nil
}
if seen == nil {
seen = make(map[string]struct{})
}
uniqueImports := make(map[ImportSpec]struct{})
imports := make([]*ImportSpec, 0)
switch t := att.Type.(type) {
case expr.UserType:
if _, wasSeen := seen[t.ID()]; wasSeen {
return imports
}
seen[t.ID()] = struct{}{}
for _, im := range safelyGetMetaTypeImports(t.Attribute(), seen) {
if im != nil {
uniqueImports[*im] = struct{}{}
}
}
case *expr.Array:
_, im := GetMetaType(t.ElemType)
if im != nil {
uniqueImports[*im] = struct{}{}
}
case *expr.Map:
_, im := GetMetaType(t.ElemType)
if im != nil {
uniqueImports[*im] = struct{}{}
}
_, im = GetMetaType(t.KeyType)
if im != nil {
uniqueImports[*im] = struct{}{}
}
case *expr.Object:
for _, key := range *t {
if key != nil {
_, im := GetMetaType(key.Attribute)
if im != nil {
uniqueImports[*im] = struct{}{}
}
}
}
}
_, im := GetMetaType(att)
if im != nil {
uniqueImports[*im] = struct{}{}
}
for imp := range uniqueImports {
// Copy loop variable into body so next iteration doesnt overwrite its address https://stackoverflow.com/questions/27610039/golang-appending-leaves-only-last-element
copy := imp
imports = append(imports, ©)
}
return imports
}
// AddServiceMetaTypeImports adds meta type imports for each method of the service expr
func AddServiceMetaTypeImports(header *SectionTemplate, svc *expr.ServiceExpr) {
for _, m := range svc.Methods {
AddImport(header, GetMetaTypeImports(m.Payload)...)
AddImport(header, GetMetaTypeImports(m.StreamingPayload)...)
AddImport(header, GetMetaTypeImports(m.Result)...)
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。