diff --git a/src/linter/ui5Types/SourceFileLinter.ts b/src/linter/ui5Types/SourceFileLinter.ts index e8cf7a6c4..8667a2dda 100644 --- a/src/linter/ui5Types/SourceFileLinter.ts +++ b/src/linter/ui5Types/SourceFileLinter.ts @@ -712,6 +712,38 @@ export default class SourceFileLinter { if (!propertySymbol) { return; } + + const propertyType = this.checker.getTypeOfSymbol(propertySymbol); + + if (propertyType.isUnion()) { + const valueType = this.checker.getTypeAtLocation(prop.initializer); + if (valueType?.isStringLiteral()) { + for (const type of propertyType.types) { + // Find out whether the value is assignable to one of the types + if (!this.checker.isTypeAssignableTo(valueType, type)) { + continue; + } + // If the type is just a string literal (no enum value), we need to look for a matching + // enum value in the list of types to check for its deprecation + if (!(type.flags & ts.TypeFlags.EnumLiteral) && type.isStringLiteral()) { + const enumType = propertyType.types.find((t) => { + return t.symbol?.name === type.value; + }); + if (!enumType) { + continue; + } + const deprecationInfo = this.getDeprecationInfo(enumType.symbol); + if (deprecationInfo) { + this.#reporter.addMessage(MESSAGE.DEPRECATED_PROPERTY, { + propertyName: type.value, + details: deprecationInfo.messageDetails, + }, prop); + } + } + } + } + } + const deprecationInfo = this.getDeprecationInfo(propertySymbol); if (!deprecationInfo) { return; diff --git a/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js b/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js index 5644014b0..2a28bcf6f 100644 --- a/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js +++ b/test/fixtures/linter/rules/NoDeprecatedApi/NoDeprecatedApi.js @@ -1,7 +1,8 @@ sap.ui.define([ "sap/m/Button", "sap/m/DateTimeInput", "sap/base/util/includes", "sap/ui/Device", "sap/ui/core/library", "sap/ui/generic/app/navigation/service/NavigationHandler", - "sap/ui/table/Table", "sap/ui/table/plugins/MultiSelectionPlugin", "sap/ui/core/Configuration", "sap/m/library" -], function(Button, DateTimeInput, includes, Device, coreLib, NavigationHandler, Table, MultiSelectionPlugin, Configuration, mobileLib) { + "sap/ui/table/Table", "sap/ui/table/plugins/MultiSelectionPlugin", "sap/ui/core/Configuration", "sap/m/library", + "sap/m/Input", "sap/m/TileContent", "sap/ui/layout/form/SimpleForm", "sap/m/ResponsivePopover" +], function(Button, DateTimeInput, includes, Device, coreLib, NavigationHandler, Table, MultiSelectionPlugin, Configuration, mobileLib, Input, TileContent, SimpleForm, ResponsivePopover) { "use strict"; var dateTimeInput = new DateTimeInput(); // Control is deprecated. A finding only appears for the module dependency, not for the usage. @@ -77,4 +78,25 @@ sap.ui.define([ // (via local function name) const sapUiXmlView = sap.ui.xmlview; const view3 = sapUiXmlView("com.ui5.troublesome.app.view.MyView"); + + const simpleForm = new SimpleForm({ + layout: "ResponsiveLayout" // SimpleFormLayout.ResponsiveLayout is deprecated + }); + + const tileContent = new TileContent({ + frameType: "TwoThirds" // FrameType.TwoThirds is deprecated + }); + + const input = new Input({ + type: "Date" // InputType.Date is deprecated + }); + + const simpleForm2 = new SimpleForm({ + layout: "ResponsiveGridLayout" // Negative test: ResponsiveGridLayout is not deprecated + }); + + const responsivePopover = new ResponsivePopover({ + // ui5lint-disable-next-line no-globals + placement: sap.m.PlacementType.Auto // Negative test: PlacementType.Auto is not deprecated + }); }); diff --git a/test/fixtures/linter/rules/NoDeprecatedApi/XMLView.view.xml b/test/fixtures/linter/rules/NoDeprecatedApi/XMLView.view.xml index 17d3b792c..a83f5a0be 100644 --- a/test/fixtures/linter/rules/NoDeprecatedApi/XMLView.view.xml +++ b/test/fixtures/linter/rules/NoDeprecatedApi/XMLView.view.xml @@ -3,6 +3,7 @@ xmlns:core="sap.ui.core" xmlns:table="sap.ui.table" xmlns:tablePlugins="sap.ui.table.plugins" + xmlns:form="sap.ui.layout.form" > @@ -41,4 +42,17 @@ + + + + + + + + + + + + + diff --git a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md index 13ebfdb41..3062932f5 100644 --- a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md +++ b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md @@ -1067,7 +1067,7 @@ Generated by [AVA](https://avajs.dev). [ { coverageInfo: [], - errorCount: 33, + errorCount: 36, fatalErrorCount: 0, filePath: 'NoDeprecatedApi.js', messages: [ @@ -1105,7 +1105,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 3, - line: 9, + line: 10, message: 'Use of deprecated property \'blocked\' of class \'Button\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1113,7 +1113,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 3, - line: 10, + line: 11, message: 'Use of deprecated property \'tap\' of class \'Button\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1121,7 +1121,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 6, - line: 13, + line: 14, message: 'Call to deprecated function \'attachTap\' of class \'Button\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1129,7 +1129,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 3, - line: 18, + line: 19, message: 'Use of deprecated property \'plugins\' of class \'Table\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1137,7 +1137,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 3, - line: 21, + line: 22, message: 'Use of deprecated property \'groupBy\' of class \'Table\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1145,7 +1145,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 24, + line: 25, message: 'Call to deprecated function \'includes\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1153,7 +1153,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 27, + line: 28, message: 'Call to deprecated function \'getIncludesFunction()\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1161,7 +1161,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 16, - line: 29, + line: 30, message: 'Call to deprecated function \'getCompatibilityVersion\' of class \'Configuration\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1169,7 +1169,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 16, - line: 30, + line: 31, message: 'Call to deprecated function \'getCompatibilityVersion\' of class \'Configuration\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1177,7 +1177,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 32, + line: 33, message: 'Use of deprecated property \'webview\' (Device.browser.webview)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1185,7 +1185,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 33, + line: 34, message: 'Use of deprecated property \'webview\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1193,7 +1193,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 35, + line: 36, message: 'Use of deprecated property \'AnimationMode\' (Configuration.AnimationMode)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1201,7 +1201,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 37, + line: 38, message: 'Use of deprecated property \'MessageType\' (coreLib.MessageType)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1209,7 +1209,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 17, - line: 39, + line: 40, message: 'Use of deprecated API \'MessageType\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1217,7 +1217,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 20, - line: 43, + line: 44, message: 'Use of deprecated API \'MessageType\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1225,7 +1225,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 47, + line: 48, message: 'Use of deprecated property \'Date\' (mobileLib.InputType.Date)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1233,7 +1233,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 20, - line: 50, + line: 51, message: 'Call to deprecated function \'storeInnerAppState\' of class \'NavigationHandler\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1241,7 +1241,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 3, - line: 54, + line: 55, message: 'Use of deprecated property \'blocked\' of class \'Button\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1249,7 +1249,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 3, - line: 55, + line: 56, message: 'Use of deprecated property \'tap\' of class \'Button\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1257,7 +1257,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 20, - line: 61, + line: 62, message: 'Access of global variable \'sap\' (sap.ui.xmlfragment)', messageDetails: 'Do not use global variables to access UI5 modules or APIs. See Best Practices for Developers (https://ui5.sap.com/#/topic/28fcd55b04654977b63dacbee0552712)', ruleId: 'no-globals', @@ -1265,7 +1265,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 27, - line: 61, + line: 62, message: 'Call to deprecated function \'xmlfragment\' (sap.ui.xmlfragment)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1273,7 +1273,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 20, - line: 64, + line: 65, message: 'Access of global variable \'sap\' (sap.ui.xmlfragment)', messageDetails: 'Do not use global variables to access UI5 modules or APIs. See Best Practices for Developers (https://ui5.sap.com/#/topic/28fcd55b04654977b63dacbee0552712)', ruleId: 'no-globals', @@ -1281,7 +1281,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 27, - line: 64, + line: 65, message: 'Call to deprecated function \'xmlfragment\' (sap.ui.xmlfragment)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1289,7 +1289,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 16, - line: 69, + line: 70, message: 'Access of global variable \'sap\' (sap.ui.xmlview)', messageDetails: 'Do not use global variables to access UI5 modules or APIs. See Best Practices for Developers (https://ui5.sap.com/#/topic/28fcd55b04654977b63dacbee0552712)', ruleId: 'no-globals', @@ -1297,7 +1297,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 23, - line: 69, + line: 70, message: 'Call to deprecated function \'xmlview\' (sap.ui.xmlview)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1305,7 +1305,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 16, - line: 72, + line: 73, message: 'Access of global variable \'sap\' (sap.ui.xmlview)', messageDetails: 'Do not use global variables to access UI5 modules or APIs. See Best Practices for Developers (https://ui5.sap.com/#/topic/28fcd55b04654977b63dacbee0552712)', ruleId: 'no-globals', @@ -1313,7 +1313,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 23, - line: 72, + line: 73, message: 'Call to deprecated function \'xmlview\' (sap.ui.xmlview)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1321,7 +1321,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 23, - line: 78, + line: 79, message: 'Use of deprecated property \'xmlview\' (sap.ui.xmlview)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -1329,12 +1329,36 @@ Generated by [AVA](https://avajs.dev). }, { column: 16, - line: 79, + line: 80, message: 'Call to deprecated function \'sapUiXmlView\' (sap.ui.xmlview)', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', severity: 2, }, + { + column: 3, + line: 83, + message: 'Use of deprecated property \'ResponsiveLayout\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, + { + column: 3, + line: 87, + message: 'Use of deprecated property \'TwoThirds\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, + { + column: 3, + line: 91, + message: 'Use of deprecated property \'Date\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, ], warningCount: 0, }, @@ -2135,13 +2159,13 @@ Generated by [AVA](https://avajs.dev). [ { coverageInfo: [], - errorCount: 15, + errorCount: 18, fatalErrorCount: 0, filePath: 'XMLView.view.xml', messages: [ { column: 2, - line: 8, + line: 9, message: 'Import of deprecated module \'sap/m/DateTimeInput\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2149,7 +2173,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 10, - line: 10, + line: 11, message: 'Use of deprecated property \'blocked\' of class \'Button\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2157,7 +2181,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 15, - line: 12, + line: 13, message: 'Use of deprecated property \'groupBy\' of class \'Table\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2165,7 +2189,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 4, - line: 13, + line: 14, message: 'Use of deprecated property \'plugins\' of class \'Table\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2173,7 +2197,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 3, - line: 19, + line: 20, message: 'Use of deprecated property \'buttons\' of class \'SegmentedButton\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2181,7 +2205,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 11, - line: 19, + line: 20, message: 'Use of deprecated property \'tap\' of class \'Button\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2189,7 +2213,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 22, + line: 23, message: 'Usage of deprecated value \'JS\' for parameter \'type\' in \'sap/ui/core/mvc/View.create\'', messageDetails: 'View.create (https://ui5.sap.com/1.120/#/api/sap.ui.core.mvc.View%23methods/sap.ui.core.mvc.View.create)', ruleId: 'no-deprecated-api', @@ -2197,7 +2221,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 23, + line: 24, message: 'Usage of deprecated value \'JSON\' for parameter \'type\' in \'sap/ui/core/mvc/View.create\'', messageDetails: 'View.create (https://ui5.sap.com/1.120/#/api/sap.ui.core.mvc.View%23methods/sap.ui.core.mvc.View.create)', ruleId: 'no-deprecated-api', @@ -2205,7 +2229,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 24, + line: 25, message: 'Usage of deprecated value \'HTML\' for parameter \'type\' in \'sap/ui/core/mvc/View.create\'', messageDetails: 'View.create (https://ui5.sap.com/1.120/#/api/sap.ui.core.mvc.View%23methods/sap.ui.core.mvc.View.create)', ruleId: 'no-deprecated-api', @@ -2213,7 +2237,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 25, + line: 26, message: 'Usage of deprecated value \'Template\' for parameter \'type\' in \'sap/ui/core/mvc/View.create\'', messageDetails: 'View.create (https://ui5.sap.com/1.120/#/api/sap.ui.core.mvc.View%23methods/sap.ui.core.mvc.View.create)', ruleId: 'no-deprecated-api', @@ -2221,7 +2245,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 27, + line: 28, message: 'Import of deprecated module \'sap/ui/core/mvc/JSView\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2229,7 +2253,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 28, + line: 29, message: 'Import of deprecated module \'sap/ui/core/mvc/JSONView\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2237,7 +2261,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 29, + line: 30, message: 'Import of deprecated module \'sap/ui/core/mvc/HTMLView\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2245,7 +2269,7 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 30, + line: 31, message: 'Import of deprecated module \'sap/ui/core/mvc/TemplateView\'', messageDetails: 'Deprecated test message', ruleId: 'no-deprecated-api', @@ -2253,12 +2277,36 @@ Generated by [AVA](https://avajs.dev). }, { column: 2, - line: 37, + line: 38, message: 'Usage of deprecated value \'HTML\' for parameter \'type\' in \'sap/ui/core/Fragment.load\'', messageDetails: 'Fragment.load (https://ui5.sap.com/1.120/#/api/sap.ui.core.Fragment%23methods/sap.ui.core.Fragment.load)', ruleId: 'no-deprecated-api', severity: 2, }, + { + column: 19, + line: 47, + message: 'Use of deprecated property \'ResponsiveLayout\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, + { + column: 15, + line: 50, + message: 'Use of deprecated property \'TwoThirds\'', + messageDetails: 'Deprecated test message', + ruleId: 'no-deprecated-api', + severity: 2, + }, + { + column: 9, + line: 53, + message: 'Use of deprecated property \'Date\'', + 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 3f043338f..3d0b4faf0 100644 Binary files a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap and b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap differ