TypeScript language service plugin that augments classes decorated with @derive to include macro-generated methods.
TypeScript Language Service Plugin for Macroforge
This plugin integrates Macroforge's compile-time macro expansion with TypeScript's Language Service to provide seamless IDE support for macro-decorated classes.
The plugin operates by intercepting TypeScript's Language Service methods and transforming source code on-the-fly:
-
Macro Expansion: When TypeScript requests a file's content via
getScriptSnapshot, this plugin intercepts the call and returns the macro-expanded version instead. -
Position Mapping: Since expanded code has different positions than the original, the plugin maintains a {@link PositionMapper} for each file to translate positions between original and expanded coordinates.
-
Virtual .d.ts Files: For each macro-containing file, the plugin generates a companion
.macroforge.d.tsfile containing type declarations for generated methods.
.ts- TypeScript files.tsx- TypeScript JSX files.svelte- Svelte components (with<script lang="ts">)
The plugin hooks into three categories of Language Service methods:
- Host-level hooks: Control what TypeScript "sees" (
getScriptSnapshot,fileExists, etc.) - Diagnostic hooks: Map error positions back to original source (
getSemanticDiagnostics) - Navigation hooks: Handle go-to-definition, references, completions, etc.
@example
{
"compilerOptions": {
"plugins": [{ "name": "@macroforge/typescript-plugin" }]
}
}npm install @macroforge/typescript-pluginparseMacroImportComments- Parses macro import comments to extract macro name to module path mappings.getExternalManifest- Attempts to load the manifest from an external macro package.getExternalMacroInfo- Looks up macro info from an external package manifest.getExternalDecoratorInfo- Looks up decorator info from an external package manifest.findDeriveAtPosition- Finds a macro name within@derive(...)decorators at a given cursor position.findDeriveKeywordAtPosition- Finds the@derivekeyword at a given cursor position.findDecoratorAtPosition- Finds a field decorator (like@serdeor@debug) at a given cursor position.findEnclosingDeriveContext- const lastCommentEnd = beforeMatch.lastIndexOf("*/getMacroHoverInfo- Generates hover information (QuickInfo) for macros and decorators at a cursor position.shouldProcess- Determines whether a file should be processed for macro expansion.- ... and 7 more
MacroConfig- Configuration options loaded frommacroforge.json.
{
"compilerOptions": {
"plugins": [{ "name": "@macroforge/typescript-plugin" }]
}
}See the full documentation on the Macroforge website.
MIT