From 9c019b0feda77beea61d1a25f5c26663b2a4cc6c Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Tue, 7 May 2024 17:59:01 +0200 Subject: [PATCH 01/27] feat: Add Linter for .library files --- src/linter/dotLibrary/DotLibraryLinter.ts | 66 +++++++++++++++++++++++ src/linter/dotLibrary/linter.ts | 29 ++++++++++ src/linter/lintWorkspace.ts | 2 + 3 files changed, 97 insertions(+) create mode 100644 src/linter/dotLibrary/DotLibraryLinter.ts create mode 100644 src/linter/dotLibrary/linter.ts diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts new file mode 100644 index 000000000..b9371803d --- /dev/null +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -0,0 +1,66 @@ +import {LintMessageSeverity} from "../LinterContext.js"; +import LinterContext from "../LinterContext.js"; +import deprecatedLibraries from "../../utils/deprecatedLibs.js"; +import {DataWithPosition, fromYaml, getPosition} from "data-with-position"; + +interface DotLibraryWithPosInfo extends DataWithPosition { + library?: { + dependencies?: { + dependency?: { + libraryName: string; + } + }[]; + }; + // TODO: add structure for line/column info +} + +export default class DotLibraryLinter { + #content; + #resourcePath; + #context: LinterContext; + + constructor(resourcePath: string, content: string, context: LinterContext) { + this.#content = content; + this.#resourcePath = resourcePath; + this.#context = context; + } + + // eslint-disable-next-line @typescript-eslint/require-await + async lint() { + try { + const parsedDotLibraryWithPosInfo = this.#parseDotLibrary(this.#content); + this.#analyzeDotLibrary(parsedDotLibraryWithPosInfo); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + this.#context.addLintingMessage(this.#resourcePath, { + severity: LintMessageSeverity.Error, + message, + ruleId: "ui5-linter-parsing-error", + fatal: true, + }); + } + } + + #parseDotLibrary(content: string): DotLibraryWithPosInfo { + // TODO: add parsing of XML structure in .library + } + + #analyzeDotLibrary(xml: DotLibraryWithPosInfo) { + // TODO: add detection of 'library.dependencies[].dependency.libraryName' + + // // Check for deprecated libraries + // yaml?.framework?.libraries?.forEach((lib) => { + // if (deprecatedLibraries.includes(lib.name.toString())) { + // const positionInfo = getPosition(lib); + // this.#context.addLintingMessage(this.#resourcePath, { + // ruleId: "ui5-linter-no-deprecated-api", + // severity: LintMessageSeverity.Error, + // fatal: undefined, + // line: positionInfo.start.line + offset, + // column: positionInfo.start.column, + // message: `Use of deprecated library '${lib.name}'`, + // }); + // } + // }); + } +} diff --git a/src/linter/dotLibrary/linter.ts b/src/linter/dotLibrary/linter.ts new file mode 100644 index 000000000..5f9f807df --- /dev/null +++ b/src/linter/dotLibrary/linter.ts @@ -0,0 +1,29 @@ +import {LinterParameters} from "../LinterContext.js"; +import DotLibraryLinter from "./DotLibraryLinter.js"; +import {Resource} from "@ui5/fs"; + +export default async function lintDotLibrary({context}: LinterParameters) { + let dotLibraryResources: Resource[]; + const pathsToLint = context.getPathsToLint(); + const reader = context.getRootReader(); + if (pathsToLint?.length) { + dotLibraryResources = []; + await Promise.all(pathsToLint.map(async (resourcePath) => { + if (!resourcePath.endsWith(".library")) { + return; + } + const resource = await reader.byPath(resourcePath); + if (!resource) { + throw new Error(`Resource not found: ${resourcePath}`); + } + dotLibraryResources.push(resource); + })); + } else { + dotLibraryResources = await reader.byGlob("/src/**/.library"); + } + + await Promise.all(dotLibraryResources.map(async (resource: Resource) => { + const linter = new DotLibraryLinter(resource.getPath(), await resource.getString(), context); + await linter.lint(); + })); +} diff --git a/src/linter/lintWorkspace.ts b/src/linter/lintWorkspace.ts index 2a15f472d..3f04811a5 100644 --- a/src/linter/lintWorkspace.ts +++ b/src/linter/lintWorkspace.ts @@ -3,6 +3,7 @@ import lintXml from "./xmlTemplate/linter.js"; import lintJson from "./manifestJson/linter.js"; import lintHtml from "./html/linter.js"; import lintUI5Yaml from "./yaml/linter.js"; +import lintDotLibrary from "./dotLibrary/linter.js"; import {taskStart} from "../utils/perf.js"; import TypeLinter from "./ui5Types/TypeLinter.js"; import LinterContext, {LintResult, LinterParameters, LinterOptions} from "./LinterContext.js"; @@ -22,6 +23,7 @@ export default async function lintWorkspace( lintJson(params), lintHtml(params), lintUI5Yaml(params), + lintDotLibrary(params) ]); const typeLinter = new TypeLinter(params); From a05bdfe62efe0bc46b5231e7f96a78b5d6c9fcd1 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Fri, 12 Jul 2024 11:41:34 +0200 Subject: [PATCH 02/27] feat: Add xml parser --- src/linter/dotLibrary/DotLibraryLinter.ts | 21 +++++--- src/linter/dotLibrary/linter.ts | 2 +- src/linter/html/parser.ts | 49 ++----------------- src/utils/xmlParser.ts | 46 +++++++++++++++++ .../src/main/js/.library | 9 ++++ test/lib/linter/linter.ts | 2 +- 6 files changed, 75 insertions(+), 54 deletions(-) create mode 100644 src/utils/xmlParser.ts diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index b9371803d..1be7153c1 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -2,6 +2,8 @@ import {LintMessageSeverity} from "../LinterContext.js"; import LinterContext from "../LinterContext.js"; import deprecatedLibraries from "../../utils/deprecatedLibs.js"; import {DataWithPosition, fromYaml, getPosition} from "data-with-position"; +import {parseXML} from "../../utils/xmlParser.js"; +import {ReadStream} from "node:fs"; interface DotLibraryWithPosInfo extends DataWithPosition { library?: { @@ -15,12 +17,12 @@ interface DotLibraryWithPosInfo extends DataWithPosition { } export default class DotLibraryLinter { - #content; + #contentStream; #resourcePath; #context: LinterContext; - constructor(resourcePath: string, content: string, context: LinterContext) { - this.#content = content; + constructor(resourcePath: string, contentStream: ReadStream, context: LinterContext) { + this.#contentStream = contentStream; this.#resourcePath = resourcePath; this.#context = context; } @@ -28,7 +30,8 @@ export default class DotLibraryLinter { // eslint-disable-next-line @typescript-eslint/require-await async lint() { try { - const parsedDotLibraryWithPosInfo = this.#parseDotLibrary(this.#content); + + const parsedDotLibraryWithPosInfo = await this.#parseDotLibrary(this.#contentStream); this.#analyzeDotLibrary(parsedDotLibraryWithPosInfo); } catch (err) { const message = err instanceof Error ? err.message : String(err); @@ -41,8 +44,14 @@ export default class DotLibraryLinter { } } - #parseDotLibrary(content: string): DotLibraryWithPosInfo { - // TODO: add parsing of XML structure in .library + async #parseDotLibrary(contentStream: ReadStream): DotLibraryWithPosInfo { + await parseXML(contentStream, (event, tag) => { + if (tag instanceof SaxTag && + event === SaxEventType.CloseTag && + tag.value === "libraryName") { + console.log(tag); + } + }); } #analyzeDotLibrary(xml: DotLibraryWithPosInfo) { diff --git a/src/linter/dotLibrary/linter.ts b/src/linter/dotLibrary/linter.ts index 5f9f807df..b579f4564 100644 --- a/src/linter/dotLibrary/linter.ts +++ b/src/linter/dotLibrary/linter.ts @@ -23,7 +23,7 @@ export default async function lintDotLibrary({context}: LinterParameters) { } await Promise.all(dotLibraryResources.map(async (resource: Resource) => { - const linter = new DotLibraryLinter(resource.getPath(), await resource.getString(), context); + const linter = new DotLibraryLinter(resource.getPath(), resource.getStream(), context); await linter.lint(); })); } diff --git a/src/linter/html/parser.ts b/src/linter/html/parser.ts index ef3d13598..2d64e47b7 100644 --- a/src/linter/html/parser.ts +++ b/src/linter/html/parser.ts @@ -1,54 +1,11 @@ import type {ReadStream} from "node:fs"; -import {Detail, SaxEventType, SAXParser, Tag as SaxTag} 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); - -let saxWasmBuffer: Buffer; -async function initSaxWasm() { - if (!saxWasmBuffer) { - const saxPath = require.resolve("sax-wasm/lib/sax-wasm.wasm"); - saxWasmBuffer = await fs.readFile(saxPath); - } - - return saxWasmBuffer; -} - -async function parseHtml(contentStream: ReadStream, parseHandler: (type: SaxEventType, tag: Detail) => void) { - const options = {highWaterMark: 32 * 1024}; // 32k chunks - const saxWasmBuffer = await initSaxWasm(); - const saxParser = new SAXParser(SaxEventType.CloseTag, options); - - saxParser.eventHandler = parseHandler; - - // Instantiate and prepare the wasm for parsing - if (!await saxParser.prepareWasm(saxWasmBuffer)) { - throw new Error("Unknown error during WASM Initialization"); - } - - // stream from a file in the current directory - contentStream.on("data", (chunk: Uint8Array) => { - 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(); -} +import {SaxEventType, Tag as SaxTag} from "sax-wasm"; +import {parseXML} from "../../utils/xmlParser.js"; export async function extractJSScriptTags(contentStream: ReadStream) { const scriptTags: SaxTag[] = []; - await parseHtml(contentStream, (event, tag) => { + await parseXML(contentStream, (event, tag) => { if (tag instanceof SaxTag && event === SaxEventType.CloseTag && tag.value === "script") { diff --git a/src/utils/xmlParser.ts b/src/utils/xmlParser.ts new file mode 100644 index 000000000..a0a899f11 --- /dev/null +++ b/src/utils/xmlParser.ts @@ -0,0 +1,46 @@ +import type {ReadStream} from "node:fs"; +import {Detail, SaxEventType, SAXParser, Tag as SaxTag} 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); + +let saxWasmBuffer: Buffer; +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: ReadStream, parseHandler: (type: SaxEventType, tag: Detail) => void) { + const options = {highWaterMark: 32 * 1024}; // 32k chunks + const saxWasmBuffer = await initSaxWasm(); + const saxParser = new SAXParser(SaxEventType.CloseTag, options); + + saxParser.eventHandler = parseHandler; + + // Instantiate and prepare the wasm for parsing + if (!await saxParser.prepareWasm(saxWasmBuffer)) { + throw new Error("Unknown error during WASM Initialization"); + } + + // stream from a file in the current directory + contentStream.on("data", (chunk: Uint8Array) => { + 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(); +} diff --git a/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library b/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library index ffbfd6836..c4f6da4d0 100644 --- a/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library +++ b/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library @@ -8,5 +8,14 @@ sap.ui.core + + sap.ca.scfld.md + + + sap.ca.scfld.md + + + sap.ca.ui + diff --git a/test/lib/linter/linter.ts b/test/lib/linter/linter.ts index 5d4da9cf3..f1227ece0 100644 --- a/test/lib/linter/linter.ts +++ b/test/lib/linter/linter.ts @@ -68,7 +68,7 @@ test.serial("lint: Some files of com.ui5.troublesome.app (without details / cove t.snapshot(preprocessLintResultsForSnapshot(res)); }); -test.serial("lint: All files of library.with.custom.paths", async (t) => { +test.only("lint: All files of library.with.custom.paths", async (t) => { const projectPath = path.join(fixturesProjectsPath, "library.with.custom.paths"); const {lintProject} = t.context; From 430ac470b659ac3baf0d8c45b5a9461cae4c6fca Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Fri, 12 Jul 2024 14:32:06 +0300 Subject: [PATCH 03/27] fix: Eslint issues --- src/linter/dotLibrary/DotLibraryLinter.ts | 57 +++++++++-------------- src/utils/xmlParser.ts | 2 +- 2 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index 1be7153c1..e0f30fda6 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -1,21 +1,10 @@ import {LintMessageSeverity} from "../LinterContext.js"; import LinterContext from "../LinterContext.js"; -import deprecatedLibraries from "../../utils/deprecatedLibs.js"; -import {DataWithPosition, fromYaml, getPosition} from "data-with-position"; +import deprecatedLibs from "../../utils/deprecatedLibs.js"; +import {SaxEventType, Tag as SaxTag} from "sax-wasm"; import {parseXML} from "../../utils/xmlParser.js"; import {ReadStream} from "node:fs"; -interface DotLibraryWithPosInfo extends DataWithPosition { - library?: { - dependencies?: { - dependency?: { - libraryName: string; - } - }[]; - }; - // TODO: add structure for line/column info -} - export default class DotLibraryLinter { #contentStream; #resourcePath; @@ -30,9 +19,8 @@ export default class DotLibraryLinter { // eslint-disable-next-line @typescript-eslint/require-await async lint() { try { - const parsedDotLibraryWithPosInfo = await this.#parseDotLibrary(this.#contentStream); - this.#analyzeDotLibrary(parsedDotLibraryWithPosInfo); + this.#analyzeDeprecatedLibs(parsedDotLibraryWithPosInfo); } catch (err) { const message = err instanceof Error ? err.message : String(err); this.#context.addLintingMessage(this.#resourcePath, { @@ -44,32 +32,33 @@ export default class DotLibraryLinter { } } - async #parseDotLibrary(contentStream: ReadStream): DotLibraryWithPosInfo { + async #parseDotLibrary(contentStream: ReadStream): Promise { + const libs = new Set(); await parseXML(contentStream, (event, tag) => { if (tag instanceof SaxTag && event === SaxEventType.CloseTag && tag.value === "libraryName") { - console.log(tag); - } + libs.add(tag.textNodes[0].value); + } }); - } - #analyzeDotLibrary(xml: DotLibraryWithPosInfo) { - // TODO: add detection of 'library.dependencies[].dependency.libraryName' + return Array.from(libs) as string[]; + } + #analyzeDeprecatedLibs(libs: string[]) { // // Check for deprecated libraries - // yaml?.framework?.libraries?.forEach((lib) => { - // if (deprecatedLibraries.includes(lib.name.toString())) { - // const positionInfo = getPosition(lib); - // this.#context.addLintingMessage(this.#resourcePath, { - // ruleId: "ui5-linter-no-deprecated-api", - // severity: LintMessageSeverity.Error, - // fatal: undefined, - // line: positionInfo.start.line + offset, - // column: positionInfo.start.column, - // message: `Use of deprecated library '${lib.name}'`, - // }); - // } - // }); + libs.forEach((lib) => { + if (deprecatedLibs.includes(lib)) { + // const positionInfo = getPosition(lib); + // this.#context.addLintingMessage(this.#resourcePath, { + // ruleId: "ui5-linter-no-deprecated-api", + // severity: LintMessageSeverity.Error, + // fatal: undefined, + // line: positionInfo.start.line + offset, + // column: positionInfo.start.column, + // message: `Use of deprecated library '${lib.name}'`, + // }); + } + }); } } diff --git a/src/utils/xmlParser.ts b/src/utils/xmlParser.ts index a0a899f11..090904818 100644 --- a/src/utils/xmlParser.ts +++ b/src/utils/xmlParser.ts @@ -1,5 +1,5 @@ import type {ReadStream} from "node:fs"; -import {Detail, SaxEventType, SAXParser, Tag as SaxTag} from "sax-wasm"; +import {Detail, SaxEventType, SAXParser} from "sax-wasm"; import {finished} from "node:stream/promises"; import fs from "node:fs/promises"; import {createRequire} from "node:module"; From e7a0bbab5a6af4a336f004ed98614593dc33bfa4 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Fri, 12 Jul 2024 14:32:39 +0300 Subject: [PATCH 04/27] fix: Remove eslint annotations --- src/linter/dotLibrary/DotLibraryLinter.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index e0f30fda6..1fab076a8 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -16,7 +16,6 @@ export default class DotLibraryLinter { this.#context = context; } - // eslint-disable-next-line @typescript-eslint/require-await async lint() { try { const parsedDotLibraryWithPosInfo = await this.#parseDotLibrary(this.#contentStream); From d78f1a7febaf759dac2191c74115007d09ee42b9 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Fri, 12 Jul 2024 13:54:04 +0200 Subject: [PATCH 05/27] feat: Detect depr. libs within .library files --- src/linter/dotLibrary/DotLibraryLinter.ts | 30 ++++++++++++----------- src/linter/lintWorkspace.ts | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index 1fab076a8..a797354b0 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -31,32 +31,34 @@ export default class DotLibraryLinter { } } - async #parseDotLibrary(contentStream: ReadStream): Promise { + async #parseDotLibrary(contentStream: ReadStream): Promise { const libs = new Set(); await parseXML(contentStream, (event, tag) => { if (tag instanceof SaxTag && event === SaxEventType.CloseTag && tag.value === "libraryName") { - libs.add(tag.textNodes[0].value); + libs.add(tag); } }); - return Array.from(libs) as string[]; + return Array.from(libs) as SaxTag[]; } - #analyzeDeprecatedLibs(libs: string[]) { + #analyzeDeprecatedLibs(libs: SaxTag[]) { // // Check for deprecated libraries libs.forEach((lib) => { - if (deprecatedLibs.includes(lib)) { - // const positionInfo = getPosition(lib); - // this.#context.addLintingMessage(this.#resourcePath, { - // ruleId: "ui5-linter-no-deprecated-api", - // severity: LintMessageSeverity.Error, - // fatal: undefined, - // line: positionInfo.start.line + offset, - // column: positionInfo.start.column, - // message: `Use of deprecated library '${lib.name}'`, - // }); + const libName = lib.textNodes[0].value; + const {line, character: column} = lib.openStart; + + if (deprecatedLibs.includes(libName)) { + this.#context.addLintingMessage(this.#resourcePath, { + ruleId: "ui5-linter-no-deprecated-api", + severity: LintMessageSeverity.Error, + fatal: undefined, + line: line + 1, + column: column + 1, + message: `Use of deprecated library '${libName}'`, + }); } }); } diff --git a/src/linter/lintWorkspace.ts b/src/linter/lintWorkspace.ts index 3f04811a5..b45f1497c 100644 --- a/src/linter/lintWorkspace.ts +++ b/src/linter/lintWorkspace.ts @@ -23,7 +23,7 @@ export default async function lintWorkspace( lintJson(params), lintHtml(params), lintUI5Yaml(params), - lintDotLibrary(params) + lintDotLibrary(params), ]); const typeLinter = new TypeLinter(params); From 8b262aca1cea8597027bffaebe903105d880fd02 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Fri, 12 Jul 2024 14:02:33 +0200 Subject: [PATCH 06/27] refactor: Rename variables --- src/linter/dotLibrary/DotLibraryLinter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index a797354b0..4ccc610ab 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -1,6 +1,6 @@ import {LintMessageSeverity} from "../LinterContext.js"; import LinterContext from "../LinterContext.js"; -import deprecatedLibs from "../../utils/deprecatedLibs.js"; +import {deprecatedLibraries} from "../../utils/deprecations.js"; import {SaxEventType, Tag as SaxTag} from "sax-wasm"; import {parseXML} from "../../utils/xmlParser.js"; import {ReadStream} from "node:fs"; @@ -18,8 +18,8 @@ export default class DotLibraryLinter { async lint() { try { - const parsedDotLibraryWithPosInfo = await this.#parseDotLibrary(this.#contentStream); - this.#analyzeDeprecatedLibs(parsedDotLibraryWithPosInfo); + const dotLibraryDependencyTags = await this.#parseDotLibrary(this.#contentStream); + this.#analyzeDeprecatedLibs(dotLibraryDependencyTags); } catch (err) { const message = err instanceof Error ? err.message : String(err); this.#context.addLintingMessage(this.#resourcePath, { @@ -50,7 +50,7 @@ export default class DotLibraryLinter { const libName = lib.textNodes[0].value; const {line, character: column} = lib.openStart; - if (deprecatedLibs.includes(libName)) { + if (deprecatedLibraries.includes(libName)) { this.#context.addLintingMessage(this.#resourcePath, { ruleId: "ui5-linter-no-deprecated-api", severity: LintMessageSeverity.Error, From f2e1065c3f2cbcfc3b264ca096979e69a0635d41 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Fri, 12 Jul 2024 15:05:13 +0300 Subject: [PATCH 07/27] fix: Eslint issues --- src/linter/html/parser.ts | 10 +++++----- src/linter/ui5Types/SourceFileLinter.ts | 4 ++-- .../amdTranspiler/moduleDeclarationToDefinition.ts | 10 +++++----- src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts | 2 +- src/linter/ui5Types/asyncComponentFlags.ts | 4 ++-- src/linter/xmlTemplate/Parser.ts | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/linter/html/parser.ts b/src/linter/html/parser.ts index 2d64e47b7..d523d95d7 100644 --- a/src/linter/html/parser.ts +++ b/src/linter/html/parser.ts @@ -17,11 +17,11 @@ export async function extractJSScriptTags(contentStream: ReadStream) { // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type#attribute_is_not_set_default_an_empty_string_or_a_javascript_mime_type return attr.name.value !== "type" || (attr.name.value === "type" && - ["", - "module", - "text/javascript", - "application/javascript", /* legacy */ - ].includes(attr.value.value.toLowerCase())); + ["", + "module", + "text/javascript", + "application/javascript", /* legacy */ + ].includes(attr.value.value.toLowerCase())); }); if (isJSScriptTag) { diff --git a/src/linter/ui5Types/SourceFileLinter.ts b/src/linter/ui5Types/SourceFileLinter.ts index cd22ed1b4..5757e73e0 100644 --- a/src/linter/ui5Types/SourceFileLinter.ts +++ b/src/linter/ui5Types/SourceFileLinter.ts @@ -73,7 +73,7 @@ export default class SourceFileLinter { this.analyzeCallExpression(node as ts.CallExpression); // Check for deprecation this.analyzeLibInitCall(node as ts.CallExpression); // Check for sap/ui/core/Lib.init usages } else if (node.kind === ts.SyntaxKind.PropertyAccessExpression || - node.kind === ts.SyntaxKind.ElementAccessExpression) { + node.kind === ts.SyntaxKind.ElementAccessExpression) { this.analyzePropertyAccessExpression( node as (ts.PropertyAccessExpression | ts.ElementAccessExpression)); // Check for global this.analyzePropertyAccessExpressionForDeprecation( @@ -305,7 +305,7 @@ export default class SourceFileLinter { if (!apiVersionNode) { // No arguments or no 'apiVersion' property nodeToHighlight = node; } else if (ts.isPropertyAssignment(apiVersionNode) && - apiVersionNode.initializer.getText() !== "2") { // String value would be "\"2\"" + apiVersionNode.initializer.getText() !== "2") { // String value would be "\"2\"" nodeToHighlight = apiVersionNode; } } diff --git a/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts b/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts index 34741900d..ec0a5537d 100644 --- a/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts +++ b/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts @@ -197,7 +197,7 @@ function getModuleBody( // node.expression)); } } else if (ts.isExpressionStatement(node) && ts.isStringLiteral(node.expression) && - node.expression.text === "use strict") { + node.expression.text === "use strict") { // Ignore "use strict" directive continue; } else { @@ -229,10 +229,10 @@ function getModuleBody( body = [createDefaultExport(nodeFactory, moduleDeclaration.factory.body)]; } } else if (ts.isClassDeclaration(moduleDeclaration.factory) || - ts.isLiteralExpression(moduleDeclaration.factory) || - ts.isArrayLiteralExpression(moduleDeclaration.factory) || - ts.isObjectLiteralExpression(moduleDeclaration.factory) || - ts.isPropertyAccessExpression(moduleDeclaration.factory)) { + ts.isLiteralExpression(moduleDeclaration.factory) || + ts.isArrayLiteralExpression(moduleDeclaration.factory) || + ts.isObjectLiteralExpression(moduleDeclaration.factory) || + ts.isPropertyAccessExpression(moduleDeclaration.factory)) { // Use factory directly body = [createDefaultExport(nodeFactory, moduleDeclaration.factory)]; } else { // Identifier diff --git a/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts b/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts index e9e166749..a906d154a 100644 --- a/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts +++ b/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts @@ -75,7 +75,7 @@ function getClassBodyFromArguments( undefined, prop.initializer.body); } else if (ts.isObjectLiteralExpression(prop.initializer) && - ts.isIdentifier(prop.name) && prop.name.text === "metadata") { + ts.isIdentifier(prop.name) && prop.name.text === "metadata") { // Transform to *static* property declaration? // This would align it with how UI5 projects should declare metadata in TypeScript, // however it's unclear whether this helps our static analysis diff --git a/src/linter/ui5Types/asyncComponentFlags.ts b/src/linter/ui5Types/asyncComponentFlags.ts index a265bacd3..5967e91dd 100644 --- a/src/linter/ui5Types/asyncComponentFlags.ts +++ b/src/linter/ui5Types/asyncComponentFlags.ts @@ -266,8 +266,8 @@ function doPropsCheck(metadata: ts.PropertyDeclaration, manifestContent: string } hasManifestDefinition = !!(componentManifest && - ts.isPropertyAssignment(componentManifest) && - componentManifest.initializer.getText() === "\"json\""); + ts.isPropertyAssignment(componentManifest) && + componentManifest.initializer.getText() === "\"json\""); } return { diff --git a/src/linter/xmlTemplate/Parser.ts b/src/linter/xmlTemplate/Parser.ts index 26707642a..07f2e5d78 100644 --- a/src/linter/xmlTemplate/Parser.ts +++ b/src/linter/xmlTemplate/Parser.ts @@ -428,7 +428,7 @@ export default class Parser { this.#generator.writeRequire(requireExpression); } else if (resolvedNamespace === FESR_NAMESPACE || - resolvedNamespace === SAP_BUILD_NAMESPACE || resolvedNamespace === SAP_UI_DT_NAMESPACE) { + resolvedNamespace === SAP_BUILD_NAMESPACE || resolvedNamespace === SAP_UI_DT_NAMESPACE) { // Silently ignore FESR, sap.build and sap.ui.dt attributes } else if (resolvedNamespace === CUSTOM_DATA_NAMESPACE) { // Add custom data element and add it as an aggregation @@ -515,7 +515,7 @@ export default class Parser { } return ownerAggregation; } else if (this.#xmlDocumentKind === DocumentKind.Fragment && moduleName === "FragmentDefinition" && - namespace === CORE_NAMESPACE) { + namespace === CORE_NAMESPACE) { // This node declares a fragment definition const node: FragmentDefinitionDeclaration = { kind: NodeKind.FragmentDefinition, From da44641968b04ccbc0fec0e70a9183ff768592fb Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Fri, 12 Jul 2024 15:06:22 +0300 Subject: [PATCH 08/27] test: Update snapshots --- test/lib/linter/snapshots/linter.ts.md | 869 +---------------------- test/lib/linter/snapshots/linter.ts.snap | Bin 8327 -> 8525 bytes 2 files changed, 12 insertions(+), 857 deletions(-) diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index 7a1f234a4..f42400108 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -4,847 +4,44 @@ The actual snapshot is saved in `linter.ts.snap`. Generated by [AVA](https://avajs.dev). -## General: Coverage.js - -> Snapshot 1 - - [ - { - coverageInfo: [ - { - category: 1, - column: 35, - line: 3, - message: 'Unable to analyze this method call because the type of identifier "get" in "oVariantManagementMapDataSelector.get({ reference: sReference })"" could not be determined', - }, - { - category: 1, - column: 4, - line: 6, - message: `Unable to analyze this method call because the type of identifier "forEach" in "oVariantManagement.variants.forEach((oVariant) => {␊ - if (oVariant.visible === false) {␊ - aHiddenVariants.push(oVariant.key);␊ - }␊ - })"" could not be determined`, - }, - { - category: 1, - column: 10, - line: 12, - message: `Unable to analyze this method call because the type of identifier "filter" in "aFlexObjects.filter((oFilteredFlexObject) => {␊ - // The following block should produce a coverage message:␊ - // "Unable to analyze this method call because the type of identifier"␊ - // However, the following line will be transformed to "[...] = ({ [...]" with␊ - // no source map entry for the added brackets (since it does not exist in source).␊ - // This poses a challenge for Reporter.ts to map to the correct location in the source file␊ - const sVariantReference = {␊ - // eslint-disable-next-line camelcase␊ - ctrl_variant: () => (oFilteredFlexObject.getVariantId()),␊ - // eslint-disable-next-line camelcase␊ - ctrl_variant_change: () => (oFilteredFlexObject.getSelector().id),␊ - change: () => (oFilteredFlexObject.getVariantReference())␊ - }[oFilteredFlexObject.getFileType()]?.();␊ - return !aHiddenVariants.includes(sVariantReference);␊ - })"" could not be determined`, - }, - { - category: 1, - column: 30, - line: 18, - message: `Unable to analyze this method call because the type of identifier in "{␊ - // eslint-disable-next-line camelcase␊ - ctrl_variant: () => (oFilteredFlexObject.getVariantId()),␊ - // eslint-disable-next-line camelcase␊ - ctrl_variant_change: () => (oFilteredFlexObject.getSelector().id),␊ - change: () => (oFilteredFlexObject.getVariantReference())␊ - }[oFilteredFlexObject.getFileType()]?.()"" could not be determined`, - }, - { - category: 1, - column: 26, - line: 20, - message: 'Unable to analyze this method call because the type of identifier "getVariantId" in "oFilteredFlexObject.getVariantId()"" could not be determined', - }, - { - category: 1, - column: 33, - line: 22, - message: 'Unable to analyze this method call because the type of identifier "getSelector" in "oFilteredFlexObject.getSelector()"" could not be determined', - }, - { - category: 1, - column: 20, - line: 23, - message: 'Unable to analyze this method call because the type of identifier "getVariantReference" in "oFilteredFlexObject.getVariantReference()"" could not be determined', - }, - { - category: 1, - column: 6, - line: 24, - message: 'Unable to analyze this method call because the type of identifier "getFileType" in "oFilteredFlexObject.getFileType()"" could not be determined', - }, - ], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'Coverage.js', - messages: [], - warningCount: 0, - }, - ] - -## General: JSDoc.js - -> Snapshot 1 - - [ - { - coverageInfo: [], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'JSDoc.js', - messages: [ - { - column: 5, - fatal: undefined, - line: 15, - message: 'Use of deprecated property \'blocked\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 8, - fatal: undefined, - line: 17, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - ] - -## General: PlainJS.js - -> Snapshot 1 - - [ - { - coverageInfo: [], - errorCount: 3, - fatalErrorCount: 0, - filePath: 'PlainJS.js', - messages: [ - { - column: 7, - fatal: undefined, - line: 6, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 23, - fatal: undefined, - line: 12, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 4, - fatal: undefined, - line: 18, - message: 'Use of deprecated property \'blocked\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - ] - -## General: Raw.js - -> Snapshot 1 - - [ - { - coverageInfo: [], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'Raw.js', - messages: [ - { - column: 5, - fatal: undefined, - line: 9, - message: 'Use of deprecated property \'blocked\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 8, - fatal: undefined, - line: 11, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - ] - -## General: TSLike.js - -> Snapshot 1 - - [ - { - coverageInfo: [], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'TSLike.js', - messages: [ - { - column: 5, - fatal: undefined, - line: 11, - message: 'Use of deprecated property \'blocked\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 8, - fatal: undefined, - line: 13, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - ] - -## General: Undetected.js - -> Snapshot 1 - - [ - { - coverageInfo: [ - { - category: 1, - column: 3, - line: 5, - message: `Unable to analyze this method call because the type of identifier "attachTap" in "btn.attachTap(function () {␊ - console.log("Tapped");␊ - })"" could not be determined`, - }, - ], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'Undetected.js', - messages: [], - warningCount: 0, - }, - ] - -## lint: All files of com.ui5.troublesome.app - -> Snapshot 1 - - [ - { - coverageInfo: [], - errorCount: 1, - fatalErrorCount: 0, - filePath: 'ui5.yaml', - messages: [ - { - column: 7, - fatal: undefined, - line: 11, - message: 'Use of deprecated library \'sap.landvisz\'', - ruleId: 'ui5-linter-no-deprecated-library', - severity: 2, - }, - ], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/Component.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [ - { - category: 1, - column: 33, - line: 8, - message: 'Unable to analyze this method call because the type of identifier "getContentDensityClass" in "this.getOwnerComponent().getContentDensityClass()"" could not be determined', - }, - ], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'webapp/controller/App.controller.js', - messages: [ - { - column: 36, - fatal: undefined, - line: 1, - message: 'Deprecated access to enum pseudo module \'sap/m/BackgroundDesign\'', - messageDetails: 'Migrating Access to Pseudo Modules (https://ui5.sap.com/#/topic/00737d6c1b864dc3ab72ef56611491c4)', - ruleId: 'ui5-linter-no-pseudo-modules', - severity: 2, - }, - { - column: 24, - fatal: undefined, - line: 10, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - { - coverageInfo: [ - { - category: 1, - column: 17, - line: 38, - message: 'Unable to analyze this method call because the type of identifier "getModel" in "this.getOwnerComponent().getModel("i18n")"" could not be determined', - }, - { - category: 1, - column: 11, - line: 39, - message: 'Unable to analyze this method call because the type of identifier "getResourceBundle" in "oModel.getResourceBundle()"" could not be determined', - }, - ], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'webapp/controller/BaseController.js', - messages: [ - { - column: 5, - fatal: undefined, - line: 9, - message: 'Use of deprecated property \'blocked\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 8, - fatal: undefined, - line: 11, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/controller/Main.controller.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/emptyFile.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/helpers/ES6Class.helper.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 5, - fatalErrorCount: 0, - filePath: 'webapp/manifest.json', - messages: [ - { - column: 17, - fatal: undefined, - line: 47, - message: 'Use of deprecated library \'sap.ui.commons\'', - ruleId: 'ui5-linter-no-deprecated-library', - severity: 2, - }, - { - column: 13, - fatal: undefined, - line: 59, - message: 'Use of deprecated property \'sap.ui5/resources/js\'', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 21, - fatal: undefined, - line: 72, - message: 'Use of deprecated property \'sap.ui5/models/odata-v4/settings/synchronizationMode\' of sap.ui.model.odata.v4.ODataModel', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 21, - fatal: undefined, - line: 78, - message: 'Use of deprecated property \'sap.ui5/models/odata-v4-via-dataSource/settings/synchronizationMode\' of sap.ui.model.odata.v4.ODataModel', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 17, - fatal: undefined, - line: 82, - message: 'Use of deprecated model type \'sap.ui5/models/odata/type="sap.ui.model.odata.ODataModel"\'', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - { - coverageInfo: [ - { - category: 1, - column: 20, - line: 6, - message: 'Unable to analyze this method call because the type of identifier "toUpperCase" in "value.toUpperCase()"" could not be determined', - }, - ], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/model/formatter.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/model/models.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [ - { - category: 1, - column: 2, - line: 6, - message: `Unable to analyze this method call because the type of identifier in "opaTest("Should open the Hello dialog", function (Given, When, Then) {␊ - // Arrangements␊ - Given.iStartMyUIComponent({␊ - componentConfig: {␊ - name: "com.ui5.troublesome.app"␊ - }␊ - });␊ - // Actions␊ - When.onTheMainPage.iPressTheSayHelloButton();␊ - // Assertions␊ - Then.onTheMainPage.iShouldSeeTheHelloDialog();␊ - // Actions␊ - When.onTheMainPage.iPressTheOkButtonInTheDialog();␊ - // Assertions␊ - Then.onTheMainPage.iShouldNotSeeTheHelloDialog();␊ - // Cleanup␊ - Then.iTeardownMyApp();␊ - })"" could not be determined`, - }, - { - category: 1, - column: 3, - line: 8, - message: `Unable to analyze this method call because the type of identifier "iStartMyUIComponent" in "Given.iStartMyUIComponent({␊ - componentConfig: {␊ - name: "com.ui5.troublesome.app"␊ - }␊ - })"" could not be determined`, - }, - { - category: 1, - column: 3, - line: 15, - message: 'Unable to analyze this method call because the type of identifier "iPressTheSayHelloButton" in "When.onTheMainPage.iPressTheSayHelloButton()"" could not be determined', - }, - { - category: 1, - column: 3, - line: 18, - message: 'Unable to analyze this method call because the type of identifier "iShouldSeeTheHelloDialog" in "Then.onTheMainPage.iShouldSeeTheHelloDialog()"" could not be determined', - }, - { - category: 1, - column: 3, - line: 21, - message: 'Unable to analyze this method call because the type of identifier "iPressTheOkButtonInTheDialog" in "When.onTheMainPage.iPressTheOkButtonInTheDialog()"" could not be determined', - }, - { - category: 1, - column: 3, - line: 24, - message: 'Unable to analyze this method call because the type of identifier "iShouldNotSeeTheHelloDialog" in "Then.onTheMainPage.iShouldNotSeeTheHelloDialog()"" could not be determined', - }, - { - category: 1, - column: 3, - line: 27, - message: 'Unable to analyze this method call because the type of identifier "iTeardownMyApp" in "Then.iTeardownMyApp()"" could not be determined', - }, - { - category: 1, - column: 2, - line: 30, - message: `Unable to analyze this method call because the type of identifier in "opaTest("Should close the Hello dialog", function (Given, When, Then) {␊ - // Arrangements␊ - Given.iStartMyUIComponent({␊ - componentConfig: {␊ - name: "com.ui5.troublesome.app"␊ - }␊ - });␊ - // Actions␊ - When.onTheMainPage.iPressTheSayHelloButton();␊ - When.onTheMainPage.iPressTheOkButtonInTheDialog();␊ - // Assertions␊ - Then.onTheMainPage.iShouldNotSeeTheHelloDialog();␊ - // Cleanup␊ - Then.iTeardownMyApp();␊ - })"" could not be determined`, - }, - { - category: 1, - column: 3, - line: 32, - message: `Unable to analyze this method call because the type of identifier "iStartMyUIComponent" in "Given.iStartMyUIComponent({␊ - componentConfig: {␊ - name: "com.ui5.troublesome.app"␊ - }␊ - })"" could not be determined`, - }, - { - category: 1, - column: 3, - line: 39, - message: 'Unable to analyze this method call because the type of identifier "iPressTheSayHelloButton" in "When.onTheMainPage.iPressTheSayHelloButton()"" could not be determined', - }, - { - category: 1, - column: 3, - line: 40, - message: 'Unable to analyze this method call because the type of identifier "iPressTheOkButtonInTheDialog" in "When.onTheMainPage.iPressTheOkButtonInTheDialog()"" could not be determined', - }, - { - category: 1, - column: 3, - line: 43, - message: 'Unable to analyze this method call because the type of identifier "iShouldNotSeeTheHelloDialog" in "Then.onTheMainPage.iShouldNotSeeTheHelloDialog()"" could not be determined', - }, - { - category: 1, - column: 3, - line: 46, - message: 'Unable to analyze this method call because the type of identifier "iTeardownMyApp" in "Then.iTeardownMyApp()"" could not be determined', - }, - ], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/test/integration/HelloJourney.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 3, - fatalErrorCount: 0, - filePath: 'webapp/test/integration/opaTests.qunit.js', - messages: [ - { - column: 18, - fatal: undefined, - line: 4, - message: 'Call to deprecated function \'attachInit\' of class \'Core\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 8, - fatal: undefined, - line: 4, - message: 'Call to deprecated function \'getCore\' (sap.ui.getCore)', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 1, - fatal: undefined, - line: 4, - message: 'Access of global variable \'sap\' (sap.ui.getCore)', - ruleId: 'ui5-linter-no-globals-js', - severity: 2, - }, - ], - warningCount: 0, - }, - { - coverageInfo: [ - { - category: 1, - column: 13, - line: 8, - message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ - id: "helloButton",␊ - viewName: "com.ui5.troublesome.app.view.Main",␊ - actions: new Press(),␊ - errorMessage: "Did not find the 'Say Hello With Dialog' button on the App view"␊ - })"" could not be determined`, - }, - { - category: 1, - column: 13, - line: 17, - message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ - controlType: "sap.m.Button",␊ - searchOpenDialogs: true,␊ - viewName: "com.ui5.troublesome.app.view.Main",␊ - actions: new Press(),␊ - errorMessage: "Did not find the 'OK' button in the Dialog"␊ - })"" could not be determined`, - }, - { - category: 1, - column: 13, - line: 29, - message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ - controlType: "sap.m.Dialog",␊ - success: function () {␊ - // we set the view busy, so we need to query the parent of the app␊ - Opa5.assert.ok(true, "The dialog is open");␊ - },␊ - errorMessage: "Did not find the dialog control"␊ - })"" could not be determined`, - }, - { - category: 1, - column: 13, - line: 40, - message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ - controlType: "sap.m.App", // dummy, I just want a check function, where I can search the DOM. Probably there is a better way for a NEGATIVE test (NO dialog).␊ - check: function () {␊ - return document.querySelectorAll(".sapMDialog").length === 0;␊ - },␊ - success: function () {␊ - Opa5.assert.ok(true, "No dialog is open");␊ - }␊ - })"" could not be determined`, - }, - ], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/test/integration/pages/Main.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [ - { - category: 1, - column: 2, - line: 6, - message: 'Unable to analyze this method call because the type of identifier "addTestPage" in "suite.addTestPage(sContextPath + "unit/unitTests.qunit.html")"" could not be determined', - }, - { - category: 1, - column: 2, - line: 7, - message: 'Unable to analyze this method call because the type of identifier "addTestPage" in "suite.addTestPage(sContextPath + "integration/opaTests.qunit.html")"" could not be determined', - }, - ], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/test/testsuite.qunit.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/test/unit/controller/App.qunit.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 3, - fatalErrorCount: 0, - filePath: 'webapp/test/unit/unitTests.qunit.js', - messages: [ - { - column: 18, - fatal: undefined, - line: 6, - message: 'Call to deprecated function \'attachInit\' of class \'Core\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 8, - fatal: undefined, - line: 6, - message: 'Call to deprecated function \'getCore\' (sap.ui.getCore)', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 1, - fatal: undefined, - line: 6, - message: 'Access of global variable \'sap\' (sap.ui.getCore)', - ruleId: 'ui5-linter-no-globals-js', - severity: 2, - }, - ], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'webapp/view/App.view.xml', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'webapp/view/Main.view.xml', - messages: [ - { - column: 2, - fatal: undefined, - line: 11, - message: 'Import of deprecated module \'sap/m/MessagePage\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 5, - fatal: undefined, - line: 22, - message: 'Use of deprecated property \'blocked\' of class \'Button\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - ] - -## lint: Some files of com.ui5.troublesome.app (without details / coverage) +## lint: All files of library.with.custom.paths > Snapshot 1 [ { coverageInfo: [], - errorCount: 2, + errorCount: 3, fatalErrorCount: 0, - filePath: 'webapp/controller/App.controller.js', + filePath: 'src/main/js/.library', messages: [ { - column: 36, - fatal: undefined, - line: 1, - message: 'Deprecated access to enum pseudo module \'sap/m/BackgroundDesign\'', - messageDetails: 'Migrating Access to Pseudo Modules (https://ui5.sap.com/#/topic/00737d6c1b864dc3ab72ef56611491c4)', - ruleId: 'ui5-linter-no-pseudo-modules', - severity: 2, - }, - { - column: 24, + column: 4, fatal: undefined, - line: 10, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + line: 12, + message: 'Use of deprecated library \'sap.ca.scfld.md\'', ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, - ], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'webapp/controller/BaseController.js', - messages: [ { - column: 5, + column: 4, fatal: undefined, - line: 9, - message: 'Use of deprecated property \'blocked\' of class \'Button\'', + line: 15, + message: 'Use of deprecated library \'sap.ca.scfld.md\'', ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, { - column: 8, + column: 4, fatal: undefined, - line: 11, - message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + line: 18, + message: 'Use of deprecated library \'sap.ca.ui\'', ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, ], warningCount: 0, }, - ] - -## lint: All files of library.with.custom.paths - -> Snapshot 1 - - [ { coverageInfo: [], errorCount: 0, @@ -1049,45 +246,3 @@ Generated by [AVA](https://avajs.dev). warningCount: 0, }, ] - -## lint: All files of library with sap.f namespace - -> Snapshot 1 - - [ - { - coverageInfo: [], - errorCount: 0, - fatalErrorCount: 0, - filePath: 'src/sap/f/LinterTest.js', - messages: [], - warningCount: 0, - }, - { - coverageInfo: [], - errorCount: 2, - fatalErrorCount: 0, - filePath: 'test/sap/f/LinterTest.js', - messages: [ - { - column: 2, - fatal: undefined, - line: 4, - message: 'Import of deprecated module \'sap/f/Avatar\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - { - column: 2, - fatal: undefined, - line: 5, - message: 'Import of deprecated module \'sap/m/DateTimeInput\'', - messageDetails: 'Deprecated test message', - ruleId: 'ui5-linter-no-deprecated-api', - severity: 2, - }, - ], - warningCount: 0, - }, - ] diff --git a/test/lib/linter/snapshots/linter.ts.snap b/test/lib/linter/snapshots/linter.ts.snap index eb1fca48fcaf38d9bad9c3133604431d734a35ae..038b9f2bda93e4cdd904b1850e6c0ee995104ff8 100644 GIT binary patch literal 8525 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 H1H%9SO>&#r literal 8327 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 Date: Fri, 12 Jul 2024 15:09:24 +0300 Subject: [PATCH 09/27] fix: Eslint issues --- src/linter/html/parser.ts | 10 +++++----- src/linter/ui5Types/SourceFileLinter.ts | 4 ++-- .../amdTranspiler/moduleDeclarationToDefinition.ts | 10 +++++----- src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts | 2 +- src/linter/ui5Types/asyncComponentFlags.ts | 4 ++-- src/linter/xmlTemplate/Parser.ts | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/linter/html/parser.ts b/src/linter/html/parser.ts index d523d95d7..2d64e47b7 100644 --- a/src/linter/html/parser.ts +++ b/src/linter/html/parser.ts @@ -17,11 +17,11 @@ export async function extractJSScriptTags(contentStream: ReadStream) { // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type#attribute_is_not_set_default_an_empty_string_or_a_javascript_mime_type return attr.name.value !== "type" || (attr.name.value === "type" && - ["", - "module", - "text/javascript", - "application/javascript", /* legacy */ - ].includes(attr.value.value.toLowerCase())); + ["", + "module", + "text/javascript", + "application/javascript", /* legacy */ + ].includes(attr.value.value.toLowerCase())); }); if (isJSScriptTag) { diff --git a/src/linter/ui5Types/SourceFileLinter.ts b/src/linter/ui5Types/SourceFileLinter.ts index 5757e73e0..cd22ed1b4 100644 --- a/src/linter/ui5Types/SourceFileLinter.ts +++ b/src/linter/ui5Types/SourceFileLinter.ts @@ -73,7 +73,7 @@ export default class SourceFileLinter { this.analyzeCallExpression(node as ts.CallExpression); // Check for deprecation this.analyzeLibInitCall(node as ts.CallExpression); // Check for sap/ui/core/Lib.init usages } else if (node.kind === ts.SyntaxKind.PropertyAccessExpression || - node.kind === ts.SyntaxKind.ElementAccessExpression) { + node.kind === ts.SyntaxKind.ElementAccessExpression) { this.analyzePropertyAccessExpression( node as (ts.PropertyAccessExpression | ts.ElementAccessExpression)); // Check for global this.analyzePropertyAccessExpressionForDeprecation( @@ -305,7 +305,7 @@ export default class SourceFileLinter { if (!apiVersionNode) { // No arguments or no 'apiVersion' property nodeToHighlight = node; } else if (ts.isPropertyAssignment(apiVersionNode) && - apiVersionNode.initializer.getText() !== "2") { // String value would be "\"2\"" + apiVersionNode.initializer.getText() !== "2") { // String value would be "\"2\"" nodeToHighlight = apiVersionNode; } } diff --git a/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts b/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts index ec0a5537d..34741900d 100644 --- a/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts +++ b/src/linter/ui5Types/amdTranspiler/moduleDeclarationToDefinition.ts @@ -197,7 +197,7 @@ function getModuleBody( // node.expression)); } } else if (ts.isExpressionStatement(node) && ts.isStringLiteral(node.expression) && - node.expression.text === "use strict") { + node.expression.text === "use strict") { // Ignore "use strict" directive continue; } else { @@ -229,10 +229,10 @@ function getModuleBody( body = [createDefaultExport(nodeFactory, moduleDeclaration.factory.body)]; } } else if (ts.isClassDeclaration(moduleDeclaration.factory) || - ts.isLiteralExpression(moduleDeclaration.factory) || - ts.isArrayLiteralExpression(moduleDeclaration.factory) || - ts.isObjectLiteralExpression(moduleDeclaration.factory) || - ts.isPropertyAccessExpression(moduleDeclaration.factory)) { + ts.isLiteralExpression(moduleDeclaration.factory) || + ts.isArrayLiteralExpression(moduleDeclaration.factory) || + ts.isObjectLiteralExpression(moduleDeclaration.factory) || + ts.isPropertyAccessExpression(moduleDeclaration.factory)) { // Use factory directly body = [createDefaultExport(nodeFactory, moduleDeclaration.factory)]; } else { // Identifier diff --git a/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts b/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts index a906d154a..e9e166749 100644 --- a/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts +++ b/src/linter/ui5Types/amdTranspiler/rewriteExtendCall.ts @@ -75,7 +75,7 @@ function getClassBodyFromArguments( undefined, prop.initializer.body); } else if (ts.isObjectLiteralExpression(prop.initializer) && - ts.isIdentifier(prop.name) && prop.name.text === "metadata") { + ts.isIdentifier(prop.name) && prop.name.text === "metadata") { // Transform to *static* property declaration? // This would align it with how UI5 projects should declare metadata in TypeScript, // however it's unclear whether this helps our static analysis diff --git a/src/linter/ui5Types/asyncComponentFlags.ts b/src/linter/ui5Types/asyncComponentFlags.ts index 5967e91dd..a265bacd3 100644 --- a/src/linter/ui5Types/asyncComponentFlags.ts +++ b/src/linter/ui5Types/asyncComponentFlags.ts @@ -266,8 +266,8 @@ function doPropsCheck(metadata: ts.PropertyDeclaration, manifestContent: string } hasManifestDefinition = !!(componentManifest && - ts.isPropertyAssignment(componentManifest) && - componentManifest.initializer.getText() === "\"json\""); + ts.isPropertyAssignment(componentManifest) && + componentManifest.initializer.getText() === "\"json\""); } return { diff --git a/src/linter/xmlTemplate/Parser.ts b/src/linter/xmlTemplate/Parser.ts index 07f2e5d78..26707642a 100644 --- a/src/linter/xmlTemplate/Parser.ts +++ b/src/linter/xmlTemplate/Parser.ts @@ -428,7 +428,7 @@ export default class Parser { this.#generator.writeRequire(requireExpression); } else if (resolvedNamespace === FESR_NAMESPACE || - resolvedNamespace === SAP_BUILD_NAMESPACE || resolvedNamespace === SAP_UI_DT_NAMESPACE) { + resolvedNamespace === SAP_BUILD_NAMESPACE || resolvedNamespace === SAP_UI_DT_NAMESPACE) { // Silently ignore FESR, sap.build and sap.ui.dt attributes } else if (resolvedNamespace === CUSTOM_DATA_NAMESPACE) { // Add custom data element and add it as an aggregation @@ -515,7 +515,7 @@ export default class Parser { } return ownerAggregation; } else if (this.#xmlDocumentKind === DocumentKind.Fragment && moduleName === "FragmentDefinition" && - namespace === CORE_NAMESPACE) { + namespace === CORE_NAMESPACE) { // This node declares a fragment definition const node: FragmentDefinitionDeclaration = { kind: NodeKind.FragmentDefinition, From ca7a962175a79439074585d1fa4de0900bed2ca6 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Fri, 12 Jul 2024 14:23:48 +0200 Subject: [PATCH 10/27] fix: Remove debug leftover --- test/lib/linter/linter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/linter/linter.ts b/test/lib/linter/linter.ts index f1227ece0..5d4da9cf3 100644 --- a/test/lib/linter/linter.ts +++ b/test/lib/linter/linter.ts @@ -68,7 +68,7 @@ test.serial("lint: Some files of com.ui5.troublesome.app (without details / cove t.snapshot(preprocessLintResultsForSnapshot(res)); }); -test.only("lint: All files of library.with.custom.paths", async (t) => { +test.serial("lint: All files of library.with.custom.paths", async (t) => { const projectPath = path.join(fixturesProjectsPath, "library.with.custom.paths"); const {lintProject} = t.context; From e9bd8afb9eb2224bfe642fb351c046eff4587b75 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Tue, 16 Jul 2024 15:47:09 +0200 Subject: [PATCH 11/27] test: Add test for xmlParser --- test/lib/utils/xmlParser.ts | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/lib/utils/xmlParser.ts diff --git a/test/lib/utils/xmlParser.ts b/test/lib/utils/xmlParser.ts new file mode 100644 index 000000000..ad955345b --- /dev/null +++ b/test/lib/utils/xmlParser.ts @@ -0,0 +1,53 @@ +import test from "ava"; +import {parseXML} from "../../../src/utils/xmlParser.js"; +import {ReadStream} from "node:fs"; +import {Readable} from "node:stream"; +import {SaxEventType, Tag as SaxTag} from "sax-wasm"; + +test("Test xmlParser with .library", async (t) => { //TODO: Remove .only + const rawContent = ` + + library.with.custom.paths + SAP SE + 1.0 + any + + + sap.ui.core + + + sap.ca.scfld.md + + + sap.ca.scfld.md + + + sap.ca.ui + + +`; + + // Convert raw .library content into stream + const contentStream = new Readable() as ReadStream; + // eslint-disable-next-line @typescript-eslint/no-empty-function + contentStream._read = () => {}; + contentStream.push(rawContent); + + // Call SAXParser with the contentStream + const libs = new Set(); + await parseXML(contentStream, (event, tag): void => { + if (tag instanceof SaxTag && + event === SaxEventType.CloseTag && + tag.value === "libraryName") { + libs.add(tag); + } + }); + + //TODO: Test if the array "libs" contains the expected values + + // t.is(libs.size, 4, "Parsed .library XML should contain 4 libraries"); + //TODO: Check if first lib is "sap.ui.core" + + + t.is(true, true, "should be true"); //TODO: remove this line +}); From 2a6533d8fa0da06cc9719c79ad0e243ab83c4bd6 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Wed, 17 Jul 2024 10:16:51 +0200 Subject: [PATCH 12/27] fix: Adjust test for xmlParser --- test/lib/utils/xmlParser.ts | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/test/lib/utils/xmlParser.ts b/test/lib/utils/xmlParser.ts index ad955345b..10cb160e9 100644 --- a/test/lib/utils/xmlParser.ts +++ b/test/lib/utils/xmlParser.ts @@ -4,8 +4,8 @@ import {ReadStream} from "node:fs"; import {Readable} from "node:stream"; import {SaxEventType, Tag as SaxTag} from "sax-wasm"; -test("Test xmlParser with .library", async (t) => { //TODO: Remove .only - const rawContent = ` +test("Test xmlParser with .library", async (t) => { + const sampleDotLibrary = ` library.with.custom.paths SAP SE @@ -31,23 +31,20 @@ test("Test xmlParser with .library", async (t) => { //TODO: Remove .only const contentStream = new Readable() as ReadStream; // eslint-disable-next-line @typescript-eslint/no-empty-function contentStream._read = () => {}; - contentStream.push(rawContent); + contentStream.push(sampleDotLibrary); + contentStream.push(null); // Call SAXParser with the contentStream - const libs = new Set(); - await parseXML(contentStream, (event, tag): void => { + const libs: SaxTag[] = []; + await parseXML(contentStream, (event, tag) => { if (tag instanceof SaxTag && event === SaxEventType.CloseTag && tag.value === "libraryName") { - libs.add(tag); + libs.push(tag); } }); - //TODO: Test if the array "libs" contains the expected values - - // t.is(libs.size, 4, "Parsed .library XML should contain 4 libraries"); - //TODO: Check if first lib is "sap.ui.core" - - - t.is(true, true, "should be true"); //TODO: remove this line + // Test parsed results + t.is(libs.length, 4, "Parsed .library XML should contain 4 libraries"); + t.is(libs[0].textNodes[0].value, "sap.ui.core", "First library should be 'sap.ui.core'"); }); From 442ae21d0a9d34cc3fdc7895fb6cfadfab26ec68 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Wed, 17 Jul 2024 10:23:13 +0200 Subject: [PATCH 13/27] refactor: Clean up --- src/linter/dotLibrary/DotLibraryLinter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index 4ccc610ab..a081f6baf 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -45,7 +45,7 @@ export default class DotLibraryLinter { } #analyzeDeprecatedLibs(libs: SaxTag[]) { - // // Check for deprecated libraries + // Check for deprecated libraries libs.forEach((lib) => { const libName = lib.textNodes[0].value; const {line, character: column} = lib.openStart; From ce5dd32d788823c6b7014c4e3bcd2426dcdf87b0 Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Wed, 17 Jul 2024 10:35:37 +0200 Subject: [PATCH 14/27] test: Update snapshots --- test/lib/linter/snapshots/linter.ts.md | 878 +++++++++++++++++++++++ test/lib/linter/snapshots/linter.ts.snap | Bin 8525 -> 8524 bytes 2 files changed, 878 insertions(+) diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index f42400108..157e64de7 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -4,6 +4,842 @@ The actual snapshot is saved in `linter.ts.snap`. Generated by [AVA](https://avajs.dev). +## General: Coverage.js + +> Snapshot 1 + + [ + { + coverageInfo: [ + { + category: 1, + column: 35, + line: 3, + message: 'Unable to analyze this method call because the type of identifier "get" in "oVariantManagementMapDataSelector.get({ reference: sReference })"" could not be determined', + }, + { + category: 1, + column: 4, + line: 6, + message: `Unable to analyze this method call because the type of identifier "forEach" in "oVariantManagement.variants.forEach((oVariant) => {␊ + if (oVariant.visible === false) {␊ + aHiddenVariants.push(oVariant.key);␊ + }␊ + })"" could not be determined`, + }, + { + category: 1, + column: 10, + line: 12, + message: `Unable to analyze this method call because the type of identifier "filter" in "aFlexObjects.filter((oFilteredFlexObject) => {␊ + // The following block should produce a coverage message:␊ + // "Unable to analyze this method call because the type of identifier"␊ + // However, the following line will be transformed to "[...] = ({ [...]" with␊ + // no source map entry for the added brackets (since it does not exist in source).␊ + // This poses a challenge for Reporter.ts to map to the correct location in the source file␊ + const sVariantReference = {␊ + // eslint-disable-next-line camelcase␊ + ctrl_variant: () => (oFilteredFlexObject.getVariantId()),␊ + // eslint-disable-next-line camelcase␊ + ctrl_variant_change: () => (oFilteredFlexObject.getSelector().id),␊ + change: () => (oFilteredFlexObject.getVariantReference())␊ + }[oFilteredFlexObject.getFileType()]?.();␊ + return !aHiddenVariants.includes(sVariantReference);␊ + })"" could not be determined`, + }, + { + category: 1, + column: 30, + line: 18, + message: `Unable to analyze this method call because the type of identifier in "{␊ + // eslint-disable-next-line camelcase␊ + ctrl_variant: () => (oFilteredFlexObject.getVariantId()),␊ + // eslint-disable-next-line camelcase␊ + ctrl_variant_change: () => (oFilteredFlexObject.getSelector().id),␊ + change: () => (oFilteredFlexObject.getVariantReference())␊ + }[oFilteredFlexObject.getFileType()]?.()"" could not be determined`, + }, + { + category: 1, + column: 26, + line: 20, + message: 'Unable to analyze this method call because the type of identifier "getVariantId" in "oFilteredFlexObject.getVariantId()"" could not be determined', + }, + { + category: 1, + column: 33, + line: 22, + message: 'Unable to analyze this method call because the type of identifier "getSelector" in "oFilteredFlexObject.getSelector()"" could not be determined', + }, + { + category: 1, + column: 20, + line: 23, + message: 'Unable to analyze this method call because the type of identifier "getVariantReference" in "oFilteredFlexObject.getVariantReference()"" could not be determined', + }, + { + category: 1, + column: 6, + line: 24, + message: 'Unable to analyze this method call because the type of identifier "getFileType" in "oFilteredFlexObject.getFileType()"" could not be determined', + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'Coverage.js', + messages: [], + warningCount: 0, + }, + ] + +## General: JSDoc.js + +> Snapshot 1 + + [ + { + coverageInfo: [], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'JSDoc.js', + messages: [ + { + column: 5, + fatal: undefined, + line: 15, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 8, + fatal: undefined, + line: 17, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + ] + +## General: PlainJS.js + +> Snapshot 1 + + [ + { + coverageInfo: [], + errorCount: 3, + fatalErrorCount: 0, + filePath: 'PlainJS.js', + messages: [ + { + column: 7, + fatal: undefined, + line: 6, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 23, + fatal: undefined, + line: 12, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 4, + fatal: undefined, + line: 18, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + ] + +## General: Raw.js + +> Snapshot 1 + + [ + { + coverageInfo: [], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'Raw.js', + messages: [ + { + column: 5, + fatal: undefined, + line: 9, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 8, + fatal: undefined, + line: 11, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + ] + +## General: TSLike.js + +> Snapshot 1 + + [ + { + coverageInfo: [], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'TSLike.js', + messages: [ + { + column: 5, + fatal: undefined, + line: 11, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 8, + fatal: undefined, + line: 13, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + ] + +## General: Undetected.js + +> Snapshot 1 + + [ + { + coverageInfo: [ + { + category: 1, + column: 3, + line: 5, + message: `Unable to analyze this method call because the type of identifier "attachTap" in "btn.attachTap(function () {␊ + console.log("Tapped");␊ + })"" could not be determined`, + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'Undetected.js', + messages: [], + warningCount: 0, + }, + ] + +## lint: All files of com.ui5.troublesome.app + +> Snapshot 1 + + [ + { + coverageInfo: [], + errorCount: 1, + fatalErrorCount: 0, + filePath: 'ui5.yaml', + messages: [ + { + column: 7, + fatal: undefined, + line: 11, + message: 'Use of deprecated library \'sap.landvisz\'', + ruleId: 'ui5-linter-no-deprecated-library', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/Component.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 33, + line: 8, + message: 'Unable to analyze this method call because the type of identifier "getContentDensityClass" in "this.getOwnerComponent().getContentDensityClass()"" could not be determined', + }, + ], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'webapp/controller/App.controller.js', + messages: [ + { + column: 36, + fatal: undefined, + line: 1, + message: 'Deprecated access to enum pseudo module \'sap/m/BackgroundDesign\'', + messageDetails: 'Migrating Access to Pseudo Modules (https://ui5.sap.com/#/topic/00737d6c1b864dc3ab72ef56611491c4)', + ruleId: 'ui5-linter-no-pseudo-modules', + severity: 2, + }, + { + column: 24, + fatal: undefined, + line: 10, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 17, + line: 38, + message: 'Unable to analyze this method call because the type of identifier "getModel" in "this.getOwnerComponent().getModel("i18n")"" could not be determined', + }, + { + category: 1, + column: 11, + line: 39, + message: 'Unable to analyze this method call because the type of identifier "getResourceBundle" in "oModel.getResourceBundle()"" could not be determined', + }, + ], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'webapp/controller/BaseController.js', + messages: [ + { + column: 5, + fatal: undefined, + line: 9, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 8, + fatal: undefined, + line: 11, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/controller/Main.controller.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/emptyFile.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/helpers/ES6Class.helper.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 5, + fatalErrorCount: 0, + filePath: 'webapp/manifest.json', + messages: [ + { + column: 17, + fatal: undefined, + line: 47, + message: 'Use of deprecated library \'sap.ui.commons\'', + ruleId: 'ui5-linter-no-deprecated-library', + severity: 2, + }, + { + column: 13, + fatal: undefined, + line: 59, + message: 'Use of deprecated property \'sap.ui5/resources/js\'', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 21, + fatal: undefined, + line: 72, + message: 'Use of deprecated property \'sap.ui5/models/odata-v4/settings/synchronizationMode\' of sap.ui.model.odata.v4.ODataModel', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 21, + fatal: undefined, + line: 78, + message: 'Use of deprecated property \'sap.ui5/models/odata-v4-via-dataSource/settings/synchronizationMode\' of sap.ui.model.odata.v4.ODataModel', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 17, + fatal: undefined, + line: 82, + message: 'Use of deprecated model type \'sap.ui5/models/odata/type="sap.ui.model.odata.ODataModel"\'', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 20, + line: 6, + message: 'Unable to analyze this method call because the type of identifier "toUpperCase" in "value.toUpperCase()"" could not be determined', + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/model/formatter.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/model/models.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 2, + line: 6, + message: `Unable to analyze this method call because the type of identifier in "opaTest("Should open the Hello dialog", function (Given, When, Then) {␊ + // Arrangements␊ + Given.iStartMyUIComponent({␊ + componentConfig: {␊ + name: "com.ui5.troublesome.app"␊ + }␊ + });␊ + // Actions␊ + When.onTheMainPage.iPressTheSayHelloButton();␊ + // Assertions␊ + Then.onTheMainPage.iShouldSeeTheHelloDialog();␊ + // Actions␊ + When.onTheMainPage.iPressTheOkButtonInTheDialog();␊ + // Assertions␊ + Then.onTheMainPage.iShouldNotSeeTheHelloDialog();␊ + // Cleanup␊ + Then.iTeardownMyApp();␊ + })"" could not be determined`, + }, + { + category: 1, + column: 3, + line: 8, + message: `Unable to analyze this method call because the type of identifier "iStartMyUIComponent" in "Given.iStartMyUIComponent({␊ + componentConfig: {␊ + name: "com.ui5.troublesome.app"␊ + }␊ + })"" could not be determined`, + }, + { + category: 1, + column: 3, + line: 15, + message: 'Unable to analyze this method call because the type of identifier "iPressTheSayHelloButton" in "When.onTheMainPage.iPressTheSayHelloButton()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 18, + message: 'Unable to analyze this method call because the type of identifier "iShouldSeeTheHelloDialog" in "Then.onTheMainPage.iShouldSeeTheHelloDialog()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 21, + message: 'Unable to analyze this method call because the type of identifier "iPressTheOkButtonInTheDialog" in "When.onTheMainPage.iPressTheOkButtonInTheDialog()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 24, + message: 'Unable to analyze this method call because the type of identifier "iShouldNotSeeTheHelloDialog" in "Then.onTheMainPage.iShouldNotSeeTheHelloDialog()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 27, + message: 'Unable to analyze this method call because the type of identifier "iTeardownMyApp" in "Then.iTeardownMyApp()"" could not be determined', + }, + { + category: 1, + column: 2, + line: 30, + message: `Unable to analyze this method call because the type of identifier in "opaTest("Should close the Hello dialog", function (Given, When, Then) {␊ + // Arrangements␊ + Given.iStartMyUIComponent({␊ + componentConfig: {␊ + name: "com.ui5.troublesome.app"␊ + }␊ + });␊ + // Actions␊ + When.onTheMainPage.iPressTheSayHelloButton();␊ + When.onTheMainPage.iPressTheOkButtonInTheDialog();␊ + // Assertions␊ + Then.onTheMainPage.iShouldNotSeeTheHelloDialog();␊ + // Cleanup␊ + Then.iTeardownMyApp();␊ + })"" could not be determined`, + }, + { + category: 1, + column: 3, + line: 32, + message: `Unable to analyze this method call because the type of identifier "iStartMyUIComponent" in "Given.iStartMyUIComponent({␊ + componentConfig: {␊ + name: "com.ui5.troublesome.app"␊ + }␊ + })"" could not be determined`, + }, + { + category: 1, + column: 3, + line: 39, + message: 'Unable to analyze this method call because the type of identifier "iPressTheSayHelloButton" in "When.onTheMainPage.iPressTheSayHelloButton()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 40, + message: 'Unable to analyze this method call because the type of identifier "iPressTheOkButtonInTheDialog" in "When.onTheMainPage.iPressTheOkButtonInTheDialog()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 43, + message: 'Unable to analyze this method call because the type of identifier "iShouldNotSeeTheHelloDialog" in "Then.onTheMainPage.iShouldNotSeeTheHelloDialog()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 46, + message: 'Unable to analyze this method call because the type of identifier "iTeardownMyApp" in "Then.iTeardownMyApp()"" could not be determined', + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/test/integration/HelloJourney.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 3, + fatalErrorCount: 0, + filePath: 'webapp/test/integration/opaTests.qunit.js', + messages: [ + { + column: 18, + fatal: undefined, + line: 4, + message: 'Call to deprecated function \'attachInit\' of class \'Core\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 8, + fatal: undefined, + line: 4, + message: 'Call to deprecated function \'getCore\' (sap.ui.getCore)', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 1, + fatal: undefined, + line: 4, + message: 'Access of global variable \'sap\' (sap.ui.getCore)', + ruleId: 'ui5-linter-no-globals-js', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 13, + line: 8, + message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ + id: "helloButton",␊ + viewName: "com.ui5.troublesome.app.view.Main",␊ + actions: new Press(),␊ + errorMessage: "Did not find the 'Say Hello With Dialog' button on the App view"␊ + })"" could not be determined`, + }, + { + category: 1, + column: 13, + line: 17, + message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ + controlType: "sap.m.Button",␊ + searchOpenDialogs: true,␊ + viewName: "com.ui5.troublesome.app.view.Main",␊ + actions: new Press(),␊ + errorMessage: "Did not find the 'OK' button in the Dialog"␊ + })"" could not be determined`, + }, + { + category: 1, + column: 13, + line: 29, + message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ + controlType: "sap.m.Dialog",␊ + success: function () {␊ + // we set the view busy, so we need to query the parent of the app␊ + Opa5.assert.ok(true, "The dialog is open");␊ + },␊ + errorMessage: "Did not find the dialog control"␊ + })"" could not be determined`, + }, + { + category: 1, + column: 13, + line: 40, + message: `Unable to analyze this method call because the type of identifier "waitFor" in "this.waitFor({␊ + controlType: "sap.m.App", // dummy, I just want a check function, where I can search the DOM. Probably there is a better way for a NEGATIVE test (NO dialog).␊ + check: function () {␊ + return document.querySelectorAll(".sapMDialog").length === 0;␊ + },␊ + success: function () {␊ + Opa5.assert.ok(true, "No dialog is open");␊ + }␊ + })"" could not be determined`, + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/test/integration/pages/Main.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 2, + line: 6, + message: 'Unable to analyze this method call because the type of identifier "addTestPage" in "suite.addTestPage(sContextPath + "unit/unitTests.qunit.html")"" could not be determined', + }, + { + category: 1, + column: 2, + line: 7, + message: 'Unable to analyze this method call because the type of identifier "addTestPage" in "suite.addTestPage(sContextPath + "integration/opaTests.qunit.html")"" could not be determined', + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/test/testsuite.qunit.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/test/unit/controller/App.qunit.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 3, + fatalErrorCount: 0, + filePath: 'webapp/test/unit/unitTests.qunit.js', + messages: [ + { + column: 18, + fatal: undefined, + line: 6, + message: 'Call to deprecated function \'attachInit\' of class \'Core\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 8, + fatal: undefined, + line: 6, + message: 'Call to deprecated function \'getCore\' (sap.ui.getCore)', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 1, + fatal: undefined, + line: 6, + message: 'Access of global variable \'sap\' (sap.ui.getCore)', + ruleId: 'ui5-linter-no-globals-js', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'webapp/view/App.view.xml', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'webapp/view/Main.view.xml', + messages: [ + { + column: 2, + fatal: undefined, + line: 11, + message: 'Import of deprecated module \'sap/m/MessagePage\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 5, + fatal: undefined, + line: 22, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + ] + +## lint: Some files of com.ui5.troublesome.app (without details / coverage) + +> Snapshot 1 + + [ + { + coverageInfo: [], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'webapp/controller/App.controller.js', + messages: [ + { + column: 36, + fatal: undefined, + line: 1, + message: 'Deprecated access to enum pseudo module \'sap/m/BackgroundDesign\'', + messageDetails: 'Migrating Access to Pseudo Modules (https://ui5.sap.com/#/topic/00737d6c1b864dc3ab72ef56611491c4)', + ruleId: 'ui5-linter-no-pseudo-modules', + severity: 2, + }, + { + column: 24, + fatal: undefined, + line: 10, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'webapp/controller/BaseController.js', + messages: [ + { + column: 5, + fatal: undefined, + line: 9, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 8, + fatal: undefined, + line: 11, + message: 'Call to deprecated function \'attachTap\' of class \'Button\'', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + ] + ## lint: All files of library.with.custom.paths > Snapshot 1 @@ -246,3 +1082,45 @@ Generated by [AVA](https://avajs.dev). warningCount: 0, }, ] + +## lint: All files of library with sap.f namespace + +> Snapshot 1 + + [ + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: 'src/sap/f/LinterTest.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 2, + fatalErrorCount: 0, + filePath: 'test/sap/f/LinterTest.js', + messages: [ + { + column: 2, + fatal: undefined, + line: 4, + message: 'Import of deprecated module \'sap/f/Avatar\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + { + column: 2, + fatal: undefined, + line: 5, + message: 'Import of deprecated module \'sap/m/DateTimeInput\'', + messageDetails: 'Deprecated test message', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + ] diff --git a/test/lib/linter/snapshots/linter.ts.snap b/test/lib/linter/snapshots/linter.ts.snap index 038b9f2bda93e4cdd904b1850e6c0ee995104ff8..816c4a8bd7772e745b12b8c2f148313b5d414fe8 100644 GIT binary patch literal 8524 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 H1H%9SO>&#r From 8f7284a9fbdd0db544bbe5550c95b02a91e6113f Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Wed, 17 Jul 2024 12:32:48 +0200 Subject: [PATCH 15/27] refactor: Use util consts in linter messages --- src/linter/dotLibrary/DotLibraryLinter.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index a081f6baf..1f0229ff6 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -4,6 +4,7 @@ import {deprecatedLibraries} from "../../utils/deprecations.js"; import {SaxEventType, Tag as SaxTag} from "sax-wasm"; import {parseXML} from "../../utils/xmlParser.js"; import {ReadStream} from "node:fs"; +import {RULES, MESSAGES, formatMessage} from "../linterReporting.js"; export default class DotLibraryLinter { #contentStream; @@ -52,12 +53,12 @@ export default class DotLibraryLinter { if (deprecatedLibraries.includes(libName)) { this.#context.addLintingMessage(this.#resourcePath, { - ruleId: "ui5-linter-no-deprecated-api", + ruleId: RULES["ui5-linter-no-deprecated-api"], severity: LintMessageSeverity.Error, fatal: undefined, line: line + 1, column: column + 1, - message: `Use of deprecated library '${libName}'`, + message: formatMessage(MESSAGES.SHORT__DEPRECATED_LIBRARY, libName), }); } }); From a6c2dacf1e4933f7e3b07efa03d10bef56809acc Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Wed, 17 Jul 2024 12:48:44 +0200 Subject: [PATCH 16/27] refactor: Use util const --- src/linter/dotLibrary/DotLibraryLinter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index 1f0229ff6..5cca0435c 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -26,7 +26,7 @@ export default class DotLibraryLinter { this.#context.addLintingMessage(this.#resourcePath, { severity: LintMessageSeverity.Error, message, - ruleId: "ui5-linter-parsing-error", + ruleId: RULES["ui5-linter-parsing-error"], fatal: true, }); } From a876b144b3ffbb5e2504af2d240410b504726088 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 11:55:13 +0300 Subject: [PATCH 17/27] fix: Use workspace reader instead of the rootReader --- src/linter/dotLibrary/linter.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/linter/dotLibrary/linter.ts b/src/linter/dotLibrary/linter.ts index b579f4564..911567870 100644 --- a/src/linter/dotLibrary/linter.ts +++ b/src/linter/dotLibrary/linter.ts @@ -2,24 +2,23 @@ import {LinterParameters} from "../LinterContext.js"; import DotLibraryLinter from "./DotLibraryLinter.js"; import {Resource} from "@ui5/fs"; -export default async function lintDotLibrary({context}: LinterParameters) { +export default async function lintDotLibrary({context, workspace}: LinterParameters) { let dotLibraryResources: Resource[]; const pathsToLint = context.getPathsToLint(); - const reader = context.getRootReader(); if (pathsToLint?.length) { dotLibraryResources = []; await Promise.all(pathsToLint.map(async (resourcePath) => { if (!resourcePath.endsWith(".library")) { return; } - const resource = await reader.byPath(resourcePath); + const resource = await workspace.byPath(resourcePath); if (!resource) { throw new Error(`Resource not found: ${resourcePath}`); } dotLibraryResources.push(resource); })); } else { - dotLibraryResources = await reader.byGlob("/src/**/.library"); + dotLibraryResources = await workspace.byGlob("/src/**/.library"); } await Promise.all(dotLibraryResources.map(async (resource: Resource) => { From 0f86b324c697a49b10058c8c9a5d1f971f35af91 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 12:16:28 +0300 Subject: [PATCH 18/27] fix: Check for empty textNodes within libraryName tag --- src/linter/dotLibrary/DotLibraryLinter.ts | 19 ++++++++++++++++++- src/linter/linterReporting.ts | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index 5cca0435c..d0f61d43f 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -48,9 +48,26 @@ export default class DotLibraryLinter { #analyzeDeprecatedLibs(libs: SaxTag[]) { // Check for deprecated libraries libs.forEach((lib) => { - const libName = lib.textNodes[0].value; const {line, character: column} = lib.openStart; + // Check for missing textNodes or for empty textNodes withing the + // libraryName tag + if (!lib.textNodes[0] || lib.textNodes[0].value.trim() === "") { + this.#context.addLintingMessage(this.#resourcePath, { + ruleId: RULES["ui5-linter-empty-library-name"], + severity: LintMessageSeverity.Warning, + fatal: undefined, + line: line + 1, + column: column + 1, + message: formatMessage(MESSAGES.SHORT__EMPTY_LIBRARY_NAME), + messageDetails: formatMessage(MESSAGES.DETAILS__EMPTY_LIBRARY_NAME), + }); + + return; + } + + const libName = lib.textNodes[0].value.trim(); + if (deprecatedLibraries.includes(libName)) { this.#context.addLintingMessage(this.#resourcePath, { ruleId: RULES["ui5-linter-no-deprecated-api"], diff --git a/src/linter/linterReporting.ts b/src/linter/linterReporting.ts index 4e1abb27f..0e2d86651 100644 --- a/src/linter/linterReporting.ts +++ b/src/linter/linterReporting.ts @@ -29,6 +29,9 @@ export const MESSAGES = { SHORT__DEPRECATED_LIBRARY: "Use of deprecated library '{0}'", SHORT__DEPRECATED_MODEL_TYPE: "Use of deprecated model type '{0}'", + + SHORT__EMPTY_LIBRARY_NAME: "Empty library name", + DETAILS__EMPTY_LIBRARY_NAME: "Library definition is provided, but a library name is missing", }; // TODO: Migrate to enum instead of Object/Map @@ -42,6 +45,7 @@ export const RULES = { "ui5-linter-parsing-error": "ui5-linter-parsing-error", "ui5-linter-no-deprecated-library": "ui5-linter-no-deprecated-library", "ui5-linter-no-deprecated-component": "ui5-linter-no-deprecated-component", + "ui5-linter-empty-library-name": "ui5-linter-empty-library-name", }; export function formatMessage(message: string, ...params: string[]) { From 40af9905723b46a2e04aff358b7b447170a56cc8 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 12:58:52 +0300 Subject: [PATCH 19/27] refactor: Extend xmlParser to support also openTags --- src/utils/xmlParser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/xmlParser.ts b/src/utils/xmlParser.ts index 090904818..4e1f142ca 100644 --- a/src/utils/xmlParser.ts +++ b/src/utils/xmlParser.ts @@ -18,7 +18,7 @@ async function initSaxWasm() { export async function parseXML(contentStream: ReadStream, parseHandler: (type: SaxEventType, tag: Detail) => void) { const options = {highWaterMark: 32 * 1024}; // 32k chunks const saxWasmBuffer = await initSaxWasm(); - const saxParser = new SAXParser(SaxEventType.CloseTag, options); + const saxParser = new SAXParser(SaxEventType.CloseTag + SaxEventType.OpenTag, options); saxParser.eventHandler = parseHandler; From 12bfaec529e562dff2831754e1c05108a1b0f295 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 12:59:40 +0300 Subject: [PATCH 20/27] refactor: Detect libs only when positioned correctly within .library file --- src/linter/dotLibrary/DotLibraryLinter.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index d0f61d43f..eddc3a996 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -34,11 +34,27 @@ export default class DotLibraryLinter { async #parseDotLibrary(contentStream: ReadStream): Promise { const libs = new Set(); + const tagsStack: string[] = []; + const libNamePath = ["library", "dependencies", "dependency"]; await parseXML(contentStream, (event, tag) => { - if (tag instanceof SaxTag && - event === SaxEventType.CloseTag && + if (!(tag instanceof SaxTag)) { + return; + } + + if (event === SaxEventType.OpenTag && !tag.selfClosing) { + tagsStack.push(tag.value); + } else if (event === SaxEventType.CloseTag && !tag.selfClosing) { + tagsStack.pop(); + } + + if (event === SaxEventType.CloseTag && tag.value === "libraryName") { - libs.add(tag); + const path = tagsStack.slice(-1 * libNamePath.length); + const isMatchingPath = libNamePath.every((lib, index) => lib === path[index]); + + if (isMatchingPath) { + libs.add(tag); + } } }); From d601d2661a2c69af50b05085e39a7374f08e4783 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 13:09:18 +0300 Subject: [PATCH 21/27] fix: Correct Glob pattern for .library files --- src/linter/dotLibrary/linter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linter/dotLibrary/linter.ts b/src/linter/dotLibrary/linter.ts index 911567870..fc13d7ca0 100644 --- a/src/linter/dotLibrary/linter.ts +++ b/src/linter/dotLibrary/linter.ts @@ -18,7 +18,7 @@ export default async function lintDotLibrary({context, workspace}: LinterParamet dotLibraryResources.push(resource); })); } else { - dotLibraryResources = await workspace.byGlob("/src/**/.library"); + dotLibraryResources = await workspace.byGlob("**/.library"); } await Promise.all(dotLibraryResources.map(async (resource: Resource) => { From 6d9f896d29562efa23087400a727949422f3ebe3 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 13:14:39 +0300 Subject: [PATCH 22/27] test: Add test for the additional cases --- .../library.with.custom.paths/src/main/js/.library | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library b/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library index c4f6da4d0..7663d30a6 100644 --- a/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library +++ b/test/fixtures/linter/projects/library.with.custom.paths/src/main/js/.library @@ -4,7 +4,20 @@ SAP SE ${version} ${copyright} + + sap.ui.ca + + sap.ui.ca + + + sap.ui.ca + + + + + + sap.ui.core From e64b03a9674feef7175e420f522e1ea04082f944 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 13:14:51 +0300 Subject: [PATCH 23/27] test: Update snapshots --- test/lib/linter/snapshots/linter.ts.md | 26 +++++++++++++++++++---- test/lib/linter/snapshots/linter.ts.snap | Bin 8524 -> 8695 bytes 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index 157e64de7..d244c7d82 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -854,7 +854,25 @@ Generated by [AVA](https://avajs.dev). { column: 4, fatal: undefined, - line: 12, + line: 16, + message: 'Empty library name', + messageDetails: 'Library definition is provided, but a library name is missing', + ruleId: 'ui5-linter-empty-library-name', + severity: 1, + }, + { + column: 4, + fatal: undefined, + line: 19, + message: 'Empty library name', + messageDetails: 'Library definition is provided, but a library name is missing', + ruleId: 'ui5-linter-empty-library-name', + severity: 1, + }, + { + column: 4, + fatal: undefined, + line: 25, message: 'Use of deprecated library \'sap.ca.scfld.md\'', ruleId: 'ui5-linter-no-deprecated-api', severity: 2, @@ -862,7 +880,7 @@ Generated by [AVA](https://avajs.dev). { column: 4, fatal: undefined, - line: 15, + line: 28, message: 'Use of deprecated library \'sap.ca.scfld.md\'', ruleId: 'ui5-linter-no-deprecated-api', severity: 2, @@ -870,13 +888,13 @@ Generated by [AVA](https://avajs.dev). { column: 4, fatal: undefined, - line: 18, + line: 31, message: 'Use of deprecated library \'sap.ca.ui\'', ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, ], - warningCount: 0, + warningCount: 2, }, { coverageInfo: [], diff --git a/test/lib/linter/snapshots/linter.ts.snap b/test/lib/linter/snapshots/linter.ts.snap index 816c4a8bd7772e745b12b8c2f148313b5d414fe8..d87751570c87a74892b750f31da3a0da8a2a10a4 100644 GIT binary patch literal 8695 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

6wV9$E-bEEFKMj!wR@72eVc_qW2g zTH)DNSl0&Ex51~|1o&hJ{INE8q7DAm1`Q#&I0SDD!8bxs8W!MF9Qz_IVF-s|XBc8( zxH$~p3`5l-0UB^XLyKVPBG|hK5{uyVi{PSVq0%Vy3(s&uny9_p52A!9|t1lBE%N>xWHL!3EY+nPh zHE{D90dlbe@|AV)$U6AtIw)Tc&FcloB@W2q4RG-WIJg1Q8{oDL0%U~)a%dx5u@PRq z5#F&89@r>A+MSV%Ho@sl@R3dM$R>DtlK@%ifIP4n9^4F%Z-(bL!}Kiz@mY19HNyuz#jO&d*I1E0%VH=^0U40>|UtY2MhMWrhNirt8+ZY>ZykcF!?5+R06*Y> z#}0#b82;ffy#FvfbQl_rz~Lis`w;!m@SuVL7VmI33v9dE}t<)#F<+b)x_GBKg(|Uj|2YU=7skev2rhkelsS&L=JU47;$yg-3Xwk(> zE{-mbEbhEy`O;`)iPCxTMQYcw<;xc@Ub zbHeP^68ei`+2v<~Na#qJu(ALX7UvtC87?dfr?PrR4_{S?7vn7qQ%1>$Ed}_H9tj^Z z4nAScJmk^Vw=}G)hG~K6VZA>Q=}Bpc*fo~(gsGsdL6{XI3m39rp}wV|-DV_UONqZU zdAX~=r>)sH8kkr)f0^1&YS-;N$Nkvpmv4$I~aW+D^vTet36 zl|!+8hLSRN_V3?1VEJD=C~$H1-g+(373*#nPW~m7UbS5goaLn6Kv3xGvT<`)+MTgF zoau+z+mM#%=uu7IlRaj-gxH>xs_Pv+>OQ64A~s`J1qU^t>uPGCjgDd3$Z&0+s&@3K zRwElMh6T^P7rRenp1;*BcD6FouI$o`e7#v8SCvFMInYR~Lse2y?POwS|Jr2ItU1n+ zhw~jkEwox_l__Z_A1x}H<;sWO-BiQ5Gnur;LH@VhpDfK+x;u@a~ z!$Qnlo|l=HUrkDFmV?=~;p`33_2WEaW&VYCac~xkm5Z`&Hd>e59oIUQxNK#0>dbob z6l9{nhUr7ukZDqHyJ}>dnQ5#vL~3$ zR6^~twVBl$$}0`Js-z-4yOU}n!+O14Hd1Nzr64-Hx7%`(&Ec4}cFrd$nN>hao;Y8m zB+I+ANJ-jK>+SN{qe%|_3y0;Cs;sMq)nij6WLw z3Bx4IN(-7yp0(-SNo83`vA+95+KHegtCr!GT|kjzy0zgJ5Yp4yqA)sP%Ql{6+<7Ho zg}%lP7GVLaC=zCx*{!B*MAN;!{jKs=`Kq*T$S0MAVdZaCBPVS6YL!p+s3}$6Do2z= zR!L=s`0kw{c~45~R6669?4(rll`C?mYDUeGPb!)8vWmQG@zqRprFkpHT@63*=mXMj4*66VkE-yMKxje^# zH~i?>rHyoOyx4L*mhJiv7A16UG-|HOnjga%+0KMI8FV|STVD023^VkCyig7d8#klJ z=#7uFqisH3iQi2kuRb(^R<2t`IiOQ;2 zzTM%iy=G!}r*Ge&vqD)j&QwS*=@B{FqXq>MA;0X78svh}Z^;Cs->3De1*6f+!ILqg zM@t*#jAQm+4$HY1PA$$*^`+AWg{pTi0+s`73MGHY#G%+uE)K;l*l{R64}1mqDd3Z! zO@gZ>xV1nY2*2d}umtx@@Er+$Z$`d%!4)nzB_=v>rYg)tt}?SM=D2yj#M>P{xbP=k zV-C~xU*{pQ!v`0Be$>PkNFLPWhJ|ie<{m1q`GR(dfw|mk+^}hIVzg|<(&2^vs5>Y0 zce;g8IseZts`1##iMD&-at~-8xYYyqdcfy}(_Z+Rw@_>r-!oqLjTfp)U_l9NDuH*E zz>f;2Gx&3fIRv562kkyM;DZnO;OAmGgE9xyXXYdD!$Lo7_Cv%E|KW!}is=l>9V79= zvD@?d*lm6T@4P>D`yv~>=l7w=7nvF7{jtXJu)SJ`Nd%NV))z7@txzPb8(MEDsTe)O zB-UzMILN*#-2&_a4gnD$0rUem0jGgG3)x+nNM`rgcGrJlM+s{fNbz%EAjQvZk{v7U zVabk_<{L=yvo4$B$1nNJJk>Y4;BFUu(FIStpwSJNh$-}(mfJBmbe@_0u6M)TZup8D zJRWEi)8{#-nzbI->;csSw|L+~9{7m|{whKpQN(<*7tEwV8@$lvg*SNN>t6V&IITLu zf%*I;nJKlk1a_5xQ34+MC6h^nc9kD1eBr}O?%(^;gUIOIL% zX0t4P-x@o8f1T*}Xbnay7Wml)GG?RJ$`Ky}5?#;fu)Ajb19n_*_mtALgY zSXu#>Rlv3i*k1v!s(=#}&?h{gR_w(M74RCN(#$-)m@S4zzO4f8sDQgG;6p+~a-N2o z#GZVz0zM-&Fkf7u`AP*mQUQ+&64w-8CtP zdfOy>1uRqb;YmY7P?y(cKYje0YGFq$TvZFV)WW-K;d^F|!a6X-1cS~T-DV!bJL}+q zI{024{H6{9li`-h@C7l+pmQng$CKfyGu2C`Kwt{2o&v9%0$&o74Eh|KOv0&H?%P3^3DKRMx}7de~eqKpatxy-(J|Gxbo`0Ko>> z&>%n@k&L~+Z-75HK>bX(WF~aX6d;borry8I1Zft`nFW{4f}^tp$TSD!zh}W8XTh{a zSk?%aHwuvH4#RdQ67hX3P?wJdpp9^MW@k8_A zpXLehIS%+I=E1+ugGcAV@8&^u6R1t_o+fy_sbKW!7n;B`9|H4XbvCm22j;^QVpMTQ z^l87;48CS)YKFDVaJ(7*tr>pb3}G>2O)i?>OTeHBO+vh1M*l4JkbKu z0+_u3R*I3t9oc04KUe^dFM#J4!1RT%bRnEx2#+iTf2#m*bFe4a3ZYim(F#4SaMPLV zhg+dsj3_RIlrFfmE;`|iba}3(!17$}Ml;8t9UIF$^ER@@@>M&skf_=fOT?_@yqIn- zboRxfYP8k#ag~)J4V&e?FcfEis!)W0vu>6%z6AVOSeSy}T*Z24` zLY$D!A((@7U9p05$8)~$S&~D!yW=bcBKjOOfa`QIq#!a7i9FRCvVH{vz5P34oqJMh zSL{@Ffo)5yyC)v&?lH#MDLNlN#4zsTa*TL{{1|68Wci0ePW3NMTr& zS|%<$cOf4AeUZX*ci3z?8+*o;1#P2efpl%LIpBEx6E;Gc3Xp!XDB4lWMFO?7qo%7F zTVZSmKg6%ck=n=wLS9Lm3Y}HReq0WXDF3oL1~OXK7KnaWzOpG5gn%ozY9_F$LX6t!-dStaIj`f*36Mn4(meB{woWf zl}pDmA@H*i@CO3jpXUR6d@|e>nkmkg40k!7>+soqu4U8b+RFXVWo>cjNhP8>-L6X- z$MaZQi3F_@L?w82;bU!gOK`6Q4@vNI2`XK%$px2}9_ZAB7 z%XjIXaL-p@-mC{mcwM;@cA9)Z8)OIVn5?}97%HJJ} ztGg7vH~*lrfJ0`3{#QYR{C#RVt@NmAp_Zy+N-7ac^bCHHUn>8Y1oudAzXT6S@Er-B zl;9Z&UXb8#(qR6&2l3ZGD6dN7z2D@$*Jbj)Qj*Sfk?)Ypjik#=-fAS>X7X_(=`oWY zH%MMHd5)1RGn1DYNuSYj?+4xR5jQ;KhNs=|-)^A;J%c;YFL@vKz&AbcTMziXFvlxE zyf(;@GKiGHb!BjS8GNBkfRx!FFIK?cE1;hMTJ4&T0YT zw?Pioz@;_th8p-_4g8-P0a9**#A-pSg%h=KcP)IQR)AF4AaALI6Ls*ZI(W1Wo~;ug zm9|mh5d}D+=xUFa>d%Uu(f@<;%OYAl)0fEQ&K7b#@mNC5<++7CUryL_zg-_?Uqb1M ztFo@iNf6$Pq0QkID&6m%CIss_JU0FP2cFC18_?E@V@g1DmEwC16vxmRhewdQZiw(9!IZ zbSPIa7|a)HlUJTEUsWL&{KdLuD?4;FmW~;%Te)(j+^xjZYMW5n_)|8;qER)mKmV3w zCfz$w#pP;$+loP$tF2#S+%XkJI;P5@W2SgY(J`^OuBNj6qHKt($Frj|9m-||gW3i& zp+*NXg)Rw)<-NVC+^xmq+Ob%oM>gkbIo)e=Et%4ynTRSYa(?oYb98hT)=(Z8H8Fw0 z`Zj6D)T3&u-7GuMG=shJv6xwxtf!Pjx?4;2sZry#fr~<+&=Gm19K1?4lL7fyOz$nM zHKECAEt86RikoON{L*q>S;Ncju`_xrpr-HO`F1_9*?DU zgVWhM+Cqa_7)#4ZEv=>vR`n|JxSHru&DwXXNiC(TsgRyF+G)I6*UWcDv{Xus=yF_( zD0)mw7?m5(bB#1?0qY$REs@scbWZ38RL@FbyoAHDnvTa3dPg*tHoBxEp&r*eOwL7= zJ~bXu(&`{YL{G&p&5htrIcSQ zPjr0&Oe^AZlG3OP3!p&D3Q`sCa!Ld=6_Dl#FiRnims+Q5?aSV%Q}=~Ocb}Y z@v#)s`v-*9k(K@tva;TRmCM%}x=7awdD)#wM9lA-Rz=s9Nbg=H`AXtuPT8d`Ww$G? z#1dQf45{wQE*TSb_wp=S+ZNqMsO~BTIAk`cXN(k{$53{+Nbs)`e9B4bWmla)Zz;XM zO4b7Pxw!>uzvMsWf~#HdeiwYs1>bi;yBmzf=sTSC-y?4LmK&aRgVzJIJaDB4?)ShS z9rT}H@;7*4nitOT!X7VZUU48#>^mg*!0@c@JFN-mR|8geiwowvV6zLJLJaFrHS>5HYv7tGJR(IuVZ_damx|F5p_U_phyL@O*5zm*$MAubI&^laQ zw`II_UAe^|vpwBorS48h@Gc2%8=kuRgr)AD9Z+{c7ld4}%>}(KxZVXna=}zL>~U6i zX*cw{;XQ8ntQ#J4L(l`=Ck^h~$4lKgjnT8}ZrH38^IkjZ?x>~i_9cwv)`+e~hg5lP z-qU2!$7^{F8xnY53l zOEwgYriLVN^yH6gfSZ7K1GfX81U?6R1$Y$rVa`tYPvEbBM}k@j8YO6vV1eW?A}5&g zvcj4nj}ELz-78rxlg~+(%Vg_-%Vd|!a+&;~%W|3gp)2b$St&^kZt_l4itV@Mka7iHlY)aW?lYE`#M|aG(s1m%*)N@Vzp4&e8kQSL=gGK3MF7eLlF#2VeBT zlRhW^NZ(67aQQ*@!x}&I`r(s)_^Mxk*4m)Y`r!pXRF^}j9QKyO`^w?7=6>y?LfKIbPKT`qsSHKe$@RtghQ3;n;Lci#7I^72SKqY**624Rk zKd%IT6|Ag+162ZarVV;!6R|pomc1Epet%%b22yas3aczs1NhQ?&JiVFG z)BE<3(ra6(7$L!Jry^KODtpzmo(^4+NyIF3= zUDgQ6#$x-BgDdbA$@7bqU)c!P2$ffeyP-EW!rL0*7NKC3Sn!TUxT_KVO(<9=7W`5p ze6)f()KAu@}?HaYb=u2R3vXkk-X+2d9pxk*;9@1bR+z(5&ql=QWI1)4JLe+ z*fCR@V1`gASmdqqisZEy$?FhaT+`YF9Zhgf6Rc^1?M-m72_j99XoCJGxV{NaG{G%R za7Pn-T4-pv$O~5%$-6-GeSM$_zT5=gYJw+(m#h*Bd!KHCUpK*jHNi_w;F~@eu)fHf zw}=utVLD8m4gsN(ZAB{CStRemB6+)u#<&?~hx*vpYXOo}S+sYMPPV8M3kt&&X%JRm}R5mG#eo ztn5zF`OW#P{$^{d>Aq%btLcSiYpZGA%jTW)dmzS()euV-5v&Azd5PCo0<9ILMP z&avK@t>F7ssR=E4Cm7#_EpVU(GA;1-7P$Ll`o$JlGS@Ls$=dE@^`++u-|cP(Kg0%@g1? zwg$)NL24enV;+3^B;?y7q}~R(c0T;i`Eciacw|02Jzs!Kur=~+?eOk)xUU_)+YZmQ z!oo$0ITL|YZgu@Hr=t6kMLTFtCU5fJ+D~sSKi{QG&@Ze$r+G2zLWHCIm7+g!Bc?onbfzK>~=a&f3xwd|- zUJ4CMVewM9a4GaH6(DUkNbNG1v<#LmgFVYYTP8pj*dU(eP_Z25Er(6ZA-Y_EEVMxq zouGHZ&7JU>PWVoz09j;%ylVx#e+4|S0-js}FRl6j5vfKtaxE?N953gSjA6O6f zuNNSl_DDt>;KT;_)CPET13bGyfUK}V?%xOxZiJs~gqJqL)J+29Je$7w;wE@x6Z~Qm z{BsjDZHDw_xOX!=w^@L%w!y2mz=SQZU<+*90=-+{!7cF87C2|C0AFJpf(N$3k*#pm zR(Q`=`0Q42Z-dTl0(7m7*2CN2b=%;YZE)*J$md1K1{>s(9T43C*YAK2?|=t)2#}37 z$o0G6#$E7WkU3> z6&?CMQKF~;#@@4<(ATMnbWHCzH}yv?G!s`%*$MZB*C>(8ds12^5nZRIV?D$5 zDOR?}%$52?kG$G?%dYGTwwo_V%fVhid0eo*B#crI@kcAco4hRe;c12^Y6*maqhF=6&; ziS)~2*%fDkNa%2xu)=`}3yY1;EEkrBQ#n184qxWPi?J4lNh9RLCI>!bhQo)fgHKp9 z4taDOT@p^Kx?zE(!|DD+q&KA{Vpp2Z6NZ8|2VqW(OkBu>g^n%>?KC0*n@aqZ$;%xM zli&4>fSDafV@ijS-eZc|E1kC^Ra(0pre4I5c214Hm@fLVbtAJ$_R z4$vuP^|ht2#dK|7GO4E4D(RdRc2tRH)KJ0WF%I}Ax>lSH2Xt3yg0SYi;DUiY*>KKU zQq6`KHvIwRXiSM~J%RQCn?C>84Ssgb{JH$II&D{y77-3m%pU#LJH#Rwi!v0uk1afF4lI7EB zX`OLnlxTN~jQVs*S9sL$=Cv$7RFwof(~mD#iw`RZiSY<9r*jxjbCM{y~K>yGh|f!qmZ<0_#} z+1$+P3l)`yw5p^cy*ra?BFp-8r>v(k>MKEXc5b!gBzK2n&e}PXq-2JJlstW=NJ)-& zr;w72sn$E?Q%935{0oQWW2&51b+g5WNXT88bbq^?){KmVn!P>rij11-H;W{dl$y{D zvdn8ilgU$7y)&sS4Jqb#e@MGLXv(T-xaAg5|6(^{f1GGWVAo@3k@C1Flq zV+TsGfK?I+GtBIELpGwBzP|o;d9!?3CaufIl!R{H->OC~x8$o`KGv(IRC%);Q4%>N zl^x%@XP zWCyj_c>iz(Ja-3aREuQHyO>Q$&fodBIvx)O3{T?ixiQriGA^dod(8`%7o3({p60+C zdUWj2hC4W3Zn+-KcKux?37s2_8mqF#$8c7*v!PB39tYE=SN(C_2)!WBmjgq_&FIzp z;$!S+TZ~uYcazAgd&h}aMS=qji(_N+aqV=q(%Fye5;F7b$92hAc}9I)7ndecS(VDS zJG{BixY*t9+gET_C}+kQ3h5O+B1d}Ez~Lg~SKU#Ad@%Y=*hvLh?*MMIFJ_$M` zxI%)P9PWYeOTK#~xKD!bN$@8l^1TZ#alvu%q67O?h1tke#x09^Zk{Rec83lw{5jXC z!*u=Z3?z2w;KDDBm{^C)gIe4$-wjLMgXOhY&@M4BmwS~PHWXfrmMd63w9sGV&I|o5 zZXs08|FyE}Jl5qzTRm{02Q&}dFMQMM6r08OTQB_H3pHghuM9Sn!EI&m zBj@W3{#IrTL1^|trw{h~;FCW1wRoLDg$?R6?j!KSd_QdTL&OjN?uWmK*BMmWM&j9H zw`cUR+u{b^8Gr2dWj1)v>_d?+Gc(TkV~t~Bd$kX75m4?}U&yeuLXk{b*ZM+9MeiNr zVy(766xdhgn}8j_K_CJofPUb5-~@1sliih#WOj#Tcl``2N?6mt6+in2uK0PoWW`GR zwq(Uh^9@|_vnF@Nk6-c`_f%i!g44g?Ato4HGg`09y>NDcBYQJ>H zR|eH(Fux48mqGgE^!kZ1cvzfP?bqM@x(uE#gGwKC_+XC@-sXc(h|{V)FxR6ei+|q- z|78^Q!*V|){cxi=t=i&T`R?|^XZ`TFAO7fvY2~n{94;1b32HxuZTyDvagNbDF`bHp z`;=HBd|5givW~_YW_$Uljp474l)4fH<(*zgTvj`6P>eNmD?a)&qbHJzaSnH1NaXtC zN?&r|-ielqQIofNq~w+ABA@0V=-aI(qH1d3Tjoupr}M56(^;aCIH(`dEjhLe1YY3i)E8&}! z@E?`%)5_tmBa|1(6XSZjep?B@7b>qRQbCPSLB-!Hfhwq|f=N{%SHb)$SXKqAt6*E< z{d=c~1@7vqf?lCev6$U6L|&z;;CL0hu?pTQR8%Zb_iV8x@6Fu-SXgL|xG?jvD!8W# z?iUKSinTpd1>X<~6^qg>M&fpTzY3ldDhP?Tch;c(MOEJRZmza$??csAgx>6fo2&ED zjk5uVzgC?`{cQl%QDa%`udA^v_IK7;7W-FgEQ|fGHI~KRUTZ}+zO*(Q-Pn5XJ8JXq z%~tk!t+gUmXT5i4ozU7F>jnpk{zhFM^-`U+#FZ@?t{)s@I#Hj$|M%nd@Tq!uv>u+V z2k!*fH34oCFCMh7aosfm?wtUSO@QA`0AB;_Zh*In7Z2LkxbAL%&o+Q@0parvP(BfM zOoX?H7Z3VGsQ2R&;Zqagv5D~fNl3YP;h-&SvG z`ZV~>G$?C?K%)S$g(UXg-v|#j!cQ9ErACe zj(`A{ZBqY80KOG~X9M7!4YOv$6|>=EvjylZ+nc{W8@@9eo|_H+IWT7qTs;RKm;-;F z;}ogcJGlj>x4?NVaJU7Iwg`}*4f5f+@Ugk@^||n?x!`JbiqP!8trhNQg@;<*e! zR@fhen}hI}7+u_c-|GuOc+n`<2H`f?+6M1zgYUHo(C}%77#00ohPwh*<*))a-ysxL zLW-yU z)AhQ*ozr?Yj_1Cde5K!93NJRp|Is|mnk7Ef7qXrN1JT&gKzrVKb!-_SZUCOfnRMyu zQpFgK=UsYpB!}`($5;wPbRqFG9i-qyDWo7W5KuYQ7czeZ1AYD5VqLpZYIp2-ZlPdP ztfw~~>*>|U*tfG7Kg4L%V{#gDnEV)HHWX71vmM67(Gux~^@->p&9FWZ9Y>WYIs%BD z|B;eJZBvgAXhY*i(1;ss=z_h*kHG33hc4Z_{@~s~o8i;jDF@{Fa)H7y3$=}3lwl_x zy|F}5hWA=*Iu(1ylm#6lXMuE8sX1Wl{&5>2Ee@m~D~Wd0@&OG^?Wm>ItgSFQ|Mi9u z+Q<%(d!!9cF4x<#7W3f1*sm&Y_K~vI=>x2|6Gki%%k%bC#ZA#qr&Qd04W11csbjno zD_=op14IMARIvwMt#RMS?%0@v|DCI{6o-?OaV4Uz&e;vdsqfskMDFCMVQ+TIf&2$X z_84Tu_y+CFmo&dfL)N!gwn#E1oQqVCstLXDaHJAfQ+oEXA@$ja*}=Bl*~hCZu5JtE z+7>kJ86)J?*xE6o|7T%eh>|}>-~3rFWIMygno(IZhetT9oqU#8I3D@Q#IljRbAh}E z;&q?l1AA;P>T;SX&XkL~@~)%dQ@f7JhU=&q!oJ%KB9~4o5!LQJTGl+4r*q0AXqO-= z!Rwt*=iDyAof14E!LKE#cEJW0yiPow;~i>O#qcN@>4B9Jxvxzz9A=DR)g9hucCT@2 zH}5fX+vpGEJTTq|a;BQzK&PVc2V-*zXV?xiWukuvZYXm@opA8RH?%xAS*L3byRFkT z?{mX#Zuo*5o^->DZn(e$S9{=oN9SYz4?XacoU`#%FD&uG4PJQ23;z(kh|5p&tjkC( zVkdKOp5wgH9bSD@(UsI0K23}b`@~Hs+m$!NIBC01(bc`NK6P^ Date: Mon, 29 Jul 2024 16:49:02 +0300 Subject: [PATCH 24/27] refactor: Provide correct ruleId --- src/linter/dotLibrary/DotLibraryLinter.ts | 2 +- test/lib/linter/snapshots/linter.ts.md | 6 +++--- test/lib/linter/snapshots/linter.ts.snap | Bin 8695 -> 8694 bytes 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index eddc3a996..54bc2589c 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -86,7 +86,7 @@ export default class DotLibraryLinter { if (deprecatedLibraries.includes(libName)) { this.#context.addLintingMessage(this.#resourcePath, { - ruleId: RULES["ui5-linter-no-deprecated-api"], + ruleId: RULES["ui5-linter-no-deprecated-library"], severity: LintMessageSeverity.Error, fatal: undefined, line: line + 1, diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index d244c7d82..52a1ce675 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -874,7 +874,7 @@ Generated by [AVA](https://avajs.dev). fatal: undefined, line: 25, message: 'Use of deprecated library \'sap.ca.scfld.md\'', - ruleId: 'ui5-linter-no-deprecated-api', + ruleId: 'ui5-linter-no-deprecated-library', severity: 2, }, { @@ -882,7 +882,7 @@ Generated by [AVA](https://avajs.dev). fatal: undefined, line: 28, message: 'Use of deprecated library \'sap.ca.scfld.md\'', - ruleId: 'ui5-linter-no-deprecated-api', + ruleId: 'ui5-linter-no-deprecated-library', severity: 2, }, { @@ -890,7 +890,7 @@ Generated by [AVA](https://avajs.dev). fatal: undefined, line: 31, message: 'Use of deprecated library \'sap.ca.ui\'', - ruleId: 'ui5-linter-no-deprecated-api', + ruleId: 'ui5-linter-no-deprecated-library', severity: 2, }, ], diff --git a/test/lib/linter/snapshots/linter.ts.snap b/test/lib/linter/snapshots/linter.ts.snap index d87751570c87a74892b750f31da3a0da8a2a10a4..5192d15b191d00ad4facb0562e536bb81bacf93f 100644 GIT binary patch literal 8694 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 UJ(fu6=Pnoj7hfO*`cTFI05eJCH2?qr literal 8695 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

6wV9$E-bEEFKMj!wR@72eVc_qW2g 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 Date: Mon, 29 Jul 2024 16:51:44 +0300 Subject: [PATCH 25/27] refactor: Remove trim from the check --- src/linter/dotLibrary/DotLibraryLinter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index 54bc2589c..f9205fe38 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -82,7 +82,7 @@ export default class DotLibraryLinter { return; } - const libName = lib.textNodes[0].value.trim(); + const libName = lib.textNodes[0].value; if (deprecatedLibraries.includes(libName)) { this.#context.addLintingMessage(this.#resourcePath, { From c76dce5a85ea952a7e465c87fba4f41650f88bcd Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 16:54:38 +0300 Subject: [PATCH 26/27] refactor: Remove empty lib check --- src/linter/dotLibrary/DotLibraryLinter.ts | 20 ++------------------ src/linter/linterReporting.ts | 4 ---- test/lib/linter/snapshots/linter.ts.md | 20 +------------------- test/lib/linter/snapshots/linter.ts.snap | Bin 8694 -> 8524 bytes 4 files changed, 3 insertions(+), 41 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index f9205fe38..44ac748db 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -65,24 +65,8 @@ export default class DotLibraryLinter { // Check for deprecated libraries libs.forEach((lib) => { const {line, character: column} = lib.openStart; - - // Check for missing textNodes or for empty textNodes withing the - // libraryName tag - if (!lib.textNodes[0] || lib.textNodes[0].value.trim() === "") { - this.#context.addLintingMessage(this.#resourcePath, { - ruleId: RULES["ui5-linter-empty-library-name"], - severity: LintMessageSeverity.Warning, - fatal: undefined, - line: line + 1, - column: column + 1, - message: formatMessage(MESSAGES.SHORT__EMPTY_LIBRARY_NAME), - messageDetails: formatMessage(MESSAGES.DETAILS__EMPTY_LIBRARY_NAME), - }); - - return; - } - - const libName = lib.textNodes[0].value; + // textNodes is always an array, but it might be empty + const libName = lib.textNodes[0]?.value; if (deprecatedLibraries.includes(libName)) { this.#context.addLintingMessage(this.#resourcePath, { diff --git a/src/linter/linterReporting.ts b/src/linter/linterReporting.ts index 0e2d86651..4e1abb27f 100644 --- a/src/linter/linterReporting.ts +++ b/src/linter/linterReporting.ts @@ -29,9 +29,6 @@ export const MESSAGES = { SHORT__DEPRECATED_LIBRARY: "Use of deprecated library '{0}'", SHORT__DEPRECATED_MODEL_TYPE: "Use of deprecated model type '{0}'", - - SHORT__EMPTY_LIBRARY_NAME: "Empty library name", - DETAILS__EMPTY_LIBRARY_NAME: "Library definition is provided, but a library name is missing", }; // TODO: Migrate to enum instead of Object/Map @@ -45,7 +42,6 @@ export const RULES = { "ui5-linter-parsing-error": "ui5-linter-parsing-error", "ui5-linter-no-deprecated-library": "ui5-linter-no-deprecated-library", "ui5-linter-no-deprecated-component": "ui5-linter-no-deprecated-component", - "ui5-linter-empty-library-name": "ui5-linter-empty-library-name", }; export function formatMessage(message: string, ...params: string[]) { diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index 52a1ce675..c01d6fc7f 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -851,24 +851,6 @@ Generated by [AVA](https://avajs.dev). fatalErrorCount: 0, filePath: 'src/main/js/.library', messages: [ - { - column: 4, - fatal: undefined, - line: 16, - message: 'Empty library name', - messageDetails: 'Library definition is provided, but a library name is missing', - ruleId: 'ui5-linter-empty-library-name', - severity: 1, - }, - { - column: 4, - fatal: undefined, - line: 19, - message: 'Empty library name', - messageDetails: 'Library definition is provided, but a library name is missing', - ruleId: 'ui5-linter-empty-library-name', - severity: 1, - }, { column: 4, fatal: undefined, @@ -894,7 +876,7 @@ Generated by [AVA](https://avajs.dev). severity: 2, }, ], - warningCount: 2, + warningCount: 0, }, { coverageInfo: [], diff --git a/test/lib/linter/snapshots/linter.ts.snap b/test/lib/linter/snapshots/linter.ts.snap index 5192d15b191d00ad4facb0562e536bb81bacf93f..5e688adcf45fd1fd3fbe9e43f28e3e4f200f518f 100644 GIT binary patch literal 8524 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 G!vFvt*th8b literal 8694 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 UJ(fu6=Pnoj7hfO*`cTFI05eJCH2?qr From 3971889e0f78ed9ba99912844484cb8998d897c6 Mon Sep 17 00:00:00 2001 From: Yavor Ivanov Date: Mon, 29 Jul 2024 17:00:02 +0300 Subject: [PATCH 27/27] refactor: Remove slicing from stack check --- src/linter/dotLibrary/DotLibraryLinter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/linter/dotLibrary/DotLibraryLinter.ts b/src/linter/dotLibrary/DotLibraryLinter.ts index 44ac748db..364919db1 100644 --- a/src/linter/dotLibrary/DotLibraryLinter.ts +++ b/src/linter/dotLibrary/DotLibraryLinter.ts @@ -49,8 +49,8 @@ export default class DotLibraryLinter { if (event === SaxEventType.CloseTag && tag.value === "libraryName") { - const path = tagsStack.slice(-1 * libNamePath.length); - const isMatchingPath = libNamePath.every((lib, index) => lib === path[index]); + const isMatchingPath = libNamePath.length === tagsStack.length && + libNamePath.every((lib, index) => lib === tagsStack[index]); if (isMatchingPath) { libs.add(tag);