...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package build
16
17 import (
18 "sort"
19 "strconv"
20
21 "cuelang.org/go/cue/ast"
22 "cuelang.org/go/cue/errors"
23 "cuelang.org/go/cue/token"
24 )
25
26 type LoadFunc func(pos token.Pos, path string) *Instance
27
28 type cueError = errors.Error
29
30 type buildError struct {
31 cueError
32 inputs []token.Pos
33 }
34
35 func (e *buildError) InputPositions() []token.Pos {
36 return e.inputs
37 }
38
39 func (inst *Instance) complete() errors.Error {
40
41
42
43
44
45
46
47
48
49
50
51 var (
52 c = inst.ctxt
53 imported = map[string][]token.Pos{}
54 )
55
56 for _, f := range inst.Files {
57 for _, decl := range f.Decls {
58 d, ok := decl.(*ast.ImportDecl)
59 if !ok {
60 continue
61 }
62 for _, spec := range d.Specs {
63 quoted := spec.Path.Value
64 path, err := strconv.Unquote(quoted)
65 if err != nil {
66 inst.Err = errors.Append(inst.Err,
67 errors.Newf(
68 spec.Path.Pos(),
69 "%s: parser returned invalid quoted string: <%s>",
70 f.Filename, quoted))
71 }
72 imported[path] = append(imported[path], spec.Pos())
73 }
74 }
75 }
76
77 paths := make([]string, 0, len(imported))
78 for path := range imported {
79 paths = append(paths, path)
80 if path == "" {
81 return &buildError{
82 errors.Newf(token.NoPos, "empty import path"),
83 imported[path],
84 }
85 }
86 }
87
88 sort.Strings(paths)
89
90 if inst.loadFunc != nil {
91 for i, path := range paths {
92 isLocal := IsLocalImport(path)
93 if isLocal {
94
95 }
96
97 imp := c.imports[path]
98 if imp == nil {
99 pos := token.NoPos
100 if len(imported[path]) > 0 {
101 pos = imported[path][0]
102 }
103 imp = inst.loadFunc(pos, path)
104 if imp == nil {
105 continue
106 }
107 if imp.Err != nil {
108 return errors.Wrapf(imp.Err, pos, "import failed")
109 }
110 imp.ImportPath = path
111
112 c.imports[path] = imp
113
114 } else if imp.parent != nil {
115
116
117 }
118 paths[i] = imp.ImportPath
119
120 inst.addImport(imp)
121 if imp.Incomplete {
122 inst.Incomplete = true
123 }
124 }
125 }
126
127 inst.ImportPaths = paths
128 inst.ImportPos = imported
129
130
131 deps := make(map[string]*Instance)
132 var q []*Instance
133 q = append(q, inst.Imports...)
134 for i := 0; i < len(q); i++ {
135 p1 := q[i]
136 path := p1.ImportPath
137
138
139
140
141
142
143
144
145
146
147
148
149 if _, ok := deps[path]; !ok {
150 deps[path] = p1
151 }
152 }
153 inst.Deps = make([]string, 0, len(deps))
154 for dep := range deps {
155 inst.Deps = append(inst.Deps, dep)
156 }
157 sort.Strings(inst.Deps)
158
159 for _, dep := range inst.Deps {
160 p1 := deps[dep]
161 if p1 == nil {
162 panic("impossible: missing entry in package cache for " + dep + " imported by " + inst.ImportPath)
163 }
164 if p1.Err != nil {
165 inst.DepsErrors = append(inst.DepsErrors, p1.Err)
166 }
167 }
168
169 return nil
170 }
171
View as plain text