Skip to content

Commit 786866c

Browse files
committed
refactor: move builtin packages to gs/
Signed-off-by: Christian Stewart <[email protected]>
1 parent 81bac4a commit 786866c

File tree

104 files changed

+176
-138
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+176
-138
lines changed

.roo/rules/aider

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
You may invoke an advanced artificial intelligence to analyze code or make edits to code by first writing the details of the task you want to complete and the prompt to `.aider-prompt` in the workspace root and then running the `aider` command-line tool with the --message-file flag set to `.aider-prompt`, including the filenames of all relevant code files and the files to edit as arguments. For example: `aider --yes-always --no-git --no-pretty --message-file .aider-prompt source_file.go other_source_file.ts information.md` - remember that `aider` is a shell command. Explicitly tell aider to not make any file changes if you don't expressly want that to happen.
22
When using the `aider` tool add the `--architect` flag when asking aider to make difficult changes to files and add `--model o4-mini` if the task is very hard and you are not using many context files. Otherwise do not specify the `--model` nor the `--architect` flags.
33
Remember that `aider` is a single-turn AI tool and cannot access git history or run commands directly. To review changes, provide the relevant file contents to `aider` via command line arguments and the `.aider-prompt` file. The `.aider-prompt` file should contain the task description and any additional context needed for the review.
4-
Pass all of the compiler source files as arguments to aider. You can use "./compiler/*.go ./builtin/builtin.ts" to include all relevant files. Also include any WIP.md file if you are using one.
4+
Pass all of the compiler source files as arguments to aider. You can use "./compiler/*.go ./gs/builtin/builtin.ts" to include all relevant files. Also include any WIP.md file if you are using one.
55
Remember to always pass a high-level context and description of the task to Aider without a specific solution, and let aider figure out what to do to solve the problem.

.roo/rules/project-info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
GoScript is an experimental Go to TypeScript transpiler that enables developers to convert high-level Go code into maintainable TypeScript. It translates Go constructs—such as structs, functions, and pointer semantics—into idiomatic TypeScript code while preserving Go's value semantics and type safety. It is designed to bridge the gap between the robust type system of Go and the flexible ecosystem of TypeScript. The GoScript runtime, located in `builtin/builtin.ts`, provides necessary helper functions and is imported in generated code using the `@goscript/builtin` alias.
1+
GoScript is an experimental Go to TypeScript transpiler that enables developers to convert high-level Go code into maintainable TypeScript. It translates Go constructs—such as structs, functions, and pointer semantics—into idiomatic TypeScript code while preserving Go's value semantics and type safety. It is designed to bridge the gap between the robust type system of Go and the flexible ecosystem of TypeScript. The GoScript runtime, located in `gs/builtin/builtin.ts`, provides necessary helper functions and is imported in generated code using the `@goscript/builtin` alias.
22
The generated output TypeScript style from the transpiler should not use semicolons and should always focus on code clarity and correctness.
33
Follow Rick Rubin's concept of being both an engineer and a reducer (not always a producer) by focusing on the shortest, most straightforward solution that is correct.

builtin/builtin.go

Lines changed: 0 additions & 11 deletions
This file was deleted.

cmd/goscript/cmd_compile.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
"github.com/pkg/errors"
1010
"github.com/sirupsen/logrus"
1111

12-
// _ ensure we include the builtin package
13-
_ "github.com/aperturerobotics/goscript/builtin"
12+
// _ ensure we include the gs package
13+
_ "github.com/aperturerobotics/goscript"
1414
)
1515

1616
var (

compiler/compiler.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"path/filepath"
1111
"strings"
1212

13+
gs "github.com/aperturerobotics/goscript"
1314
"github.com/sirupsen/logrus"
1415
"golang.org/x/tools/go/packages"
1516
)
@@ -140,6 +141,16 @@ func (c *Compiler) CompilePackages(ctx context.Context, patterns ...string) erro
140141

