All files / src/objects _abstract_object.ts

95.55% Statements 129/135
91.42% Branches 32/35
100% Functions 15/15
95.55% Lines 129/135

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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 1351x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7591x 7591x 7591x 7591x 7591x 1x 1x 329x 329x 1x 1x 251x 251x 1x 1x 45934x 45934x 1x 1x 8874x 8874x 1x 1x 7563x 7563x 7563x 1x 1x 26488x 26488x 1x 1x 194x 201x 189x 189x 201x 5x 5x 1x 1x 40x 40x 40x 40x 40x 40x 40x     1x 1x 15674x 15674x 1x 1x 85x 85x 85x     85x 85x 1x 1x 6691x 6691x 6691x 6691x 6878x 764x 764x 6878x 5927x 6691x 5951x 3x 3x 5951x 5924x 5924x 1x 1x 3147x 3147x 458x 458x 2689x 2689x 1x 1x 496x 496x 501x 495x 495x 495x 501x 1x 1x 1x 1x 2997x 2997x 2629x 2629x 368x 368x 2997x     2997x 1x 1x
import {IFile} from "../files/_ifile";
import {IAllowedNaming, IObject, IParseResult} from "./_iobject";
import {XMLParser} from "fast-xml-parser";
import {Issue} from "../issue";
import {Version} from "../version";
import {Identifier} from "../abap/4_file_information/_identifier";
import {Identifier as IdentifierToken} from "../abap/1_lexer/tokens/identifier";
import {Position} from "../position";
import {IRegistry} from "../_iregistry";
 
export abstract class AbstractObject implements IObject {
  protected old: readonly Issue[];
  protected dirty: boolean;
  private files: IFile[];
  private readonly name: string;
 
  public abstract getType(): string;
  public abstract getAllowedNaming(): IAllowedNaming;
  public abstract getDescription(): string | undefined;
 
  public constructor(name: string) {
    this.name = name;
    this.files = [];
    this.old = [];
    this.dirty = false;
  }
 
  public getParsingIssues() {
    return this.old;
  }
 
  public parse(_version?: Version, _globalMacros?: readonly string[], _reg?: IRegistry): IParseResult {
    return {updated: false, runtime: 0};
  }
 
  public getName(): string {
    return this.name;
  }
 
  public setDirty(): void {
    this.dirty = true;
  }
 
  public addFile(file: IFile) {
    this.setDirty();
    this.files.push(file);
  }
 
  public getFiles(): readonly IFile[] {
    return this.files;
  }
 
  public containsFile(filename: string): boolean {
    for (const f of this.files) {
      if (f.getFilename() === filename) {
        return true;
      }
    }
    return false;
  }
 
  public removeFile(file: IFile): void {
    this.setDirty();
    for (let i = 0; i < this.files.length; i++) {
      if (this.files[i].getFilename() === file.getFilename()) {
        this.files.splice(i, 1);
        return;
      }
    }
    throw new Error("removeFile: file not found");
  }
 
  public isDirty() {
    return this.dirty;
  }
 
  public getIdentifier(): Identifier | undefined {
    // this method can be redefined in each object type to give a better result
    const file = this.getXMLFile();
    if (file === undefined) {
      return undefined;
    }
    return new Identifier(new IdentifierToken(new Position(1, 1), this.getName()), file.getFilename());
  }
 
  public getXMLFile() {
// todo, https://github.com/abaplint/abaplint/issues/673 uris
    const expected1 = this.getName().toLowerCase().replace(/\//g, "#") + "." + this.getType().toLowerCase() + ".xml";
    const expected2 = this.getName().toLowerCase().replace(/\//g, "%23") + "." + this.getType().toLowerCase() + ".xml";
    for (const file of this.getFiles()) {
      if (file.getFilename().endsWith(expected1) || file.getFilename().endsWith(expected2)) {
        return file;
      }
    }
    // uri fallback, assume there is only one xml file
    for (const file of this.getFiles()) {
      if (file.getFilename().endsWith(".xml")) {
        return file;
      }
    }
    return undefined;
  }
 
  public getXML(): string | undefined {
    const file = this.getXMLFile();
    if (file) {
      return file.getRaw();
    }
    return undefined;
  }
 
  public updateFile(file: IFile) {
    this.setDirty();
    for (let i = 0; i < this.files.length; i++) {
      if (this.files[i].getFilename() === file.getFilename()) {
        this.files[i] = file;
        return;
      }
    }
    throw new Error("updateFile: file not found");
  }
 
  protected parseRaw2(): any | undefined {
    const xml = this.getXML();
    if (xml === undefined) {
      return undefined;
    }
    try {
      return new XMLParser({parseTagValue: false, ignoreAttributes: true, trimValues: false}).parse(xml);
    } catch {
      return undefined;
    }
  }
 
}