UNPKG

@dev-build-deploy/diagnose-it

Version:
153 lines (152 loc) 6.43 kB
"use strict"; /* * SPDX-FileCopyrightText: 2023 Kevin de Jong <monkaii@hotmail.com> * SPDX-License-Identifier: MIT */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractFromFile = exports.extractFromSarif = void 0; const readline_1 = __importDefault(require("readline")); const fs_1 = __importDefault(require("fs")); const diagnosticsMessage_1 = require("./diagnosticsMessage"); const sarif = __importStar(require("@dev-build-deploy/sarif-it")); const LLVM_EXPRESSIVE_DIAGNOSTICS_REGEX = new RegExp("(?:\\s*)(?<file>[\\w,-.]+):(?<lineNumber>[0-9]+):(?<columnNumber>[0-9]+): (?<messageType>(error|warning|note)): (?<message>(.*))"); function getDiagnosticsLevelFromString(value) { if (value === "error") return diagnosticsMessage_1.DiagnosticsLevelEnum.Error; if (value === "warning") return diagnosticsMessage_1.DiagnosticsLevelEnum.Warning; return diagnosticsMessage_1.DiagnosticsLevelEnum.Note; } /** * Extracts Expressive Diagnostic messages from SARIF. * * NOTE: currently we only support: * - plain text files * - the results of the last run * * @param sarif The SARIF to extract messages from. * @param run Index of run, defaults to the last run. * * @returns Async Generator of Expressive Messages. */ function* extractFromSarif(sarif, run = undefined) { var _a, _b, _c, _d, _e, _f, _g, _h; const sarifObj = sarif.properties(); if (run === undefined) { run = sarifObj.runs.length - 1; } const results = (_a = sarifObj.runs[run].results) !== null && _a !== void 0 ? _a : []; for (const result of results) { for (const location of (_b = result.locations) !== null && _b !== void 0 ? _b : []) { if (result.message.text === undefined || location.physicalLocation === undefined) { continue; } const region = location.physicalLocation.region; const line = (_c = region === null || region === void 0 ? void 0 : region.startLine) !== null && _c !== void 0 ? _c : 1; const column = (_d = region === null || region === void 0 ? void 0 : region.startColumn) !== null && _d !== void 0 ? _d : 1; const snippet = (_e = region === null || region === void 0 ? void 0 : region.snippet) === null || _e === void 0 ? void 0 : _e.text; const msg = new diagnosticsMessage_1.DiagnosticsMessage({ file: (_g = (_f = location.physicalLocation.artifactLocation) === null || _f === void 0 ? void 0 : _f.uri) !== null && _g !== void 0 ? _g : "", message: { text: result.message.text, linenumber: line, column, }, level: getDiagnosticsLevelFromString((_h = result.level) !== null && _h !== void 0 ? _h : "warning"), }); if (snippet !== undefined) { msg.setContext(line, snippet); } yield msg; } } } exports.extractFromSarif = extractFromSarif; /** * Extracts Expressive Diagnostic messages from a raw file. * This can be used to extract messages from compiler output * * @param filePath Path to file to extract messages from. */ async function* extractRaw(filePath) { let currentMessage = undefined; let matchIndex = 0; const lineReader = readline_1.default.createInterface({ input: fs_1.default.createReadStream(filePath), crlfDelay: Infinity, }); for await (const line of lineReader) { const match = LLVM_EXPRESSIVE_DIAGNOSTICS_REGEX.exec(line); if (match && match.groups) { currentMessage = new diagnosticsMessage_1.DiagnosticsMessage({ file: match.groups.file, message: { text: match.groups.message, linenumber: parseInt(match.groups.lineNumber), column: parseInt(match.groups.columnNumber), }, level: getDiagnosticsLevelFromString(match.groups.messageType), }); matchIndex = line.length - line.trimStart().length; } else if (currentMessage) { const lineNumber = currentMessage.message.linenumber; if (lineNumber !== undefined) { currentMessage = currentMessage.setContext(lineNumber, line.substring(matchIndex)); } yield currentMessage; currentMessage = undefined; } } if (currentMessage) { yield currentMessage; } } /** * Extracts Expressive Diagnostic messages from a file. * This can be used to extract messages from compile output * * @param filePath Path to file to extract messages from. * @returns Async Generator of Expressive Messages. * * @see https://clang.llvm.org/diagnostics.html */ async function* extractFromFile(filePath) { if (filePath.endsWith(".sarif") || filePath.endsWith(".json.sarif")) { const sarifData = sarif.Log.fromFile(filePath); for (const message of extractFromSarif(sarifData)) { yield message; } return; } for await (const message of extractRaw(filePath)) { yield message; } } exports.extractFromFile = extractFromFile;