All files / src macro_references.ts

92.77% Statements 77/83
75% Branches 18/24
100% Functions 8/8
92.77% Lines 77/83

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 831x 1x 1x 1x 9913x 9913x 9913x 9913x 9913x 9913x 9913x 9913x 9913x 9913x 77x 60x 77x 13x 13x 64x 64x 9913x 9913x 6x 6x 6x 6x 6x     9913x 9913x 43x 37x 37x 43x 43x 9913x 9913x 274x 274x 10x 10x 274x 274x 9913x 9913x 10x 10x 10x 10x 4x 4x 4x 4x 10x 10x 9913x 9913x 10348x 10348x 10348x 9913x 9913x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x     9913x 9913x
import {IFilenameAndToken, IMacroReferences} from "./_imacro_references";
import {AbstractToken} from "./abap/1_lexer/tokens/abstract_token";
import {Position} from "./position";
 
export class MacroReferences implements IMacroReferences {
  private readonly definitions: {[filename: string]: {
    token: AbstractToken,
    start: Position,
    end: Position,
  }[]} = {};
 
  private readonly references: {[filename: string]: IFilenameAndToken[]} = {};
 
  public addDefinition(ref: IFilenameAndToken, start: Position, end: Position): void {
    if (this.definitions[ref.filename] === undefined) {
      this.definitions[ref.filename] = [];
    } else if (this.definitions[ref.filename].find((d) => d.token.getStart().equals(ref.token.getStart()))) {
      return;
    }
    this.definitions[ref.filename].push({token: ref.token, start, end});
  }
 
  public getDefinitionRange(filename: string, token: AbstractToken): {start: Position, end: Position} | undefined {
    for (const d of this.definitions[filename] || []) {
      if (d.token.getStart().equals(token.getStart())) {
        return {start: d.start, end: d.end};
      }
    }
    return undefined;
  }
 
  public addReference(ref: IFilenameAndToken): void {
    if (this.references[ref.filename] === undefined) {
      this.references[ref.filename] = [];
    }
    this.references[ref.filename].push(ref);
  }
 
  public listDefinitionsByFile(filename: string): AbstractToken[] {
    const ret: AbstractToken[] = [];
    for (const d of this.definitions[filename] || []) {
      ret.push(d.token);
    }
    return ret;
  }
 
  public listUsagesbyMacro(filename: string, token: AbstractToken): IFilenameAndToken[] {
    const ret: IFilenameAndToken[] = [];
    const tokenStr = token.getStr().toUpperCase();
 
    for (const ref of this.references[filename] || []) {
      if (ref.token.getStr().toUpperCase() === tokenStr) {
        ret.push(ref);
      }
    }
    return ret;
  }
 
  public clear(filename: string): void {
    delete this.definitions[filename];
    delete this.references[filename];
  }
 
  public findDefinitionByUsage(filename: string, token: AbstractToken): {filename: string, token: AbstractToken} | undefined {
    const tokenStr = token.getStr().toUpperCase();
 
    for (const ref of this.references[filename] || []) {
      if (ref.token.getStart().equals(token.getStart())) {
        for (const d of this.definitions[ref.filename] || []) {
          if (d.token.getStr().toUpperCase() === tokenStr) {
            return {
              filename: ref.filename,
              token: d.token,
            };
          }
        }

      }
    }
    return undefined;
  }
 
}