From 156e7470c0fb2665b97319f89a6a076548a7bd5f Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Tue, 3 Dec 2024 16:11:45 +0100 Subject: [PATCH] fix: Detect deprecations in new expressions with ID This solves the gap of not detecting usage of deprecated UI5 metadata (e.g. properties, aggregations, events) when using the constructor with an ID as first argument. --- src/linter/ui5Types/SourceFileLinter.ts | 73 ++++++++++-------- src/linter/ui5Types/utils.ts | 16 ++++ .../rules/NoDeprecatedApi/NoDeprecatedApi.js | 8 ++ .../NoDeprecatedApiTypeScript.ts | 10 ++- .../rules/snapshots/NoDeprecatedApi.ts.md | 36 ++++++++- .../rules/snapshots/NoDeprecatedApi.ts.snap | Bin 16459 -> 16647 bytes 6 files changed, 108 insertions(+), 35 deletions(-) diff --git a/src/linter/ui5Types/SourceFileLinter.ts b/src/linter/ui5Types/SourceFileLinter.ts index d11d650dd..26c45b725 100644 --- a/src/linter/ui5Types/SourceFileLinter.ts +++ b/src/linter/ui5Types/SourceFileLinter.ts @@ -1,4 +1,4 @@ -import ts, {Identifier, SymbolFlags} from "typescript"; +import ts, {SymbolFlags} from "typescript"; import path from "node:path/posix"; import {getLogger} from "@ui5/logger"; import SourceFileReporter from "./SourceFileReporter.js"; @@ -6,7 +6,7 @@ import LinterContext, {ResourcePath, CoverageCategory} from "../LinterContext.js import {MESSAGE} from "../messages.js"; import analyzeComponentJson from "./asyncComponentFlags.js"; import {deprecatedLibraries, deprecatedThemes} from "../../utils/deprecations.js"; -import {getPropertyName} from "./utils.js"; +import {getPropertyName, getSymbolForPropertyInConstructSignatures} from "./utils.js"; import {taskStart} from "../../utils/perf.js"; import {getPositionsForNode} from "../../utils/nodePosition.js"; import {TraceMap} from "@jridgewell/trace-mapping"; @@ -680,38 +680,47 @@ export default class SourceFileLinter { this.#analyzeNewOdataModelV4(node); } + if (!node.arguments?.length) { + // Nothing to check + return; + } + // There can be multiple and we need to find the right one - const [constructSignature] = classType.getConstructSignatures(); - - node.arguments?.forEach((arg, argIdx) => { - const argumentType = constructSignature.getTypeParameterAtPosition(argIdx); - if (ts.isObjectLiteralExpression(arg)) { - arg.properties.forEach((prop) => { - if (ts.isPropertyAssignment(prop)) { // TODO: Necessary? - const propNameIdentifier = prop.name as Identifier; - const propText = propNameIdentifier.escapedText || propNameIdentifier.text; - const propertySymbol = argumentType.getProperty(propText); - - // this.checker.getContextualType(arg) // same as nodeType - // const propertySymbol = allProps.find((symbol) => { - // return symbol.escapedName === propNameIdentifier; - // }); - if (propertySymbol) { - const deprecationInfo = this.getDeprecationInfo(propertySymbol); - if (deprecationInfo) { - this.#reporter.addMessage(MESSAGE.DEPRECATED_PROPERTY_OF_CLASS, - { - propertyName: propertySymbol.escapedName as string, - className: this.checker.typeToString(nodeType), - details: deprecationInfo.messageDetails, - }, - prop - ); - } - } - } - }); + const allConstructSignatures = classType.getConstructSignatures(); + // We can ignore all signatures that have a different number of parameters + const possibleConstructSignatures = allConstructSignatures.filter((constructSignature) => { + return constructSignature.getParameters().length === node.arguments?.length; + }); + + node.arguments.forEach((arg, argIdx) => { + // Only handle object literals, ignoring the optional first id argument or other unrelated arguments + if (!ts.isObjectLiteralExpression(arg)) { + return; } + arg.properties.forEach((prop) => { + if (!ts.isPropertyAssignment(prop)) { + return; + } + const propertyName = getPropertyName(prop.name); + const propertySymbol = getSymbolForPropertyInConstructSignatures( + possibleConstructSignatures, argIdx, propertyName + ); + if (!propertySymbol) { + return; + } + const deprecationInfo = this.getDeprecationInfo(propertySymbol); + if (!deprecationInfo) { + return; + } + this.#reporter.addMessage(MESSAGE.DEPRECATED_PROPERTY_OF_CLASS, + { + propertyName: propertySymbol.escapedName as string, + className: this.checker.typeToString(nodeType), + details: deprecationInfo.messageDetails, + }, + prop + ); + }); }); } diff --git a/src/linter/ui5Types/utils.ts b/src/linter/ui5Types/utils.ts index 98ec56f5f..5aa2fcb08 100644 --- a/src/linter/ui5Types/utils.ts +++ b/src/linter/ui5Types/utils.ts @@ -7,3 +7,19 @@ export function getPropertyName(node: ts.PropertyName | ts.Expression): string { return node.getText(); } } + +export function getSymbolForPropertyInConstructSignatures( + constructSignatures: readonly ts.Signature[], + argumentPosition: number, + propertyName: string +): ts.Symbol | undefined { + for (const constructSignature of constructSignatures) { + const propertySymbol = constructSignature + .getTypeParameterAtPosition(argumentPosition) + .getProperty(propertyName); + if (propertySymbol) { + return propertySymbol; + } + } + return undefined; +} diff --git a/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js b/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js index 78b9a6b2b..a5801731c 100644 --- a/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js +++ b/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js @@ -48,4 +48,12 @@ sap.ui.define([ const navigationHandler = new NavigationHandler({}); navigationHandler.storeInnerAppState({}); // Method "storeInnerAppState" is deprecated + + // Detection of deprecated API in constructor when an ID is passed as first argument + var btn2 = new Button("btn2", { + blocked: true, // Property "blocked" is deprecated + tap: () => console.log("Tapped"), // Event "tap" is deprecated + + ...moreArgs // Should be ignored + }); }); diff --git a/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApiTypeScript.ts b/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApiTypeScript.ts index f0936fc1d..f2d57408c 100644 --- a/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApiTypeScript.ts +++ b/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApiTypeScript.ts @@ -12,7 +12,7 @@ import {InputType} from "sap/m/library"; var dateTimeInput = new DateTimeInput(); // Control is deprecated. A finding only appears for the module dependency, not for the usage. var btn = new Button({ - blocked: true, // Property "blocked" is deprecated + "blocked": true, // Property "blocked" is deprecated tap: () => console.log("Tapped") // Event "tap" is deprecated }); @@ -43,3 +43,11 @@ InputType.Date; // Enum value "InputType.Date" is deprecated const navigationHandler = new NavigationHandler({}); navigationHandler.storeInnerAppState({}); // Method "storeInnerAppState" is deprecated + +// Detection of deprecated API in constructor when an ID is passed as first argument +var btn2 = new Button("btn2", { + blocked: true, // Property "blocked" is deprecated + "tap": () => console.log("Tapped"), // Event "tap" is deprecated + + ...moreArgs // Should be ignored +}); diff --git a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md index c17db1388..76aa81e7c 100644 --- a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md +++ b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md @@ -870,7 +870,7 @@ Generated by [AVA](https://avajs.dev). [ { coverageInfo: [], - errorCount: 23, + errorCount: 25, fatalErrorCount: 0, filePath: 'NoDeprecatedApi.js', messages: [ @@ -1058,6 +1058,22 @@ Generated by [AVA](https://avajs.dev). ruleId: 'no-deprecated-api', severity: 2, }, + { + column: 3, + line: 54, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, + { + column: 3, + line: 55, + message: 'Use of deprecated property \'tap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, ], warningCount: 0, }, @@ -1070,7 +1086,7 @@ Generated by [AVA](https://avajs.dev). [ { coverageInfo: [], - errorCount: 18, + errorCount: 20, fatalErrorCount: 0, filePath: 'NoDeprecatedApiTypeScript.ts', messages: [ @@ -1218,6 +1234,22 @@ Generated by [AVA](https://avajs.dev). ruleId: 'no-deprecated-api', severity: 2, }, + { + column: 2, + line: 49, + message: 'Use of deprecated property \'blocked\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, + { + column: 2, + line: 50, + message: 'Use of deprecated property \'tap\' of class \'Button\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, ], warningCount: 0, }, diff --git a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap index d9d1177f11d4c730d377b1ce2c89e54880a02254..99323e5847ad7b86b25eb86d55ad5862876b48c3 100644 GIT binary patch literal 16647 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 literal 16459 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