UNPKG

@ui5/linter

Version:

A static code analysis tool for UI5

89 lines 3.46 kB
import { Attribute, SaxEventType, Tag } from "sax-wasm"; import { parseXml } from "../utils/xmlParser.js"; import XmlEnabledFix from "../linter/ui5Types/fix/XmlEnabledFix.js"; import { removeConflictingFixes } from "./utils.js"; export default async function generateChangesXml(messages, changeSets, content, resource) { const lines = content.split("\n"); const nodeSearchInfo = new Set(); let events = 0; // Collect all fixes from the messages for (const { fix } of messages) { if (!fix || !(fix instanceof XmlEnabledFix)) { continue; } // Map "position for search" (calculated from the transpiled AST using the source map) to the absolute // position in the XML file const { position: fixStart, xmlEventTypes } = fix.getNodeSearchParameters(); if (!xmlEventTypes) { throw new Error(`Fix ${fix.constructor.name} does not provide xmlEventTypes for autofix`); } for (const eventType of xmlEventTypes) { events |= eventType; } nodeSearchInfo.add({ fix, xmlEventTypes, position: { line: fixStart.line - 1, // Convert to 0-based line character: fixStart.column - 1, // Convert to 0-based column }, }); } const toPositionCallback = function (pos) { return toPosition(pos, lines); }; const matchedFixes = new Set(); await parseXml(resource.getStream(), (event, data) => { if (data instanceof Tag) { if (event === SaxEventType.OpenTag) { for (const { position, fix, xmlEventTypes } of nodeSearchInfo) { if (xmlEventTypes.includes(SaxEventType.OpenTag)) { if (data.openStart.line === position.line && data.openStart.character === position.character) { fix.visitAutofixXmlNode(data, toPositionCallback); } } } } } else if (data instanceof Attribute) { for (const nodeInfo of nodeSearchInfo) { const { position, fix, xmlEventTypes } = nodeInfo; if (xmlEventTypes.includes(event)) { if (data.name.start.line === position.line && data.name.start.character === position.character && fix.visitAutofixXmlNode(data, toPositionCallback)) { matchedFixes.add(fix); nodeSearchInfo.delete(nodeInfo); } } } } }, events); removeConflictingFixes(matchedFixes); // TBD: Collect dependencies etc. for (const fix of matchedFixes) { const changes = fix.generateChanges?.(); if (Array.isArray(changes)) { for (const change of changes) { changeSets.push(change); } } else if (changes) { changeSets.push(changes); } } } function toPosition(position, lines) { let pos; if (position.line === 0) { pos = position.character; } else { pos = 0; for (let i = 0; i < position.line; i++) { pos += lines[i].length + 1; // +1 for the newline character we used to split the lines with } pos += position.character; } return pos; } //# sourceMappingURL=generateChangesXml.js.map