fix: handle multi-line param() attributes in parameter detection
Switch from single multiline regex to line-by-line scanning that skips PowerShell attribute decorators like [Parameter(Mandatory=$true)] and [ValidateSet(...)]. This correctly detects parameters with attribute lines above them (the most common real-world pattern). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -178,27 +178,36 @@ function extractParamBlockCandidates(
|
||||
block: { start: number; end: number }
|
||||
): ParameterCandidate[] {
|
||||
const lines = script.split('\n')
|
||||
const blockText = lines.slice(block.start, block.end + 1).join('\n')
|
||||
const candidates: ParameterCandidate[] = []
|
||||
|
||||
const paramRegex = /(?:\[(\w+)\])?\s*\$(\w+)(?:\s*=\s*(.+?))?(?:\s*,\s*$|\s*$|\s*\))/gm
|
||||
let match: RegExpExecArray | null
|
||||
// Scan each line in the param block for $VarName patterns.
|
||||
// Lines with [Parameter(...)], [ValidateSet(...)], etc. don't contain $VarName
|
||||
// so they are naturally skipped. The type annotation [string], [int], etc.
|
||||
// appears on the same line as $VarName.
|
||||
const varLineRegex = /(?:\[(\w+)\])?\s*\$(\w+)(?:\s*=\s*(.+?))?(?:\s*,?\s*$)/
|
||||
|
||||
for (let i = block.start; i <= block.end; i++) {
|
||||
const trimmed = lines[i].trim()
|
||||
|
||||
// Skip attribute lines like [Parameter(...)], [ValidateSet(...)], etc.
|
||||
if (/^\[(?:Parameter|ValidateSet|ValidateRange|ValidatePattern|ValidateScript|ValidateLength|ValidateCount|Alias|AllowNull|AllowEmptyString|AllowEmptyCollection)\s*\(/i.test(trimmed)) {
|
||||
continue
|
||||
}
|
||||
|
||||
const match = trimmed.match(varLineRegex)
|
||||
if (!match) continue
|
||||
|
||||
while ((match = paramRegex.exec(blockText)) !== null) {
|
||||
const typeAnnotation = match[1] || null
|
||||
const varName = match[2]
|
||||
const rawDefault = match[3]?.trim() ?? null
|
||||
|
||||
// Skip if type looks like an attribute we didn't catch above
|
||||
if (typeAnnotation && /^Parameter$/i.test(typeAnnotation)) continue
|
||||
|
||||
const key = toSnakeCase(varName)
|
||||
const { type, sensitive, reason } = inferType(typeAnnotation, rawDefault, varName)
|
||||
const defaultValue = parseDefault(rawDefault, type)
|
||||
|
||||
const lineIndex = lines.findIndex((line, idx) =>
|
||||
idx >= block.start && idx <= block.end && line.includes(`$${varName}`)
|
||||
)
|
||||
|
||||
candidates.push({
|
||||
variableName: `$${varName}`,
|
||||
suggestedKey: key,
|
||||
@@ -207,8 +216,8 @@ function extractParamBlockCandidates(
|
||||
sensitive,
|
||||
defaultValue,
|
||||
source: 'param_block',
|
||||
lineNumber: lineIndex !== -1 ? lineIndex + 1 : block.start + 1,
|
||||
matchedLine: lineIndex !== -1 ? lines[lineIndex].trim() : `$${varName}`,
|
||||
lineNumber: i + 1,
|
||||
matchedLine: trimmed,
|
||||
inferenceReason: reason,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user