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