Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 22631x 22631x 22631x 22631x 1x 11317x 11317x 11317x 11317x 11317x 33788x 33788x 33788x 33788x 33788x 33788x 33788x 33788x 11317x 11317x 11063x 11063x 11317x 11317x 233x 233x 11317x 11317x 245x 245x 245x 245x 245x 245x 245x 245x 5635x 5635x 5623x 5623x 12x 12x 5635x 1x 1x 1x 1x 1x 1x 12x 245x 245x 245x 11317x 11317x 1137x 1137x 1137x 381x 374x 374x 381x 3x 3x 381x 1137x 1137x 892x 892x 1137x 1137x 1137x 11317x 11317x | /* eslint-disable max-len */
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {SyntaxLogic} from "../abap/5_syntax/syntax";
import {ABAPObject} from "../objects/_abap_object";
import {ISpaghettiScopeNode} from "../abap/5_syntax/_spaghetti_scope";
import {ReferenceType} from "../abap/5_syntax/_reference";
import {MethodDefinition} from "../abap/types";
import {Position} from "../position";
export class StaticCallViaInstanceConf extends BasicRuleConfig {
/** Allow in test class includes */
public allowInTestclassIncludes?: boolean = false;
}
export class StaticCallViaInstance extends ABAPRule {
private conf = new StaticCallViaInstanceConf();
public getMetadata(): IRuleMetadata {
return {
key: "static_call_via_instance",
title: "Static call via instance variable",
shortDescription: `Static method call via instance variable`,
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-call-static-methods-through-instance-variables`,
tags: [RuleTag.Styleguide],
};
}
public getConfig() {
return this.conf;
}
public setConfig(conf: StaticCallViaInstanceConf) {
this.conf = conf;
}
public runParsed(file: ABAPFile, obj: ABAPObject): Issue[] {
const issues: Issue[] = [];
if (this.getConfig().allowInTestclassIncludes === true && file.getFilename().includes(".testclasses.")) {
return [];
}
const staticMethodCalls = this.listMethodCalls(file.getFilename(), new SyntaxLogic(this.reg, obj).run().spaghetti.getTop());
const tokens = file.getTokens();
for (let i = 0; i < tokens.length - 1; i++) {
const token = tokens[i];
if (token.getStr() !== "->") {
continue;
}
const next = tokens[i + 1];
for (const s of staticMethodCalls) {
if (s.equals(next!.getStart())) {
const message = "Avoid calling static method via instance";
issues.push(Issue.atToken(file, token, message, this.getMetadata().key));
break;
}
}
}
return issues;
}
private listMethodCalls(filename: string, node: ISpaghettiScopeNode): Position[] {
const ret: Position[] = [];
for (const r of node.getData().references) {
if (r.referenceType !== ReferenceType.MethodReference || r.position.getFilename() !== filename) {
continue;
}
if (r.resolved instanceof MethodDefinition && r.resolved.isStatic() === true) {
ret.push(r.position.getStart());
}
}
for (const child of node.getChildren()) {
ret.push(...this.listMethodCalls(filename, child));
}
return ret;
}
}
|