All files / src/pretty_printer fix_keyword_case.ts

97.06% Statements 33/34
93.75% Branches 15/16
100% Functions 5/5
97.06% Lines 33/34

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           41x 41x 41x 41x       149x 253x 42x 42x 13x   29x 29x 211x 103x 103x 103x 19x   108x 108x           149x       29x       19x 19x 19x 19x       48x 48x   48x   48x      
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 Eif (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");
  }
 
}