transpiler

package
v0.1.0-dev.128 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Validates function context (self/no-self) compatibility on assignments.

Handles translation of JS built-in methods and objects to Lua equivalents.

Unified self-detection system. Both functionNeedsSelf (definition side) and calleeNeedsSelf (call site) route through computeDeclarationContextType.

TSTL delegates JSX to TypeScript's transformJsx which converts JSX to React.createElement() calls before TSTL processes them. Since tslua doesn't use tsgo's transformer pipeline, we handle JSX AST nodes directly, producing equivalent Lua output.

Handles Number constructor methods, instance methods, and property access.

Package transpiler walks the TypeScript AST and emits Lua code.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BundleProgram

func BundleProgram(results []TranspileResult, sourceRoot string, lualibContent []byte, opts BundleOptions) (string, error)

BundleProgram takes transpiled per-file results and produces a single bundled Lua string. sourceRoot is used to convert TranspileResult.FileName to dot-separated module names. If lualibContent is non-empty, it is included as a "lualib_bundle" module entry.

func ModuleNameFromPath

func ModuleNameFromPath(filePath, sourceRoot string) string

ModuleNameFromPath converts an absolute .ts file path to a dot-separated module name relative to sourceRoot. This matches the logic in resolveModulePath (modules.go).

func ScanLuaForLualibDeps

func ScanLuaForLualibDeps(lua string) []string

ScanLuaForLualibDeps scans Lua source code for ____lualib references and returns the export names found (e.g. "__TS__ArrayIndexOf").

func ValidLuaLibImport

func ValidLuaLibImport(s string) bool

ValidLuaLibImport returns true if s is a recognized luaLibImport value.

func ValidTarget

func ValidTarget(s string) bool

ValidTarget returns whether the given string is a valid LuaTarget.

Types

type AnnotationKind

type AnnotationKind int
const (
	AnnotNoSelf AnnotationKind = iota
	AnnotNoSelfInFile
	AnnotCompileMembersOnly
	AnnotNoResolution
)

type ArrayAdapter

type ArrayAdapter struct {
	// Length emits the Lua expression for `arr.length` on array-typed
	// expressions. Default: `#arr` (or `table.getn(arr)` for Lua 5.0).
	Length LengthEmitter
}

ArrayAdapter names the emitters for Array primitives.

type BundleOptions

type BundleOptions struct {
	EntryModule string    // module name for the entry point (e.g., "main")
	LuaTarget   LuaTarget // needed for Lua 5.0 vs 5.1+ require shim variant
}

BundleOptions configures Lua bundle generation.

type ClassStyle

type ClassStyle string

ClassStyle controls how TypeScript classes are emitted to Lua. Use a preset name: "" or "tstl" (default), "luabind", "middleclass", "inline".

const (
	ClassStyleTSTL        ClassStyle = ""            // default: TSTL prototype chains
	ClassStyleLuabind     ClassStyle = "luabind"     // luabind (C++ binding)
	ClassStyleMiddleclass ClassStyle = "middleclass" // middleclass library
	ClassStyleInline      ClassStyle = "inline"      // inline setmetatable (rbxts-style, no runtime library)
)

type DeferredTransfer

type DeferredTransfer struct {
	Kind     TransferKind
	TSLabel  string // "" for unlabeled
	FlagName string // Lua identifier for the sentinel flag
	Dispatch []lua.Statement
}

DeferredTransfer describes a break/continue that had to be replaced with a sentinel-flag assignment + return because the jump would have crossed the pcall/awaiter function boundary. The transformTryStatement visitor consumes these to emit flag declarations and post-pcall dispatch.

type EmitMode

type EmitMode string

EmitMode controls whether the transpiler matches TSTL output exactly or applies optimizations.

const (
	// EmitModeTSTL matches TSTL's Lua output for codegen parity (default).
	EmitModeTSTL EmitMode = "tstl"
	// EmitModeOptimized applies known-safe improvements (e.g., skip unnecessary tostring() wraps).
	EmitModeOptimized EmitMode = "optimized"
)

type ExtensionKind

type ExtensionKind string

ExtensionKind identifies a TSTL language extension type.

