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 22369x 22369x 22369x 22369x 1x 11186x 11186x 11186x 11186x 11186x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 33410x 11186x 11186x 10929x 10929x 11186x 11186x 246x 246x 11186x 11186x 268x 268x 268x 268x 268x 268x 268x 268x 6124x 6124x 6112x 6112x 12x 12x 6124x 1x 1x 1x 1x 1x 1x 12x 268x 268x 268x 11186x 11186x 1220x 1220x 1220x 396x 389x 389x 396x 3x 3x 396x 1220x 1220x 952x 952x 1220x 1220x 1220x 11186x 11186x | /* 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;
}
}
|