141142
// Compile all packages
142143
for _, pkg := range pkgs {
144+
// Check if the package has a handwritten equivalent
145+
_, gsErr := gs.GsOverrides.ReadDir("gs/" + pkg.PkgPath)
146+
if gsErr != nil && !os.IsNotExist(gsErr) {
147+
return gsErr
148+
}
149+
if gsErr == nil {
150+
c.le.Infof("Skipping compilation for overridden package %s", pkg.PkgPath)
151+
continue
152+
}
153+
143154
// Skip packages that failed to load
144155
if len(pkg.Errors) > 0 {
145156
c.le.WithError(pkg.Errors[0]).Warnf("Skipping package %s due to errors", pkg.PkgPath)
@@ -328,8 +339,8 @@ func NewFileCompiler(
328339
// top-level declarations in the Go file.
329340
func (c *FileCompiler) Compile(ctx context.Context) error {
330341
f := c.ast
331-
332342
pkgPath := c.pkg.PkgPath
343+
333344
outputFilePath := TranslateGoFilePathToTypescriptFilePath(pkgPath, filepath.Base(c.fullPath))
334345
outputFilePathAbs := filepath.Join(c.compilerConfig.OutputPathRoot, outputFilePath)
335346

@@ -349,7 +360,7 @@ func (c *FileCompiler) Compile(ctx context.Context) error {
349360
goWriter := NewGoToTSCompiler(c.codeWriter, c.pkg, c.Analysis)
350361

351362
// Add import for the goscript runtime using namespace import and alias
352-
c.codeWriter.WriteLine("import * as $ from \"@goscript/builtin\";")
363+
c.codeWriter.WriteLinef("import * as $ from %q;", "@goscript/builtin/builtin.js")
353364
c.codeWriter.WriteLine("") // Add a newline after the import
354365

355366
if err := goWriter.WriteDecls(f.Decls); err != nil {
@@ -368,7 +379,7 @@ type GoToTSCompiler struct {
368379

369380
pkg *packages.Package
370381

371-
analysis *Analysis // Holds analysis information for code generation decisions
382+
analysis *Analysis
372383
}
373384

374385
// It initializes the compiler with a `TSCodeWriter` for output,

compiler/spec.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,20 @@ func (c *GoToTSCompiler) WriteImportSpec(a *ast.ImportSpec) {
253253
impName = a.Name.Name
254254
}
255255

256-
importPath := translateGoPathToTypescriptPath(goPath)
256+
// All Go package imports are mapped to the @goscript/ scope.
257+
// The TypeScript compiler will resolve these using tsconfig paths to either
258+
// handwritten versions (in .goscript-assets) or transpiled versions (in goscript).
259+
var tsImportPath string
260+
if goPath == "github.com/aperturerobotics/goscript/builtin" {
261+
tsImportPath = "@goscript/builtin/builtin.js"
262+
} else {
263+
tsImportPath = "@goscript/" + goPath
264+
}
265+
257266
c.analysis.Imports[impName] = &fileImport{
258-
importPath: importPath,
267+
importPath: tsImportPath,
259268
importVars: make(map[string]struct{}),
260269
}
261270

262-
c.tsw.WriteImport(impName, importPath+"/index.js")
271+
c.tsw.WriteImport(impName, tsImportPath+"/index.js")
263272
}

compliance/compliance.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ func copyFile(src, dst string) error {
437437
// It includes all "*.gs.ts" and "index.ts" files found recursively within testDir.
438438
// It sets up "paths" aliases for:
439439
// - The test's own generated package: "@goscript/PARENT_MODULE/compliance/tests/TEST_NAME/*" -> "./*"
440-
// - The goscript builtin types: "@goscript/builtin" -> relative path to "workspaceDir/builtin/builtin.ts"
440+
// - The goscript builtin types: "@goscript/builtin" -> relative path to "workspaceDir/gs/builtin/builtin.ts"
441441
//
442442
// Returns the path to the generated "tsconfig.json" file.
443443
func WriteTypeCheckConfig(t *testing.T, parentModulePath, workspaceDir, testDir string) string {
@@ -500,16 +500,12 @@ func WriteTypeCheckConfig(t *testing.T, parentModulePath, workspaceDir, testDir
500500
compilerOptions := maps.Clone(tsconfig["compilerOptions"].(map[string]interface{}))
501501
compilerOptions["baseUrl"] = "." // testDir is baseUrl
502502

503-
// For paths in tsconfig, it's often better to use relative paths from baseUrl if possible,
504-
// but for @goscript/builtin, pointing to the canonical one is important.
505-
// It needs to be relative from testDir (baseUrl) to workspaceDir/builtin/builtin.ts
506-
builtinTsRelPath := filepath.ToSlash(filepath.Join(relWorkspacePath, "builtin", "builtin.ts"))
507-
508503
// Alias for this test's own generated packages
504+
builtinTsRelPath := filepath.ToSlash(filepath.Join(relWorkspacePath, "gs", "*"))
509505
testPkgGoPathPrefix := fmt.Sprintf("%s/compliance/tests/%s", parentModulePath, testName)
510506
compilerOptions["paths"] = map[string][]string{
511-
fmt.Sprintf("@goscript/%s/*", testPkgGoPathPrefix): {"./*"}, // Maps to files in testDir/*
512-
"@goscript/builtin": {builtinTsRelPath},
507+
fmt.Sprintf("@goscript/%s/*", testPkgGoPathPrefix): {"./*"},
508+
"@goscript/*": {builtinTsRelPath},
513509
}
514510
tsconfig["compilerOptions"] = compilerOptions
515511

@@ -623,13 +619,20 @@ func RunGoScriptTestDir(t *testing.T, workspaceDir, testDir string) {
623619

624620
tempDir := PrepareTestRunDir(t, testDir)
625621

622+
// Calculate the relative path from tempDir to the workspace's gs/builtin/builtin.ts
623+
gsBuiltinPath := filepath.Join(workspaceDir, "gs", "*")
624+
relGsBuiltinPath, err := filepath.Rel(tempDir, gsBuiltinPath)
625+
if err != nil {
626+
t.Fatalf("failed to calculate relative path from tempDir (%s) to gs/builtin/builtin.ts (%s): %v", tempDir, gsBuiltinPath, err)
627+
}
628+
relGsBuiltinPath = filepath.ToSlash(relGsBuiltinPath) // Ensure forward slashes for tsconfig
629+
626630
// tsconfig.json for the runner execution in tempDir
627631
runnerTsConfig := maps.Clone(baseTsConfig)
628632
runnerCompilerOptions := maps.Clone(runnerTsConfig["compilerOptions"].(map[string]interface{}))
629633
runnerCompilerOptions["baseUrl"] = "." // tempDir is baseUrl
630634
runnerCompilerOptions["paths"] = map[string][]string{
631-
"@goscript/*": {"./output/@goscript/*"}, // Maps to tempDir/output/@goscript/*
632-
"@goscript/builtin": {"../../../../builtin/builtin.ts"}, // Maps to workspace/builtin/builtin.ts
635+
"@goscript/*": {"./output/@goscript/*", relGsBuiltinPath},
633636
}
634637
runnerTsConfig["compilerOptions"] = runnerCompilerOptions
635638

compliance/tests/array_literal/array_literal.gs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Generated file based on array_literal.go
22
// Updated when compliance tests are re-run, DO NOT EDIT!
33

4-
import * as $ from "@goscript/builtin";
4+
import * as $ from "@goscript/builtin/builtin.js";
55

66
export function main(): void {
77
// Test basic array literal

compliance/tests/assign_op/assign_op.gs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Generated file based on assign_op.go
22
// Updated when compliance tests are re-run, DO NOT EDIT!
33

4-
import * as $ from "@goscript/builtin";
4+
import * as $ from "@goscript/builtin/builtin.js";
55

66
export function main(): void {
77
let a: number = 5

compliance/tests/async_basic/async_basic.gs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Generated file based on async_basic.go
22
// Updated when compliance tests are re-run, DO NOT EDIT!
33

4-
import * as $ from "@goscript/builtin";
4+
import * as $ from "@goscript/builtin/builtin.js";
55

66
// This function receives from a channel, making it async.
77
async function receiveFromChan(ch: $.Channel<number>): Promise<number> {

0 commit comments

Comments
 (0)