goscript 0.0.83 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +13 -1
  2. package/cmd/goscript/cmd_compile.go +70 -69
  3. package/cmd/goscript/cmd_compile_test.go +79 -0
  4. package/cmd/goscript/main.go +10 -5
  5. package/compiler/compile-request.go +218 -0
  6. package/compiler/compiler.go +16 -1336
  7. package/compiler/compliance_test.go +196 -0
  8. package/compiler/config.go +6 -13
  9. package/compiler/diagnostic.go +70 -0
  10. package/compiler/index.test.ts +28 -28
  11. package/compiler/index.ts +40 -72
  12. package/compiler/lowered-program.go +132 -0
  13. package/compiler/lowering.go +3576 -0
  14. package/compiler/override-registry.go +422 -0
  15. package/compiler/override-registry_test.go +207 -0
  16. package/compiler/package-graph.go +231 -0
  17. package/compiler/package-graph_test.go +281 -0
  18. package/compiler/result.go +13 -0
  19. package/compiler/runtime-contract.go +279 -0
  20. package/compiler/runtime-contract_test.go +90 -0
  21. package/compiler/semantic-model-types.go +110 -0
  22. package/compiler/semantic-model.go +922 -0
  23. package/compiler/semantic-model_test.go +416 -0
  24. package/compiler/service.go +133 -0
  25. package/compiler/skeleton_test.go +1145 -0
  26. package/compiler/typescript-emitter.go +663 -0
  27. package/compiler/wasm/compile.go +2 -3
  28. package/compiler/wasm/compile_test.go +29 -0
  29. package/compiler/wasm_api.go +10 -159
  30. package/dist/compiler/index.d.ts +1 -3
  31. package/dist/compiler/index.js +31 -55
  32. package/dist/compiler/index.js.map +1 -1
  33. package/dist/gs/builtin/builtin.d.ts +13 -0
  34. package/dist/gs/builtin/builtin.js +27 -7
  35. package/dist/gs/builtin/builtin.js.map +1 -1
  36. package/dist/gs/builtin/channel.d.ts +3 -3
  37. package/dist/gs/builtin/channel.js.map +1 -1
  38. package/dist/gs/builtin/hostio.d.ts +86 -0
  39. package/dist/gs/builtin/hostio.js +266 -0
  40. package/dist/gs/builtin/hostio.js.map +1 -0
  41. package/dist/gs/builtin/index.d.ts +1 -0
  42. package/dist/gs/builtin/index.js +1 -0
  43. package/dist/gs/builtin/index.js.map +1 -1
  44. package/dist/gs/builtin/print.d.ts +8 -0
  45. package/dist/gs/builtin/print.js +111 -0
  46. package/dist/gs/builtin/print.js.map +1 -0
  47. package/dist/gs/builtin/slice.d.ts +1 -1
  48. package/dist/gs/builtin/slice.js.map +1 -1
  49. package/dist/gs/builtin/type.d.ts +11 -0
  50. package/dist/gs/builtin/type.js +55 -1
  51. package/dist/gs/builtin/type.js.map +1 -1
  52. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  53. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  54. package/dist/gs/bytes/reader.gs.js.map +1 -1
  55. package/dist/gs/context/context.js.map +1 -1
  56. package/dist/gs/crypto/rand/index.d.ts +5 -0
  57. package/dist/gs/crypto/rand/index.js +77 -0
  58. package/dist/gs/crypto/rand/index.js.map +1 -0
  59. package/dist/gs/encoding/json/index.d.ts +3 -0
  60. package/dist/gs/encoding/json/index.js +160 -0
  61. package/dist/gs/encoding/json/index.js.map +1 -0
  62. package/dist/gs/fmt/fmt.js +2 -22
  63. package/dist/gs/fmt/fmt.js.map +1 -1
  64. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -1
  65. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +1 -1
  66. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  67. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  68. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  69. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  70. package/dist/gs/go/scanner/index.d.ts +29 -0
  71. package/dist/gs/go/scanner/index.js +120 -0
  72. package/dist/gs/go/scanner/index.js.map +1 -0
  73. package/dist/gs/go/token/index.d.ts +31 -0
  74. package/dist/gs/go/token/index.js +82 -0
  75. package/dist/gs/go/token/index.js.map +1 -0
  76. package/dist/gs/internal/abi/index.js.map +1 -1
  77. package/dist/gs/io/fs/fs.js.map +1 -1
  78. package/dist/gs/io/fs/readdir.js.map +1 -1
  79. package/dist/gs/io/fs/readfile.js.map +1 -1
  80. package/dist/gs/io/fs/stat.js.map +1 -1
  81. package/dist/gs/io/fs/sub.js.map +1 -1
  82. package/dist/gs/io/io.js.map +1 -1
  83. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  84. package/dist/gs/os/error.gs.js +2 -4
  85. package/dist/gs/os/error.gs.js.map +1 -1
  86. package/dist/gs/os/exec.gs.js.map +1 -1
  87. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  88. package/dist/gs/os/rawconn_js.gs.js.map +1 -1
  89. package/dist/gs/os/root_js.gs.js.map +1 -1
  90. package/dist/gs/os/tempfile.gs.js +66 -9
  91. package/dist/gs/os/tempfile.gs.js.map +1 -1
  92. package/dist/gs/os/types.gs.js.map +1 -1
  93. package/dist/gs/os/types_js.gs.d.ts +2 -51
  94. package/dist/gs/os/types_js.gs.js +67 -105
  95. package/dist/gs/os/types_js.gs.js.map +1 -1
  96. package/dist/gs/os/types_unix.gs.js.map +1 -1
  97. package/dist/gs/path/filepath/match.js.map +1 -1
  98. package/dist/gs/path/match.js.map +1 -1
  99. package/dist/gs/path/path.js.map +1 -1
  100. package/dist/gs/reflect/index.d.ts +2 -2
  101. package/dist/gs/reflect/index.js +1 -1
  102. package/dist/gs/reflect/index.js.map +1 -1
  103. package/dist/gs/reflect/map.js.map +1 -1
  104. package/dist/gs/reflect/type.d.ts +2 -1
  105. package/dist/gs/reflect/type.js +85 -14
  106. package/dist/gs/reflect/type.js.map +1 -1
  107. package/dist/gs/reflect/types.js.map +1 -1
  108. package/dist/gs/reflect/visiblefields.js.map +1 -1
  109. package/dist/gs/runtime/runtime.js.map +1 -1
  110. package/dist/gs/sort/sort.gs.js.map +1 -1
  111. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  112. package/dist/gs/strconv/quote.gs.js.map +1 -1
  113. package/dist/gs/strings/builder.js.map +1 -1
  114. package/dist/gs/strings/reader.js.map +1 -1
  115. package/dist/gs/strings/replace.js.map +1 -1
  116. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  117. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  118. package/dist/gs/sync/sync.d.ts +1 -0
  119. package/dist/gs/sync/sync.js +12 -0
  120. package/dist/gs/sync/sync.js.map +1 -1
  121. package/dist/gs/time/time.js.map +1 -1
  122. package/dist/gs/unicode/unicode.js.map +1 -1
  123. package/go.mod +2 -2
  124. package/gs/builtin/builtin.ts +31 -6
  125. package/gs/builtin/hostio.test.ts +246 -0
  126. package/gs/builtin/hostio.ts +413 -0
  127. package/gs/builtin/index.ts +1 -0
  128. package/gs/builtin/print.test.ts +48 -0
  129. package/gs/builtin/print.ts +154 -0
  130. package/gs/builtin/runtime-contract.test.ts +230 -0
  131. package/gs/builtin/type.ts +84 -1
  132. package/gs/crypto/rand/index.test.ts +32 -0
  133. package/gs/crypto/rand/index.ts +90 -0
  134. package/gs/crypto/rand/meta.json +5 -0
  135. package/gs/encoding/json/index.test.ts +65 -0
  136. package/gs/encoding/json/index.ts +186 -0
  137. package/gs/fmt/fmt.test.ts +41 -30
  138. package/gs/fmt/fmt.ts +2 -22
  139. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +23 -0
  140. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +3 -1
  141. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +3 -1
  142. package/gs/go/scanner/index.test.ts +50 -0
  143. package/gs/go/scanner/index.ts +157 -0
  144. package/gs/go/token/index.test.ts +21 -0
  145. package/gs/go/token/index.ts +120 -0
  146. package/gs/os/file_unix_js.test.ts +103 -0
  147. package/gs/os/meta.json +1 -2
  148. package/gs/os/tempfile.gs.test.ts +85 -0
  149. package/gs/os/tempfile.gs.ts +71 -11
  150. package/gs/os/types_js.gs.ts +74 -153
  151. package/gs/reflect/index.ts +1 -1
  152. package/gs/reflect/type.ts +106 -17
  153. package/gs/reflect/typefor.test.ts +75 -0
  154. package/gs/sync/sync.test.ts +24 -0
  155. package/gs/sync/sync.ts +12 -0
  156. package/package.json +13 -13
  157. package/compiler/analysis.go +0 -3475
  158. package/compiler/analysis_test.go +0 -338
  159. package/compiler/assignment.go +0 -580
  160. package/compiler/builtin_test.go +0 -92
  161. package/compiler/code-writer.go +0 -115
  162. package/compiler/compiler_test.go +0 -149
  163. package/compiler/composite-lit.go +0 -779
  164. package/compiler/config_test.go +0 -62
  165. package/compiler/constraint.go +0 -86
  166. package/compiler/decl.go +0 -801
  167. package/compiler/expr-call-async.go +0 -188
  168. package/compiler/expr-call-builtins.go +0 -208
  169. package/compiler/expr-call-helpers.go +0 -382
  170. package/compiler/expr-call-make.go +0 -318
  171. package/compiler/expr-call-type-conversion.go +0 -520
  172. package/compiler/expr-call.go +0 -413
  173. package/compiler/expr-selector.go +0 -343
  174. package/compiler/expr-star.go +0 -82
  175. package/compiler/expr-type.go +0 -442
  176. package/compiler/expr-value.go +0 -89
  177. package/compiler/expr.go +0 -773
  178. package/compiler/field.go +0 -183
  179. package/compiler/gs_dependencies_test.go +0 -298
  180. package/compiler/lit.go +0 -322
  181. package/compiler/output.go +0 -72
  182. package/compiler/primitive.go +0 -149
  183. package/compiler/protobuf.go +0 -697
  184. package/compiler/sanitize.go +0 -100
  185. package/compiler/spec-struct.go +0 -995
  186. package/compiler/spec-value.go +0 -540
  187. package/compiler/spec.go +0 -725
  188. package/compiler/stmt-assign.go +0 -664
  189. package/compiler/stmt-for.go +0 -266
  190. package/compiler/stmt-range.go +0 -475
  191. package/compiler/stmt-select.go +0 -262
  192. package/compiler/stmt-type-switch.go +0 -147
  193. package/compiler/stmt.go +0 -1308
  194. package/compiler/type-assert.go +0 -386
  195. package/compiler/type-info.go +0 -156
  196. package/compiler/type-utils.go +0 -207
  197. package/compiler/type.go +0 -892