const (
	ExtMultiFunction  ExtensionKind = "MultiFunction"
	ExtRangeFunction  ExtensionKind = "RangeFunction"
	ExtVarargConstant ExtensionKind = "VarargConstant"

	ExtAddition                 ExtensionKind = "Addition"
	ExtAdditionMethod           ExtensionKind = "AdditionMethod"
	ExtSubtraction              ExtensionKind = "Subtraction"
	ExtSubtractionMethod        ExtensionKind = "SubtractionMethod"
	ExtMultiplication           ExtensionKind = "Multiplication"
	ExtMultiplicationMethod     ExtensionKind = "MultiplicationMethod"
	ExtDivision                 ExtensionKind = "Division"
	ExtDivisionMethod           ExtensionKind = "DivisionMethod"
	ExtModulo                   ExtensionKind = "Modulo"
	ExtModuloMethod             ExtensionKind = "ModuloMethod"
	ExtPower                    ExtensionKind = "Power"
	ExtPowerMethod              ExtensionKind = "PowerMethod"
	ExtFloorDivision            ExtensionKind = "FloorDivision"
	ExtFloorDivisionMethod      ExtensionKind = "FloorDivisionMethod"
	ExtBitwiseAnd               ExtensionKind = "BitwiseAnd"
	ExtBitwiseAndMethod         ExtensionKind = "BitwiseAndMethod"
	ExtBitwiseOr                ExtensionKind = "BitwiseOr"
	ExtBitwiseOrMethod          ExtensionKind = "BitwiseOrMethod"
	ExtBitwiseExclusiveOr       ExtensionKind = "BitwiseExclusiveOr"
	ExtBitwiseExclusiveOrMethod ExtensionKind = "BitwiseExclusiveOrMethod"
	ExtBitwiseLeftShift         ExtensionKind = "BitwiseLeftShift"
	ExtBitwiseLeftShiftMethod   ExtensionKind = "BitwiseLeftShiftMethod"
	ExtBitwiseRightShift        ExtensionKind = "BitwiseRightShift"
	ExtBitwiseRightShiftMethod  ExtensionKind = "BitwiseRightShiftMethod"
	ExtConcat                   ExtensionKind = "Concat"
	ExtConcatMethod             ExtensionKind = "ConcatMethod"
	ExtLessThan                 ExtensionKind = "LessThan"
	ExtLessThanMethod           ExtensionKind = "LessThanMethod"
	ExtGreaterThan              ExtensionKind = "GreaterThan"
	ExtGreaterThanMethod        ExtensionKind = "GreaterThanMethod"
	ExtNegation                 ExtensionKind = "Negation"
	ExtNegationMethod           ExtensionKind = "NegationMethod"
	ExtBitwiseNot               ExtensionKind = "BitwiseNot"
	ExtBitwiseNotMethod         ExtensionKind = "BitwiseNotMethod"
	ExtLength                   ExtensionKind = "Length"
	ExtLengthMethod             ExtensionKind = "LengthMethod"

	ExtTableNew           ExtensionKind = "TableNew"
	ExtTableDelete        ExtensionKind = "TableDelete"
	ExtTableDeleteMethod  ExtensionKind = "TableDeleteMethod"
	ExtTableGet           ExtensionKind = "TableGet"
	ExtTableGetMethod     ExtensionKind = "TableGetMethod"
	ExtTableHas           ExtensionKind = "TableHas"
	ExtTableHasMethod     ExtensionKind = "TableHasMethod"
	ExtTableSet           ExtensionKind = "TableSet"
	ExtTableSetMethod     ExtensionKind = "TableSetMethod"
	ExtTableAddKey        ExtensionKind = "TableAddKey"
	ExtTableAddKeyMethod  ExtensionKind = "TableAddKeyMethod"
	ExtTableIsEmpty       ExtensionKind = "TableIsEmpty"
	ExtTableIsEmptyMethod ExtensionKind = "TableIsEmptyMethod"
)

type FunctionDefinitionInfo

type FunctionDefinitionInfo struct {
	ReferencedSymbols map[SymbolID]int // symbols referenced within the function body (count)
	Definition        lua.Statement    // the transformed lua statement (local decl or assignment)
}

FunctionDefinitionInfo tracks a function declaration registered in a scope.

type IterableExtensionKind

type IterableExtensionKind string
const (
	IterableKindIterable IterableExtensionKind = "Iterable"
	IterableKindPairs    IterableExtensionKind = "Pairs"
	IterableKindPairsKey IterableExtensionKind = "PairsKey"
)

type LengthEmitter

type LengthEmitter interface {
	Emit(t *Transpiler, arr lua.Expression) lua.Expression
}

LengthEmitter produces a Lua expression for an array length read. Implementations are branchless on the caller side: every emit site calls `t.adapters.Array.Length.Emit(t, arr)` and lets the emitter decide whether to emit a native operator or a function call.

type LuaLibImportKind

type LuaLibImportKind string

