All files / src/pretty_printer fix_keyword_case.ts

96.92% Statements 63/65
94.74% Branches 18/19
100% Functions 5/5
96.92% Lines 63/65

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 651x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 41x 41x 41x 41x 41x 1x 1x 149x 253x 42x 42x 13x 13x 29x 29x 253x 103x 103x 103x 19x 19x 211x 108x 108x     253x 149x 149x 149x 1x 1x 29x 29x 1x 1x 19x 19x 19x 19x 19x 1x 1x 48x 48x 48x 48x 48x 48x 48x 1x 1x
import {StatementNode, ExpressionNode, TokenNode, TokenNodeRegex} from "../abap/nodes";
import {Identifier} from "../abap/1_lexer/tokens";
import {Position} from "../position";
import {KeywordCase, KeywordCaseStyle} from "../rules/keyword_case";
import * as Tokens from "../abap/1_lexer/tokens";
import {IConfiguration} from "../_config";
 
export class FixCase {
  private fileContents: string;
  private readonly config: IConfiguration;
  private readonly keywordCase: KeywordCase;
 
  public constructor(fileContents: string, config: IConfiguration) {
    this.keywordCase = new KeywordCase();
    this.keywordCase.setConfig(config.readByRule(this.keywordCase.getMetadata().key));
    this.fileContents = fileContents;
    this.config = config;
  }
 
  public execute(statement: StatementNode | ExpressionNode): string {
    for (const child of statement.getChildren()) {
      if (child instanceof TokenNodeRegex) {
        const token = child.get();
        if (token instanceof Tokens.String) {
          continue;
        }
        this.replaceString(token.getStart(), this.formatNonKeyword(token.getStr()));
        continue;
      } else if (child instanceof TokenNode) {
        const token = child.get();
        const str = token.getStr();
        if (this.keywordCase.violatesRule(str) && token instanceof Identifier) {
          this.replaceString(token.getStart(), this.formatKeyword(str));
        }
      } else if (child instanceof ExpressionNode) {
        this.execute(child);
      } else {
        throw new Error("pretty printer, traverse, unexpected node type");
      }
    }
 
    return this.fileContents;
  }
 
  private formatNonKeyword(str: string): string {
    return str.toLowerCase();
  }
 
  private formatKeyword(keyword: string): string {
    const ruleKey = this.keywordCase.getMetadata().key;
    const rule = this.config.readByRule(ruleKey);
    const style: KeywordCaseStyle = rule ? rule["style"] : KeywordCaseStyle.Upper;
    return style === KeywordCaseStyle.Lower ? keyword.toLowerCase() : keyword.toUpperCase();
  }
 
  private replaceString(pos: Position, str: string) {
    const lines = this.fileContents.split("\n");
    const line = lines[pos.getRow() - 1];
 
    lines[pos.getRow() - 1] = line.substr(0, pos.getCol() - 1) + str + line.substr(pos.getCol() + str.length - 1);
 
    this.fileContents = lines.join("\n");
  }
 
}