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 22175x 22175x 22175x 22175x 1x 11089x 11089x 11089x 11089x 11089x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 33121x 11089x 11089x 10834x 10834x 11089x 11089x 244x 244x 11089x 11089x 266x 266x 266x 266x 266x 266x 266x 266x 6002x 6002x 5990x 5990x 12x 12x 6002x 1x 1x 1x 1x 1x 1x 12x 266x 266x 266x 11089x 11089x 1212x 1212x 1212x 390x 383x 383x 390x 3x 3x 390x 1212x 1212x 946x 946x 1212x 1212x 1212x 11089x 11089x | /* 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;
}
}
|