@ui5/linter
Version:
A static code analysis tool for UI5
81 lines • 3.24 kB
JavaScript
import { SaxEventType, SAXParser } from "sax-wasm";
import { finished } from "node:stream/promises";
import fs from "node:fs/promises";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
export function isSaxParserToJSON(tag) {
const tagAsSaxParserToJSON = tag;
return !!tag &&
Object.prototype.hasOwnProperty.call(tagAsSaxParserToJSON, "openStart") &&
Object.prototype.hasOwnProperty.call(tagAsSaxParserToJSON, "openEnd") &&
Object.prototype.hasOwnProperty.call(tagAsSaxParserToJSON, "closeStart") &&
Object.prototype.hasOwnProperty.call(tagAsSaxParserToJSON, "closeEnd") &&
Object.prototype.hasOwnProperty.call(tagAsSaxParserToJSON, "attributes") &&
Object.prototype.hasOwnProperty.call(tagAsSaxParserToJSON, "textNodes");
}
export function isSaxText(tag) {
return !!tag &&
Object.prototype.hasOwnProperty.call(tag, "start") &&
Object.prototype.hasOwnProperty.call(tag, "end") &&
Object.prototype.hasOwnProperty.call(tag, "value");
}
/* The following regex is derived from the multi-line variant defined in ui5types/directives.ts
Note that this regex allows for double-hyphen comments, even though they are "not recommended" in XML and HTML as
per the spec and might not be allowed in some parsers: https://www.w3.org/TR/REC-xml/#sec-comments
*/
const DIRECTIVE_REGEX = /\s*ui5lint-(enable|disable)(?:-((?:next-)?line))?(\s+(?:[\w-]+\s*,\s*)*(?:\s*[\w-]+))?\s*,?\s*(?:--[\s\S]*?)?$/;
export function extractDirective(comment) {
if (!comment.value) {
return;
}
const match = DIRECTIVE_REGEX.exec(comment.value);
if (!match) {
return;
}
const action = match[1];
const scope = match[2];
const ruleNames = match[3]?.split(",").map((rule) => rule.trim()) ?? [];
return {
action,
scope,
ruleNames,
line: comment.start.line + 1,
column: comment.start.character + 1,
};
}
let saxWasmBuffer;
export async function initSaxWasm() {
if (!saxWasmBuffer) {
const saxPath = require.resolve("sax-wasm/lib/sax-wasm.wasm");
saxWasmBuffer = await fs.readFile(saxPath);
}
return saxWasmBuffer;
}
export async function parseXml(contentStream, parseHandler, events = SaxEventType.CloseTag | SaxEventType.OpenTag | SaxEventType.Comment) {
const saxWasmBuffer = await initSaxWasm();
const saxParser = new SAXParser(events);
saxParser.eventHandler = parseHandler;
// Instantiate and prepare the wasm for parsing
if (!await saxParser.prepareWasm(saxWasmBuffer)) {
throw new Error("Unknown error during WASM Initialization");
}
// Start the stream
contentStream.on("data", (chunk) => {
try {
saxParser.write(chunk);
}
catch (err) {
if (err instanceof Error) {
// In case of an error, destroy the content stream to make the
// error bubble up to our callers
contentStream.destroy(err);
}
else {
throw err;
}
}
});
await finished(contentStream);
saxParser.end();
}
//# sourceMappingURL=xmlParser.js.map