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 91 92 93 94 95 96 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 24155x 24155x 24155x 24155x 1x 12079x 12079x 12079x 12079x 12079x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 36090x 12079x 12079x 11812x 11812x 12079x 12079x 255x 255x 12079x 12079x 276x 276x 276x 276x 276x 276x 276x 276x 6503x 6503x 6491x 6491x 12x 12x 6503x 1x 1x 1x 1x 1x 1x 12x 276x 276x 276x 12079x 12079x 1292x 1292x 1292x 433x 423x 423x 433x 6x 6x 433x 1292x 1292x 1016x 1016x 1292x 1292x 1292x 12079x 12079x | /* 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],
badExample: `METHOD run.
NEW lcl_helper( )->static_method( ).
ENDMETHOD.`,
goodExample: `METHOD run.
lcl_helper=>static_method( ).
ENDMETHOD.`,
};
}
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;
}
}
|