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 42x 42x 42x 42x 42x 1x 1x 154x 262x 44x 44x 13x 13x 31x 31x 262x 106x 106x 106x 20x 20x 218x 112x 112x     262x 154x 154x 154x 1x 1x 31x 31x 1x 1x 20x 20x 20x 20x 20x 1x 1x 51x 51x 51x 51x 51x 51x 51x 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");
  }
 
}