LuaLibImportKind controls how lualib polyfill functions are included in output.

const (
	// LuaLibImportRequire emits require("lualib_bundle") and expects the bundle on the Lua path.
	LuaLibImportRequire LuaLibImportKind = "require"
	// LuaLibImportRequireMinimal is like Require, but the emitted lualib_bundle.lua
	// contains only features actually used by the program (plus transitive deps).
	LuaLibImportRequireMinimal LuaLibImportKind = "require-minimal"
	// LuaLibImportInline embeds the lualib bundle directly in the output.
	LuaLibImportInline LuaLibImportKind = "inline"
	// LuaLibImportNone suppresses all lualib imports, assumes features are provided externally.
	LuaLibImportNone LuaLibImportKind = "none"
)

type LuaRequire

type LuaRequire struct {
	From        int
	To          int
	RequirePath string
}

LuaRequire represents a require() call found in Lua source code.

func FindLuaRequires

func FindLuaRequires(lua string) []LuaRequire

FindLuaRequires scans Lua source code for require() calls, properly handling strings and comments to avoid false positives.

type LuaTarget

type LuaTarget string

LuaTarget represents the Lua version to target.

const (
	LuaTargetUniversal LuaTarget = "universal"
	LuaTargetLua50     LuaTarget = "5.0"
	LuaTargetLua51     LuaTarget = "5.1"
	LuaTargetLua52     LuaTarget = "5.2"
	LuaTargetLua53     LuaTarget = "5.3"
	LuaTargetLua54     LuaTarget = "5.4"
	LuaTargetLua55     LuaTarget = "5.5"
	LuaTargetLuaJIT    LuaTarget = "JIT"
	LuaTargetLuau      LuaTarget = "Luau"
)

func (LuaTarget) AllowsUnicodeIds

func (t LuaTarget) AllowsUnicodeIds() bool

AllowsUnicodeIds returns whether the target supports unicode characters in identifiers.

func (LuaTarget) BitLibrary

func (t LuaTarget) BitLibrary() string

BitLibrary returns the name of the built-in bit manipulation library, or "" if none. LuaJIT has "bit", Lua 5.2 has "bit32", others have none.

func (LuaTarget) DisplayName

func (t LuaTarget) DisplayName() string

DisplayName returns the TSTL-compatible display name for the target. JIT → "LuaJIT", others → "Lua 5.0", "Lua universal", etc.

func (LuaTarget) HasConditionalExpression

func (t LuaTarget) HasConditionalExpression() bool

HasConditionalExpression returns whether the target supports if-then-else expressions. Luau has `if cond then expr else expr` as a native ternary.

func (LuaTarget) HasLengthOperator

func (t LuaTarget) HasLengthOperator() bool

HasLengthOperator returns whether the target supports the # length operator. Lua 5.0 does not have #; use table.getn() / string.len() instead.

func (LuaTarget) HasMathHuge

func (t LuaTarget) HasMathHuge() bool

HasMathHuge returns whether the target has math.huge. Lua 5.0 does not; use 1/0 instead.

func (LuaTarget) HasModOperator

func (t LuaTarget) HasModOperator() bool

HasModOperator returns whether the target supports the % modulo operator. Lua 5.0 does not; use math.mod() instead.

func (LuaTarget) HasNativeBitwise

func (t LuaTarget) HasNativeBitwise() bool

HasNativeBitwise returns whether the target supports native bitwise operators (&, |, ~, <<, >>). Lua 5.3+ has these.

func (LuaTarget) HasNativeContinue

func (t LuaTarget) HasNativeContinue() bool

HasNativeContinue returns whether the target supports the `continue` keyword natively. Luau is the only target with native continue.

func (LuaTarget) HasVarargDots

func (t LuaTarget) HasVarargDots() bool

HasVarargDots returns whether the target supports ... vararg syntax. Lua 5.0 uses the implicit `arg` table instead.

func (LuaTarget) LenExpr

func (t LuaTarget) LenExpr(expr lua.Expression) lua.Expression

LenExpr returns the Lua expression for getting the length of expr. Lua 5.0: table.getn(expr); Lua 5.1+: #expr.

func (LuaTarget) MathAtan2Name

func (t LuaTarget) MathAtan2Name() string

MathAtan2Name returns the short function name for two-argument arctangent. Lua 5.3+ merged atan2 into math.atan(y, x), so returns "atan"; others return "atan2".

func (LuaTarget) Runtime

func (t LuaTarget) Runtime() string

Runtime returns the executable name for running Lua code with this target.

func (LuaTarget) StrLenExpr

