All files / src/pretty_printer fix_keyword_case.ts

96.92% Statements 63/65
94.73% 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 33x 33x 33x 33x 33x 1x 1x 129x 221x 36x 36x 8x 8x 28x 28x 221x 89x 89x 89x 20x 20x 185x 96x 96x     221x 129x 129x 129x 1x 1x 28x 28x 1x 1x 20x 20x 20x 20x 20x 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.StringToken) {
          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");
  }
 
}