@@ -0,0 +1,416 @@
1
+ package compiler
2
+
3
+ import (
4
+ "context"
5
+ "go/types"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ func TestSemanticModelBuildsDeclarationFacts(t *testing.T) {
12
+ moduleDir := writePackageGraphFixture(t, map[string]string{
13
+ "go.mod": "module example.test/semantic\n\ngo 1.25.3\n",
14
+ "main.go": strings.Join([]string{
15
+ "package semantic",
16
+ "import \"fmt\"",
17
+ "type Counter struct { Value int }",
18
+ "const Answer = 42",
19
+ "var Global Counter",
20
+ "func Print() { fmt.Println(Answer) }",
21
+ "",
22
+ }, "\n"),
23
+ })
24
+ graph := loadPackageGraph(t, &CompileRequest{
25
+ Patterns: []string{"."},
26
+ Dir: moduleDir,
27
+ OutputPath: filepath.Join(t.TempDir(), "out"),
28
+ DependencyMode: DependencyModeRequested,
29
+ RuntimeEmissionMode: RuntimeEmissionModeEmit,
30
+ })
31
+ model := buildSemanticModel(t, graph)
32
+ semPkg := requireSemanticPackage(t, model, "example.test/semantic")
33
+
34
+ for _, decl := range []struct {
35
+ kind string
36
+ name string
37
+ }{
38
+ {kind: "type", name: "Counter"},
39
+ {kind: "const", name: "Answer"},
40
+ {kind: "var", name: "Global"},
41
+ {kind: "func", name: "Print"},
42
+ } {
43
+ if !hasSemanticDeclaration(semPkg, decl.kind, decl.name) {
44
+ t.Fatalf("missing declaration %s %s in %#v", decl.kind, decl.name, semPkg.declarations)
45
+ }
46
+ }
47
+ if len(semPkg.imports) != 1 || semPkg.imports[0].path != "fmt" {
48
+ t.Fatalf("unexpected imports: %#v", semPkg.imports)
49
+ }
50
+
51
+ global := requireSemanticValue(t, model, graph, "example.test/semantic", "Global")
52
+ if !global.topLevel || global.zeroValueKind != "struct-zero" {
53
+ t.Fatalf("unexpected Global value facts: %#v", global)
54
+ }
55
+ if global.position.file == "" || global.position.line == 0 {
56
+ t.Fatalf("expected Global source position, got %#v", global.position)
57
+ }
58
+ if len(semPkg.initOrder) != 1 || semPkg.initOrder[0].Name() != "Global" {
59
+ t.Fatalf("unexpected init order: %#v", semPkg.initOrder)
60
+ }
61
+ }
62
+
63
+ func TestSemanticModelRecordsAddressTakenVarRefs(t *testing.T) {
64
+ moduleDir := writePackageGraphFixture(t, map[string]string{
65
+ "go.mod": "module example.test/varref\n\ngo 1.25.3\n",
66
+ "main.go": strings.Join([]string{
67
+ "package varref",
68
+ "func Use() {",
69
+ " x := 1",
70
+ " p := &x",
71
+ " _ = &p",
72
+ "}",
73
+ "",
74
+ }, "\n"),
75
+ })
76
+ graph := loadPackageGraph(t, &CompileRequest{
77
+ Patterns: []string{"."},
78
+ Dir: moduleDir,
79
+ OutputPath: filepath.Join(t.TempDir(), "out"),
80
+ DependencyMode: DependencyModeRequested,
81
+ RuntimeEmissionMode: RuntimeEmissionModeEmit,
82
+ })
83
+ model := buildSemanticModel(t, graph)
84
+
85
+ for _, name := range []string{"x", "p"} {
86
+ obj := requireDefinedObject(t, graph, "example.test/varref", name)
87
+ if !model.addressTaken[obj] || !model.needsVarRef[obj] {
88
+ t.Fatalf("expected %s to be address-taken and need VarRef", name)
89
+ }
90
+ }
91
+ }
92
+
93
+ func TestSemanticModelRecordsStructFieldsAndReceivers(t *testing.T) {
94
+ moduleDir := writePackageGraphFixture(t, map[string]string{
95
+ "go.mod": "module example.test/structs\n\ngo 1.25.3\n",
96
+ "main.go": strings.Join([]string{
97
+ "package structs",
98
+ "type Counter struct {",
99
+ " // Value counts reads.",
100
+ " Value int",
101
+ " Label string",
102
+ "}",
103
+ "func (c Counter) Read() int { return c.Value }",
104
+ "func (c *Counter) Set(v int) { c.Value = v }",
105
+ "",
106
+ }, "\n"),
107
+ })
108
+ graph := loadPackageGraph(t, &CompileRequest{
109
+ Patterns: []string{"."},
110
+ Dir: moduleDir,
111
+ OutputPath: filepath.Join(t.TempDir(), "out"),
112
+ DependencyMode: DependencyModeRequested,
113
+ RuntimeEmissionMode: RuntimeEmissionModeEmit,
114
+ })
115
+ model := buildSemanticModel(t, graph)
116
+ counter := requireSemanticType(t, graph, model, "example.test/structs", "Counter")
117
+
118
+ if len(counter.fields) != 2 ||
119
+ counter.fields[0].name != "Value" ||
120
+ counter.fields[1].name != "Label" {
121
+ t.Fatalf("unexpected Counter fields: %#v", counter.fields)
122
+ }
123
+ if counter.fields[0].doc != "Value counts reads." {
124
+ t.Fatalf("unexpected Counter.Value doc: %#v", counter.fields[0].doc)
125
+ }
126
+
127
+ read := requireDefinedFunc(t, graph, "example.test/structs", "Read")
128
+ set := requireDefinedFunc(t, graph, "example.test/structs", "Set")
129
+ if model.functions[read].receiver == nil ||
130
+ model.functions[read].receiver.Obj().Name() != "Counter" ||
131
+ model.functions[read].receiverPointer {
132
+ t.Fatalf("unexpected value receiver facts: %#v", model.functions[read])
133
+ }
134
+ if model.functions[set].receiver == nil ||
135
+ model.functions[set].receiver.Obj().Name() != "Counter" ||
136
+ !model.functions[set].receiverPointer {
137
+ t.Fatalf("unexpected pointer receiver facts: %#v", model.functions[set])
138
+ }
139
+ }
140
+
141
+ func TestSemanticModelMarksNamedValueForPointerReceiverCall(t *testing.T) {
142
+ moduleDir := writePackageGraphFixture(t, map[string]string{
143
+ "go.mod": "module example.test/namedrecv\n\ngo 1.25.3\n",
144
+ "main.go": strings.Join([]string{
145
+ "package namedrecv",
146
+ "type Numbers []int",
147
+ "func (n *Numbers) Add(v int) { *n = append(*n, v) }",
148
+ "func Use() {",
149
+ " var n Numbers",
150
+ " n.Add(1)",
151
+ "}",
152
+ "",
153
+ }, "\n"),
154
+ })
155
+ graph := loadPackageGraph(t, &CompileRequest{
156
+ Patterns: []string{"."},
157
+ Dir: moduleDir,
158
+ OutputPath: filepath.Join(t.TempDir(), "out"),
159
+ DependencyMode: DependencyModeRequested,
160
+ RuntimeEmissionMode: RuntimeEmissionModeEmit,
161
+ })
162
+ model := buildSemanticModel(t, graph)
163
+ found := false
164
+ for obj := range model.needsVarRef {
165
+ if obj.Name() == "n" {
166
+ found = true
167
+ break
168
+ }
169
+ }
170
+ if !found {
171
+ t.Fatalf("expected named slice value receiver call to force VarRef")
172
+ }
173
+ }
174
+
175
+ func TestSemanticModelRecordsGeneratedImportNeeds(t *testing.T) {
176
+ moduleDir := writePackageGraphFixture(t, map[string]string{
177
+ "go.mod": "module example.test/imports\n\ngo 1.25.3\n",
178
+ "main.go": strings.Join([]string{
179
+ "package imports",
180
+ "import \"example.test/imports/subpkg\"",
181
+ "var Zero subpkg.Item",
182
+ "",
183
+ }, "\n"),
184
+ "subpkg/item.go": "package subpkg\ntype Item struct { Value int }\n",
185
+ })
186
+ graph := loadPackageGraph(t, &CompileRequest{
187
+ Patterns: []string{"."},
188
+ Dir: moduleDir,
189
+ OutputPath: filepath.Join(t.TempDir(), "out"),
190
+ DependencyMode: DependencyModeRequested,
191
+ RuntimeEmissionMode: RuntimeEmissionModeEmit,
192
+ })
193
+ model := buildSemanticModel(t, graph)
194
+
195
+ imports := generatedImportsForFile(t, model, "main.go")
196
+ if !imports["example.test/imports/subpkg"] {
197
+ t.Fatalf("expected generated import for subpkg, got %#v", imports)
198
+ }
199
+ }
200
+
201
+ func TestSemanticModelRecordsInterfaceAssertionAndNilFacts(t *testing.T) {
202
+ moduleDir := writePackageGraphFixture(t, map[string]string{
203
+ "go.mod": "module example.test/interfaces\n\ngo 1.25.3\n",
204
+ "main.go": strings.Join([]string{
205
+ "package interfaces",
206
+ "type Reader interface { Read() int }",
207
+ "type Impl struct{}",
208
+ "func (Impl) Read() int { return 1 }",
209
+ "func Use() {",
210
+ " var i Reader = Impl{}",
211
+ " _, _ = i.(Impl)",
212
+ " var p *Impl = nil",
213
+ " var sink Reader = p",
214
+ " var empty interface{} = nil",
215
+ " _, _ = sink, empty",
216
+ "}",
217
+ "",
218
+ }, "\n"),
219
+ })
220
+ graph := loadPackageGraph(t, &CompileRequest{
221
+ Patterns: []string{"."},
222
+ Dir: moduleDir,
223
+ OutputPath: filepath.Join(t.TempDir(), "out"),
224
+ DependencyMode: DependencyModeRequested,
225
+ RuntimeEmissionMode: RuntimeEmissionModeEmit,
226
+ })
227
+ model := buildSemanticModel(t, graph)
228
+ semPkg := requireSemanticPackage(t, model, "example.test/interfaces")
229
+
230
+ if len(semPkg.typeAssertions) != 1 ||
231
+ !strings.Contains(semPkg.typeAssertions[0].target.String(), "Impl") {
232
+ t.Fatalf("unexpected type assertions: %#v", semPkg.typeAssertions)
233
+ }
234
+ for _, kind := range []string{"typed-nil", "typed-nil-interface-risk", "nil-interface"} {
235
+ if !hasNilFactKind(semPkg, kind) {
236
+ t.Fatalf("missing nil fact %q in %#v", kind, semPkg.nilFacts)
237
+ }
238
+ }
239
+ if !hasInterfaceImplementation(model, "Impl", "Reader", false) {
240
+ t.Fatalf("missing Impl -> Reader interface implementation: %#v", model.interfaceImplementations)
241
+ }
242
+ }
243
+
244
+ func TestSemanticModelColorsAsyncFunctionsAndOverrides(t *testing.T) {
245
+ moduleDir := writePackageGraphFixture(t, map[string]string{
246
+ "go.mod": "module example.test/async\n\ngo 1.25.3\n",
247
+ "main.go": strings.Join([]string{
248
+ "package async",
249
+ "import \"sync\"",
250
+ "type Locker interface { Lock() }",
251
+ "type AsyncLocker struct { ch chan struct{} }",
252
+ "func (a *AsyncLocker) Lock() { <-a.ch }",
253
+ "func UseInterface(l Locker) { l.Lock() }",
254
+ "func CallChannel(a *AsyncLocker) { a.Lock() }",
255
+ "func UseMutex(mu *sync.Mutex) { mu.Lock() }",
256
+ "func Immediate() {}",
257
+ "",
258
+ }, "\n"),
259
+ })
260
+ graph := loadPackageGraph(t, &CompileRequest{
261
+ Patterns: []string{"."},
262
+ Dir: moduleDir,
263
+ OutputPath: filepath.Join(t.TempDir(), "out"),
264
+ DependencyMode: DependencyModeAll,
265
+ RuntimeEmissionMode: RuntimeEmissionModeEmit,
266
+ })
267
+ model := buildSemanticModel(t, graph)
268
+
269
+ for _, name := range []string{"UseInterface", "CallChannel", "UseMutex"} {
270
+ fn := requireDefinedFunc(t, graph, "example.test/async", name)
271
+ if !model.functions[fn].async {
272
+ t.Fatalf("expected %s to be async, got %#v", name, model.functions[fn])
273
+ }
274
+ }
275
+ immediate := requireDefinedFunc(t, graph, "example.test/async", "Immediate")
276
+ if model.functions[immediate].async {
277
+ t.Fatalf("did not expect Immediate to be async: %#v", model.functions[immediate])
278
+ }
279
+ if !hasInterfaceImplementation(model, "AsyncLocker", "Locker", true) {
280
+ t.Fatalf("missing *AsyncLocker -> Locker implementation: %#v", model.interfaceImplementations)
281
+ }
282
+ }
283
+
284
+ func buildSemanticModel(t *testing.T, graph *PackageGraph) *SemanticModel {
285
+ t.Helper()
286
+
287
+ model, diagnostics := NewSemanticModelOwner(NewOverrideRegistryOwner()).Build(context.Background(), graph)
288
+ if diagnosticsHaveErrors(diagnostics) {
289
+ t.Fatalf("semantic model build failed: %#v", diagnostics)
290
+ }
291
+ if model == nil {
292
+ t.Fatalf("semantic model build returned nil")
293
+ }
294
+ return model
295
+ }
296
+
297
+ func requireSemanticPackage(t *testing.T, model *SemanticModel, pkgPath string) *semanticPackage {
298
+ t.Helper()
299
+
300
+ semPkg := model.packages[pkgPath]
301
+ if semPkg == nil {
302
+ t.Fatalf("missing semantic package %q in %#v", pkgPath, model.packages)
303
+ }
304
+ return semPkg
305
+ }
306
+
307
+ func hasSemanticDeclaration(semPkg *semanticPackage, kind string, name string) bool {
308
+ for _, decl := range semPkg.declarations {
309
+ if decl.kind == kind && decl.name == name {
310
+ return true
311
+ }
312
+ }
313
+ return false
314
+ }
315
+
316
+ func requireSemanticValue(
317
+ t *testing.T,
318
+ model *SemanticModel,
319
+ graph *PackageGraph,
320
+ pkgPath string,
321
+ name string,
322
+ ) *semanticValue {
323
+ t.Helper()
324
+
325
+ obj := requireDefinedObject(t, graph, pkgPath, name)
326
+ value := model.values[obj]
327
+ if value == nil {
328
+ t.Fatalf("missing semantic value for %s", name)
329
+ }
330
+ return value
331
+ }
332
+
333
+ func requireSemanticType(
334
+ t *testing.T,
335
+ graph *PackageGraph,
336
+ model *SemanticModel,
337
+ pkgPath string,
338
+ name string,
339
+ ) *semanticType {
340
+ t.Helper()
341
+
342
+ obj, _ := requireDefinedObject(t, graph, pkgPath, name).(*types.TypeName)
343
+ if obj == nil {
344
+ t.Fatalf("defined object %s is not a type", name)
345
+ }
346
+ named, _ := obj.Type().(*types.Named)
347
+ if named == nil {
348
+ t.Fatalf("defined type %s is not named", name)
349
+ }
350
+ semType := model.types[named]
351
+ if semType == nil {
352
+ t.Fatalf("missing semantic type for %s", name)
353
+ }
354
+ return semType
355
+ }
356
+
357
+ func requireDefinedFunc(t *testing.T, graph *PackageGraph, pkgPath string, name string) *types.Func {
358
+ t.Helper()
359
+
360
+ fn, _ := requireDefinedObject(t, graph, pkgPath, name).(*types.Func)
361
+ if fn == nil {
362
+ t.Fatalf("defined object %s is not a function", name)
363
+ }
364
+ return fn
365
+ }
366
+
367
+ func requireDefinedObject(t *testing.T, graph *PackageGraph, pkgPath string, name string) types.Object {
368
+ t.Helper()
369
+
370
+ pkg := graph.packagesByPath[pkgPath]
371
+ if pkg == nil {
372
+ t.Fatalf("missing loaded package %q", pkgPath)
373
+ }
374
+ for ident, obj := range pkg.TypesInfo.Defs {
375
+ if ident.Name == name && obj != nil {
376
+ return obj
377
+ }
378
+ }
379
+ t.Fatalf("missing defined object %s in %s", name, pkgPath)
380
+ return nil
381
+ }
382
+
383
+ func generatedImportsForFile(t *testing.T, model *SemanticModel, base string) map[string]bool {
384
+ t.Helper()
385
+
386
+ for file, imports := range model.generatedImports {
387
+ if filepath.Base(file) == base {
388
+ return imports
389
+ }
390
+ }
391
+ t.Fatalf("missing generated imports for %s in %#v", base, model.generatedImports)
392
+ return nil
393
+ }
394
+
395
+ func hasNilFactKind(semPkg *semanticPackage, kind string) bool {
396
+ for _, fact := range semPkg.nilFacts {
397
+ if fact.kind == kind {
398
+ return true
399
+ }
400
+ }
401
+ return false
402
+ }
403
+
404
+ func hasInterfaceImplementation(model *SemanticModel, typ string, iface string, pointer bool) bool {
405
+ for _, implementation := range model.interfaceImplementations {
406
+ if implementation.pointer != pointer ||
407
+ implementation.typ == nil ||
408
+ implementation.iface == nil {
409
+ continue
410
+ }
411
+ if implementation.typ.Obj().Name() == typ && implementation.iface.Obj().Name() == iface {
412
+ return true
413
+ }
414
+ }
415
+ return false
416
+ }
@@ -0,0 +1,133 @@
1
+ package compiler
2
+
3
+ import "context"
4
+
5
+ // CompileService owns the v2 compiler pipeline.
6
+ type CompileService struct {
7
+ requestOwner *CompileRequestOwner
8
+ graphOwner *PackageGraphOwner
9
+ semanticOwner *SemanticModelOwner
10
+ loweringOwner *LoweringOwner
11
+ emitterOwner *TypeScriptEmitOwner
12
+ runtimeOwner *RuntimeContractOwner
13
+ overrideOwner *OverrideRegistryOwner
14
+ }
15
+
16
+ // NewCompileService creates a compile service with every pipeline owner.
17
+ func NewCompileService() *CompileService {
18
+ overrideOwner := NewOverrideRegistryOwner()
19
+ runtimeOwner := NewRuntimeContractOwner()
20
+ return &CompileService{
21
+ requestOwner: NewCompileRequestOwner(),
22
+ graphOwner: NewPackageGraphOwner(),
23
+ semanticOwner: NewSemanticModelOwner(overrideOwner),
24
+ loweringOwner: NewLoweringOwner(runtimeOwner, overrideOwner),
25
+ emitterOwner: NewTypeScriptEmitOwner(runtimeOwner),
26
+ runtimeOwner: runtimeOwner,
27
+ overrideOwner: overrideOwner,
28
+ }
29
+ }
30
+
31
+ // RequestOwner returns the compile request owner.
32
+ func (s *CompileService) RequestOwner() *CompileRequestOwner {
33
+ return s.requestOwner
34
+ }
35
+
36
+ // PackageGraphOwner returns the package graph owner.
37
+ func (s *CompileService) PackageGraphOwner() *PackageGraphOwner {
38
+ return s.graphOwner
39
+ }
40
+
41
+ // SemanticModelOwner returns the semantic model owner.
42
+ func (s *CompileService) SemanticModelOwner() *SemanticModelOwner {
43
+ return s.semanticOwner
44
+ }
45
+
46
+ // LoweringOwner returns the lowering owner.
47
+ func (s *CompileService) LoweringOwner() *LoweringOwner {
48
+ return s.loweringOwner
49
+ }
50
+
51
+ // TypeScriptEmitOwner returns the TypeScript emit owner.
52
+ func (s *CompileService) TypeScriptEmitOwner() *TypeScriptEmitOwner {
53
+ return s.emitterOwner
54
+ }
55
+
56
+ // RuntimeContractOwner returns the runtime contract owner.
57
+ func (s *CompileService) RuntimeContractOwner() *RuntimeContractOwner {
58
+ return s.runtimeOwner
59
+ }
60
+
61
+ // OverrideRegistryOwner returns the override registry owner.
62
+ func (s *CompileService) OverrideRegistryOwner() *OverrideRegistryOwner {
63
+ return s.overrideOwner
64
+ }
65
+
66
+ // Compile runs one request through the v2 pipeline.
67
+ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*CompilationResult, error) {
68
+ if err := ctx.Err(); err != nil {
69
+ return nil, err
70
+ }
71
+
72
+ result := &CompilationResult{}
73
+ if req != nil {
74
+ result.OriginalPackages = append([]string(nil), req.Patterns...)
75
+ }
76
+
77
+ diagnostics := s.requestOwner.Validate(req)
78
+ if diagnosticsHaveErrors(diagnostics) {
79
+ result.Diagnostics = diagnostics
80
+ return result, NewCompileError(diagnostics)
81
+ }
82
+
83
+ graph, graphDiagnostics := s.graphOwner.Load(ctx, req)
84
+ diagnostics = append(diagnostics, graphDiagnostics...)
85
+ if graph != nil {
86
+ result.OriginalPackages = append([]string(nil), graph.RequestedPackagePaths...)
87
+ }
88
+ if diagnosticsHaveErrors(diagnostics) {
89
+ result.Diagnostics = diagnostics
90
+ return result, NewCompileError(diagnostics)
91
+ }
92
+
93
+ semanticModel, semanticDiagnostics := s.semanticOwner.Build(ctx, graph)
94
+ diagnostics = append(diagnostics, semanticDiagnostics...)
95
+ if diagnosticsHaveErrors(diagnostics) {
96
+ result.Diagnostics = diagnostics
97
+ return result, NewCompileError(diagnostics)
98
+ }
99
+
100
+ overridePlan, overrideDiagnostics := s.overrideOwner.CopyPlan(ctx, req, graph)
101
+ diagnostics = append(diagnostics, overrideDiagnostics...)
102
+ if diagnosticsHaveErrors(diagnostics) {
103
+ result.Diagnostics = diagnostics
104
+ return result, NewCompileError(diagnostics)
105
+ }
106
+
107
+ loweredProgram, loweringDiagnostics := s.loweringOwner.Build(ctx, semanticModel)
108
+ diagnostics = append(diagnostics, loweringDiagnostics...)
109
+ if diagnosticsHaveErrors(diagnostics) {
110
+ result.Diagnostics = diagnostics
111
+ return result, NewCompileError(diagnostics)
112
+ }
113
+
114
+ compiledPackages, emitDiagnostics := s.emitterOwner.Emit(ctx, req, loweredProgram)
115
+ diagnostics = append(diagnostics, emitDiagnostics...)
116
+ if diagnosticsHaveErrors(diagnostics) {
117
+ result.Diagnostics = diagnostics
118
+ return result, NewCompileError(diagnostics)
119
+ }
120
+ result.CompiledPackages = append(result.CompiledPackages, compiledPackages...)
121
+
122
+ copiedPackages, copyDiagnostics := s.overrideOwner.CopyPackages(ctx, req, overridePlan)
123
+ diagnostics = append(diagnostics, copyDiagnostics...)
124
+ if diagnosticsHaveErrors(diagnostics) {
125
+ result.CopiedPackages = append(result.CopiedPackages, copiedPackages...)
126
+ result.Diagnostics = diagnostics
127
+ return result, NewCompileError(diagnostics)
128
+ }
129
+ result.CopiedPackages = append(result.CopiedPackages, copiedPackages...)
130
+
131
+ result.Diagnostics = diagnostics
132
+ return result, nil
133
+ }