func (t LuaTarget) StrLenExpr(expr lua.Expression) lua.Expression

StrLenExpr returns the Lua expression for getting the length of a string expr. Lua 5.0: string.len(expr); Lua 5.1+: #expr.

func (LuaTarget) SupportsFloorDiv

func (t LuaTarget) SupportsFloorDiv() bool

SupportsFloorDiv returns whether the target supports the // floor division operator. Lua 5.3+ has this.

func (LuaTarget) SupportsGoto

func (t LuaTarget) SupportsGoto() bool

SupportsGoto returns whether the target supports goto statements and labels. LuaJIT and Lua 5.2+ support goto; vanilla Lua 5.0, 5.1 and Universal do not.

func (LuaTarget) UsesLua50Unpack

func (t LuaTarget) UsesLua50Unpack() bool

UsesLua50Unpack returns whether the target uses Lua 5.0's unpack (no bounds args).

func (LuaTarget) UsesTableUnpack

func (t LuaTarget) UsesTableUnpack() bool

UsesTableUnpack returns whether the target uses table.unpack() instead of global unpack(). Lua 5.2+ moved unpack into the table library. Universal uses a lualib shim.

type ModuleDependency

type ModuleDependency struct {
	// RequirePath is the dot-separated path in the emitted require("...").
	RequirePath string
	// ResolvedPath is the absolute filesystem path of the resolved module.
	// Empty if resolution failed or the specifier was in noResolvePaths.
	ResolvedPath string
	// IsExternal is true when the resolved file lives outside the project
	// source root (e.g. node_modules).
	IsExternal bool
	// IsLuaSource is true when the resolved file is a .lua file (not
	// transpiled from .ts/.tsx).
	IsLuaSource bool
}

ModuleDependency describes a single require() emitted by a transpiled file. Populated during transformation by resolveModulePath.

type RuntimeAdapters

type RuntimeAdapters struct {
	Array ArrayAdapter

	// HasUserAdapter reports whether any user declaration overrode a default.
	// The CLI uses this to decide whether to rebuild lualib from source.
	HasUserAdapter bool
}

RuntimeAdapters holds per-category runtime adapter configuration for a program. Every adapter slot is always populated: the default emits native Lua operators (e.g. `#arr`) via Go AST construction; a user-provided @lua*Runtime declaration replaces the default with a call to a named Lua function.

Kernel scope: only Array.length is wired. See notes/adapters/architecture.md.

func NewDefaultAdapters

func NewDefaultAdapters() *RuntimeAdapters

NewDefaultAdapters returns a RuntimeAdapters populated with tslua's built-in emitters. Every subsequent lookup on the returned value emits the native Lua operator or lualib call that tslua would emit without any adapter.

func ScanAdapters

func ScanAdapters(program *compiler.Program, ch *checker.Checker) (*RuntimeAdapters, []*ast.Diagnostic)

ScanAdapters inspects a program for @lua*Runtime adapter declarations and returns a populated RuntimeAdapters plus any diagnostics from signature validation. The result always contains working emitters: slots the user did not override, or whose user declaration failed validation, keep tslua's defaults.

Expected declaration form:

declare function Len(arr: readonly unknown[]): number;

/** @luaArrayRuntime */
declare const MyArrayRuntime: {
    length: typeof Len;
};

A ch of nil skips validation (used by callers that cannot supply a checker).

func ScanAdaptersFromProgram

func ScanAdaptersFromProgram(program *compiler.Program) (*RuntimeAdapters, []*ast.Diagnostic)

ScanAdaptersFromProgram is a convenience wrapper around ScanAdapters that obtains a checker from the program itself. Intended for callers (e.g. the CLI) that want the scanned adapters without managing checker lifecycle.

func (*RuntimeAdapters) Any

func (r *RuntimeAdapters) Any() bool

Any reports whether any user declaration overrode a default emitter. Callers use it to decide whether to rebuild lualib from source (cost: one full lualib pass) or use the embedded pre-built bundle (zero cost). Safe to call on a nil receiver: nil adapters means "no user adapter".

type Scope

type Scope struct {
	Type              ScopeType
	ID                int
	Node              *ast.Node
	ReferencedSymbols map[SymbolID]int // symbols referenced in this scope (reference count)
	VariableDecls     []TrackedVarDecl // variable declarations for hoisting
	FunctionDefs      map[SymbolID]*FunctionDefinitionInfo
	ImportStatements  []lua.Statement // import statements to hoist to top

	// Flags set when a return/break/continue inside a try/catch needs to be
	// deferred to post-check logic after the pcall (sync) or awaiter chain
	// (async). Break/continue inside the pcall/awaiter function body can't
	// use goto/break directly because Lua forbids crossing function boundaries
	// with either, so we assign a sentinel flag and return, then dispatch
	// after the try wrapper.
	TryHasReturn         bool
	TryDeferredTransfers []DeferredTransfer
}

