@rushstack/problem-matcher
Advanced tools
| "use strict"; | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||
| // See LICENSE in the project root for license information. | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.parseProblemMatchersJson = void 0; | ||
| var ProblemMatcher_1 = require("./ProblemMatcher"); | ||
| Object.defineProperty(exports, "parseProblemMatchersJson", { enumerable: true, get: function () { return ProblemMatcher_1.parseProblemMatchersJson; } }); | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAgB3D,mDAA4D;AAAnD,0HAAA,wBAAwB,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Parse VS Code style problem matcher definitions and use them to extract\n * structured problem reports from strings.\n *\n * @packageDocumentation\n */\n\nexport type {\n ProblemSeverity,\n IProblemMatcher,\n IProblemMatcherJson,\n IProblemPattern,\n IProblem\n} from './ProblemMatcher';\nexport { parseProblemMatchersJson } from './ProblemMatcher';\n"]} |
| "use strict"; | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||
| // See LICENSE in the project root for license information. | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.parseProblemMatchersJson = parseProblemMatchersJson; | ||
| /** | ||
| * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects. | ||
| * | ||
| * @public | ||
| */ | ||
| function parseProblemMatchersJson(problemMatchers) { | ||
| const result = []; | ||
| for (const matcher of problemMatchers) { | ||
| const problemPatterns = Array.isArray(matcher.pattern) | ||
| ? matcher.pattern | ||
| : [matcher.pattern]; | ||
| if (problemPatterns.length === 0) { | ||
| continue; | ||
| } | ||
| const name = matcher.name; | ||
| const defaultSeverity = matcher.severity; | ||
| const compiled = compileProblemPatterns(problemPatterns); | ||
| if (compiled.length === 1) { | ||
| result.push(createSingleLineMatcher(name, compiled[0], defaultSeverity)); | ||
| } | ||
| else { | ||
| result.push(createMultiLineMatcher(name, compiled, defaultSeverity)); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function toNumber(text) { | ||
| if (!text) { | ||
| return undefined; | ||
| } | ||
| const n = parseInt(text, 10); | ||
| return isNaN(n) ? undefined : n; | ||
| } | ||
| function normalizeSeverity(raw) { | ||
| if (!raw) { | ||
| return undefined; | ||
| } | ||
| const lowered = raw.toLowerCase(); | ||
| // Support full words as well as common abbreviations (e.g. single-letter tokens) | ||
| if (lowered.indexOf('err') === 0) | ||
| return 'error'; | ||
| if (lowered.indexOf('warn') === 0) | ||
| return 'warning'; | ||
| if (lowered.indexOf('info') === 0) | ||
| return 'info'; | ||
| return undefined; | ||
| } | ||
| function compileProblemPatterns(problemPatterns) { | ||
| return problemPatterns.map((problemPattern) => { | ||
| let reStr = problemPattern.regexp; | ||
| if (/\\r?\\n\$/.test(reStr) || /\\n\$/.test(reStr)) { | ||
| // already newline aware | ||
| } | ||
| else if (reStr.length > 0 && reStr.charAt(reStr.length - 1) === '$') { | ||
| reStr = reStr.slice(0, -1) + '\\r?\\n$'; | ||
| } | ||
| else { | ||
| reStr = reStr + '(?:\\r?\\n)'; | ||
| } | ||
| const re = new RegExp(reStr); | ||
| return { re, spec: problemPattern }; | ||
| }); | ||
| } | ||
| function createEmptyCaptures() { | ||
| return { messageParts: [] }; | ||
| } | ||
| /** | ||
| * Apply one pattern's regex match to the (possibly accumulating) captures. | ||
| */ | ||
| function applyPatternCaptures(spec, reMatch, captures, defaultSeverity) { | ||
| if (spec.file && reMatch[spec.file]) { | ||
| captures.file = reMatch[spec.file]; | ||
| } | ||
| if (spec.location && reMatch[spec.location]) { | ||
| const loc = reMatch[spec.location]; | ||
| const parts = loc.split(/[,.:]/).filter((s) => s.length > 0); | ||
| if (parts.length === 1) { | ||
| captures.line = toNumber(parts[0]); | ||
| } | ||
| else if (parts.length === 2) { | ||
| captures.line = toNumber(parts[0]); | ||
| captures.column = toNumber(parts[1]); | ||
| } | ||
| else if (parts.length === 4) { | ||
| captures.line = toNumber(parts[0]); | ||
| captures.column = toNumber(parts[1]); | ||
| captures.endLine = toNumber(parts[2]); | ||
| captures.endColumn = toNumber(parts[3]); | ||
| } | ||
| } | ||
| else { | ||
| if (spec.line && reMatch[spec.line]) { | ||
| captures.line = toNumber(reMatch[spec.line]); | ||
| } | ||
| if (spec.column && reMatch[spec.column]) { | ||
| captures.column = toNumber(reMatch[spec.column]); | ||
| } | ||
| } | ||
| if (spec.endLine && reMatch[spec.endLine]) { | ||
| captures.endLine = toNumber(reMatch[spec.endLine]); | ||
| } | ||
| if (spec.endColumn && reMatch[spec.endColumn]) { | ||
| captures.endColumn = toNumber(reMatch[spec.endColumn]); | ||
| } | ||
| if (spec.severity && reMatch[spec.severity]) { | ||
| captures.severity = normalizeSeverity(reMatch[spec.severity]) || defaultSeverity; | ||
| } | ||
| else if (!captures.severity && defaultSeverity) { | ||
| captures.severity = defaultSeverity; | ||
| } | ||
| if (spec.code && reMatch[spec.code]) { | ||
| captures.code = reMatch[spec.code]; | ||
| } | ||
| if (spec.message && reMatch[spec.message]) { | ||
| captures.messageParts.push(reMatch[spec.message]); | ||
| } | ||
| } | ||
| function finalizeProblem(matcherName, captures, defaultSeverity) { | ||
| // For multi-line patterns, use only the last non-empty message part | ||
| const message = captures.messageParts.length > 0 ? captures.messageParts[captures.messageParts.length - 1] : ''; | ||
| return { | ||
| matcherName, | ||
| file: captures.file, | ||
| line: captures.line, | ||
| column: captures.column, | ||
| endLine: captures.endLine, | ||
| endColumn: captures.endColumn, | ||
| severity: captures.severity || defaultSeverity, | ||
| code: captures.code, | ||
| message: message | ||
| }; | ||
| } | ||
| function createSingleLineMatcher(name, compiled, defaultSeverity) { | ||
| const { re, spec } = compiled; | ||
| return { | ||
| name, | ||
| exec(line) { | ||
| const match = re.exec(line); | ||
| if (!match) { | ||
| return false; | ||
| } | ||
| const captures = createEmptyCaptures(); | ||
| applyPatternCaptures(spec, match, captures, defaultSeverity); | ||
| return finalizeProblem(name, captures, defaultSeverity); | ||
| } | ||
| }; | ||
| } | ||
| function createMultiLineMatcher(name, compiled, defaultSeverity) { | ||
| // currentIndex points to the next pattern we expect to match. When it equals compiled.length | ||
| // and the last pattern is a loop, we are in a special "loop state" where additional lines | ||
| // should be attempted against only the last pattern to emit more problems. | ||
| let currentIndex = 0; | ||
| const lastSpec = compiled[compiled.length - 1].spec; | ||
| const lastIsLoop = !!lastSpec.loop; | ||
| let captures = createEmptyCaptures(); | ||
| return { | ||
| name, | ||
| exec(line) { | ||
| let effectiveMatch = null; | ||
| let effectiveSpec; | ||
| // Determine matching behavior based on current state | ||
| if (currentIndex === compiled.length && lastIsLoop) { | ||
| // Loop state: only try to match the last pattern | ||
| const lastPattern = compiled[compiled.length - 1]; | ||
| effectiveMatch = lastPattern.re.exec(line); | ||
| if (!effectiveMatch) { | ||
| // Exit loop state and reset for a potential new sequence | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| // Attempt to treat this line as a fresh start (pattern 0) | ||
| const first = compiled[0]; | ||
| const fresh = first.re.exec(line); | ||
| if (!fresh) { | ||
| return false; | ||
| } | ||
| effectiveMatch = fresh; | ||
| effectiveSpec = first.spec; | ||
| currentIndex = compiled.length > 1 ? 1 : compiled.length; | ||
| } | ||
| else { | ||
| effectiveSpec = lastPattern.spec; | ||
| // currentIndex remains compiled.length (loop state) until we decide to emit | ||
| } | ||
| } | ||
| else { | ||
| // Normal multi-line progression state | ||
| const active = compiled[currentIndex]; | ||
| const reMatch = active.re.exec(line); | ||
| if (!reMatch) { | ||
| // Reset and maybe attempt new start | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| const { re: re0, spec: spec0 } = compiled[0]; | ||
| const restartMatch = re0.exec(line); | ||
| if (!restartMatch) { | ||
| return false; | ||
| } | ||
| effectiveMatch = restartMatch; | ||
| effectiveSpec = spec0; | ||
| currentIndex = compiled.length > 1 ? 1 : compiled.length; | ||
| } | ||
| else { | ||
| effectiveMatch = reMatch; | ||
| effectiveSpec = active.spec; | ||
| currentIndex++; | ||
| } | ||
| } | ||
| applyPatternCaptures(effectiveSpec, effectiveMatch, captures, defaultSeverity); | ||
| // If we haven't matched all patterns yet (and not in loop state), wait for more lines | ||
| if (currentIndex < compiled.length) { | ||
| return false; | ||
| } | ||
| // We have matched the full sequence (either first completion or a loop iteration) | ||
| const problem = finalizeProblem(name, captures, defaultSeverity); | ||
| if (lastIsLoop) { | ||
| // Stay in loop state; reset fields that accumulate per problem but retain other context (e.g., file if first pattern captured it?) | ||
| // For safety, if the last pattern provided the file each iteration we keep overwriting anyway. | ||
| captures.messageParts = []; | ||
| // Do not clear entire captures to allow preceding pattern data (e.g., summary) to persist if desirable. | ||
| } | ||
| else { | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| } | ||
| return problem; | ||
| } | ||
| }; | ||
| } | ||
| //# sourceMappingURL=ProblemMatcher.js.map |
| {"version":3,"file":"ProblemMatcher.js","sourceRoot":"","sources":["../src/ProblemMatcher.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Represents the severity level of a problem.\n *\n * @public\n */\nexport type ProblemSeverity = 'error' | 'warning' | 'info';\n\n/**\n * Represents a problem (generally an error or warning) detected in the console output.\n *\n * @public\n */\nexport interface IProblem {\n /** The name of the matcher that detected the problem. */\n readonly matcherName: string;\n /** Parsed message from the problem matcher */\n readonly message: string;\n /** Parsed severity level from the problem matcher */\n readonly severity?: ProblemSeverity;\n /** Parsed file path from the problem matcher */\n readonly file?: string;\n /** Parsed line number from the problem matcher */\n readonly line?: number;\n /** Parsed column number from the problem matcher */\n readonly column?: number;\n /** Parsed ending line number from the problem matcher */\n readonly endLine?: number;\n /** Parsed ending column number from the problem matcher */\n readonly endColumn?: number;\n /** Parsed error or warning code from the problem matcher */\n readonly code?: string;\n}\n\n/**\n * A problem matcher processes one line at a time and returns an {@link IProblem} if a match occurs.\n *\n * @remarks\n * Multi-line matchers may keep internal state and emit on a later line; they can also optionally\n * implement `flush()` to emit any buffered problems when the stream closes.\n *\n * @public\n */\nexport interface IProblemMatcher {\n /** A friendly (and stable) name identifying the matcher. */\n readonly name: string;\n /**\n * Attempt to match a problem for the provided line of console output.\n *\n * @param line - A single line of text, always terminated with a newline character (\\\\n).\n * @returns A problem if recognized, otherwise `false`.\n */\n exec(line: string): IProblem | false;\n /**\n * Flush any buffered state and return additional problems. Optional.\n */\n flush?(): IProblem[];\n}\n\n/**\n * VS Code style problem matcher pattern definition.\n *\n * @remarks\n * This mirrors the shape used in VS Code's `problemMatcher.pattern` entries.\n * Reference: https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher\n *\n * @public\n */\nexport interface IProblemPattern {\n /** A regular expression used to match the problem. */\n regexp: string;\n /** Match index for the file path. */\n file?: number;\n /** Match index for the location. */\n location?: number;\n /** Match index for the starting line number. */\n line?: number;\n /** Match index for the starting column number. */\n column?: number;\n /** Match index for the ending line number. */\n endLine?: number;\n /** Match index for the ending column number. */\n endColumn?: number;\n /** Match index for the severity level. */\n severity?: number;\n /** Match index for the problem code. */\n code?: number;\n /** Match index for the problem message. */\n message: number;\n /** If true, the last pattern in a multi-line matcher may repeat (loop) producing multiple problems */\n loop?: boolean;\n}\n\n/**\n * Minimal VS Code problem matcher definition.\n *\n * @public\n */\nexport interface IProblemMatcherJson {\n /** A friendly (and stable) name identifying the matcher. */\n name: string;\n /** An optional default severity to apply if the pattern does not capture one. */\n severity?: ProblemSeverity;\n /** A single pattern or an array of patterns to match. */\n pattern: IProblemPattern | IProblemPattern[];\n}\n\n/**\n * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects.\n *\n * @public\n */\nexport function parseProblemMatchersJson(problemMatchers: IProblemMatcherJson[]): IProblemMatcher[] {\n const result: IProblemMatcher[] = [];\n\n for (const matcher of problemMatchers) {\n const problemPatterns: IProblemPattern[] = Array.isArray(matcher.pattern)\n ? matcher.pattern\n : [matcher.pattern];\n if (problemPatterns.length === 0) {\n continue;\n }\n\n const name: string = matcher.name;\n const defaultSeverity: ProblemSeverity | undefined = matcher.severity;\n const compiled: ICompiledProblemPattern[] = compileProblemPatterns(problemPatterns);\n\n if (compiled.length === 1) {\n result.push(createSingleLineMatcher(name, compiled[0], defaultSeverity));\n } else {\n result.push(createMultiLineMatcher(name, compiled, defaultSeverity));\n }\n }\n\n return result;\n}\n\nfunction toNumber(text: string | undefined): number | undefined {\n if (!text) {\n return undefined;\n }\n const n: number = parseInt(text, 10);\n return isNaN(n) ? undefined : n;\n}\n\nfunction normalizeSeverity(raw: string | undefined): ProblemSeverity | undefined {\n if (!raw) {\n return undefined;\n }\n const lowered: string = raw.toLowerCase();\n // Support full words as well as common abbreviations (e.g. single-letter tokens)\n if (lowered.indexOf('err') === 0) return 'error';\n if (lowered.indexOf('warn') === 0) return 'warning';\n if (lowered.indexOf('info') === 0) return 'info';\n return undefined;\n}\n\ninterface ICompiledProblemPattern {\n re: RegExp;\n spec: IProblemPattern;\n}\n\nfunction compileProblemPatterns(problemPatterns: IProblemPattern[]): ICompiledProblemPattern[] {\n return problemPatterns.map((problemPattern) => {\n let reStr: string = problemPattern.regexp;\n if (/\\\\r?\\\\n\\$/.test(reStr) || /\\\\n\\$/.test(reStr)) {\n // already newline aware\n } else if (reStr.length > 0 && reStr.charAt(reStr.length - 1) === '$') {\n reStr = reStr.slice(0, -1) + '\\\\r?\\\\n$';\n } else {\n reStr = reStr + '(?:\\\\r?\\\\n)';\n }\n const re: RegExp = new RegExp(reStr);\n return { re, spec: problemPattern };\n });\n}\n\n/**\n * Shared capture structure used by both single-line and multi-line implementations.\n */\ninterface ICapturesMutable {\n file?: string;\n line?: number;\n column?: number;\n endLine?: number;\n endColumn?: number;\n severity?: ProblemSeverity;\n code?: string;\n messageParts: string[];\n}\n\nfunction createEmptyCaptures(): ICapturesMutable {\n return { messageParts: [] };\n}\n\n/**\n * Apply one pattern's regex match to the (possibly accumulating) captures.\n */\nfunction applyPatternCaptures(\n spec: IProblemPattern,\n reMatch: RegExpExecArray,\n captures: ICapturesMutable,\n defaultSeverity: ProblemSeverity | undefined\n): void {\n if (spec.file && reMatch[spec.file]) {\n captures.file = reMatch[spec.file];\n }\n\n if (spec.location && reMatch[spec.location]) {\n const loc: string = reMatch[spec.location];\n const parts: string[] = loc.split(/[,.:]/).filter((s) => s.length > 0);\n if (parts.length === 1) {\n captures.line = toNumber(parts[0]);\n } else if (parts.length === 2) {\n captures.line = toNumber(parts[0]);\n captures.column = toNumber(parts[1]);\n } else if (parts.length === 4) {\n captures.line = toNumber(parts[0]);\n captures.column = toNumber(parts[1]);\n captures.endLine = toNumber(parts[2]);\n captures.endColumn = toNumber(parts[3]);\n }\n } else {\n if (spec.line && reMatch[spec.line]) {\n captures.line = toNumber(reMatch[spec.line]);\n }\n if (spec.column && reMatch[spec.column]) {\n captures.column = toNumber(reMatch[spec.column]);\n }\n }\n\n if (spec.endLine && reMatch[spec.endLine]) {\n captures.endLine = toNumber(reMatch[spec.endLine]);\n }\n if (spec.endColumn && reMatch[spec.endColumn]) {\n captures.endColumn = toNumber(reMatch[spec.endColumn]);\n }\n\n if (spec.severity && reMatch[spec.severity]) {\n captures.severity = normalizeSeverity(reMatch[spec.severity]) || defaultSeverity;\n } else if (!captures.severity && defaultSeverity) {\n captures.severity = defaultSeverity;\n }\n\n if (spec.code && reMatch[spec.code]) {\n captures.code = reMatch[spec.code];\n }\n\n if (spec.message && reMatch[spec.message]) {\n captures.messageParts.push(reMatch[spec.message]);\n }\n}\n\nfunction finalizeProblem(\n matcherName: string,\n captures: ICapturesMutable,\n defaultSeverity: ProblemSeverity | undefined\n): IProblem {\n // For multi-line patterns, use only the last non-empty message part\n const message: string =\n captures.messageParts.length > 0 ? captures.messageParts[captures.messageParts.length - 1] : '';\n\n return {\n matcherName,\n file: captures.file,\n line: captures.line,\n column: captures.column,\n endLine: captures.endLine,\n endColumn: captures.endColumn,\n severity: captures.severity || defaultSeverity,\n code: captures.code,\n message: message\n };\n}\n\nfunction createSingleLineMatcher(\n name: string,\n compiled: ICompiledProblemPattern,\n defaultSeverity: ProblemSeverity | undefined\n): IProblemMatcher {\n const { re, spec } = compiled;\n return {\n name,\n exec(line: string): IProblem | false {\n const match: RegExpExecArray | null = re.exec(line);\n if (!match) {\n return false;\n }\n const captures: ICapturesMutable = createEmptyCaptures();\n applyPatternCaptures(spec, match, captures, defaultSeverity);\n return finalizeProblem(name, captures, defaultSeverity);\n }\n };\n}\n\nfunction createMultiLineMatcher(\n name: string,\n compiled: ICompiledProblemPattern[],\n defaultSeverity: ProblemSeverity | undefined\n): IProblemMatcher {\n // currentIndex points to the next pattern we expect to match. When it equals compiled.length\n // and the last pattern is a loop, we are in a special \"loop state\" where additional lines\n // should be attempted against only the last pattern to emit more problems.\n let currentIndex: number = 0;\n const lastSpec: IProblemPattern = compiled[compiled.length - 1].spec;\n const lastIsLoop: boolean = !!lastSpec.loop;\n\n let captures: ICapturesMutable = createEmptyCaptures();\n\n return {\n name,\n exec(line: string): IProblem | false {\n let effectiveMatch: RegExpExecArray | null = null;\n let effectiveSpec: IProblemPattern | undefined;\n\n // Determine matching behavior based on current state\n if (currentIndex === compiled.length && lastIsLoop) {\n // Loop state: only try to match the last pattern\n const lastPattern: ICompiledProblemPattern = compiled[compiled.length - 1];\n effectiveMatch = lastPattern.re.exec(line);\n if (!effectiveMatch) {\n // Exit loop state and reset for a potential new sequence\n currentIndex = 0;\n captures = createEmptyCaptures();\n // Attempt to treat this line as a fresh start (pattern 0)\n const first: ICompiledProblemPattern = compiled[0];\n const fresh: RegExpExecArray | null = first.re.exec(line);\n if (!fresh) {\n return false;\n }\n effectiveMatch = fresh;\n effectiveSpec = first.spec;\n currentIndex = compiled.length > 1 ? 1 : compiled.length;\n } else {\n effectiveSpec = lastPattern.spec;\n // currentIndex remains compiled.length (loop state) until we decide to emit\n }\n } else {\n // Normal multi-line progression state\n const active: ICompiledProblemPattern = compiled[currentIndex];\n const reMatch: RegExpExecArray | null = active.re.exec(line);\n if (!reMatch) {\n // Reset and maybe attempt new start\n currentIndex = 0;\n captures = createEmptyCaptures();\n const { re: re0, spec: spec0 } = compiled[0];\n const restartMatch: RegExpExecArray | null = re0.exec(line);\n if (!restartMatch) {\n return false;\n }\n effectiveMatch = restartMatch;\n effectiveSpec = spec0;\n currentIndex = compiled.length > 1 ? 1 : compiled.length;\n } else {\n effectiveMatch = reMatch;\n effectiveSpec = active.spec;\n currentIndex++;\n }\n }\n\n applyPatternCaptures(\n effectiveSpec as IProblemPattern,\n effectiveMatch as RegExpExecArray,\n captures,\n defaultSeverity\n );\n\n // If we haven't matched all patterns yet (and not in loop state), wait for more lines\n if (currentIndex < compiled.length) {\n return false;\n }\n\n // We have matched the full sequence (either first completion or a loop iteration)\n const problem: IProblem = finalizeProblem(name, captures, defaultSeverity);\n\n if (lastIsLoop) {\n // Stay in loop state; reset fields that accumulate per problem but retain other context (e.g., file if first pattern captured it?)\n // For safety, if the last pattern provided the file each iteration we keep overwriting anyway.\n captures.messageParts = [];\n // Do not clear entire captures to allow preceding pattern data (e.g., summary) to persist if desirable.\n } else {\n currentIndex = 0;\n captures = createEmptyCaptures();\n }\n\n return problem;\n }\n };\n}\n"]} |
| /** | ||
| * Parse VS Code style problem matcher definitions and use them to extract | ||
| * structured problem reports from strings. | ||
| * | ||
| * @packageDocumentation | ||
| */ | ||
| export type { ProblemSeverity, IProblemMatcher, IProblemMatcherJson, IProblemPattern, IProblem } from './ProblemMatcher'; | ||
| export { parseProblemMatchersJson } from './ProblemMatcher'; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC"} |
| /** | ||
| * Represents the severity level of a problem. | ||
| * | ||
| * @public | ||
| */ | ||
| export type ProblemSeverity = 'error' | 'warning' | 'info'; | ||
| /** | ||
| * Represents a problem (generally an error or warning) detected in the console output. | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblem { | ||
| /** The name of the matcher that detected the problem. */ | ||
| readonly matcherName: string; | ||
| /** Parsed message from the problem matcher */ | ||
| readonly message: string; | ||
| /** Parsed severity level from the problem matcher */ | ||
| readonly severity?: ProblemSeverity; | ||
| /** Parsed file path from the problem matcher */ | ||
| readonly file?: string; | ||
| /** Parsed line number from the problem matcher */ | ||
| readonly line?: number; | ||
| /** Parsed column number from the problem matcher */ | ||
| readonly column?: number; | ||
| /** Parsed ending line number from the problem matcher */ | ||
| readonly endLine?: number; | ||
| /** Parsed ending column number from the problem matcher */ | ||
| readonly endColumn?: number; | ||
| /** Parsed error or warning code from the problem matcher */ | ||
| readonly code?: string; | ||
| } | ||
| /** | ||
| * A problem matcher processes one line at a time and returns an {@link IProblem} if a match occurs. | ||
| * | ||
| * @remarks | ||
| * Multi-line matchers may keep internal state and emit on a later line; they can also optionally | ||
| * implement `flush()` to emit any buffered problems when the stream closes. | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblemMatcher { | ||
| /** A friendly (and stable) name identifying the matcher. */ | ||
| readonly name: string; | ||
| /** | ||
| * Attempt to match a problem for the provided line of console output. | ||
| * | ||
| * @param line - A single line of text, always terminated with a newline character (\\n). | ||
| * @returns A problem if recognized, otherwise `false`. | ||
| */ | ||
| exec(line: string): IProblem | false; | ||
| /** | ||
| * Flush any buffered state and return additional problems. Optional. | ||
| */ | ||
| flush?(): IProblem[]; | ||
| } | ||
| /** | ||
| * VS Code style problem matcher pattern definition. | ||
| * | ||
| * @remarks | ||
| * This mirrors the shape used in VS Code's `problemMatcher.pattern` entries. | ||
| * Reference: https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblemPattern { | ||
| /** A regular expression used to match the problem. */ | ||
| regexp: string; | ||
| /** Match index for the file path. */ | ||
| file?: number; | ||
| /** Match index for the location. */ | ||
| location?: number; | ||
| /** Match index for the starting line number. */ | ||
| line?: number; | ||
| /** Match index for the starting column number. */ | ||
| column?: number; | ||
| /** Match index for the ending line number. */ | ||
| endLine?: number; | ||
| /** Match index for the ending column number. */ | ||
| endColumn?: number; | ||
| /** Match index for the severity level. */ | ||
| severity?: number; | ||
| /** Match index for the problem code. */ | ||
| code?: number; | ||
| /** Match index for the problem message. */ | ||
| message: number; | ||
| /** If true, the last pattern in a multi-line matcher may repeat (loop) producing multiple problems */ | ||
| loop?: boolean; | ||
| } | ||
| /** | ||
| * Minimal VS Code problem matcher definition. | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblemMatcherJson { | ||
| /** A friendly (and stable) name identifying the matcher. */ | ||
| name: string; | ||
| /** An optional default severity to apply if the pattern does not capture one. */ | ||
| severity?: ProblemSeverity; | ||
| /** A single pattern or an array of patterns to match. */ | ||
| pattern: IProblemPattern | IProblemPattern[]; | ||
| } | ||
| /** | ||
| * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects. | ||
| * | ||
| * @public | ||
| */ | ||
| export declare function parseProblemMatchersJson(problemMatchers: IProblemMatcherJson[]): IProblemMatcher[]; | ||
| //# sourceMappingURL=ProblemMatcher.d.ts.map |
| {"version":3,"file":"ProblemMatcher.d.ts","sourceRoot":"","sources":["../src/ProblemMatcher.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACrC;;OAEG;IACH,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,sGAAsG;IACtG,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,yDAAyD;IACzD,OAAO,EAAE,eAAe,GAAG,eAAe,EAAE,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,mBAAmB,EAAE,GAAG,eAAe,EAAE,CAuBlG"} |
| // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||
| // See LICENSE in the project root for license information. | ||
| export { parseProblemMatchersJson } from './ProblemMatcher'; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAgB3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Parse VS Code style problem matcher definitions and use them to extract\n * structured problem reports from strings.\n *\n * @packageDocumentation\n */\n\nexport type {\n ProblemSeverity,\n IProblemMatcher,\n IProblemMatcherJson,\n IProblemPattern,\n IProblem\n} from './ProblemMatcher';\nexport { parseProblemMatchersJson } from './ProblemMatcher';\n"]} |
| // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||
| // See LICENSE in the project root for license information. | ||
| /** | ||
| * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects. | ||
| * | ||
| * @public | ||
| */ | ||
| export function parseProblemMatchersJson(problemMatchers) { | ||
| const result = []; | ||
| for (const matcher of problemMatchers) { | ||
| const problemPatterns = Array.isArray(matcher.pattern) | ||
| ? matcher.pattern | ||
| : [matcher.pattern]; | ||
| if (problemPatterns.length === 0) { | ||
| continue; | ||
| } | ||
| const name = matcher.name; | ||
| const defaultSeverity = matcher.severity; | ||
| const compiled = compileProblemPatterns(problemPatterns); | ||
| if (compiled.length === 1) { | ||
| result.push(createSingleLineMatcher(name, compiled[0], defaultSeverity)); | ||
| } | ||
| else { | ||
| result.push(createMultiLineMatcher(name, compiled, defaultSeverity)); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function toNumber(text) { | ||
| if (!text) { | ||
| return undefined; | ||
| } | ||
| const n = parseInt(text, 10); | ||
| return isNaN(n) ? undefined : n; | ||
| } | ||
| function normalizeSeverity(raw) { | ||
| if (!raw) { | ||
| return undefined; | ||
| } | ||
| const lowered = raw.toLowerCase(); | ||
| // Support full words as well as common abbreviations (e.g. single-letter tokens) | ||
| if (lowered.indexOf('err') === 0) | ||
| return 'error'; | ||
| if (lowered.indexOf('warn') === 0) | ||
| return 'warning'; | ||
| if (lowered.indexOf('info') === 0) | ||
| return 'info'; | ||
| return undefined; | ||
| } | ||
| function compileProblemPatterns(problemPatterns) { | ||
| return problemPatterns.map((problemPattern) => { | ||
| let reStr = problemPattern.regexp; | ||
| if (/\\r?\\n\$/.test(reStr) || /\\n\$/.test(reStr)) { | ||
| // already newline aware | ||
| } | ||
| else if (reStr.length > 0 && reStr.charAt(reStr.length - 1) === '$') { | ||
| reStr = reStr.slice(0, -1) + '\\r?\\n$'; | ||
| } | ||
| else { | ||
| reStr = reStr + '(?:\\r?\\n)'; | ||
| } | ||
| const re = new RegExp(reStr); | ||
| return { re, spec: problemPattern }; | ||
| }); | ||
| } | ||
| function createEmptyCaptures() { | ||
| return { messageParts: [] }; | ||
| } | ||
| /** | ||
| * Apply one pattern's regex match to the (possibly accumulating) captures. | ||
| */ | ||
| function applyPatternCaptures(spec, reMatch, captures, defaultSeverity) { | ||
| if (spec.file && reMatch[spec.file]) { | ||
| captures.file = reMatch[spec.file]; | ||
| } | ||
| if (spec.location && reMatch[spec.location]) { | ||
| const loc = reMatch[spec.location]; | ||
| const parts = loc.split(/[,.:]/).filter((s) => s.length > 0); | ||
| if (parts.length === 1) { | ||
| captures.line = toNumber(parts[0]); | ||
| } | ||
| else if (parts.length === 2) { | ||
| captures.line = toNumber(parts[0]); | ||
| captures.column = toNumber(parts[1]); | ||
| } | ||
| else if (parts.length === 4) { | ||
| captures.line = toNumber(parts[0]); | ||
| captures.column = toNumber(parts[1]); | ||
| captures.endLine = toNumber(parts[2]); | ||
| captures.endColumn = toNumber(parts[3]); | ||
| } | ||
| } | ||
| else { | ||
| if (spec.line && reMatch[spec.line]) { | ||
| captures.line = toNumber(reMatch[spec.line]); | ||
| } | ||
| if (spec.column && reMatch[spec.column]) { | ||
| captures.column = toNumber(reMatch[spec.column]); | ||
| } | ||
| } | ||
| if (spec.endLine && reMatch[spec.endLine]) { | ||
| captures.endLine = toNumber(reMatch[spec.endLine]); | ||
| } | ||
| if (spec.endColumn && reMatch[spec.endColumn]) { | ||
| captures.endColumn = toNumber(reMatch[spec.endColumn]); | ||
| } | ||
| if (spec.severity && reMatch[spec.severity]) { | ||
| captures.severity = normalizeSeverity(reMatch[spec.severity]) || defaultSeverity; | ||
| } | ||
| else if (!captures.severity && defaultSeverity) { | ||
| captures.severity = defaultSeverity; | ||
| } | ||
| if (spec.code && reMatch[spec.code]) { | ||
| captures.code = reMatch[spec.code]; | ||
| } | ||
| if (spec.message && reMatch[spec.message]) { | ||
| captures.messageParts.push(reMatch[spec.message]); | ||
| } | ||
| } | ||
| function finalizeProblem(matcherName, captures, defaultSeverity) { | ||
| // For multi-line patterns, use only the last non-empty message part | ||
| const message = captures.messageParts.length > 0 ? captures.messageParts[captures.messageParts.length - 1] : ''; | ||
| return { | ||
| matcherName, | ||
| file: captures.file, | ||
| line: captures.line, | ||
| column: captures.column, | ||
| endLine: captures.endLine, | ||
| endColumn: captures.endColumn, | ||
| severity: captures.severity || defaultSeverity, | ||
| code: captures.code, | ||
| message: message | ||
| }; | ||
| } | ||
| function createSingleLineMatcher(name, compiled, defaultSeverity) { | ||
| const { re, spec } = compiled; | ||
| return { | ||
| name, | ||
| exec(line) { | ||
| const match = re.exec(line); | ||
| if (!match) { | ||
| return false; | ||
| } | ||
| const captures = createEmptyCaptures(); | ||
| applyPatternCaptures(spec, match, captures, defaultSeverity); | ||
| return finalizeProblem(name, captures, defaultSeverity); | ||
| } | ||
| }; | ||
| } | ||
| function createMultiLineMatcher(name, compiled, defaultSeverity) { | ||
| // currentIndex points to the next pattern we expect to match. When it equals compiled.length | ||
| // and the last pattern is a loop, we are in a special "loop state" where additional lines | ||
| // should be attempted against only the last pattern to emit more problems. | ||
| let currentIndex = 0; | ||
| const lastSpec = compiled[compiled.length - 1].spec; | ||
| const lastIsLoop = !!lastSpec.loop; | ||
| let captures = createEmptyCaptures(); | ||
| return { | ||
| name, | ||
| exec(line) { | ||
| let effectiveMatch = null; | ||
| let effectiveSpec; | ||
| // Determine matching behavior based on current state | ||
| if (currentIndex === compiled.length && lastIsLoop) { | ||
| // Loop state: only try to match the last pattern | ||
| const lastPattern = compiled[compiled.length - 1]; | ||
| effectiveMatch = lastPattern.re.exec(line); | ||
| if (!effectiveMatch) { | ||
| // Exit loop state and reset for a potential new sequence | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| // Attempt to treat this line as a fresh start (pattern 0) | ||
| const first = compiled[0]; | ||
| const fresh = first.re.exec(line); | ||
| if (!fresh) { | ||
| return false; | ||
| } | ||
| effectiveMatch = fresh; | ||
| effectiveSpec = first.spec; | ||
| currentIndex = compiled.length > 1 ? 1 : compiled.length; | ||
| } | ||
| else { | ||
| effectiveSpec = lastPattern.spec; | ||
| // currentIndex remains compiled.length (loop state) until we decide to emit | ||
| } | ||
| } | ||
| else { | ||
| // Normal multi-line progression state | ||
| const active = compiled[currentIndex]; | ||
| const reMatch = active.re.exec(line); | ||
| if (!reMatch) { | ||
| // Reset and maybe attempt new start | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| const { re: re0, spec: spec0 } = compiled[0]; | ||
| const restartMatch = re0.exec(line); | ||
| if (!restartMatch) { | ||
| return false; | ||
| } | ||
| effectiveMatch = restartMatch; | ||
| effectiveSpec = spec0; | ||
| currentIndex = compiled.length > 1 ? 1 : compiled.length; | ||
| } | ||
| else { | ||
| effectiveMatch = reMatch; | ||
| effectiveSpec = active.spec; | ||
| currentIndex++; | ||
| } | ||
| } | ||
| applyPatternCaptures(effectiveSpec, effectiveMatch, captures, defaultSeverity); | ||
| // If we haven't matched all patterns yet (and not in loop state), wait for more lines | ||
| if (currentIndex < compiled.length) { | ||
| return false; | ||
| } | ||
| // We have matched the full sequence (either first completion or a loop iteration) | ||
| const problem = finalizeProblem(name, captures, defaultSeverity); | ||
| if (lastIsLoop) { | ||
| // Stay in loop state; reset fields that accumulate per problem but retain other context (e.g., file if first pattern captured it?) | ||
| // For safety, if the last pattern provided the file each iteration we keep overwriting anyway. | ||
| captures.messageParts = []; | ||
| // Do not clear entire captures to allow preceding pattern data (e.g., summary) to persist if desirable. | ||
| } | ||
| else { | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| } | ||
| return problem; | ||
| } | ||
| }; | ||
| } | ||
| //# sourceMappingURL=ProblemMatcher.js.map |
| {"version":3,"file":"ProblemMatcher.js","sourceRoot":"","sources":["../src/ProblemMatcher.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Represents the severity level of a problem.\n *\n * @public\n */\nexport type ProblemSeverity = 'error' | 'warning' | 'info';\n\n/**\n * Represents a problem (generally an error or warning) detected in the console output.\n *\n * @public\n */\nexport interface IProblem {\n /** The name of the matcher that detected the problem. */\n readonly matcherName: string;\n /** Parsed message from the problem matcher */\n readonly message: string;\n /** Parsed severity level from the problem matcher */\n readonly severity?: ProblemSeverity;\n /** Parsed file path from the problem matcher */\n readonly file?: string;\n /** Parsed line number from the problem matcher */\n readonly line?: number;\n /** Parsed column number from the problem matcher */\n readonly column?: number;\n /** Parsed ending line number from the problem matcher */\n readonly endLine?: number;\n /** Parsed ending column number from the problem matcher */\n readonly endColumn?: number;\n /** Parsed error or warning code from the problem matcher */\n readonly code?: string;\n}\n\n/**\n * A problem matcher processes one line at a time and returns an {@link IProblem} if a match occurs.\n *\n * @remarks\n * Multi-line matchers may keep internal state and emit on a later line; they can also optionally\n * implement `flush()` to emit any buffered problems when the stream closes.\n *\n * @public\n */\nexport interface IProblemMatcher {\n /** A friendly (and stable) name identifying the matcher. */\n readonly name: string;\n /**\n * Attempt to match a problem for the provided line of console output.\n *\n * @param line - A single line of text, always terminated with a newline character (\\\\n).\n * @returns A problem if recognized, otherwise `false`.\n */\n exec(line: string): IProblem | false;\n /**\n * Flush any buffered state and return additional problems. Optional.\n */\n flush?(): IProblem[];\n}\n\n/**\n * VS Code style problem matcher pattern definition.\n *\n * @remarks\n * This mirrors the shape used in VS Code's `problemMatcher.pattern` entries.\n * Reference: https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher\n *\n * @public\n */\nexport interface IProblemPattern {\n /** A regular expression used to match the problem. */\n regexp: string;\n /** Match index for the file path. */\n file?: number;\n /** Match index for the location. */\n location?: number;\n /** Match index for the starting line number. */\n line?: number;\n /** Match index for the starting column number. */\n column?: number;\n /** Match index for the ending line number. */\n endLine?: number;\n /** Match index for the ending column number. */\n endColumn?: number;\n /** Match index for the severity level. */\n severity?: number;\n /** Match index for the problem code. */\n code?: number;\n /** Match index for the problem message. */\n message: number;\n /** If true, the last pattern in a multi-line matcher may repeat (loop) producing multiple problems */\n loop?: boolean;\n}\n\n/**\n * Minimal VS Code problem matcher definition.\n *\n * @public\n */\nexport interface IProblemMatcherJson {\n /** A friendly (and stable) name identifying the matcher. */\n name: string;\n /** An optional default severity to apply if the pattern does not capture one. */\n severity?: ProblemSeverity;\n /** A single pattern or an array of patterns to match. */\n pattern: IProblemPattern | IProblemPattern[];\n}\n\n/**\n * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects.\n *\n * @public\n */\nexport function parseProblemMatchersJson(problemMatchers: IProblemMatcherJson[]): IProblemMatcher[] {\n const result: IProblemMatcher[] = [];\n\n for (const matcher of problemMatchers) {\n const problemPatterns: IProblemPattern[] = Array.isArray(matcher.pattern)\n ? matcher.pattern\n : [matcher.pattern];\n if (problemPatterns.length === 0) {\n continue;\n }\n\n const name: string = matcher.name;\n const defaultSeverity: ProblemSeverity | undefined = matcher.severity;\n const compiled: ICompiledProblemPattern[] = compileProblemPatterns(problemPatterns);\n\n if (compiled.length === 1) {\n result.push(createSingleLineMatcher(name, compiled[0], defaultSeverity));\n } else {\n result.push(createMultiLineMatcher(name, compiled, defaultSeverity));\n }\n }\n\n return result;\n}\n\nfunction toNumber(text: string | undefined): number | undefined {\n if (!text) {\n return undefined;\n }\n const n: number = parseInt(text, 10);\n return isNaN(n) ? undefined : n;\n}\n\nfunction normalizeSeverity(raw: string | undefined): ProblemSeverity | undefined {\n if (!raw) {\n return undefined;\n }\n const lowered: string = raw.toLowerCase();\n // Support full words as well as common abbreviations (e.g. single-letter tokens)\n if (lowered.indexOf('err') === 0) return 'error';\n if (lowered.indexOf('warn') === 0) return 'warning';\n if (lowered.indexOf('info') === 0) return 'info';\n return undefined;\n}\n\ninterface ICompiledProblemPattern {\n re: RegExp;\n spec: IProblemPattern;\n}\n\nfunction compileProblemPatterns(problemPatterns: IProblemPattern[]): ICompiledProblemPattern[] {\n return problemPatterns.map((problemPattern) => {\n let reStr: string = problemPattern.regexp;\n if (/\\\\r?\\\\n\\$/.test(reStr) || /\\\\n\\$/.test(reStr)) {\n // already newline aware\n } else if (reStr.length > 0 && reStr.charAt(reStr.length - 1) === '$') {\n reStr = reStr.slice(0, -1) + '\\\\r?\\\\n$';\n } else {\n reStr = reStr + '(?:\\\\r?\\\\n)';\n }\n const re: RegExp = new RegExp(reStr);\n return { re, spec: problemPattern };\n });\n}\n\n/**\n * Shared capture structure used by both single-line and multi-line implementations.\n */\ninterface ICapturesMutable {\n file?: string;\n line?: number;\n column?: number;\n endLine?: number;\n endColumn?: number;\n severity?: ProblemSeverity;\n code?: string;\n messageParts: string[];\n}\n\nfunction createEmptyCaptures(): ICapturesMutable {\n return { messageParts: [] };\n}\n\n/**\n * Apply one pattern's regex match to the (possibly accumulating) captures.\n */\nfunction applyPatternCaptures(\n spec: IProblemPattern,\n reMatch: RegExpExecArray,\n captures: ICapturesMutable,\n defaultSeverity: ProblemSeverity | undefined\n): void {\n if (spec.file && reMatch[spec.file]) {\n captures.file = reMatch[spec.file];\n }\n\n if (spec.location && reMatch[spec.location]) {\n const loc: string = reMatch[spec.location];\n const parts: string[] = loc.split(/[,.:]/).filter((s) => s.length > 0);\n if (parts.length === 1) {\n captures.line = toNumber(parts[0]);\n } else if (parts.length === 2) {\n captures.line = toNumber(parts[0]);\n captures.column = toNumber(parts[1]);\n } else if (parts.length === 4) {\n captures.line = toNumber(parts[0]);\n captures.column = toNumber(parts[1]);\n captures.endLine = toNumber(parts[2]);\n captures.endColumn = toNumber(parts[3]);\n }\n } else {\n if (spec.line && reMatch[spec.line]) {\n captures.line = toNumber(reMatch[spec.line]);\n }\n if (spec.column && reMatch[spec.column]) {\n captures.column = toNumber(reMatch[spec.column]);\n }\n }\n\n if (spec.endLine && reMatch[spec.endLine]) {\n captures.endLine = toNumber(reMatch[spec.endLine]);\n }\n if (spec.endColumn && reMatch[spec.endColumn]) {\n captures.endColumn = toNumber(reMatch[spec.endColumn]);\n }\n\n if (spec.severity && reMatch[spec.severity]) {\n captures.severity = normalizeSeverity(reMatch[spec.severity]) || defaultSeverity;\n } else if (!captures.severity && defaultSeverity) {\n captures.severity = defaultSeverity;\n }\n\n if (spec.code && reMatch[spec.code]) {\n captures.code = reMatch[spec.code];\n }\n\n if (spec.message && reMatch[spec.message]) {\n captures.messageParts.push(reMatch[spec.message]);\n }\n}\n\nfunction finalizeProblem(\n matcherName: string,\n captures: ICapturesMutable,\n defaultSeverity: ProblemSeverity | undefined\n): IProblem {\n // For multi-line patterns, use only the last non-empty message part\n const message: string =\n captures.messageParts.length > 0 ? captures.messageParts[captures.messageParts.length - 1] : '';\n\n return {\n matcherName,\n file: captures.file,\n line: captures.line,\n column: captures.column,\n endLine: captures.endLine,\n endColumn: captures.endColumn,\n severity: captures.severity || defaultSeverity,\n code: captures.code,\n message: message\n };\n}\n\nfunction createSingleLineMatcher(\n name: string,\n compiled: ICompiledProblemPattern,\n defaultSeverity: ProblemSeverity | undefined\n): IProblemMatcher {\n const { re, spec } = compiled;\n return {\n name,\n exec(line: string): IProblem | false {\n const match: RegExpExecArray | null = re.exec(line);\n if (!match) {\n return false;\n }\n const captures: ICapturesMutable = createEmptyCaptures();\n applyPatternCaptures(spec, match, captures, defaultSeverity);\n return finalizeProblem(name, captures, defaultSeverity);\n }\n };\n}\n\nfunction createMultiLineMatcher(\n name: string,\n compiled: ICompiledProblemPattern[],\n defaultSeverity: ProblemSeverity | undefined\n): IProblemMatcher {\n // currentIndex points to the next pattern we expect to match. When it equals compiled.length\n // and the last pattern is a loop, we are in a special \"loop state\" where additional lines\n // should be attempted against only the last pattern to emit more problems.\n let currentIndex: number = 0;\n const lastSpec: IProblemPattern = compiled[compiled.length - 1].spec;\n const lastIsLoop: boolean = !!lastSpec.loop;\n\n let captures: ICapturesMutable = createEmptyCaptures();\n\n return {\n name,\n exec(line: string): IProblem | false {\n let effectiveMatch: RegExpExecArray | null = null;\n let effectiveSpec: IProblemPattern | undefined;\n\n // Determine matching behavior based on current state\n if (currentIndex === compiled.length && lastIsLoop) {\n // Loop state: only try to match the last pattern\n const lastPattern: ICompiledProblemPattern = compiled[compiled.length - 1];\n effectiveMatch = lastPattern.re.exec(line);\n if (!effectiveMatch) {\n // Exit loop state and reset for a potential new sequence\n currentIndex = 0;\n captures = createEmptyCaptures();\n // Attempt to treat this line as a fresh start (pattern 0)\n const first: ICompiledProblemPattern = compiled[0];\n const fresh: RegExpExecArray | null = first.re.exec(line);\n if (!fresh) {\n return false;\n }\n effectiveMatch = fresh;\n effectiveSpec = first.spec;\n currentIndex = compiled.length > 1 ? 1 : compiled.length;\n } else {\n effectiveSpec = lastPattern.spec;\n // currentIndex remains compiled.length (loop state) until we decide to emit\n }\n } else {\n // Normal multi-line progression state\n const active: ICompiledProblemPattern = compiled[currentIndex];\n const reMatch: RegExpExecArray | null = active.re.exec(line);\n if (!reMatch) {\n // Reset and maybe attempt new start\n currentIndex = 0;\n captures = createEmptyCaptures();\n const { re: re0, spec: spec0 } = compiled[0];\n const restartMatch: RegExpExecArray | null = re0.exec(line);\n if (!restartMatch) {\n return false;\n }\n effectiveMatch = restartMatch;\n effectiveSpec = spec0;\n currentIndex = compiled.length > 1 ? 1 : compiled.length;\n } else {\n effectiveMatch = reMatch;\n effectiveSpec = active.spec;\n currentIndex++;\n }\n }\n\n applyPatternCaptures(\n effectiveSpec as IProblemPattern,\n effectiveMatch as RegExpExecArray,\n captures,\n defaultSeverity\n );\n\n // If we haven't matched all patterns yet (and not in loop state), wait for more lines\n if (currentIndex < compiled.length) {\n return false;\n }\n\n // We have matched the full sequence (either first completion or a loop iteration)\n const problem: IProblem = finalizeProblem(name, captures, defaultSeverity);\n\n if (lastIsLoop) {\n // Stay in loop state; reset fields that accumulate per problem but retain other context (e.g., file if first pattern captured it?)\n // For safety, if the last pattern provided the file each iteration we keep overwriting anyway.\n captures.messageParts = [];\n // Do not clear entire captures to allow preceding pattern data (e.g., summary) to persist if desirable.\n } else {\n currentIndex = 0;\n captures = createEmptyCaptures();\n }\n\n return problem;\n }\n };\n}\n"]} |
+12
-0
@@ -5,2 +5,14 @@ { | ||
| { | ||
| "version": "0.2.0", | ||
| "tag": "@rushstack/problem-matcher_v0.2.0", | ||
| "date": "Thu, 19 Feb 2026 00:04:53 GMT", | ||
| "comments": { | ||
| "minor": [ | ||
| { | ||
| "comment": "Normalize package layout. CommonJS is now under `lib-commonjs`, DTS is now under `lib-dts`, and ESM is now under `lib-esm`. Imports to `lib` still work as before, handled by the `\"exports\"` field in `package.json`." | ||
| } | ||
| ] | ||
| } | ||
| }, | ||
| { | ||
| "version": "0.1.1", | ||
@@ -7,0 +19,0 @@ "tag": "@rushstack/problem-matcher_v0.1.1", |
+8
-1
| # Change Log - @rushstack/problem-matcher | ||
| This log was last generated on Tue, 30 Sep 2025 23:57:45 GMT and should not be manually modified. | ||
| This log was last generated on Thu, 19 Feb 2026 00:04:53 GMT and should not be manually modified. | ||
| ## 0.2.0 | ||
| Thu, 19 Feb 2026 00:04:53 GMT | ||
| ### Minor changes | ||
| - Normalize package layout. CommonJS is now under `lib-commonjs`, DTS is now under `lib-dts`, and ESM is now under `lib-esm`. Imports to `lib` still work as before, handled by the `"exports"` field in `package.json`. | ||
| ## 0.1.1 | ||
@@ -6,0 +13,0 @@ Tue, 30 Sep 2025 23:57:45 GMT |
@@ -8,5 +8,5 @@ // This file is read by tools that parse documentation comments conforming to the TSDoc standard. | ||
| "packageName": "@microsoft/api-extractor", | ||
| "packageVersion": "7.52.11" | ||
| "packageVersion": "7.55.2" | ||
| } | ||
| ] | ||
| } |
+27
-6
| { | ||
| "name": "@rushstack/problem-matcher", | ||
| "version": "0.1.1", | ||
| "version": "0.2.0", | ||
| "description": "A library for parsing VS Code style problem matchers", | ||
| "main": "lib/index.js", | ||
| "typings": "dist/problem-matcher.d.ts", | ||
| "main": "./lib-commonjs/index.js", | ||
| "module": "./lib-esm/index.js", | ||
| "types": "./dist/problem-matcher.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/problem-matcher.d.ts", | ||
| "import": "./lib-esm/index.js", | ||
| "require": "./lib-commonjs/index.js" | ||
| }, | ||
| "./lib/*": { | ||
| "types": "./lib-dts/*.d.ts", | ||
| "import": "./lib-esm/*.js", | ||
| "require": "./lib-commonjs/*.js" | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, | ||
| "typesVersions": { | ||
| "*": { | ||
| "lib/*": [ | ||
| "lib-dts/*" | ||
| ] | ||
| } | ||
| }, | ||
| "license": "MIT", | ||
@@ -13,6 +34,5 @@ "repository": { | ||
| }, | ||
| "dependencies": {}, | ||
| "devDependencies": { | ||
| "@rushstack/heft": "0.74.3", | ||
| "eslint": "~9.25.1", | ||
| "@rushstack/heft": "1.1.7", | ||
| "eslint": "~9.37.0", | ||
| "decoupled-local-node-rig": "1.0.0" | ||
@@ -28,2 +48,3 @@ }, | ||
| }, | ||
| "sideEffects": false, | ||
| "scripts": { | ||
@@ -30,0 +51,0 @@ "build": "heft build --clean", |
| /** | ||
| * Parse VS Code style problem matcher definitions and use them to extract | ||
| * structured problem reports from strings. | ||
| * | ||
| * @packageDocumentation | ||
| */ | ||
| export type { ProblemSeverity, IProblemMatcher, IProblemMatcherJson, IProblemPattern, IProblem } from './ProblemMatcher'; | ||
| export { parseProblemMatchersJson } from './ProblemMatcher'; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC"} |
| "use strict"; | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||
| // See LICENSE in the project root for license information. | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.parseProblemMatchersJson = void 0; | ||
| var ProblemMatcher_1 = require("./ProblemMatcher"); | ||
| Object.defineProperty(exports, "parseProblemMatchersJson", { enumerable: true, get: function () { return ProblemMatcher_1.parseProblemMatchersJson; } }); | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAgB3D,mDAA4D;AAAnD,0HAAA,wBAAwB,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Parse VS Code style problem matcher definitions and use them to extract\n * structured problem reports from strings.\n *\n * @packageDocumentation\n */\n\nexport type {\n ProblemSeverity,\n IProblemMatcher,\n IProblemMatcherJson,\n IProblemPattern,\n IProblem\n} from './ProblemMatcher';\nexport { parseProblemMatchersJson } from './ProblemMatcher';\n"]} |
| /** | ||
| * Represents the severity level of a problem. | ||
| * | ||
| * @public | ||
| */ | ||
| export type ProblemSeverity = 'error' | 'warning' | 'info'; | ||
| /** | ||
| * Represents a problem (generally an error or warning) detected in the console output. | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblem { | ||
| /** The name of the matcher that detected the problem. */ | ||
| readonly matcherName: string; | ||
| /** Parsed message from the problem matcher */ | ||
| readonly message: string; | ||
| /** Parsed severity level from the problem matcher */ | ||
| readonly severity?: ProblemSeverity; | ||
| /** Parsed file path from the problem matcher */ | ||
| readonly file?: string; | ||
| /** Parsed line number from the problem matcher */ | ||
| readonly line?: number; | ||
| /** Parsed column number from the problem matcher */ | ||
| readonly column?: number; | ||
| /** Parsed ending line number from the problem matcher */ | ||
| readonly endLine?: number; | ||
| /** Parsed ending column number from the problem matcher */ | ||
| readonly endColumn?: number; | ||
| /** Parsed error or warning code from the problem matcher */ | ||
| readonly code?: string; | ||
| } | ||
| /** | ||
| * A problem matcher processes one line at a time and returns an {@link IProblem} if a match occurs. | ||
| * | ||
| * @remarks | ||
| * Multi-line matchers may keep internal state and emit on a later line; they can also optionally | ||
| * implement `flush()` to emit any buffered problems when the stream closes. | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblemMatcher { | ||
| /** A friendly (and stable) name identifying the matcher. */ | ||
| readonly name: string; | ||
| /** | ||
| * Attempt to match a problem for the provided line of console output. | ||
| * | ||
| * @param line - A single line of text, always terminated with a newline character (\\n). | ||
| * @returns A problem if recognized, otherwise `false`. | ||
| */ | ||
| exec(line: string): IProblem | false; | ||
| /** | ||
| * Flush any buffered state and return additional problems. Optional. | ||
| */ | ||
| flush?(): IProblem[]; | ||
| } | ||
| /** | ||
| * VS Code style problem matcher pattern definition. | ||
| * | ||
| * @remarks | ||
| * This mirrors the shape used in VS Code's `problemMatcher.pattern` entries. | ||
| * Reference: https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblemPattern { | ||
| /** A regular expression used to match the problem. */ | ||
| regexp: string; | ||
| /** Match index for the file path. */ | ||
| file?: number; | ||
| /** Match index for the location. */ | ||
| location?: number; | ||
| /** Match index for the starting line number. */ | ||
| line?: number; | ||
| /** Match index for the starting column number. */ | ||
| column?: number; | ||
| /** Match index for the ending line number. */ | ||
| endLine?: number; | ||
| /** Match index for the ending column number. */ | ||
| endColumn?: number; | ||
| /** Match index for the severity level. */ | ||
| severity?: number; | ||
| /** Match index for the problem code. */ | ||
| code?: number; | ||
| /** Match index for the problem message. */ | ||
| message: number; | ||
| /** If true, the last pattern in a multi-line matcher may repeat (loop) producing multiple problems */ | ||
| loop?: boolean; | ||
| } | ||
| /** | ||
| * Minimal VS Code problem matcher definition. | ||
| * | ||
| * @public | ||
| */ | ||
| export interface IProblemMatcherJson { | ||
| /** A friendly (and stable) name identifying the matcher. */ | ||
| name: string; | ||
| /** An optional default severity to apply if the pattern does not capture one. */ | ||
| severity?: ProblemSeverity; | ||
| /** A single pattern or an array of patterns to match. */ | ||
| pattern: IProblemPattern | IProblemPattern[]; | ||
| } | ||
| /** | ||
| * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects. | ||
| * | ||
| * @public | ||
| */ | ||
| export declare function parseProblemMatchersJson(problemMatchers: IProblemMatcherJson[]): IProblemMatcher[]; | ||
| //# sourceMappingURL=ProblemMatcher.d.ts.map |
| {"version":3,"file":"ProblemMatcher.d.ts","sourceRoot":"","sources":["../src/ProblemMatcher.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACrC;;OAEG;IACH,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,sGAAsG;IACtG,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,yDAAyD;IACzD,OAAO,EAAE,eAAe,GAAG,eAAe,EAAE,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,mBAAmB,EAAE,GAAG,eAAe,EAAE,CAuBlG"} |
| "use strict"; | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||
| // See LICENSE in the project root for license information. | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.parseProblemMatchersJson = parseProblemMatchersJson; | ||
| /** | ||
| * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects. | ||
| * | ||
| * @public | ||
| */ | ||
| function parseProblemMatchersJson(problemMatchers) { | ||
| const result = []; | ||
| for (const matcher of problemMatchers) { | ||
| const problemPatterns = Array.isArray(matcher.pattern) | ||
| ? matcher.pattern | ||
| : [matcher.pattern]; | ||
| if (problemPatterns.length === 0) { | ||
| continue; | ||
| } | ||
| const name = matcher.name; | ||
| const defaultSeverity = matcher.severity; | ||
| const compiled = compileProblemPatterns(problemPatterns); | ||
| if (compiled.length === 1) { | ||
| result.push(createSingleLineMatcher(name, compiled[0], defaultSeverity)); | ||
| } | ||
| else { | ||
| result.push(createMultiLineMatcher(name, compiled, defaultSeverity)); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function toNumber(text) { | ||
| if (!text) { | ||
| return undefined; | ||
| } | ||
| const n = parseInt(text, 10); | ||
| return isNaN(n) ? undefined : n; | ||
| } | ||
| function normalizeSeverity(raw) { | ||
| if (!raw) { | ||
| return undefined; | ||
| } | ||
| const lowered = raw.toLowerCase(); | ||
| // Support full words as well as common abbreviations (e.g. single-letter tokens) | ||
| if (lowered.indexOf('err') === 0) | ||
| return 'error'; | ||
| if (lowered.indexOf('warn') === 0) | ||
| return 'warning'; | ||
| if (lowered.indexOf('info') === 0) | ||
| return 'info'; | ||
| return undefined; | ||
| } | ||
| function compileProblemPatterns(problemPatterns) { | ||
| return problemPatterns.map((problemPattern) => { | ||
| let reStr = problemPattern.regexp; | ||
| if (/\\r?\\n\$/.test(reStr) || /\\n\$/.test(reStr)) { | ||
| // already newline aware | ||
| } | ||
| else if (reStr.length > 0 && reStr.charAt(reStr.length - 1) === '$') { | ||
| reStr = reStr.slice(0, -1) + '\\r?\\n$'; | ||
| } | ||
| else { | ||
| reStr = reStr + '(?:\\r?\\n)'; | ||
| } | ||
| const re = new RegExp(reStr); | ||
| return { re, spec: problemPattern }; | ||
| }); | ||
| } | ||
| function createEmptyCaptures() { | ||
| return { messageParts: [] }; | ||
| } | ||
| /** | ||
| * Apply one pattern's regex match to the (possibly accumulating) captures. | ||
| */ | ||
| function applyPatternCaptures(spec, reMatch, captures, defaultSeverity) { | ||
| if (spec.file && reMatch[spec.file]) { | ||
| captures.file = reMatch[spec.file]; | ||
| } | ||
| if (spec.location && reMatch[spec.location]) { | ||
| const loc = reMatch[spec.location]; | ||
| const parts = loc.split(/[,.:]/).filter((s) => s.length > 0); | ||
| if (parts.length === 1) { | ||
| captures.line = toNumber(parts[0]); | ||
| } | ||
| else if (parts.length === 2) { | ||
| captures.line = toNumber(parts[0]); | ||
| captures.column = toNumber(parts[1]); | ||
| } | ||
| else if (parts.length === 4) { | ||
| captures.line = toNumber(parts[0]); | ||
| captures.column = toNumber(parts[1]); | ||
| captures.endLine = toNumber(parts[2]); | ||
| captures.endColumn = toNumber(parts[3]); | ||
| } | ||
| } | ||
| else { | ||
| if (spec.line && reMatch[spec.line]) { | ||
| captures.line = toNumber(reMatch[spec.line]); | ||
| } | ||
| if (spec.column && reMatch[spec.column]) { | ||
| captures.column = toNumber(reMatch[spec.column]); | ||
| } | ||
| } | ||
| if (spec.endLine && reMatch[spec.endLine]) { | ||
| captures.endLine = toNumber(reMatch[spec.endLine]); | ||
| } | ||
| if (spec.endColumn && reMatch[spec.endColumn]) { | ||
| captures.endColumn = toNumber(reMatch[spec.endColumn]); | ||
| } | ||
| if (spec.severity && reMatch[spec.severity]) { | ||
| captures.severity = normalizeSeverity(reMatch[spec.severity]) || defaultSeverity; | ||
| } | ||
| else if (!captures.severity && defaultSeverity) { | ||
| captures.severity = defaultSeverity; | ||
| } | ||
| if (spec.code && reMatch[spec.code]) { | ||
| captures.code = reMatch[spec.code]; | ||
| } | ||
| if (spec.message && reMatch[spec.message]) { | ||
| captures.messageParts.push(reMatch[spec.message]); | ||
| } | ||
| } | ||
| function finalizeProblem(matcherName, captures, defaultSeverity) { | ||
| // For multi-line patterns, use only the last non-empty message part | ||
| const message = captures.messageParts.length > 0 ? captures.messageParts[captures.messageParts.length - 1] : ''; | ||
| return { | ||
| matcherName, | ||
| file: captures.file, | ||
| line: captures.line, | ||
| column: captures.column, | ||
| endLine: captures.endLine, | ||
| endColumn: captures.endColumn, | ||
| severity: captures.severity || defaultSeverity, | ||
| code: captures.code, | ||
| message: message | ||
| }; | ||
| } | ||
| function createSingleLineMatcher(name, compiled, defaultSeverity) { | ||
| const { re, spec } = compiled; | ||
| return { | ||
| name, | ||
| exec(line) { | ||
| const match = re.exec(line); | ||
| if (!match) { | ||
| return false; | ||
| } | ||
| const captures = createEmptyCaptures(); | ||
| applyPatternCaptures(spec, match, captures, defaultSeverity); | ||
| return finalizeProblem(name, captures, defaultSeverity); | ||
| } | ||
| }; | ||
| } | ||
| function createMultiLineMatcher(name, compiled, defaultSeverity) { | ||
| // currentIndex points to the next pattern we expect to match. When it equals compiled.length | ||
| // and the last pattern is a loop, we are in a special "loop state" where additional lines | ||
| // should be attempted against only the last pattern to emit more problems. | ||
| let currentIndex = 0; | ||
| const lastSpec = compiled[compiled.length - 1].spec; | ||
| const lastIsLoop = !!lastSpec.loop; | ||
| let captures = createEmptyCaptures(); | ||
| return { | ||
| name, | ||
| exec(line) { | ||
| let effectiveMatch = null; | ||
| let effectiveSpec; | ||
| // Determine matching behavior based on current state | ||
| if (currentIndex === compiled.length && lastIsLoop) { | ||
| // Loop state: only try to match the last pattern | ||
| const lastPattern = compiled[compiled.length - 1]; | ||
| effectiveMatch = lastPattern.re.exec(line); | ||
| if (!effectiveMatch) { | ||
| // Exit loop state and reset for a potential new sequence | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| // Attempt to treat this line as a fresh start (pattern 0) | ||
| const first = compiled[0]; | ||
| const fresh = first.re.exec(line); | ||
| if (!fresh) { | ||
| return false; | ||
| } | ||
| effectiveMatch = fresh; | ||
| effectiveSpec = first.spec; | ||
| currentIndex = compiled.length > 1 ? 1 : compiled.length; | ||
| } | ||
| else { | ||
| effectiveSpec = lastPattern.spec; | ||
| // currentIndex remains compiled.length (loop state) until we decide to emit | ||
| } | ||
| } | ||
| else { | ||
| // Normal multi-line progression state | ||
| const active = compiled[currentIndex]; | ||
| const reMatch = active.re.exec(line); | ||
| if (!reMatch) { | ||
| // Reset and maybe attempt new start | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| const { re: re0, spec: spec0 } = compiled[0]; | ||
| const restartMatch = re0.exec(line); | ||
| if (!restartMatch) { | ||
| return false; | ||
| } | ||
| effectiveMatch = restartMatch; | ||
| effectiveSpec = spec0; | ||
| currentIndex = compiled.length > 1 ? 1 : compiled.length; | ||
| } | ||
| else { | ||
| effectiveMatch = reMatch; | ||
| effectiveSpec = active.spec; | ||
| currentIndex++; | ||
| } | ||
| } | ||
| applyPatternCaptures(effectiveSpec, effectiveMatch, captures, defaultSeverity); | ||
| // If we haven't matched all patterns yet (and not in loop state), wait for more lines | ||
| if (currentIndex < compiled.length) { | ||
| return false; | ||
| } | ||
| // We have matched the full sequence (either first completion or a loop iteration) | ||
| const problem = finalizeProblem(name, captures, defaultSeverity); | ||
| if (lastIsLoop) { | ||
| // Stay in loop state; reset fields that accumulate per problem but retain other context (e.g., file if first pattern captured it?) | ||
| // For safety, if the last pattern provided the file each iteration we keep overwriting anyway. | ||
| captures.messageParts = []; | ||
| // Do not clear entire captures to allow preceding pattern data (e.g., summary) to persist if desirable. | ||
| } | ||
| else { | ||
| currentIndex = 0; | ||
| captures = createEmptyCaptures(); | ||
| } | ||
| return problem; | ||
| } | ||
| }; | ||
| } | ||
| //# sourceMappingURL=ProblemMatcher.js.map |
| {"version":3,"file":"ProblemMatcher.js","sourceRoot":"","sources":["../src/ProblemMatcher.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Represents the severity level of a problem.\n *\n * @public\n */\nexport type ProblemSeverity = 'error' | 'warning' | 'info';\n\n/**\n * Represents a problem (generally an error or warning) detected in the console output.\n *\n * @public\n */\nexport interface IProblem {\n /** The name of the matcher that detected the problem. */\n readonly matcherName: string;\n /** Parsed message from the problem matcher */\n readonly message: string;\n /** Parsed severity level from the problem matcher */\n readonly severity?: ProblemSeverity;\n /** Parsed file path from the problem matcher */\n readonly file?: string;\n /** Parsed line number from the problem matcher */\n readonly line?: number;\n /** Parsed column number from the problem matcher */\n readonly column?: number;\n /** Parsed ending line number from the problem matcher */\n readonly endLine?: number;\n /** Parsed ending column number from the problem matcher */\n readonly endColumn?: number;\n /** Parsed error or warning code from the problem matcher */\n readonly code?: string;\n}\n\n/**\n * A problem matcher processes one line at a time and returns an {@link IProblem} if a match occurs.\n *\n * @remarks\n * Multi-line matchers may keep internal state and emit on a later line; they can also optionally\n * implement `flush()` to emit any buffered problems when the stream closes.\n *\n * @public\n */\nexport interface IProblemMatcher {\n /** A friendly (and stable) name identifying the matcher. */\n readonly name: string;\n /**\n * Attempt to match a problem for the provided line of console output.\n *\n * @param line - A single line of text, always terminated with a newline character (\\\\n).\n * @returns A problem if recognized, otherwise `false`.\n */\n exec(line: string): IProblem | false;\n /**\n * Flush any buffered state and return additional problems. Optional.\n */\n flush?(): IProblem[];\n}\n\n/**\n * VS Code style problem matcher pattern definition.\n *\n * @remarks\n * This mirrors the shape used in VS Code's `problemMatcher.pattern` entries.\n * Reference: https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher\n *\n * @public\n */\nexport interface IProblemPattern {\n /** A regular expression used to match the problem. */\n regexp: string;\n /** Match index for the file path. */\n file?: number;\n /** Match index for the location. */\n location?: number;\n /** Match index for the starting line number. */\n line?: number;\n /** Match index for the starting column number. */\n column?: number;\n /** Match index for the ending line number. */\n endLine?: number;\n /** Match index for the ending column number. */\n endColumn?: number;\n /** Match index for the severity level. */\n severity?: number;\n /** Match index for the problem code. */\n code?: number;\n /** Match index for the problem message. */\n message: number;\n /** If true, the last pattern in a multi-line matcher may repeat (loop) producing multiple problems */\n loop?: boolean;\n}\n\n/**\n * Minimal VS Code problem matcher definition.\n *\n * @public\n */\nexport interface IProblemMatcherJson {\n /** A friendly (and stable) name identifying the matcher. */\n name: string;\n /** An optional default severity to apply if the pattern does not capture one. */\n severity?: ProblemSeverity;\n /** A single pattern or an array of patterns to match. */\n pattern: IProblemPattern | IProblemPattern[];\n}\n\n/**\n * Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects.\n *\n * @public\n */\nexport function parseProblemMatchersJson(problemMatchers: IProblemMatcherJson[]): IProblemMatcher[] {\n const result: IProblemMatcher[] = [];\n\n for (const matcher of problemMatchers) {\n const problemPatterns: IProblemPattern[] = Array.isArray(matcher.pattern)\n ? matcher.pattern\n : [matcher.pattern];\n if (problemPatterns.length === 0) {\n continue;\n }\n\n const name: string = matcher.name;\n const defaultSeverity: ProblemSeverity | undefined = matcher.severity;\n const compiled: ICompiledProblemPattern[] = compileProblemPatterns(problemPatterns);\n\n if (compiled.length === 1) {\n result.push(createSingleLineMatcher(name, compiled[0], defaultSeverity));\n } else {\n result.push(createMultiLineMatcher(name, compiled, defaultSeverity));\n }\n }\n\n return result;\n}\n\nfunction toNumber(text: string | undefined): number | undefined {\n if (!text) {\n return undefined;\n }\n const n: number = parseInt(text, 10);\n return isNaN(n) ? undefined : n;\n}\n\nfunction normalizeSeverity(raw: string | undefined): ProblemSeverity | undefined {\n if (!raw) {\n return undefined;\n }\n const lowered: string = raw.toLowerCase();\n // Support full words as well as common abbreviations (e.g. single-letter tokens)\n if (lowered.indexOf('err') === 0) return 'error';\n if (lowered.indexOf('warn') === 0) return 'warning';\n if (lowered.indexOf('info') === 0) return 'info';\n return undefined;\n}\n\ninterface ICompiledProblemPattern {\n re: RegExp;\n spec: IProblemPattern;\n}\n\nfunction compileProblemPatterns(problemPatterns: IProblemPattern[]): ICompiledProblemPattern[] {\n return problemPatterns.map((problemPattern) => {\n let reStr: string = problemPattern.regexp;\n if (/\\\\r?\\\\n\\$/.test(reStr) || /\\\\n\\$/.test(reStr)) {\n // already newline aware\n } else if (reStr.length > 0 && reStr.charAt(reStr.length - 1) === '$') {\n reStr = reStr.slice(0, -1) + '\\\\r?\\\\n$';\n } else {\n reStr = reStr + '(?:\\\\r?\\\\n)';\n }\n const re: RegExp = new RegExp(reStr);\n return { re, spec: problemPattern };\n });\n}\n\n/**\n * Shared capture structure used by both single-line and multi-line implementations.\n */\ninterface ICapturesMutable {\n file?: string;\n line?: number;\n column?: number;\n endLine?: number;\n endColumn?: number;\n severity?: ProblemSeverity;\n code?: string;\n messageParts: string[];\n}\n\nfunction createEmptyCaptures(): ICapturesMutable {\n return { messageParts: [] };\n}\n\n/**\n * Apply one pattern's regex match to the (possibly accumulating) captures.\n */\nfunction applyPatternCaptures(\n spec: IProblemPattern,\n reMatch: RegExpExecArray,\n captures: ICapturesMutable,\n defaultSeverity: ProblemSeverity | undefined\n): void {\n if (spec.file && reMatch[spec.file]) {\n captures.file = reMatch[spec.file];\n }\n\n if (spec.location && reMatch[spec.location]) {\n const loc: string = reMatch[spec.location];\n const parts: string[] = loc.split(/[,.:]/).filter((s) => s.length > 0);\n if (parts.length === 1) {\n captures.line = toNumber(parts[0]);\n } else if (parts.length === 2) {\n captures.line = toNumber(parts[0]);\n captures.column = toNumber(parts[1]);\n } else if (parts.length === 4) {\n captures.line = toNumber(parts[0]);\n captures.column = toNumber(parts[1]);\n captures.endLine = toNumber(parts[2]);\n captures.endColumn = toNumber(parts[3]);\n }\n } else {\n if (spec.line && reMatch[spec.line]) {\n captures.line = toNumber(reMatch[spec.line]);\n }\n if (spec.column && reMatch[spec.column]) {\n captures.column = toNumber(reMatch[spec.column]);\n }\n }\n\n if (spec.endLine && reMatch[spec.endLine]) {\n captures.endLine = toNumber(reMatch[spec.endLine]);\n }\n if (spec.endColumn && reMatch[spec.endColumn]) {\n captures.endColumn = toNumber(reMatch[spec.endColumn]);\n }\n\n if (spec.severity && reMatch[spec.severity]) {\n captures.severity = normalizeSeverity(reMatch[spec.severity]) || defaultSeverity;\n } else if (!captures.severity && defaultSeverity) {\n captures.severity = defaultSeverity;\n }\n\n if (spec.code && reMatch[spec.code]) {\n captures.code = reMatch[spec.code];\n }\n\n if (spec.message && reMatch[spec.message]) {\n captures.messageParts.push(reMatch[spec.message]);\n }\n}\n\nfunction finalizeProblem(\n matcherName: string,\n captures: ICapturesMutable,\n defaultSeverity: ProblemSeverity | undefined\n): IProblem {\n // For multi-line patterns, use only the last non-empty message part\n const message: string =\n captures.messageParts.length > 0 ? captures.messageParts[captures.messageParts.length - 1] : '';\n\n return {\n matcherName,\n file: captures.file,\n line: captures.line,\n column: captures.column,\n endLine: captures.endLine,\n endColumn: captures.endColumn,\n severity: captures.severity || defaultSeverity,\n code: captures.code,\n message: message\n };\n}\n\nfunction createSingleLineMatcher(\n name: string,\n compiled: ICompiledProblemPattern,\n defaultSeverity: ProblemSeverity | undefined\n): IProblemMatcher {\n const { re, spec } = compiled;\n return {\n name,\n exec(line: string): IProblem | false {\n const match: RegExpExecArray | null = re.exec(line);\n if (!match) {\n return false;\n }\n const captures: ICapturesMutable = createEmptyCaptures();\n applyPatternCaptures(spec, match, captures, defaultSeverity);\n return finalizeProblem(name, captures, defaultSeverity);\n }\n };\n}\n\nfunction createMultiLineMatcher(\n name: string,\n compiled: ICompiledProblemPattern[],\n defaultSeverity: ProblemSeverity | undefined\n): IProblemMatcher {\n // currentIndex points to the next pattern we expect to match. When it equals compiled.length\n // and the last pattern is a loop, we are in a special \"loop state\" where additional lines\n // should be attempted against only the last pattern to emit more problems.\n let currentIndex: number = 0;\n const lastSpec: IProblemPattern = compiled[compiled.length - 1].spec;\n const lastIsLoop: boolean = !!lastSpec.loop;\n\n let captures: ICapturesMutable = createEmptyCaptures();\n\n return {\n name,\n exec(line: string): IProblem | false {\n let effectiveMatch: RegExpExecArray | null = null;\n let effectiveSpec: IProblemPattern | undefined;\n\n // Determine matching behavior based on current state\n if (currentIndex === compiled.length && lastIsLoop) {\n // Loop state: only try to match the last pattern\n const lastPattern: ICompiledProblemPattern = compiled[compiled.length - 1];\n effectiveMatch = lastPattern.re.exec(line);\n if (!effectiveMatch) {\n // Exit loop state and reset for a potential new sequence\n currentIndex = 0;\n captures = createEmptyCaptures();\n // Attempt to treat this line as a fresh start (pattern 0)\n const first: ICompiledProblemPattern = compiled[0];\n const fresh: RegExpExecArray | null = first.re.exec(line);\n if (!fresh) {\n return false;\n }\n effectiveMatch = fresh;\n effectiveSpec = first.spec;\n currentIndex = compiled.length > 1 ? 1 : compiled.length;\n } else {\n effectiveSpec = lastPattern.spec;\n // currentIndex remains compiled.length (loop state) until we decide to emit\n }\n } else {\n // Normal multi-line progression state\n const active: ICompiledProblemPattern = compiled[currentIndex];\n const reMatch: RegExpExecArray | null = active.re.exec(line);\n if (!reMatch) {\n // Reset and maybe attempt new start\n currentIndex = 0;\n captures = createEmptyCaptures();\n const { re: re0, spec: spec0 } = compiled[0];\n const restartMatch: RegExpExecArray | null = re0.exec(line);\n if (!restartMatch) {\n return false;\n }\n effectiveMatch = restartMatch;\n effectiveSpec = spec0;\n currentIndex = compiled.length > 1 ? 1 : compiled.length;\n } else {\n effectiveMatch = reMatch;\n effectiveSpec = active.spec;\n currentIndex++;\n }\n }\n\n applyPatternCaptures(\n effectiveSpec as IProblemPattern,\n effectiveMatch as RegExpExecArray,\n captures,\n defaultSeverity\n );\n\n // If we haven't matched all patterns yet (and not in loop state), wait for more lines\n if (currentIndex < compiled.length) {\n return false;\n }\n\n // We have matched the full sequence (either first completion or a loop iteration)\n const problem: IProblem = finalizeProblem(name, captures, defaultSeverity);\n\n if (lastIsLoop) {\n // Stay in loop state; reset fields that accumulate per problem but retain other context (e.g., file if first pattern captured it?)\n // For safety, if the last pattern provided the file each iteration we keep overwriting anyway.\n captures.messageParts = [];\n // Do not clear entire captures to allow preceding pattern data (e.g., summary) to persist if desirable.\n } else {\n currentIndex = 0;\n captures = createEmptyCaptures();\n }\n\n return problem;\n }\n };\n}\n"]} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
77760
71.09%19
26.67%754
48.13%6
50%1
Infinity%