All files / src/rules superclass_final.ts

100% Statements 79/79
100% Branches 22/22
100% Functions 6/6
100% Lines 79/79

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 791x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10430x 10430x 10430x 10430x 31097x 31097x 31097x 31097x 31097x 31097x 31097x 10430x 10430x 1x 1x 10430x 10430x 9906x 9906x 10430x 10430x 243x 243x 10430x 10430x 266x 266x 266x 125x 125x 111x 111x 14x 125x 5x 5x 14x 125x 9x 11x 11x 9x 9x 11x 9x 125x 5x 5x 4x 4x 5x 125x 1x 1x 1x 1x 1x 125x 1x 1x 1x 125x 266x 266x 266x 10430x
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import * as Objects from "../objects";
import {BasicRuleConfig} from "./_basic_rule_config";
import {Class} from "../objects";
import {InfoClassDefinition} from "../abap/4_file_information/_abap_file_information";
import {RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {ABAPObject} from "..";
 
export class SuperclassFinalConf extends BasicRuleConfig {
}
 
export class SuperclassFinal extends ABAPRule {
  private conf = new SuperclassFinalConf();
 
  public getMetadata() {
    return {
      key: "superclass_final",
      title: "Super class final",
      shortDescription: `Checks that classes which are inherited from are not declared as FINAL.`,
      tags: [RuleTag.Syntax],
    };
  }
 
  private getMessage(): string {
    return "Superclasses cannot be FINAL";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: SuperclassFinalConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile, obj: ABAPObject) {
    const output: Issue[] = [];
 
    for (const definition of file.getInfo().listClassDefinitions()) {
      const sup = definition.superClassName;
      if (sup === undefined) {
        continue;
      }
      let localLookup = true;
      if (obj instanceof Objects.Class && file.getFilename().match(/\.clas\.abap$/)) {
        localLookup = false;
      }
      let found: InfoClassDefinition | undefined = undefined;
      if (localLookup) {
        for (const f of obj.getABAPFiles()) {
          found = f.getInfo().getClassDefinitionByName(sup);
          if (found !== undefined) {
            break;
          }
        }
      }
      if (found === undefined) {
        const clas = this.reg.getObject("CLAS", sup) as Class;
        if (clas) {
          found = clas.getClassDefinition();
        }
      }
      if (found === undefined) {
        const message = "Super class \"" + sup + "\" not found";
        const issue = Issue.atIdentifier(definition.identifier, message, this.getMetadata().key, this.conf.severity);
        output.push(issue);
        continue;
      }
      if (found.isFinal === true) {
        const issue = Issue.atIdentifier(definition.identifier, this.getMessage(), this.getMetadata().key, this.conf.severity);
        output.push(issue);
      }
    }
 
    return output;
  }
}