1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package runtime
16
17 import (
18 "strings"
19
20 "cuelang.org/go/cue/ast"
21 "cuelang.org/go/cue/ast/astutil"
22 "cuelang.org/go/cue/build"
23 "cuelang.org/go/cue/errors"
24 "cuelang.org/go/cue/stats"
25 "cuelang.org/go/cue/token"
26 "cuelang.org/go/internal"
27 "cuelang.org/go/internal/core/adt"
28 "cuelang.org/go/internal/core/compile"
29 )
30
31 type Config struct {
32 Runtime *Runtime
33 Filename string
34 ImportPath string
35
36 Counts *stats.Counts
37
38 compile.Config
39 }
40
41
42
43 func (x *Runtime) Build(cfg *Config, b *build.Instance) (v *adt.Vertex, errs errors.Error) {
44 if err := b.Complete(); err != nil {
45 return nil, b.Err
46 }
47 if v := x.getNodeFromInstance(b); v != nil {
48 return v, b.Err
49 }
50
51
52
53
54
55
56
57
58 errs = b.Err
59
60
61 for _, file := range b.Files {
62 file.VisitImports(func(d *ast.ImportDecl) {
63 for _, s := range d.Specs {
64 errs = errors.Append(errs, x.buildSpec(cfg, b, s))
65 }
66 })
67 }
68
69 err := x.ResolveFiles(b)
70 errs = errors.Append(errs, err)
71
72 var cc *compile.Config
73 if cfg != nil {
74 cc = &cfg.Config
75 }
76 if cfg != nil && cfg.ImportPath != "" {
77 b.ImportPath = cfg.ImportPath
78 b.PkgName = astutil.ImportPathName(b.ImportPath)
79 }
80 v, err = compile.Files(cc, x, b.ID(), b.Files...)
81 errs = errors.Append(errs, err)
82
83 errs = errors.Append(errs, x.injectImplementations(b, v))
84
85 if errs != nil {
86 v = adt.ToVertex(&adt.Bottom{Err: errs})
87 b.Err = errs
88 }
89
90 x.AddInst(b.ImportPath, v, b)
91
92 return v, errs
93 }
94
95 func dummyLoad(token.Pos, string) *build.Instance { return nil }
96
97 func (r *Runtime) Compile(cfg *Config, source interface{}) (*adt.Vertex, *build.Instance) {
98 ctx := build.NewContext()
99 var filename string
100 if cfg != nil && cfg.Filename != "" {
101 filename = cfg.Filename
102 }
103 p := ctx.NewInstance(filename, dummyLoad)
104 if err := p.AddFile(filename, source); err != nil {
105 return nil, p
106 }
107 v, _ := r.Build(cfg, p)
108 return v, p
109 }
110
111 func (r *Runtime) CompileFile(cfg *Config, file *ast.File) (*adt.Vertex, *build.Instance) {
112 ctx := build.NewContext()
113 filename := file.Filename
114 if cfg != nil && cfg.Filename != "" {
115 filename = cfg.Filename
116 }
117 p := ctx.NewInstance(filename, dummyLoad)
118 err := p.AddSyntax(file)
119 if err != nil {
120 return nil, p
121 }
122 _, p.PkgName, _ = internal.PackageInfo(file)
123 v, _ := r.Build(cfg, p)
124 return v, p
125 }
126
127 func (x *Runtime) buildSpec(cfg *Config, b *build.Instance, spec *ast.ImportSpec) (errs errors.Error) {
128 info, err := astutil.ParseImportSpec(spec)
129 if err != nil {
130 return errors.Promote(err, "invalid import path")
131 }
132
133 pkg := b.LookupImport(info.ID)
134 if pkg == nil {
135 if strings.Contains(info.ID, ".") {
136 return errors.Newf(spec.Pos(),
137 "package %q imported but not defined in %s",
138 info.ID, b.ImportPath)
139 } else if x.index.builtinPaths[info.ID] == nil {
140 return errors.Newf(spec.Pos(),
141 "builtin package %q undefined", info.ID)
142 }
143 return nil
144 }
145
146 if v := x.getNodeFromInstance(pkg); v != nil {
147 return pkg.Err
148 }
149
150 if _, err := x.Build(cfg, pkg); err != nil {
151 return err
152 }
153
154 return nil
155 }
156
View as plain text