Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cmd/tslua/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,12 @@ func runEval(source string) error {
return fmt.Errorf("unsupported luaLibImport: %s (supported: require, inline, none)", luaLibImportFlag)
}
opts := transpiler.TranspileOptions{
LuaLibImport: luaLibImport,
Trace: traceFlag,
EmitMode: transpiler.EmitMode(emitModeFlag),
NoImplicitSelf: noImplicitSelfFlag,
NoImplicitGlobalVariables: noImplicitGlobalVariablesFlag,
ClassStyle: transpiler.ClassStyle(classStyleFlag),
LuaLibImport: luaLibImport,
Trace: traceFlag,
}
if luaLibImport == transpiler.LuaLibImportInline {
if fd, err := lualib.FeatureDataForTarget(string(luaTarget)); err == nil {
Expand Down
167 changes: 98 additions & 69 deletions cmd/tslua/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,28 @@ var (
)

var (
projectFlag string
outdirFlag string
luaTargetFlag string
emitModeFlag string
diagFormatFlag string
cpuprofileFlag string
luaBundleFlag string
luaBundleEntryFlag string
exportAsGlobalFlag bool
verboseFlag bool
timingFlag bool
watchFlag bool
luaLibImportFlag string
socketFlag string
evalSourceFlag string
sourceMapFlag bool
noImplicitSelfFlag bool
traceFlag bool
projectFlag string
outdirFlag string
luaTargetFlag string
emitModeFlag string
diagFormatFlag string
cpuprofileFlag string
luaBundleFlag string
luaBundleEntryFlag string
exportAsGlobalFlag bool
verboseFlag bool
timingFlag bool
watchFlag bool
luaLibImportFlag string
socketFlag string
evalSourceFlag string
sourceMapFlag bool
sourceMapTracebackFlag bool
inlineSourceMapFlag bool
noImplicitSelfFlag bool
noImplicitGlobalVariablesFlag bool
classStyleFlag string
traceFlag bool
)

func main() {
Expand All @@ -61,22 +65,26 @@ func main() {
}
rootCmd.SetVersionTemplate("{{.Version}}\n")

// Persistent flags: shared across root and subcommands.
// Persistent flags: shared across root and subcommands (affect transpilation behavior).
rootCmd.PersistentFlags().StringVar(&luaTargetFlag, "luaTarget", "JIT", "Lua target version (JIT, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, Luau, universal)")
rootCmd.PersistentFlags().StringVar(&diagFormatFlag, "diagnosticFormat", "tstl", "diagnostic code format (tstl, native)")
rootCmd.PersistentFlags().StringVar(&cpuprofileFlag, "cpuprofile", "", "write CPU profile to file")
rootCmd.PersistentFlags().BoolVar(&timingFlag, "timing", false, "print phase timings to stderr")
rootCmd.PersistentFlags().StringVar(&luaLibImportFlag, "luaLibImport", "require", "how lualib features are included (require, inline, none)")
rootCmd.PersistentFlags().StringVar(&emitModeFlag, "emitMode", "tstl", "emit mode: tstl (match TSTL output) or optimized")
rootCmd.PersistentFlags().BoolVar(&noImplicitSelfFlag, "noImplicitSelf", false, "default functions to no-self unless annotated")
rootCmd.PersistentFlags().BoolVar(&noImplicitGlobalVariablesFlag, "noImplicitGlobalVariables", false, "force local declarations in script-mode top-level scope")
rootCmd.PersistentFlags().StringVar(&classStyleFlag, "classStyle", "", "class emit style (tstl, luabind, middleclass, inline)")

// Root-only flags: project build mode.
rootCmd.Flags().StringVarP(&projectFlag, "project", "p", "", "path to tsconfig.json")
rootCmd.Flags().StringVar(&outdirFlag, "outdir", "", "output directory for Lua files (default: stdout)")
rootCmd.Flags().StringVar(&emitModeFlag, "emitMode", "tstl", "emit mode: tstl (match TSTL output) or optimized")
rootCmd.Flags().StringVar(&luaBundleFlag, "luaBundle", "", "output all modules as a single bundled Lua file")
rootCmd.Flags().StringVar(&luaBundleEntryFlag, "luaBundleEntry", "", "entry point source file for bundle mode")
rootCmd.Flags().BoolVar(&exportAsGlobalFlag, "exportAsGlobal", false, "strip module wrapper, emit exports as globals")
rootCmd.Flags().BoolVar(&sourceMapFlag, "sourceMap", false, "generate .lua.map source map files")
rootCmd.Flags().BoolVar(&noImplicitSelfFlag, "noImplicitSelf", false, "default functions to no-self unless annotated")
rootCmd.Flags().BoolVar(&sourceMapTracebackFlag, "sourceMapTraceback", false, "register source maps at runtime for debug.traceback rewriting")
rootCmd.Flags().BoolVar(&inlineSourceMapFlag, "inlineSourceMap", false, "embed source map as base64 data URL in Lua output")
rootCmd.Flags().BoolVar(&verboseFlag, "verbose", false, "print each output file path")
rootCmd.Flags().BoolVarP(&watchFlag, "watch", "w", false, "watch for file changes and rebuild")

Expand Down Expand Up @@ -165,22 +173,52 @@ func main() {

// buildConfig holds resolved settings shared across builds.
type buildConfig struct {
cwd string
configDir string
configParseResult *tsoptions.ParsedCommandLine
sourceRoot string
outdir string
diagFormat dw.DiagnosticFormat
luaTarget transpiler.LuaTarget
emitMode transpiler.EmitMode
luaLibImport transpiler.LuaLibImportKind
luaBundle string
luaBundleEntry string
exportAsGlobal bool
exportAsGlobalMatch string
noImplicitSelf bool
sourceMap bool
stderrIsTerminal bool
cwd string
configDir string
configParseResult *tsoptions.ParsedCommandLine
sourceRoot string
outdir string
diagFormat dw.DiagnosticFormat
luaTarget transpiler.LuaTarget
emitMode transpiler.EmitMode
luaLibImport transpiler.LuaLibImportKind
luaBundle string
luaBundleEntry string
exportAsGlobal bool
exportAsGlobalMatch string
noImplicitSelf bool
noImplicitGlobalVariables bool
sourceMap bool
sourceMapTraceback bool
inlineSourceMap bool
classStyle transpiler.ClassStyle
stderrIsTerminal bool
}

// transpileOpts returns the TranspileOptions derived from this build config.
// This is the single chokepoint for CLI entrypoints — all TranspileOptions
// construction for project builds goes through here.
func (cfg *buildConfig) transpileOpts() transpiler.TranspileOptions {
opts := transpiler.TranspileOptions{
EmitMode: cfg.emitMode,
ExportAsGlobal: cfg.exportAsGlobal,
ExportAsGlobalMatch: cfg.exportAsGlobalMatch,
NoImplicitSelf: cfg.noImplicitSelf,
NoImplicitGlobalVariables: cfg.noImplicitGlobalVariables,
LuaLibImport: cfg.luaLibImport,
SourceMap: cfg.sourceMap,
SourceMapTraceback: cfg.sourceMapTraceback,
InlineSourceMap: cfg.inlineSourceMap,
ClassStyle: cfg.classStyle,
}
if cfg.luaLibImport == transpiler.LuaLibImportInline {
if fd, err := lualib.FeatureDataForTarget(string(cfg.luaTarget)); err == nil {
opts.LualibFeatureData = fd
} else {
opts.LualibInlineContent = lualibInlineContent(cfg.luaTarget)
}
}
return opts
}

func run(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -279,23 +317,29 @@ func run(cmd *cobra.Command, args []string) error {
}
}

sourceMap := sourceMapFlag || sourceMapTracebackFlag || inlineSourceMapFlag || configParseResult.CompilerOptions().SourceMap.IsTrue()

cfg := &buildConfig{
cwd: cwd,
configDir: string(configDir),
configParseResult: configParseResult,
sourceRoot: sourceRoot,
outdir: outdir,
diagFormat: diagFormat,
luaTarget: luaTarget,
emitMode: emitMode,
luaLibImport: luaLibImport,
luaBundle: luaBundleFlag,
luaBundleEntry: luaBundleEntryFlag,
exportAsGlobal: exportAsGlobal,
exportAsGlobalMatch: exportAsGlobalMatch,
noImplicitSelf: noImplicitSelfFlag,
sourceMap: sourceMapFlag || configParseResult.CompilerOptions().SourceMap.IsTrue(),
stderrIsTerminal: stderrIsTerminal,
cwd: cwd,
configDir: string(configDir),
configParseResult: configParseResult,
sourceRoot: sourceRoot,
outdir: outdir,
diagFormat: diagFormat,
luaTarget: luaTarget,
emitMode: emitMode,
luaLibImport: luaLibImport,
luaBundle: luaBundleFlag,
luaBundleEntry: luaBundleEntryFlag,
exportAsGlobal: exportAsGlobal,
exportAsGlobalMatch: exportAsGlobalMatch,
noImplicitSelf: noImplicitSelfFlag,
noImplicitGlobalVariables: noImplicitGlobalVariablesFlag,
sourceMap: sourceMap,
sourceMapTraceback: sourceMapTracebackFlag,
inlineSourceMap: inlineSourceMapFlag,
classStyle: transpiler.ClassStyle(classStyleFlag),
stderrIsTerminal: stderrIsTerminal,
}

if watchFlag {
Expand Down Expand Up @@ -326,22 +370,7 @@ func runOnce(cfg *buildConfig, host compiler.CompilerHost) error {

tCheck := time.Now()

opts := transpiler.TranspileOptions{
EmitMode: cfg.emitMode,
ExportAsGlobal: cfg.exportAsGlobal,
ExportAsGlobalMatch: cfg.exportAsGlobalMatch,
NoImplicitSelf: cfg.noImplicitSelf,
LuaLibImport: cfg.luaLibImport,
SourceMap: cfg.sourceMap,
}
if cfg.luaLibImport == transpiler.LuaLibImportInline {
if fd, err := lualib.FeatureDataForTarget(string(cfg.luaTarget)); err == nil {
opts.LualibFeatureData = fd
} else {
opts.LualibInlineContent = lualibInlineContent(cfg.luaTarget)
}
}
results, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, nil, opts)
results, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, nil, cfg.transpileOpts())

hasErrors := reportDiagnostics(cfg, semanticDiags, transpileDiags)

Expand Down
15 changes: 15 additions & 0 deletions cmd/tslua/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,9 @@ func transpileOptsFromRequest(req serverRequest) transpiler.TranspileOptions {
if v, ok := req.CompilerOptions["noImplicitSelf"].(bool); ok && v {
opts.NoImplicitSelf = true
}
if v, ok := req.CompilerOptions["noImplicitGlobalVariables"].(bool); ok && v {
opts.NoImplicitGlobalVariables = true
}
if v, ok := req.CompilerOptions["sourceMap"].(bool); ok && v {
opts.SourceMap = true
}
Expand All @@ -541,6 +544,18 @@ func transpileOptsFromRequest(req serverRequest) transpiler.TranspileOptions {
opts.InlineSourceMap = true
opts.SourceMap = true // inline requires source map generation
}
if v, ok := req.CompilerOptions["emitMode"].(string); ok && v != "" {
opts.EmitMode = transpiler.EmitMode(v)
}
if v, ok := req.CompilerOptions["classStyle"].(string); ok && v != "" {
opts.ClassStyle = transpiler.ClassStyle(v)
}
if v, ok := req.CompilerOptions["luaLibImport"].(string); ok && v != "" {
opts.LuaLibImport = transpiler.LuaLibImportKind(v)
}
if v, ok := req.CompilerOptions["exportAsGlobal"].(bool); ok && v {
opts.ExportAsGlobal = true
}
return opts
}

Expand Down
19 changes: 3 additions & 16 deletions cmd/tslua/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ func runWatch(cfg *buildConfig, host compiler.CompilerHost) error {
semanticDiags := compiler.SortAndDeduplicateDiagnostics(
incremental.Program_GetSemanticDiagnostics(incrProg, context.Background(), nil),
)
results, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, nil, transpiler.TranspileOptions{
EmitMode: cfg.emitMode,
ExportAsGlobal: cfg.exportAsGlobal,
ExportAsGlobalMatch: cfg.exportAsGlobalMatch,
NoImplicitSelf: cfg.noImplicitSelf,
})
results, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, nil, cfg.transpileOpts())
for _, r := range results {
cachedResults[r.FileName] = r
}
Expand Down Expand Up @@ -189,11 +184,7 @@ func runWatch(cfg *buildConfig, host compiler.CompilerHost) error {

tCheck := time.Now()

freshResults, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, changedFiles, transpiler.TranspileOptions{
EmitMode: cfg.emitMode,
ExportAsGlobal: cfg.exportAsGlobal,
ExportAsGlobalMatch: cfg.exportAsGlobalMatch,
})
freshResults, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, changedFiles, cfg.transpileOpts())
for _, r := range freshResults {
cachedResults[r.FileName] = r
}
Expand Down Expand Up @@ -237,11 +228,7 @@ func runWatch(cfg *buildConfig, host compiler.CompilerHost) error {
fmt.Fprintf(os.Stderr, "build finished in %.2fms\n", msf(time.Since(t0)))
} else {
// Async path: transpile+write immediately, incr+check in background.
freshResults, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, changedFiles, transpiler.TranspileOptions{
EmitMode: cfg.emitMode,
ExportAsGlobal: cfg.exportAsGlobal,
ExportAsGlobalMatch: cfg.exportAsGlobalMatch,
})
freshResults, transpileDiags := transpiler.TranspileProgramWithOptions(program, cfg.sourceRoot, cfg.luaTarget, changedFiles, cfg.transpileOpts())
for _, r := range freshResults {
cachedResults[r.FileName] = r
}
Expand Down
8 changes: 8 additions & 0 deletions cmd/wasm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ type wasmOptions struct {
ClassStyle string `json:"classStyle,omitempty"`
NoImplicitSelf bool `json:"noImplicitSelf,omitempty"`
NoImplicitGlobalVariables bool `json:"noImplicitGlobalVariables,omitempty"`
ExportAsGlobal bool `json:"exportAsGlobal,omitempty"`
SourceMap bool `json:"sourceMap,omitempty"`
SourceMapTraceback bool `json:"sourceMapTraceback,omitempty"`
InlineSourceMap bool `json:"inlineSourceMap,omitempty"`
Trace bool `json:"trace,omitempty"`
} `json:"tstl,omitempty"`
}
Expand Down Expand Up @@ -197,6 +201,10 @@ func transpile(tsCode string, wopts wasmOptions) transpileResult {
ClassStyle: transpiler.ClassStyle(wopts.TSTL.ClassStyle),
NoImplicitSelf: wopts.TSTL.NoImplicitSelf,
NoImplicitGlobalVariables: wopts.TSTL.NoImplicitGlobalVariables,
ExportAsGlobal: wopts.TSTL.ExportAsGlobal,
SourceMap: wopts.TSTL.SourceMap || wopts.TSTL.SourceMapTraceback || wopts.TSTL.InlineSourceMap,
SourceMapTraceback: wopts.TSTL.SourceMapTraceback,
InlineSourceMap: wopts.TSTL.InlineSourceMap,
Trace: wopts.TSTL.Trace,
}
if fd, err := lualib.FeatureDataForTarget(string(lt)); err == nil {
Expand Down
3 changes: 2 additions & 1 deletion extern/tstl-test-util.patch
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ index 2871f6e..219208c 100644
const program = this.getProgram();
const preEmitDiagnostics = ts.getPreEmitDiagnostics(program);
const collector = createEmitOutputCollector(this.options.extension);
@@ -256,6 +267,228 @@ export abstract class TestBuilder {
@@ -256,6 +267,229 @@ export abstract class TestBuilder {
return { diagnostics: [...diagnostics], transpiledFiles: collector.files };
}

Expand Down Expand Up @@ -116,6 +116,7 @@ index 2871f6e..219208c 100644
+ jsxFactory: this.options.jsxFactory,
+ jsxFragmentFactory: this.options.jsxFragmentFactory,
+ noImplicitSelf: this.options.noImplicitSelf,
+ noImplicitGlobalVariables: this.options.noImplicitGlobalVariables,
+ },
+ });
+
Expand Down
1 change: 1 addition & 0 deletions internal/transpiler/classes.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ func (t *Transpiler) transformClassConstructor(classRef lua.Expression, construc
// Constructor: param defaults, super call, param properties, field inits, body
if constructor != nil {
ctor := constructor.AsConstructorDeclaration()
t.computeOptimizedVarArgs(ctor.Parameters, ctor.Body, false)
bodyStmts = append(bodyStmts, t.transformParamPreamble(ctor.Parameters)...)

// Transform the constructor body and split out the super call
Expand Down