API Stability Notice
Macroforge is under active development. The API is not yet stable and may change between versions. Some documentation sections may be outdated.
PositionMapper
macroforge v0.1.80
Stub kept for API parity with the NAPI build: the constructor ignores its argument and both mapping methods always return `null`. WASM callers should use `NativeMapper` (from `processFile`'s plugin flow) for real position mapping.
Getting a Mapper
import { NativePlugin, PositionMapper } from "macroforge";
const plugin = new NativePlugin();
const result = plugin.processFile("user.ts", code, { version: "1" });
// Get the mapper for this file
const mapper = plugin.getMapper("user.ts");
if (mapper) {
// Use the mapper...
}Methods
isEmpty()
Check if the mapper has any mappings:
isEmpty(): booleanoriginalToExpanded()
Map a position from original to expanded code:
originalToExpanded(pos: number): numberexpandedToOriginal()
Map a position from expanded to original code:
expandedToOriginal(pos: number): number | nullReturns null if the position is in generated code.
isInGenerated()
Check if a position is in macro-generated code:
isInGenerated(pos: number): booleangeneratedBy()
Get the name of the macro that generated code at a position:
generatedBy(pos: number): string | nullmapSpanToOriginal()
Map a span (range) from expanded to original code:
mapSpanToOriginal(start: number, length: number): SpanResult | null
interface SpanResult {
start: number;
length: number;
}mapSpanToExpanded()
Map a span from original to expanded code:
mapSpanToExpanded(start: number, length: number): SpanResultExample: Error Position Mapping
import { NativePlugin } from "macroforge";
const plugin = new NativePlugin();
function mapError(filepath: string, expandedPos: number, message: string) {
const mapper = plugin.getMapper(filepath);
if (!mapper) return null;
// Check if the error is in generated code
if (mapper.isInGenerated(expandedPos)) {
const macroName = mapper.generatedBy(expandedPos);
return {
message: `Error in code generated by @derive(${macroName}): ${message}`,
// Find the @derive decorator position
position: findDecoratorPosition(filepath)
};
}
// Map to original position
const originalPos = mapper.expandedToOriginal(expandedPos);
if (originalPos !== null) {
return {
message,
position: originalPos
};
}
return null;
}Performance
Position mapping uses binary search with O(log n) complexity:
- Fast lookups even for large files
- Minimal memory overhead
- Thread-safe access