All files / src/objects _abap_object.ts

92.66% Statements 101/109
72.41% Branches 21/29
88.88% Functions 8/9
92.66% Lines 101/109

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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 1091x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6111x 6111x 6111x 6111x 1x 1x     1x 1x 6452x 42x 42x 6410x 6410x 6410x 6410x 6410x 6410x 6410x 6410x 6410x 6410x 1x 1x 7104x 7104x 7104x 7104x 1x 1x 37546x 37546x 1x 1x 780x 786x 776x 776x 786x 4x 4x 1x 1x 6166x 6166x 6166x 6179x 6143x 6143x 6179x 23x 6166x 9x 9x 9x 9x 14x 14x 1x 1x 13x 13x 13x 13x 13x 1x 1x 13x 13x 13x     13x 13x 50x 38x     38x 38x     38x 38x 50x 13x 1x 1x
import {AbstractObject} from "./_abstract_object";
import {xmlToArray, unescape} from "../xml_utils";
import {ABAPParser} from "../abap/abap_parser";
import {Version} from "../version";
import {ISyntaxResult} from "../abap/5_syntax/_spaghetti_scope";
import {IParseResult} from "./_iobject";
import {ABAPFile} from "../abap/abap_file";
import {IRegistry} from "../_iregistry";
 
export interface ITextElements {[key: string]: string}
 
export abstract class ABAPObject extends AbstractObject {
  private parsed: readonly ABAPFile[];
  protected texts: ITextElements | undefined;
  public syntaxResult: ISyntaxResult | undefined; // do not use this outside of SyntaxLogic class, todo: refactor
 
  public abstract getSequencedFiles(): readonly ABAPFile[];
  public abstract getDescription(): string | undefined;
 
  public constructor(name: string) {
    super(name);
    this.parsed = [];
    this.texts = undefined;
  }
 
  public static is(x: any): x is ABAPObject {
    return !!x && x instanceof ABAPObject;
  }
 
  public parse(version: Version, globalMacros?: readonly string[], reg?: IRegistry): IParseResult {
    if (this.isDirty() === false) {
      return {updated: false, runtime: 0};
    }
 
    const abapFiles = this.getFiles().filter(f => f.getFilename().endsWith(".abap"));
    const result = new ABAPParser(version, globalMacros, reg).parse(abapFiles);
 
    this.parsed = result.output;
    this.old = result.issues;
    this.dirty = false;
 
    return {updated: true, runtime: result.runtime, runtimeExtra: result.runtimeExtra};
  }
 
  public setDirty(): void {
    this.syntaxResult = undefined;
    this.texts = undefined;
    super.setDirty();
  }
 
  public getABAPFiles(): readonly ABAPFile[] {
    return this.parsed;
  }
 
  public getABAPFileByName(filename: string): ABAPFile | undefined {
    for (const p of this.parsed) {
      if (p.getFilename() === filename) {
        return p;
      }
    }
    return undefined;
  }
 
  public getMainABAPFile(): ABAPFile | undefined {
    // todo, uris, https://github.com/abaplint/abaplint/issues/673
    const search = this.getName().replace(/\//g, "#").toLowerCase() + "." + this.getType().toLowerCase() + ".abap";
    for (const file of this.getABAPFiles()) {
      if (file.getFilename().endsWith(search)) {
        return file;
      }
    }
    // uri fallback,
    for (const file of this.getABAPFiles()) {
      if (file.getFilename().endsWith(".abap")) {
        return file;
      }
    }
    return undefined;
  }
 
  public getTexts(): ITextElements {
    if (this.texts === undefined) {
      this.findTexts(this.parseRaw2());
    }
    return this.texts!;
  }
 
  protected findTexts(parsed: any) {
    this.texts = {};
 
    if (parsed?.abapGit["asx:abap"]["asx:values"]?.TPOOL?.item === undefined) {
      return;
    }
 
    for (const t of xmlToArray(parsed.abapGit["asx:abap"]["asx:values"].TPOOL.item)) {
      if (t?.ID === "I") {
        if (t.KEY === undefined) {
          throw new Error("findTexts, undefined");
        }
        const key = t.KEY;
        if (key === undefined) {
          continue;
        }
        this.texts[key.toUpperCase()] = t.ENTRY ? unescape(t.ENTRY) : "";
      }
    }
  }
 
}