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
package/compiler/field.go DELETED
@@ -1,183 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "go/ast"
5
- "go/types"
6
- )
7
-
8
- // WriteFieldList translates a Go field list (`ast.FieldList`), which can represent
9
- // function parameters, function results, or struct fields, into its TypeScript equivalent.
10
- // - If `isArguments` is true (for function parameters/results):
11
- // It iterates through `a.List`, writing each field as `name: type`. Parameter
12
- // names and types are written using `WriteField` and `WriteGoType` respectively.
13
- // Multiple parameters are comma-separated.
14
- // - If `isArguments` is false (for struct fields):
15
- // It writes an opening brace `{`, indents, then writes each field definition
16
- // using `WriteField`, followed by a closing brace `}`. If the field list is
17
- // empty or nil, it simply writes `{}`.
18
- //
19
- // This function is a key part of generating TypeScript type signatures for functions
20
- // and interfaces, as well as struct type definitions.
21
- func (c *GoToTSCompiler) WriteFieldList(a *ast.FieldList, isArguments bool) {
22
- if !isArguments && (a == nil || a.NumFields() == 0) {
23
- c.tsw.WriteLiterally("{}")
24
- return
25
- }
26
-
27
- if !isArguments && a.Opening.IsValid() {
28
- c.tsw.WriteLine("{")
29
- c.tsw.Indent(1)
30
- }
31
-
32
- // Check if this is a variadic function parameter list
33
- isVariadic := false
34
- if isArguments && a != nil && len(a.List) > 0 {
35
- lastParam := a.List[len(a.List)-1]
36
- if _, ok := lastParam.Type.(*ast.Ellipsis); ok {
37
- isVariadic = true
38
- }
39
- }
40
-
41
- if isArguments && isVariadic {
42
- // Handle non-variadic parameters first
43
- for i, field := range a.List[:len(a.List)-1] {
44
- if i > 0 {
45
- c.tsw.WriteLiterally(", ")
46
- }
47
-
48
- // Handle multiple parameter names for the same type
49
- for j, name := range field.Names {
50
- if j > 0 {
51
- c.tsw.WriteLiterally(", ")
52
- }
53
- c.tsw.WriteLiterally(c.sanitizeIdentifier(name.Name))
54
- c.tsw.WriteLiterally(": ")
55
- // Use WriteTypeExpr to preserve qualified names like os.FileInfo
56
- c.WriteTypeExpr(field.Type)
57
- }
58
- }
59
-
60
- // Handle the variadic parameter
61
- lastParam := a.List[len(a.List)-1]
62
- if len(a.List) > 1 {
63
- c.tsw.WriteLiterally(", ")
64
- }
65
-
66
- for i, name := range lastParam.Names {
67
- if i > 0 {
68
- c.tsw.WriteLiterally(", ")
69
- }
70
- c.tsw.WriteLiterally("...")
71
- c.tsw.WriteLiterally(c.sanitizeIdentifier(name.Name))
72
- }
73
-
74
- c.tsw.WriteLiterally(": ")
75
- if ellipsis, ok := lastParam.Type.(*ast.Ellipsis); ok {
76
- // Get the actual variadic parameter type from the type checker
77
- // This gives us the slice type (e.g., []interface{})
78
- variadicType := c.pkg.TypesInfo.TypeOf(lastParam.Type)
79
- if sliceType, isSlice := variadicType.(*types.Slice); isSlice {
80
- // For variadic parameters, write the element type followed by []
81
- // This handles interface{} properly by generating "any[]" instead of "null | any[]"
82
- c.WriteGoType(sliceType.Elem(), GoTypeContextVariadicParam)
83
- c.tsw.WriteLiterally("[]")
84
- } else {
85
- // Fallback to the original AST-based approach for edge cases
86
- c.WriteTypeExpr(ellipsis.Elt)
87
- c.tsw.WriteLiterally("[]")
88
- }
89
- }
90
- } else {
91
- // Handle regular parameter list for function declarations
92
- for i, field := range a.List {
93
- if i > 0 && isArguments {
94
- c.tsw.WriteLiterally(", ")
95
- }
96
-
97
- if isArguments {
98
- // For function parameters with multiple names, write each with its type
99
- for j, name := range field.Names {
100
- if j > 0 {
101
- c.tsw.WriteLiterally(", ")
102
- }
103
- c.tsw.WriteLiterally(c.sanitizeIdentifier(name.Name))
104
- c.tsw.WriteLiterally(": ")
105
- // Use WriteTypeExpr to preserve qualified names like os.FileInfo
106
- c.WriteTypeExpr(field.Type)
107
- }
108
- } else {
109
- // For struct fields and other non-argument fields
110
- c.WriteField(field, false)
111
- }
112
- }
113
- }
114
-
115
- if !isArguments && a.Closing.IsValid() {
116
- c.tsw.Indent(-1)
117
- c.tsw.WriteLine("}")
118
- }
119
- }
120
-
121
- // WriteField translates a single Go field (`ast.Field`) from a field list
122
- // (e.g., in a struct type or function signature) into its TypeScript representation.
123
- // - If `isArguments` is false (struct field):
124
- // - Documentation comments (`field.Doc`, `field.Comment`) are preserved.
125
- // - If the field is anonymous (embedded), it's skipped as promotions are handled
126
- // elsewhere (e.g., during struct class generation).
127
- // - For named fields, it writes `public fieldName: FieldType_ts`. The field name
128
- // retains its Go casing. The type is translated using `WriteGoType`.
129
- // - Go struct tags (`field.Tag`) are written as a trailing comment.
130
- //
131
- // - If `isArguments` is true (function parameter):
132
- // - It writes the parameter name (retaining Go casing). The type is handled
133
- // by the caller (`WriteFieldList`).
134
- //
135
- // This function is used by `WriteFieldList` to process individual items within
136
- // parameter lists and struct field definitions.
137
- func (c *GoToTSCompiler) WriteField(field *ast.Field, isArguments bool) {
138
- if !isArguments {
139
- if field.Doc != nil {
140
- c.WriteDoc(field.Doc)
141
- }
142
- if field.Comment != nil {
143
- c.WriteDoc(field.Comment)
144
- }
145
- }
146
-
147
- // Check if this is an embedded field (anonymous field)
148
- if len(field.Names) == 0 && !isArguments {
149
- // This is an embedded field, so we're adding promotions instead of declaring it directly
150
- return
151
- }
152
-
153
- for i, name := range field.Names {
154
- if i > 0 && isArguments {
155
- c.tsw.WriteLiterally(", ")
156
- }
157
-
158
- // argument names: keep original casing, no access modifier
159
- if isArguments {
160
- c.tsw.WriteLiterally(c.sanitizeIdentifier(name.Name))
161
- // Argument type is handled in WriteFieldList, so continue
162
- continue
163
- } else {
164
- // All struct fields are public in TypeScript, keeping original Go casing
165
- c.tsw.WriteLiterally("public ")
166
- c.tsw.WriteLiterally(name.Name)
167
- }
168
-
169
- // write type for struct fields (not arguments)
170
- c.tsw.WriteLiterally(": ")
171
- typ := c.pkg.TypesInfo.TypeOf(field.Type)
172
- c.WriteGoType(typ, GoTypeContextGeneral) // Use WriteGoType for field type
173
-
174
- if !isArguments {
175
- // write tag comment if any for struct fields
176
- if field.Tag != nil {
177
- c.tsw.WriteCommentLinef("tag: %s", field.Tag.Value)
178
- } else {
179
- c.tsw.WriteLine("") // No semicolon
180
- }
181
- }
182
- }
183
- }
@@ -1,298 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "context"
5
- "os"
6
- "path/filepath"
7
- "slices"
8
- "strings"
9
- "testing"
10
-
11
- "github.com/sirupsen/logrus"
12
- )
13
-
14
- func TestReadGsPackageMetadata(t *testing.T) {
15
- // Create a basic compiler configuration
16
- config := &Config{
17
- OutputPath: "./test_output",
18
- Dir: ".",
19
- }
20
-
21
- // Create a logger (set to warn level to reduce noise in tests)
22
- logger := logrus.New()
23
- logger.SetLevel(logrus.WarnLevel)
24
- le := logrus.NewEntry(logger)
25
-
26
- // Create a compiler
27
- comp, err := NewCompiler(config, le, nil)
28
- if err != nil {
29
- t.Fatalf("Failed to create compiler: %v", err)
30
- }
31
-
32
- // Test reading metadata from the bytes package
33
- metadata, err := comp.ReadGsPackageMetadata("gs/bytes")
34
- if err != nil {
35
- t.Fatalf("Failed to read metadata: %v", err)
36
- }
37
-
38
- // Check that we found the expected dependencies
39
- if len(metadata.Dependencies) == 0 {
40
- t.Errorf("Expected at least one dependency, got none")
41
- }
42
-
43
- // Check for the specific "iter" dependency
44
- foundIter := slices.Contains(metadata.Dependencies, "iter")
45
-
46
- if !foundIter {
47
- t.Errorf("Expected to find 'iter' dependency, got dependencies: %v", metadata.Dependencies)
48
- }
49
-
50
- // Also check for other expected dependencies from the bytes package
51
- expectedDeps := []string{"errors", "io", "iter", "unicode", "unicode/utf8", "unsafe"}
52
- for _, expected := range expectedDeps {
53
- found := slices.Contains(metadata.Dependencies, expected)
54
- if !found {
55
- t.Errorf("Expected to find dependency '%s', got dependencies: %v", expected, metadata.Dependencies)
56
- }
57
- }
58
- }
59
-
60
- func TestReadGsPackageMetadataWithAsyncMethods(t *testing.T) {
61
- // Create a basic compiler configuration
62
- config := &Config{
63
- OutputPath: "./test_output",
64
- Dir: ".",
65
- }
66
-
67
- // Create a logger (set to warn level to reduce noise in tests)
68
- logger := logrus.New()
69
- logger.SetLevel(logrus.WarnLevel)
70
- le := logrus.NewEntry(logger)
71
-
72
- // Create a compiler
73
- comp, err := NewCompiler(config, le, nil)
74
- if err != nil {
75
- t.Fatalf("Failed to create compiler: %v", err)
76
- }
77
-
78
- // Test reading metadata from the sync package (which has async methods)
79
- metadata, err := comp.ReadGsPackageMetadata("gs/sync")
80
- if err != nil {
81
- t.Fatalf("Failed to read metadata: %v", err)
82
- }
83
-
84
- // Check that we have async methods
85
- if len(metadata.AsyncMethods) == 0 {
86
- t.Errorf("Expected at least one async method for sync package, got none")
87
- }
88
-
89
- // Check for specific async methods
90
- expectedAsyncMethods := []string{"Mutex.Lock", "WaitGroup.Wait", "RWMutex.Lock"}
91
- for _, methodName := range expectedAsyncMethods {
92
- if isAsync, exists := metadata.AsyncMethods[methodName]; !exists {
93
- t.Errorf("Expected to find async method '%s'", methodName)
94
- } else if !isAsync {
95
- t.Errorf("Expected method '%s' to be async, but it's not", methodName)
96
- }
97
- }
98
- }
99
-
100
- func TestReadGsPackageMetadataNonExistent(t *testing.T) {
101
- // Create a basic compiler configuration
102
- config := &Config{
103
- OutputPath: "./test_output",
104
- Dir: ".",
105
- }
106
-
107
- // Create a logger (set to warn level to reduce noise in tests)
108
- logger := logrus.New()
109
- logger.SetLevel(logrus.WarnLevel)
110
- le := logrus.NewEntry(logger)
111
-
112
- // Create a compiler
113
- comp, err := NewCompiler(config, le, nil)
114
- if err != nil {
115
- t.Fatalf("Failed to create compiler: %v", err)
116
- }
117
-
118
- // Test reading metadata from a non-existent package
119
- metadata, err := comp.ReadGsPackageMetadata("gs/nonexistent")
120
- if err != nil {
121
- t.Fatalf("Expected no error for non-existent package, got: %v", err)
122
- }
123
-
124
- // Should return empty metadata for non-existent packages
125
- if len(metadata.Dependencies) != 0 {
126
- t.Errorf("Expected empty dependencies for non-existent package, got: %v", metadata.Dependencies)
127
- }
128
-
129
- if len(metadata.AsyncMethods) != 0 {
130
- t.Errorf("Expected empty async methods for non-existent package, got: %v", metadata.AsyncMethods)
131
- }
132
- }
133
-
134
- func TestCompilePackagesCopiesHandwrittenDependencies(t *testing.T) {
135
- tempDir, err := os.MkdirTemp("", "goscript-gs-deps")
136
- if err != nil {
137
- t.Fatalf("Failed to create temp dir: %v", err)
138
- }
139
- defer os.RemoveAll(tempDir)
140
-
141
- wd, err := os.Getwd()
142
- if err != nil {
143
- t.Fatalf("Failed to get working directory: %v", err)
144
- }
145
-
146
- config := &Config{
147
- OutputPath: tempDir,
148
- Dir: filepath.Dir(wd),
149
- AllDependencies: true,
150
- DisableEmitBuiltin: false,
151
- }
152
-
153
- logger := logrus.New()
154
- logger.SetLevel(logrus.WarnLevel)
155
- le := logrus.NewEntry(logger)
156
-
157
- comp, err := NewCompiler(config, le, nil)
158
- if err != nil {
159
- t.Fatalf("Failed to create compiler: %v", err)
160
- }
161
-
162
- _, err = comp.CompilePackages(
163
- context.Background(),
164
- "github.com/aperturerobotics/goscript/tests/tests/package_import_slices",
165
- )
166
- if err != nil {
167
- t.Fatalf("Compilation failed: %v", err)
168
- }
169
-
170
- cmpPath := filepath.Join(tempDir, "@goscript", "cmp", "index.ts")
171
- if _, err := os.Stat(cmpPath); err != nil {
172
- t.Fatalf("Expected handwritten dependency at %s: %v", cmpPath, err)
173
- }
174
- }
175
-
176
- func TestCompilePackagesEmitTypeScriptImportSpecifiers(t *testing.T) {
177
- tempDir, err := os.MkdirTemp("", "goscript-ts-imports")
178
- if err != nil {
179
- t.Fatalf("Failed to create temp dir: %v", err)
180
- }
181
- defer os.RemoveAll(tempDir)
182
-
183
- wd, err := os.Getwd()
184
- if err != nil {
185
- t.Fatalf("Failed to get working directory: %v", err)
186
- }
187
-
188
- config := &Config{
189
- OutputPath: tempDir,
190
- Dir: filepath.Dir(wd),
191
- AllDependencies: true,
192
- DisableEmitBuiltin: false,
193
- }
194
-
195
- logger := logrus.New()
196
- logger.SetLevel(logrus.WarnLevel)
197
- le := logrus.NewEntry(logger)
198
-
199
- comp, err := NewCompiler(config, le, nil)
200
- if err != nil {
201
- t.Fatalf("Failed to create compiler: %v", err)
202
- }
203
-
204
- _, err = comp.CompilePackages(
205
- context.Background(),
206
- "github.com/aperturerobotics/goscript/tests/tests/package_import",
207
- "github.com/aperturerobotics/goscript/tests/tests/map_value_field_access_cross_file",
208
- )
209
- if err != nil {
210
- t.Fatalf("Compilation failed: %v", err)
211
- }
212
-
213
- assertFileContains(t,
214
- filepath.Join(
215
- tempDir,
216
- "@goscript",
217
- "github.com",
218
- "aperturerobotics",
219
- "goscript",
220
- "tests",
221
- "tests",
222
- "package_import",
223
- "package_import.gs.ts",
224
- ),
225
- []string{
226
- `@goscript/builtin/index.ts`,
227
- `@goscript/github.com/aperturerobotics/goscript/tests/tests/package_import/subpkg/index.ts`,
228
- },
229
- []string{
230
- ".js",
231
- },
232
- )
233
-
234
- assertFileContains(t,
235
- filepath.Join(
236
- tempDir,
237
- "@goscript",
238
- "github.com",
239
- "aperturerobotics",
240
- "goscript",
241
- "tests",
242
- "tests",
243
- "package_import",
244
- "subpkg",
245
- "index.ts",
246
- ),
247
- []string{
248
- `"./subpkg.gs.ts"`,
249
- },
250
- []string{
251
- ".gs.js",
252
- },
253
- )
254
-
255
- assertFileContains(t,
256
- filepath.Join(
257
- tempDir,
258
- "@goscript",
259
- "github.com",
260
- "aperturerobotics",
261
- "goscript",
262
- "tests",
263
- "tests",
264
- "map_value_field_access_cross_file",
265
- "read.gs.ts",
266
- ),
267
- []string{
268
- `"./types.gs.ts"`,
269
- `@goscript/builtin/index.ts`,
270
- },
271
- []string{
272
- ".gs.js",
273
- "index.js",
274
- },
275
- )
276
- }
277
-
278
- func assertFileContains(t *testing.T, path string, want []string, wantAbsent []string) {
279
- t.Helper()
280
-
281
- data, err := os.ReadFile(path)
282
- if err != nil {
283
- t.Fatalf("Failed to read %s: %v", path, err)
284
- }
285
- text := string(data)
286
-
287
- for _, s := range want {
288
- if !strings.Contains(text, s) {
289
- t.Fatalf("Expected %s to contain %q\n%s", path, s, text)
290
- }
291
- }
292
-
293
- for _, s := range wantAbsent {
294
- if strings.Contains(text, s) {
295
- t.Fatalf("Expected %s to omit %q\n%s", path, s, text)
296
- }
297
- }
298
- }