UNPKG

@macroforge/mcp-server

Version:

MCP server for Macroforge documentation and code analysis

106 lines (77 loc) • 6.2 kB
# Cross-File Macros & Diagnostics ## Importing macros A macro defined in one file can be used in another via an `import macro` JSDoc comment: ```typescript /** import macro { $vec } from "./macros" */ const xs = $vec(1, 2, 3); ``` Specifiers resolve in this order: the bare path, then `.ts`, `.tsx`, `index.ts`, `index.tsx`. ## The project registry requirement Cross-file resolution is **not automatic**. The expander only resolves imported macros when a project-wide declarative registry has been installed, which means passing `declarativeRegistryJson` in `ExpandOptions`: ```typescript import { expandSync, scanProjectSync } from '@macroforge/core'; const scan = scanProjectSync({ root: './src' }); const result = expandSync(source, 'src/app.ts', { declarativeRegistryJson: scan.declarativeRegistryJson }); ``` The bundled integrations (Vite plugin, CLI, preprocessor) do this for you. If you call `expandSync` directly and omit it, relative `import macro` specifiers emit an error diagnostic per import and resolve nothing. Bare **package** specifiers are skipped silently rather than erroring — they fall through to the proc-macro loader. ## Proc-macro fallback `$`-prefixed names are a reserved namespace. When a `$name(...)` call's callee is not a declarative macro, it's dispatched as a function-like **procedural** macro, with the module resolved from an `import macro` comment or from a plain `import { $foo } from "pkg"` statement. The same applies to `$Name<...>` in type position. Practical consequence: don't name ordinary functions with a leading `$` in a file where macros are active. ## Diagnostics ### Discovery and parse errors (fatal) | Message | Cause | | -------------------------------------------------------- | ------------------------------------------------------------ | | `${…}` interpolation in template | The macro body is a mini-language, not a JS template literal | | Spread in object form | `macroRules({ ...opts })` isn't supported | | Non-static key | Object-form keys must be literal identifiers/strings | | Unknown option key | Lists the accepted keys | | Bad `mode` string | Must be one of the four modes or their camelCase aliases | | Bad `kind` | Must be `"value"` or `"type"` | | `megamorphismThreshold` not a number / out of range | Must be a numeric literal in 0–255 | | `runtimeName` missing `$__cluster__` | The template needs the placeholder | | Missing `expand` | Required in the object form | | Sharing mode without `runtime` + `call` | Both are required to share | | `kind: "type"` with a sharing mode, `runtime`, or `call` | Types have no runtime representation | | Macro definition has no arms | Empty body | | Unbalanced delimiters | Check parens/braces in the body | | Arm does not start with `(` | Arms begin with a parenthesized pattern | | Expected `=>` after pattern | Missing arrow | | Expected `:<Kind>` / unknown fragment kind | Lists the known kinds | | Expected `*`, `+`, or `?` after repetition | A repetition needs a count suffix | | Unterminated repetition / macro call | Missing closing delimiter | | Duplicate macro name | Two definitions with identical or overlapping scopes | ### Match errors | Message | Cause | | ------------------------- | --------------------------------------------------------------------------------------------------------------- | | `NoArmMatched` | No arm matched. Lists every pattern tried, and notes that backtracking was attempted. | | `UnsupportedFragmentKind` | A fragment kind that can't appear in this position — includes a per-kind explanation and suggested alternative. | ### Expansion errors `UnboundName`, `WrongBindingShape`, `InconsistentSequenceLength`, `UnanchoredRepetition`, `RecursionLimit` (depth 256), `UnknownMacroCall`, `MalformedMacroCallArgs`, `NestedMatchFailure`. ### Type-position errors - _"macro `$X` is value-only; cannot use it in type position"_ - _"no arm of type-position macro matched"_ ### Analyzer diagnostics | Level | Message | | ------- | --------------------------------------------------------------------------- | | Warning | Cluster recommendation — call sites partitioned into N clusters | | Warning | ForceExpand — too many distinct shapes; suggests `share-anyway` to override | | Warning | A call site matched no cluster; fell back to the single helper | | Info | Running without a type registry; structural clustering disabled | | Info | Analyzer telemetry, when enabled | ### Post-expansion validation In **dev builds only**, the expander re-parses its own output and reports _"macro `$foo` produced invalid TypeScript: …"_, attributing the failure to the originating macro. This catches template bugs that would otherwise surface as a confusing syntax error in generated code.