The generated event handler snippet now declares the proc with an args block. This enables parameters to be referenced within the handler body. The change makes the snippet compatible with events that pass arguments. - Include an args block in the proc declaration for event handlers.
117 lines
2.9 KiB
TypeScript
117 lines
2.9 KiB
TypeScript
export interface CdlEventHandler {
|
|
eventName: string
|
|
parameterNames: string[]
|
|
}
|
|
|
|
function structuralCode(line: string): string {
|
|
let result = ""
|
|
let inString = false
|
|
let escaped = false
|
|
|
|
for (const character of line) {
|
|
if (escaped) {
|
|
escaped = false
|
|
result += inString ? " " : character
|
|
continue
|
|
}
|
|
if (character === "\\") {
|
|
escaped = true
|
|
result += inString ? " " : character
|
|
continue
|
|
}
|
|
if (character === '"') {
|
|
inString = !inString
|
|
result += " "
|
|
continue
|
|
}
|
|
if (character === "#" && !inString) {
|
|
break
|
|
}
|
|
result += inString ? " " : character
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
function braceDelta(line: string): number {
|
|
let delta = 0
|
|
for (const character of structuralCode(line)) {
|
|
if (character === "{") {
|
|
delta += 1
|
|
} else if (character === "}") {
|
|
delta -= 1
|
|
}
|
|
}
|
|
return delta
|
|
}
|
|
|
|
export function cdlEventHandlerAtLine(
|
|
source: string,
|
|
declarationLine: number
|
|
): CdlEventHandler | undefined {
|
|
const lines = source.split(/\r?\n/)
|
|
const declaration = lines[declarationLine]
|
|
if (declaration === undefined) {
|
|
return undefined
|
|
}
|
|
|
|
const eventMatch = /^\s*EVENT\s+([^\s{]+)/.exec(structuralCode(declaration))
|
|
if (!eventMatch) {
|
|
return undefined
|
|
}
|
|
|
|
const parameterNames: string[] = []
|
|
let eventOpened = false
|
|
let depth = 0
|
|
|
|
for (let lineNumber = declarationLine; lineNumber < lines.length; lineNumber++) {
|
|
const line = lines[lineNumber]
|
|
const code = structuralCode(line)
|
|
|
|
if (eventOpened && depth === 1) {
|
|
const parameterMatch = /^\s*PARAM\s+([^\s{]+)/.exec(code)
|
|
if (parameterMatch) {
|
|
parameterNames.push(parameterMatch[1])
|
|
}
|
|
}
|
|
|
|
const delta = braceDelta(line)
|
|
if (!eventOpened && delta > 0) {
|
|
eventOpened = true
|
|
}
|
|
if (eventOpened) {
|
|
depth += delta
|
|
if (depth <= 0) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
eventName: eventMatch[1],
|
|
parameterNames
|
|
}
|
|
}
|
|
|
|
function momEventName(eventName: string): string {
|
|
return `MOM_${eventName.replace(/^MOM_/i, "")}`
|
|
}
|
|
|
|
function momVariableName(parameterName: string): string {
|
|
return `mom_${parameterName.replace(/^mom_/i, "")}`
|
|
}
|
|
|
|
export function createCdlEventHandlerSnippet(handler: CdlEventHandler): string {
|
|
const globals = [
|
|
...new Set(handler.parameterNames.map((parameter) => momVariableName(parameter)))
|
|
]
|
|
const lines = [`proc ${momEventName(handler.eventName)} {args} {`]
|
|
|
|
if (globals.length > 0) {
|
|
lines.push(...globals.map((variable) => ` global ${variable}`), "")
|
|
}
|
|
lines.push(" #Put your UDE Handler Tcl here", "", "}")
|
|
|
|
return lines.join("\n")
|
|
}
|