diff --git a/src/detectors/typeChecker/FileLinter.ts b/src/detectors/typeChecker/FileLinter.ts index 56fe6a7ec..26265ba44 100644 --- a/src/detectors/typeChecker/FileLinter.ts +++ b/src/detectors/typeChecker/FileLinter.ts @@ -211,15 +211,16 @@ export default class FileLinter { messageDetails: deprecationInfo.messageDetails, }); } - + /** * Extracts & builds object literal * - * @param node + * @param node * @returns {object} */ extractPropsRecursive = (node: ts.ObjectLiteralExpression) => { - const properties: Record = Object.create(null); + type propsType = Record; + const properties = Object.create(null) as propsType; node.properties?.forEach((prop) => { if (!ts.isPropertyAssignment(prop) || !prop.name) { @@ -231,30 +232,28 @@ export default class FileLinter { properties[key] = {value: false, node: prop.initializer}; } else if (prop.initializer.kind === ts.SyntaxKind.NullKeyword) { properties[key] = {value: null, node: prop.initializer}; - } if (ts.isObjectLiteralExpression(prop.initializer) && prop.initializer.properties) { - properties[key] = { value: this.extractPropsRecursive(prop.initializer), node: prop.initializer }; - } else if ( - (ts.isIdentifier(prop.initializer) || - ts.isNumericLiteral(prop.initializer) || - ts.isStringLiteral(prop.initializer)) - - && prop.initializer.text) { + } else if (ts.isObjectLiteralExpression(prop.initializer) && prop.initializer.properties) { + properties[key] = {value: this.extractPropsRecursive(prop.initializer), node: prop.initializer}; + } else if ((ts.isIdentifier(prop.initializer) || + ts.isNumericLiteral(prop.initializer) || + ts.isStringLiteral(prop.initializer)) && + prop.initializer.text) { properties[key] = {value: prop.initializer.getText(), node: prop.initializer}; } }); return properties; - } + }; analyzeLibInitCall(node: ts.CallExpression) { const nodeExp = node.expression as ts.PropertyAccessExpression; const {symbol} = this.#checker.getTypeAtLocation(nodeExp); - const methodName = symbol && symbol.getName(); - + const methodName = symbol?.getName(); + // TS parser uses some intermediate types that are not available as definitions. // In this case SymbolObject which is a ts.Symbol + ts.Node and that's // why we need these ugly type castings const importDeclaration = - ((((symbol as unknown) as ts.Node)?.parent?.parent as unknown) as ts.Symbol)?.getName() as string; + ((((symbol as unknown) as ts.Node)?.parent?.parent as unknown) as ts.Symbol)?.getName(); if (importDeclaration !== "\"sap/ui/core/Lib\"" || methodName !== "init") { return; @@ -269,10 +268,10 @@ export default class FileLinter { } else { const apiKeyProp = this.extractPropsRecursive(initArg); - if (!apiKeyProp["apiVersion"]) { - nodeToHighlight = node; - } else if (apiKeyProp["apiVersion"].value !== "2") { // String value would be "\"2\"" - nodeToHighlight = apiKeyProp["apiVersion"].node; + if (!apiKeyProp.apiVersion) { + nodeToHighlight = node; + } else if (apiKeyProp.apiVersion.value !== "2") { // String value would be "\"2\"" + nodeToHighlight = apiKeyProp.apiVersion.node; } } diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index 75d04cb91..cdbc22a70 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -900,7 +900,7 @@ Generated by [AVA](https://avajs.dev). }, { coverageInfo: [], - errorCount: 8, + errorCount: 9, fatalErrorCount: 0, filePath: 'src/main/js/library.js', messages: [ @@ -937,7 +937,7 @@ Generated by [AVA](https://avajs.dev). severity: 2, }, { - column: 3, + column: 15, fatal: undefined, line: 21, message: 'Call to Library.init() must be declared with property {apiVersion: 2}', @@ -945,17 +945,25 @@ Generated by [AVA](https://avajs.dev). severity: 2, }, { - column: 3, + column: 15, fatal: undefined, line: 24, message: 'Call to Library.init() must be declared with property {apiVersion: 2}', ruleId: 'ui5-linter-no-partially-deprecated-api', severity: 2, }, + { + column: 15, + fatal: undefined, + line: 27, + message: 'Call to Library.init() must be declared with property {apiVersion: 2}', + ruleId: 'ui5-linter-no-partially-deprecated-api', + severity: 2, + }, { column: 2, fatal: undefined, - line: 38, + line: 41, message: 'Call to deprecated function \'initLibrary\' of class \'Core\'', messageDetails: 'Deprecated test message', ruleId: 'ui5-linter-no-deprecated-api', @@ -964,7 +972,7 @@ Generated by [AVA](https://avajs.dev). { column: 2, fatal: undefined, - line: 38, + line: 41, message: 'Call to deprecated function \'getCore\' (sap.ui.getCore)', messageDetails: 'Deprecated test message', ruleId: 'ui5-linter-no-deprecated-api',