All files / src/rules ambiguous_statement.ts

97.75% Statements 87/89
94.11% Branches 16/17
100% Functions 7/7
97.75% Lines 87/89

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 891x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10327x 10327x 10327x 10327x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 30812x 10327x 10327x 2x 2x 10327x 10327x 9814x 9814x 10327x 10327x 241x 241x 10327x 10327x 262x 262x 262x     262x 262x 1448x 1448x 1448x 1x 1448x 3x 1447x 1x 1444x 2x 2x 1448x 1448x 2x 2x 2x 1448x 1448x 262x 262x 262x 10327x 10327x 7x 7x 7x 7x 7x 7x 7x 7x 7x 10327x 10327x
import {Issue} from "../issue";
import * as Statements from "../abap/2_statements/statements";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {StatementNode} from "../abap/nodes";
import {IStatement} from "../abap/2_statements/statements/_statement";
import {Combi} from "../abap/2_statements/combi";
import {IRegistry} from "../_iregistry";
import {Version} from "../version";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
 
export class AmbiguousStatementConf extends BasicRuleConfig {
}
 
export class AmbiguousStatement extends ABAPRule {
  private conf = new AmbiguousStatementConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "ambiguous_statement",
      title: "Check for ambigious statements",
      shortDescription: `Checks for ambiguity between deleting or modifying from internal and database table
Add "TABLE" keyword or "@" for escaping SQL variables
 
Only works if the target version is 740sp05 or above`,
      tags: [RuleTag.SingleFile],
      badExample: `DELETE foo FROM bar.
MODIFY foo FROM bar.`,
      goodExample: `DELETE foo FROM @bar.
MODIFY TABLE foo FROM bar.
MODIFY zfoo FROM @wa.`,
    };
  }
 
  private getMessage(): string {
    return "Ambiguous statement. Use explicit syntax.";
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: AmbiguousStatementConf) {
    this.conf = conf;
  }
 
  public runParsed(file: ABAPFile) {
    const issues: Issue[] = [];
 
    if (this.reg.getConfig().getVersion() < Version.v740sp05) {
      return [];
    }
 
    for (const statement of file.getStatements()) {
      let match = false;
 
      if (statement.get() instanceof Statements.DeleteDatabase) {
        match = this.tryMatch(statement, this.reg, Statements.DeleteInternal);
      } else if (statement.get() instanceof Statements.DeleteInternal) {
        match = this.tryMatch(statement, this.reg, Statements.DeleteDatabase);
      } else if (statement.get() instanceof Statements.ModifyInternal) {
        match = this.tryMatch(statement, this.reg, Statements.ModifyDatabase);
      } else if (statement.get() instanceof Statements.ModifyDatabase) {
        match = this.tryMatch(statement, this.reg, Statements.ModifyInternal);
      }
 
      if (match) {
        const issue = Issue.atStatement(file, statement, this.getMessage(), this.getMetadata().key, this.conf.severity);
        issues.push(issue);
      }
 
    }
 
    return issues;
  }
 
  private tryMatch(st: StatementNode, reg: IRegistry, type1: new () => IStatement): boolean {
    const ver = reg.getConfig().getVersion();
 
    const tokens = st.getTokens().slice(0);
    tokens.pop();
 
    const match = Combi.run(new type1().getMatcher(), tokens, ver);
 
    return match !== undefined;
  }
 
}