All files / src/rules prefer_returning_to_exporting.ts

97.97% Statements 97/99
97.22% Branches 35/36
100% Functions 5/5
97.97% Lines 97/99

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 97 98 99 100 1011x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11305x 11305x 11305x 11305x 11305x 33736x 33736x 33736x 33736x 33736x 33736x 33736x 33736x 33736x 33736x 33736x 33736x 33736x 11305x 11305x 10802x 10802x 11305x 11305x 232x 232x 11305x 11305x 251x 251x 251x 251x 12x 12x 239x 251x 64x     64x 64x 64x 56x 56x 8x 8x 64x 1x 1x 7x 7x 64x 1x 1x 6x 6x 6x 6x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 64x 4x 4x 2x 2x 2x 2x 2x 239x 239x 239x 11305x 11305x    
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import * as Statements from "../abap/2_statements/statements";
import * as Expressions from "../abap/2_statements/expressions";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class PreferReturningToExportingConf extends BasicRuleConfig {
}
 
export class PreferReturningToExporting extends ABAPRule {
 
  private conf = new PreferReturningToExportingConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "prefer_returning_to_exporting",
      title: "Prefer RETURNING to EXPORTING",
      shortDescription: `Prefer RETURNING to EXPORTING. Generic types cannot be RETURNING.`,
      extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-returning-to-exporting
https://docs.abapopenchecks.org/checks/44/`,
      tags: [RuleTag.Styleguide, RuleTag.SingleFile],
      badExample: `CLASS lcl DEFINITION.
  PUBLIC SECTION.
    METHODS test EXPORTING ev_foo TYPE i.
ENDCLASS.`,
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: PreferReturningToExportingConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile): Issue[] {
    const ret: Issue[] = [];
 
    const stru = file.getStructure();
    if (stru === undefined) {
      return [];
    }
 
    for (const def of stru.findAllStatements(Statements.MethodDef)) {
      if (def.findFirstExpression(Expressions.MethodDefChanging)) {
        continue;
      }
 
      const exporting = def.findFirstExpression(Expressions.MethodDefExporting);
      if (exporting === undefined) {
        continue;
      }
 
      const returning = def.findFirstExpression(Expressions.MethodDefReturning);
      if (returning !== undefined) {
        continue;
      }
 
      const params = exporting.findDirectExpressions(Expressions.MethodParam);
      if (params.length !== 1) {
        continue;
      }
 
      const concat = params[0].concatTokens().toUpperCase();
 
      if (concat.endsWith("TYPE ANY")
          || concat.endsWith("TYPE ANY TABLE")
          || concat.endsWith("TYPE C")
          || concat.endsWith("TYPE CLIKE")
          || concat.endsWith("TYPE CSEQUENCE")
          || concat.endsWith("TYPE DATA")
          || concat.endsWith("TYPE DECFLOAT")
          || concat.endsWith("TYPE HASHED TABLE")
          || concat.endsWith("TYPE INDEX TABLE")
          || concat.endsWith("TYPE N")
          || concat.endsWith("TYPE NUMERIC")
          || concat.endsWith("TYPE OBJECT")
          || concat.endsWith("TYPE P")
          || concat.endsWith("TYPE SIMPLE")
          || concat.endsWith("TYPE SORTED TABLE")
          || concat.endsWith("TYPE STANDARD TABLE")
          || concat.endsWith("TYPE TABLE")
          || concat.endsWith("TYPE X")
          || concat.endsWith("TYPE XSEQUENCE")) {
        continue;
      }
 
      const token = params[0].getFirstToken();
      const issue = Issue.atToken(file, token, "Prefer RETURNING to EXPORTING", this.getMetadata().key, this.conf.severity);
      ret.push(issue);
    }
 
    return ret;
  }
 
}