github.com/ManabuSeki/goa-v1@v1.4.3/goagen/codegen/import_spec.go (about) 1 package codegen 2 3 import ( 4 "fmt" 5 6 "github.com/goadesign/goa/design" 7 ) 8 9 // ImportSpec defines a generated import statement. 10 type ImportSpec struct { 11 Name string 12 Path string 13 } 14 15 // NewImport creates an import spec. 16 func NewImport(name, path string) *ImportSpec { 17 return &ImportSpec{Name: name, Path: path} 18 } 19 20 // SimpleImport creates an import with no explicit path component. 21 func SimpleImport(path string) *ImportSpec { 22 return &ImportSpec{Path: path} 23 } 24 25 // Code returns the Go import statement for the ImportSpec. 26 func (s *ImportSpec) Code() string { 27 if len(s.Name) > 0 { 28 return fmt.Sprintf(`%s "%s"`, s.Name, s.Path) 29 } 30 return fmt.Sprintf(`"%s"`, s.Path) 31 } 32 33 // AttributeImports constructs a new ImportsSpec slice from an existing slice and adds in imports specified in 34 // struct:field:type Metadata tags. 35 func AttributeImports(att *design.AttributeDefinition, imports []*ImportSpec, seen []*design.AttributeDefinition) []*ImportSpec { 36 37 for _, a := range seen { 38 if att == a { 39 return imports 40 } 41 } 42 seen = append(seen, att) 43 44 if tname, ok := att.Metadata["struct:field:type"]; ok { 45 if len(tname) > 1 { 46 tagImp := SimpleImport(tname[1]) 47 impSlice := []*ImportSpec{tagImp} 48 imports = appendImports(imports, impSlice) 49 } 50 } 51 52 switch t := att.Type.(type) { 53 case *design.UserTypeDefinition: 54 return appendImports(imports, AttributeImports(t.AttributeDefinition, imports, seen)) 55 case *design.MediaTypeDefinition: 56 return appendImports(imports, AttributeImports(t.AttributeDefinition, imports, seen)) 57 case design.Object: 58 t.IterateAttributes(func(n string, t *design.AttributeDefinition) error { 59 imports = appendImports(imports, AttributeImports(t, imports, seen)) 60 return nil 61 }) 62 return imports 63 case *design.Array: 64 return appendImports(imports, AttributeImports(t.ElemType, imports, seen)) 65 case *design.Hash: 66 imports = appendImports(imports, AttributeImports(t.KeyType, imports, seen)) 67 return appendImports(imports, AttributeImports(t.ElemType, imports, seen)) 68 } 69 70 return imports 71 } 72 73 // appendImports appends two ImportSpec slices and preserves uniqueness 74 func appendImports(i, a []*ImportSpec) []*ImportSpec { 75 for _, v := range a { 76 contains := false 77 for _, att := range i { 78 if att.Path == v.Path { 79 contains = true 80 break 81 } 82 } 83 if contains != true { 84 i = append(i, v) 85 } 86 } 87 return i 88 }