...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package astutil
16
17 import (
18 "path"
19 "strconv"
20 "strings"
21
22 "cuelang.org/go/cue/ast"
23 "cuelang.org/go/cue/token"
24 )
25
26
27
28
29
30
31
32
33 func ImportPathName(id string) string {
34 name := path.Base(id)
35 if p := strings.LastIndexByte(name, ':'); p > 0 {
36 name = name[p+1:]
37 }
38 return name
39 }
40
41
42 type ImportInfo struct {
43 Ident string
44 PkgName string
45 ID string
46 Dir string
47 }
48
49
50 func ParseImportSpec(spec *ast.ImportSpec) (info ImportInfo, err error) {
51 str, err := strconv.Unquote(spec.Path.Value)
52 if err != nil {
53 return info, err
54 }
55
56 info.ID = str
57
58 if p := strings.LastIndexByte(str, ':'); p > 0 {
59 info.Dir = str[:p]
60 info.PkgName = str[p+1:]
61 } else {
62 info.Dir = str
63 info.PkgName = path.Base(str)
64 }
65
66 if spec.Name != nil {
67 info.Ident = spec.Name.Name
68 } else {
69 info.Ident = info.PkgName
70 }
71
72 return info, nil
73 }
74
75
76
77 func CopyComments(to, from ast.Node) {
78 if from == nil {
79 return
80 }
81 ast.SetComments(to, from.Comments())
82 }
83
84
85 func CopyPosition(to, from ast.Node) {
86 if from == nil {
87 return
88 }
89 ast.SetPos(to, from.Pos())
90 }
91
92
93
94 func CopyMeta(to, from ast.Node) ast.Node {
95 if from == nil {
96 return to
97 }
98 ast.SetComments(to, from.Comments())
99 ast.SetPos(to, from.Pos())
100 return to
101 }
102
103
104
105 func insertImport(decls *[]ast.Decl, spec *ast.ImportSpec) *ast.ImportSpec {
106 x, _ := ParseImportSpec(spec)
107
108 a := *decls
109
110 var imports *ast.ImportDecl
111 var orig *ast.ImportSpec
112
113 p := 0
114 outer:
115 for i := 0; i < len(a); i++ {
116 d := a[i]
117 switch t := d.(type) {
118 default:
119 break outer
120
121 case *ast.Package:
122 p = i + 1
123 case *ast.CommentGroup:
124 p = i + 1
125 case *ast.Attribute:
126 continue
127 case *ast.ImportDecl:
128 p = i + 1
129 imports = t
130 for _, s := range t.Specs {
131 y, _ := ParseImportSpec(s)
132 if y.ID != x.ID {
133 continue
134 }
135 orig = s
136 if x.Ident == "" || y.Ident == x.Ident {
137 return s
138 }
139 }
140 }
141 }
142
143
144 if imports == nil {
145 imports = &ast.ImportDecl{}
146 preamble := append(a[:p:p], imports)
147 a = append(preamble, a[p:]...)
148 *decls = a
149 }
150
151 if orig != nil {
152 CopyComments(spec, orig)
153 }
154 imports.Specs = append(imports.Specs, spec)
155 ast.SetRelPos(imports.Specs[0], token.NoRelPos)
156
157 return spec
158 }
159
View as plain text