diff --git a/src/linter/ui5Types/SourceFileLinter.ts b/src/linter/ui5Types/SourceFileLinter.ts index b803f239..9302844c 100644 --- a/src/linter/ui5Types/SourceFileLinter.ts +++ b/src/linter/ui5Types/SourceFileLinter.ts @@ -156,7 +156,8 @@ export default class SourceFileLinter { // Analyze renderer property when it's referenced by a variable or even another module // i.e. { renderer: Renderer } if (ts.isIdentifier(node.initializer)) { - const {symbol: {declarations}} = this.#checker.getTypeAtLocation(node); + const {symbol} = this.#checker.getTypeAtLocation(node); + const {declarations} = symbol ?? {}; declarations?.forEach((declaration) => this.analyzeControlRendererInternals(declaration)); } else { // Analyze renderer property when it's directly embedded in the renderer object diff --git a/test/fixtures/linter/rules/Render/Control_1.js b/test/fixtures/linter/rules/Render/1Control.js similarity index 84% rename from test/fixtures/linter/rules/Render/Control_1.js rename to test/fixtures/linter/rules/Render/1Control.js index a2d40f56..1463e216 100644 --- a/test/fixtures/linter/rules/Render/Control_1.js +++ b/test/fixtures/linter/rules/Render/1Control.js @@ -1,5 +1,5 @@ sap.ui.define(["sap/ui/core/Control"], function (Control) { - var myControl = Control.extend("myControl", { + var myControl = Control.extend("mycomp.myControl", { metadata: {}, renderer: { apiVersion: 1, diff --git a/test/fixtures/linter/rules/Render/2Control.js b/test/fixtures/linter/rules/Render/2Control.js new file mode 100644 index 00000000..fe9030d5 --- /dev/null +++ b/test/fixtures/linter/rules/Render/2Control.js @@ -0,0 +1,8 @@ +sap.ui.define(["sap/ui/core/Control", "./2ControlRenderer"], function (Control, Renderer) { + var myControl = Control.extend("mycomp.myControl", { + metadata: {}, + renderer: Renderer, + }); + + return myControl; +}); diff --git a/test/fixtures/linter/rules/Render/_Renderer_2.js b/test/fixtures/linter/rules/Render/2ControlRenderer.js similarity index 100% rename from test/fixtures/linter/rules/Render/_Renderer_2.js rename to test/fixtures/linter/rules/Render/2ControlRenderer.js diff --git a/test/fixtures/linter/rules/Render/Control_3.js b/test/fixtures/linter/rules/Render/3Control.js similarity index 82% rename from test/fixtures/linter/rules/Render/Control_3.js rename to test/fixtures/linter/rules/Render/3Control.js index fbb57af6..8a38c96d 100644 --- a/test/fixtures/linter/rules/Render/Control_3.js +++ b/test/fixtures/linter/rules/Render/3Control.js @@ -1,5 +1,5 @@ sap.ui.define(["sap/ui/core/Control"], function (Control) { - var myControl = Control.extend("myControl", { + var myControl = Control.extend("mycomp.myControl", { metadata: {}, renderer: (oRm, oMyControl) => { oRm.openStart("div", oMyControl); diff --git a/test/fixtures/linter/rules/Render/Control_4.js b/test/fixtures/linter/rules/Render/4Control.js similarity index 74% rename from test/fixtures/linter/rules/Render/Control_4.js rename to test/fixtures/linter/rules/Render/4Control.js index 1bf41ff3..80bf79b6 100644 --- a/test/fixtures/linter/rules/Render/Control_4.js +++ b/test/fixtures/linter/rules/Render/4Control.js @@ -6,11 +6,7 @@ sap.ui.define(["sap/ui/core/Control"], function (Control) { oRm.close("div"); }; - const a = zzzz; - const b = a; - const c = b; - - var myControl = Control.extend("myControl", { + var myControl = Control.extend("mycomp.myControl", { metadata: {}, renderer, }); diff --git a/test/fixtures/linter/rules/Render/5Control.js b/test/fixtures/linter/rules/Render/5Control.js new file mode 100644 index 00000000..389aeb6d --- /dev/null +++ b/test/fixtures/linter/rules/Render/5Control.js @@ -0,0 +1,8 @@ +sap.ui.define(["sap/ui/core/Control", "./5ControlRenderer"], function (Control, Renderer) { + var myControl = Control.extend("mycomp.myControl", { + metadata: {}, + renderer: Renderer, + }); + + return myControl; +}); diff --git a/test/fixtures/linter/rules/Render/_Renderer_5.js b/test/fixtures/linter/rules/Render/5ControlRenderer.js similarity index 100% rename from test/fixtures/linter/rules/Render/_Renderer_5.js rename to test/fixtures/linter/rules/Render/5ControlRenderer.js diff --git a/test/fixtures/linter/rules/Render/Control_6.js b/test/fixtures/linter/rules/Render/6Control.js similarity index 85% rename from test/fixtures/linter/rules/Render/Control_6.js rename to test/fixtures/linter/rules/Render/6Control.js index f7e21f9f..0dcdf8f8 100644 --- a/test/fixtures/linter/rules/Render/Control_6.js +++ b/test/fixtures/linter/rules/Render/6Control.js @@ -1,5 +1,5 @@ sap.ui.define(["sap/ui/core/Control"], function (Control) { - var myControl = Control.extend("myControl", { + var myControl = Control.extend("mycomp.myControl", { metadata: {}, renderer: { apiVersion: 2, diff --git a/test/fixtures/linter/rules/Render/7Control.js b/test/fixtures/linter/rules/Render/7Control.js new file mode 100644 index 00000000..e12b5f1d --- /dev/null +++ b/test/fixtures/linter/rules/Render/7Control.js @@ -0,0 +1,8 @@ +sap.ui.define(["sap/ui/core/Control", "./7ControlRenderer"], function (Control, Renderer) { + var myControl = Control.extend("mycomp.myControl", { + metadata: {}, + renderer: Renderer, + }); + + return myControl; +}); diff --git a/test/fixtures/linter/rules/Render/_Renderer_7.js b/test/fixtures/linter/rules/Render/7ControlRenderer.js similarity index 100% rename from test/fixtures/linter/rules/Render/_Renderer_7.js rename to test/fixtures/linter/rules/Render/7ControlRenderer.js diff --git a/test/fixtures/linter/rules/Render/8Control.js b/test/fixtures/linter/rules/Render/8Control.js new file mode 100644 index 00000000..35ae8b4c --- /dev/null +++ b/test/fixtures/linter/rules/Render/8Control.js @@ -0,0 +1,8 @@ +sap.ui.define(["sap/ui/core/Control", "./8ControlRenderer"], function (Control, Renderer) { + var myControl = Control.extend("mycomp.myControl", { + metadata: {}, + renderer: Renderer, + }); + + return myControl; +}); diff --git a/test/fixtures/linter/rules/Render/_Renderer_8.js b/test/fixtures/linter/rules/Render/8ControlRenderer.js similarity index 100% rename from test/fixtures/linter/rules/Render/_Renderer_8.js rename to test/fixtures/linter/rules/Render/8ControlRenderer.js diff --git a/test/fixtures/linter/rules/Render/Control_2.js b/test/fixtures/linter/rules/Render/Control_2.js deleted file mode 100644 index 72311d7a..00000000 --- a/test/fixtures/linter/rules/Render/Control_2.js +++ /dev/null @@ -1,8 +0,0 @@ -sap.ui.define(["sap/ui/core/Control", "./_2Renderer"], function (Control, Renderer) { - var myControl = Control.extend("myControl", { - metadata: {}, - renderer: Renderer, - }); - - return myControl; -}); diff --git a/test/fixtures/linter/rules/Render/Control_5.js b/test/fixtures/linter/rules/Render/Control_5.js deleted file mode 100644 index e5ece499..00000000 --- a/test/fixtures/linter/rules/Render/Control_5.js +++ /dev/null @@ -1,8 +0,0 @@ -sap.ui.define(["sap/ui/core/Control", "./_5Renderer"], function (Control, Renderer) { - var myControl = Control.extend("myControl", { - metadata: {}, - renderer: Renderer, - }); - - return myControl; -}); diff --git a/test/fixtures/linter/rules/Render/Control_7.js b/test/fixtures/linter/rules/Render/Control_7.js deleted file mode 100644 index 6d06ee18..00000000 --- a/test/fixtures/linter/rules/Render/Control_7.js +++ /dev/null @@ -1,8 +0,0 @@ -sap.ui.define(["sap/ui/core/Control", "./_7Renderer"], function (Control, Renderer) { - var myControl = Control.extend("myControl", { - metadata: {}, - renderer: Renderer, - }); - - return myControl; -}); diff --git a/test/fixtures/linter/rules/Render/Control_8.js b/test/fixtures/linter/rules/Render/Control_8.js deleted file mode 100644 index 4db0c145..00000000 --- a/test/fixtures/linter/rules/Render/Control_8.js +++ /dev/null @@ -1,8 +0,0 @@ -sap.ui.define(["sap/ui/core/Control", "./_8Renderer"], function (Control, Renderer) { - var myControl = Control.extend("myControl", { - metadata: {}, - renderer: Renderer, - }); - - return myControl; -}); diff --git a/test/lib/linter/_linterHelper.ts b/test/lib/linter/_linterHelper.ts index 5707903c..a9208f1d 100644 --- a/test/lib/linter/_linterHelper.ts +++ b/test/lib/linter/_linterHelper.ts @@ -82,7 +82,7 @@ export function createTestsForFixtures(fixturesPath: string) { if (!testFiles.length) { throw new Error(`Failed to find any fixtures in directory ${fixturesPath}`); } - if (fixturesPath.includes("AsyncComponentFlags")) { + if (fixturesPath.includes("AsyncComponentFlags") || fixturesPath.includes("Render")) { const dirName = path.basename(fixturesPath); testDefinition({ testName: dirName, diff --git a/test/lib/linter/rules/snapshots/Render.ts.md b/test/lib/linter/rules/snapshots/Render.ts.md new file mode 100644 index 00000000..a0b8c866 --- /dev/null +++ b/test/lib/linter/rules/snapshots/Render.ts.md @@ -0,0 +1,311 @@ +# Snapshot report for `test/lib/linter/rules/Render.ts` + +The actual snapshot is saved in `Render.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## General: Render + +> Snapshot 1 + + [ + { + coverageInfo: [ + { + category: 1, + column: 5, + line: 7, + message: 'Unable to analyze this method call because the type of identifier "openStart" in "oRm.openStart("div", oMyControl)"" could not be determined', + }, + { + category: 1, + column: 5, + line: 8, + message: 'Unable to analyze this method call because the type of identifier "class" in "oRm.class("mycssclass")"" could not be determined', + }, + { + category: 1, + column: 5, + line: 9, + message: 'Unable to analyze this method call because the type of identifier "openEnd" in "oRm.openEnd()"" could not be determined', + }, + { + category: 1, + column: 5, + line: 10, + message: 'Unable to analyze this method call because the type of identifier "close" in "oRm.close("div")"" could not be determined', + }, + ], + errorCount: 1, + fatalErrorCount: 0, + filePath: '1Control.js', + messages: [ + { + column: 4, + line: 5, + message: 'Use of deprecated renderer. Define explicitly {apiVersion: 2} parameter in renderer object', + messageDetails: '"Renderer Object (https://ui5.sap.com/#/topic/c9ab34570cc14ea5ab72a6d1a4a03e3f)",', + ruleId: 'no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 1, + fatalErrorCount: 0, + filePath: '2Control.js', + messages: [ + { + column: 16, + line: 1, + message: 'Use of deprecated renderer. Define explicitly {apiVersion: 2} parameter in renderer object', + messageDetails: '"Renderer Object (https://ui5.sap.com/#/topic/c9ab34570cc14ea5ab72a6d1a4a03e3f)",', + ruleId: 'no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: '2ControlRenderer.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 4, + line: 5, + message: 'Unable to analyze this method call because the type of identifier "openStart" in "oRm.openStart("div", oMyControl)"" could not be determined', + }, + { + category: 1, + column: 4, + line: 6, + message: 'Unable to analyze this method call because the type of identifier "class" in "oRm.class("mycssclass")"" could not be determined', + }, + { + category: 1, + column: 4, + line: 7, + message: 'Unable to analyze this method call because the type of identifier "openEnd" in "oRm.openEnd()"" could not be determined', + }, + { + category: 1, + column: 4, + line: 8, + message: 'Unable to analyze this method call because the type of identifier "close" in "oRm.close("div")"" could not be determined', + }, + ], + errorCount: 1, + fatalErrorCount: 0, + filePath: '3Control.js', + messages: [ + { + column: 13, + line: 4, + message: 'Use of deprecated renderer. Define explicitly {apiVersion: 2} parameter in renderer object', + messageDetails: '"Renderer Object (https://ui5.sap.com/#/topic/c9ab34570cc14ea5ab72a6d1a4a03e3f)",', + ruleId: 'no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 3, + line: 3, + message: 'Unable to analyze this method call because the type of identifier "openStart" in "oRm.openStart("div", oMyControl)"" could not be determined', + }, + { + category: 1, + column: 3, + line: 4, + message: 'Unable to analyze this method call because the type of identifier "class" in "oRm.class("mycssclass")"" could not be determined', + }, + { + category: 1, + column: 3, + line: 5, + message: 'Unable to analyze this method call because the type of identifier "openEnd" in "oRm.openEnd()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 6, + message: 'Unable to analyze this method call because the type of identifier "close" in "oRm.close("div")"" could not be determined', + }, + ], + errorCount: 2, + fatalErrorCount: 0, + filePath: '4Control.js', + messages: [ + { + column: 19, + line: 2, + message: 'Use of deprecated renderer. Define explicitly {apiVersion: 2} parameter in renderer object', + messageDetails: '"Renderer Object (https://ui5.sap.com/#/topic/c9ab34570cc14ea5ab72a6d1a4a03e3f)",', + ruleId: 'no-deprecated-api', + severity: 2, + }, + { + column: 19, + line: 2, + message: 'Use of deprecated renderer. Define explicitly {apiVersion: 2} parameter in renderer object', + messageDetails: '"Renderer Object (https://ui5.sap.com/#/topic/c9ab34570cc14ea5ab72a6d1a4a03e3f)",', + ruleId: 'no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 1, + fatalErrorCount: 0, + filePath: '5Control.js', + messages: [ + { + column: 72, + line: 1, + message: 'Use of deprecated renderer. Define explicitly {apiVersion: 2} parameter in renderer object', + messageDetails: '"Renderer Object (https://ui5.sap.com/#/topic/c9ab34570cc14ea5ab72a6d1a4a03e3f)",', + ruleId: 'no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: '5ControlRenderer.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 5, + line: 7, + message: 'Unable to analyze this method call because the type of identifier "openStart" in "oRm.openStart("div", oMyControl)"" could not be determined', + }, + { + category: 1, + column: 5, + line: 8, + message: 'Unable to analyze this method call because the type of identifier "icon" in "oRm.icon("sap-icon://appointment", null, { title: null })"" could not be determined', + }, + { + category: 1, + column: 5, + line: 9, + message: 'Unable to analyze this method call because the type of identifier "openEnd" in "oRm.openEnd()"" could not be determined', + }, + { + category: 1, + column: 5, + line: 10, + message: 'Unable to analyze this method call because the type of identifier "close" in "oRm.close("div")"" could not be determined', + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: '6Control.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: '7Control.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 3, + line: 8, + message: 'Unable to analyze this method call because the type of identifier "openStart" in "oRm.openStart("div", oMyControl)"" could not be determined', + }, + { + category: 1, + column: 3, + line: 9, + message: 'Unable to analyze this method call because the type of identifier "icon" in "oRm.icon("sap-icon://appointment", null, { title: null })"" could not be determined', + }, + { + category: 1, + column: 3, + line: 10, + message: 'Unable to analyze this method call because the type of identifier "openEnd" in "oRm.openEnd()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 11, + message: 'Unable to analyze this method call because the type of identifier "close" in "oRm.close("div")"" could not be determined', + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: '7ControlRenderer.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [], + errorCount: 0, + fatalErrorCount: 0, + filePath: '8Control.js', + messages: [], + warningCount: 0, + }, + { + coverageInfo: [ + { + category: 1, + column: 3, + line: 8, + message: 'Unable to analyze this method call because the type of identifier "openStart" in "oRm.openStart("div", oMyControl)"" could not be determined', + }, + { + category: 1, + column: 3, + line: 10, + message: 'Unable to analyze this method call because the type of identifier "openEnd" in "oRm.openEnd()"" could not be determined', + }, + { + category: 1, + column: 3, + line: 11, + message: 'Unable to analyze this method call because the type of identifier "close" in "oRm.close("div")"" could not be determined', + }, + { + category: 1, + column: 3, + line: 15, + message: 'Unable to analyze this method call because the type of identifier "icon" in "oRm.icon("sap-icon://appointment", null, { title: null })"" could not be determined', + }, + ], + errorCount: 0, + fatalErrorCount: 0, + filePath: '8ControlRenderer.js', + messages: [], + warningCount: 0, + }, + ] diff --git a/test/lib/linter/rules/snapshots/Render.ts.snap b/test/lib/linter/rules/snapshots/Render.ts.snap new file mode 100644 index 00000000..09b9986f Binary files /dev/null and b/test/lib/linter/rules/snapshots/Render.ts.snap differ