Scope tracks symbol references and declarations within a lexical scope.

type ScopeType

type ScopeType int

ScopeType identifies the kind of scope being tracked.

const (
	ScopeFile ScopeType = 1 << iota
	ScopeFunction
	ScopeSwitch
	ScopeLoop
	ScopeConditional
	ScopeBlock
	ScopeTry
	ScopeCatch
)

type SymbolID

type SymbolID int

SymbolID is a unique identifier for a tracked symbol within a transpilation.

type SymbolInfo

type SymbolInfo struct {
	Symbol         *ast.Symbol
	FirstSeenAtPos int // source position where first referenced
}

SymbolInfo tracks when a symbol was first referenced.

type TrackedVarDecl

type TrackedVarDecl struct {
	Stmt      *lua.VariableDeclarationStatement
	SymbolIDs []SymbolID
}

TrackedVarDecl pairs a variable declaration statement with the symbol IDs of its identifiers.

type TransferKind

type TransferKind int

TransferKind identifies the kind of deferred control-flow transfer out of a try/catch body.

const (
	TransferBreak TransferKind = iota
	TransferContinue
)

type TranspileOptions

type TranspileOptions struct {
	EmitMode                  EmitMode
	ExportAsGlobal            bool                    // strip module wrapper, emit exports as globals
	ExportAsGlobalMatch       string                  // regex: only apply ExportAsGlobal to files whose source path matches
	NoImplicitSelf            bool                    // unresolved calls default to no-self
	NoImplicitGlobalVariables bool                    // force local declarations in script-mode top-level scope
	LuaLibImport              LuaLibImportKind        // how lualib features are included (default: require)
	LualibInlineContent       string                  // lualib bundle content for inline mode (full bundle fallback)
	LualibFeatureData         *lualibinfo.FeatureData // per-feature data for selective inline mode
	SourceMap                 bool                    // generate source maps
	SourceMapTraceback        bool                    // register source maps at runtime for debug.traceback rewriting
	InlineSourceMap           bool                    // embed source map as base64 data: URL in Lua output
	Trace                     bool                    // emit --[[trace: ...]] comments showing which TS node produced each Lua statement
	ClassStyle                ClassStyle              // alternative class emit style (default: TSTL prototype chains)
	NoResolvePaths            []string                // module specifiers to emit as-is without resolving (TSTL noResolvePaths)
	Adapters                  *RuntimeAdapters        // runtime adapters; nil triggers ScanAdapters on the program
}

TranspileOptions holds configuration for transpilation.

type TranspileResult

type TranspileResult struct {
	FileName        string
	Lua             string
	SourceMap       string // V3 source map JSON (empty if source maps disabled)
	Declaration     string // .d.ts content (empty if declaration emission disabled)
	UsesLualib      bool
	UsesMiddleclass bool               // file emits require("middleclass"); tooling should make the module resolvable
	ExportedNames   []string           // names exported by this file (populated when ExportAsGlobal is set)
	LualibDeps      []string           // lualib features used by this file (populated when NoLualibImport is set)
	Dependencies    []ModuleDependency // module dependencies discovered during transformation
	TransformDur    time.Duration      // time spent transforming TS AST → Lua AST
	PrintDur        time.Duration      // time spent printing Lua AST → string
}

TranspileResult contains the Lua output for a single source file.

func TranspileProgram

func TranspileProgram(program *compiler.Program, sourceRoot string, luaTarget LuaTarget, onlyFiles map[string]bool, emitMode ...EmitMode) ([]TranspileResult, []*ast.Diagnostic)

TranspileProgram transpiles all user source files in the program. sourceRoot is the root directory for computing relative Lua module paths. If onlyFiles is non-nil, only files in the set are transpiled.

func TranspileProgramWithOptions

func TranspileProgramWithOptions(program *compiler.Program, sourceRoot string, luaTarget LuaTarget, onlyFiles map[string]bool, opts TranspileOptions) ([]TranspileResult, []*ast.Diagnostic)

TranspileProgramWithOptions transpiles all user source files with full options.

type Transpiler

type Transpiler struct {
	// contains filtered or unexported fields
}

Transpiler holds the state needed for transpiling a single source file.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL