|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function createMacroRuntimeError({ message, call, def, macroName }) { |
|
|
const inferredName = inferMacroName(call, def, macroName); |
|
|
|
|
|
const error = new Error(message); |
|
|
error.name = 'MacroRuntimeError'; |
|
|
|
|
|
error.isMacroRuntimeError = true; |
|
|
|
|
|
error.macroName = inferredName; |
|
|
|
|
|
error.macroRange = call && call.range ? call.range : null; |
|
|
|
|
|
if (call) error.macroCall = call; |
|
|
|
|
|
if (def) error.macroDefinition = def; |
|
|
|
|
|
return error; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function logMacroRuntimeWarning({ message, call, def, macroName, error }) { |
|
|
const payload = buildMacroPayload({ call, def, macroName, error }); |
|
|
console.warn('[Macro] Warning:', message, payload); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function logMacroInternalError({ message, call, macroName, error }) { |
|
|
const payload = buildMacroPayload({ call, def: undefined, macroName, error }); |
|
|
console.error('[Macro] Error:', message, payload); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function logMacroRegisterWarning({ message, macroName, error = undefined }) { |
|
|
const payload = buildMacroPayload({ macroName, error }); |
|
|
console.warn('[Macro] Warning:', message, payload); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function logMacroRegisterError({ message, macroName, error = undefined }) { |
|
|
const payload = buildMacroPayload({ macroName, error }); |
|
|
console.error('[Macro] Registration Error:', message, payload); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function logMacroGeneralError({ message, error }) { |
|
|
console.error('[Macro] Error:', message, error); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function logMacroSyntaxWarning({ phase, input, errors }) { |
|
|
if (!errors || errors.length === 0) { |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const issues = errors.map((err) => { |
|
|
const hasOwnLine = typeof err.line === 'number'; |
|
|
const hasOwnColumn = typeof err.column === 'number'; |
|
|
|
|
|
const token = (err.token); |
|
|
|
|
|
const line = hasOwnLine ? err.line : (token && typeof token.startLine === 'number' ? token.startLine : null); |
|
|
const column = hasOwnColumn ? err.column : (token && typeof token.startColumn === 'number' ? token.startColumn : null); |
|
|
|
|
|
|
|
|
let length = null; |
|
|
if (typeof err.length === 'number') { |
|
|
length = err.length; |
|
|
} else if (token && typeof token.startOffset === 'number' && typeof token.endOffset === 'number') { |
|
|
length = token.endOffset - token.startOffset + 1; |
|
|
} |
|
|
|
|
|
return { |
|
|
message: err.message, |
|
|
line, |
|
|
column, |
|
|
length, |
|
|
}; |
|
|
}); |
|
|
|
|
|
const label = phase === 'lexing' ? 'Lexing' : 'Parsing'; |
|
|
|
|
|
|
|
|
const payload = { |
|
|
phase, |
|
|
count: issues.length, |
|
|
issues, |
|
|
input, |
|
|
}; |
|
|
|
|
|
console.warn('[Macro] Warning:', `${label} errors detected`, payload); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function buildMacroPayload({ call, def, macroName, error }) { |
|
|
const inferredName = inferMacroName(call, def, macroName); |
|
|
|
|
|
|
|
|
const payload = { |
|
|
macroName: inferredName, |
|
|
}; |
|
|
|
|
|
if (call && call.range) payload.range = call.range; |
|
|
if (call && typeof call.rawInner === 'string') payload.raw = call.rawInner; |
|
|
if (call) payload.call = call; |
|
|
if (def) payload.def = def; |
|
|
if (error) payload.error = error; |
|
|
|
|
|
return payload; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function inferMacroName(call, def, explicit) { |
|
|
if (typeof explicit === 'string' && explicit.trim()) { |
|
|
return explicit.trim(); |
|
|
} |
|
|
if (call && typeof call.name === 'string' && call.name.trim()) { |
|
|
return call.name.trim(); |
|
|
} |
|
|
if (def && typeof def.name === 'string' && def.name.trim()) { |
|
|
return def.name.trim(); |
|
|
} |
|
|
return 'unknown'; |
|
|
} |
|
|
|