UNPKG

@ui5/linter

Version:

A static code analysis tool for UI5

78 lines 3.54 kB
import { deprecatedLibraries, deprecatedThemeLibraries } from "../../utils/deprecations.js"; import { fromYaml, getPosition } from "data-with-position"; import { MESSAGE } from "../messages.js"; // This regex is derived from the single-line variant defined in ui5types/directives.ts const DIRECTIVE_REGEX = /#\s*ui5lint-(enable|disable)(?:-((?:next-)?line))?([ \t]+(?:[\w-]+[ \t]*,[ \t]*)*(?:[ \t]*[\w-]+))?[ \t]*,?[ \t]*(?:--.*)?$/mg; export default class YamlLinter { #content; #resourcePath; #context; constructor(resourcePath, content, context) { this.#content = content; this.#resourcePath = resourcePath; this.#context = context; } // eslint-disable-next-line @typescript-eslint/require-await async lint() { try { // Split Yaml file into part documents by '---' separator const allDocuments = this.#content.split(/(?:\r\n|\r|\n)---/g); // Calculate the starting line number of each part document let lineNumberOffset = 0; allDocuments.forEach((document) => { // Parse content only of the current part const parsedYamlWithPosInfo = this.#parseYaml(document); // Analyze part content with line number offset this.#analyzeYaml(parsedYamlWithPosInfo, lineNumberOffset); this.#collectDirectives(document, lineNumberOffset); // Update line number offset for next part lineNumberOffset += document.split(/\r\n|\r|\n/g).length; }); } catch (err) { const message = err instanceof Error ? err.message : String(err); this.#context.addLintingMessage(this.#resourcePath, MESSAGE.PARSING_ERROR, { message }); } } #parseYaml(content) { // Create JS object from YAML content with position information return fromYaml(content); } #analyzeYaml(yaml, offset) { // Check for deprecated libraries yaml?.framework?.libraries?.forEach((lib) => { const libraryName = lib.name.toString(); if (deprecatedLibraries.includes(libraryName) || deprecatedThemeLibraries.includes(libraryName)) { const positionInfo = getPosition(lib); this.#context.addLintingMessage(this.#resourcePath, MESSAGE.DEPRECATED_LIBRARY, { libraryName, }, { line: positionInfo.start.line + offset, column: positionInfo.start.column, }); } }); } #collectDirectives(content, offset) { const matches = content.matchAll(DIRECTIVE_REGEX); for (const match of matches) { const action = (match[1] ?? match[4]); const scope = (match[2] ?? match[5]); const rules = match[3] ?? match[6]; let ruleNames = rules?.split(",") ?? []; ruleNames = ruleNames.map((rule) => rule.trim()); // Determine line and column of match const left = content.slice(0, match.index); const line = (left.match(/\n/g) ?? []).length + 1 + offset; const lastIndexOf = left.lastIndexOf("\n") + 1; const column = match.index - lastIndexOf + 1; this.#context.addDirective(this.#resourcePath, { action, scope, ruleNames, line, column, }); } } } //# sourceMappingURL=YamlLinter.js.map