All files / src/abap/3_structures structure_parser.ts

100% Statements 66/66
100% Branches 17/17
100% Functions 3/3
100% Lines 66/66

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 661x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7580x 7580x 7580x 7580x 25643x 25643x 974x 974x 24669x 24669x 7580x 7580x 7580x 1x 1x 1x 1x 7580x 7580x 379x 7580x 87x 7201x 7114x 7114x 7114x 7580x 1x 1x 7580x 7580x 3x 3x 7580x 7580x 7580x 392x 392x 392x 7580x 188x 188x 188x 188x 188x 7000x 7000x 7000x 1x 1x
import {Unknown, Empty, Comment as StatementComment} from "../2_statements/statements/_statement";
import {IStructure} from "./structures/_structure";
import * as Structures from "./structures";
import {Issue} from "../../issue";
import {StructureNode, StatementNode} from "../nodes";
import {Position} from "../../position";
import {IStructureResult} from "./structure_result";
import {IStatementResult} from "../2_statements/statement_result";
import {IFile} from "../../files/_ifile";
import {Severity} from "../../severity";
import {IStructureRunnable} from "./structures/_structure_runnable";
 
export class StructureParser {
  private static readonly singletons: {[index: string]: IStructureRunnable} = {};
 
  public static run(input: IStatementResult): IStructureResult {
    const structure = this.findStructureForFile(input.file.getFilename());
 
    const filtered: StatementNode[] = [];
    for (const s of input.statements) {
      const get = s.get();
      if (get instanceof StatementComment || get instanceof Empty || get instanceof Unknown) {
        continue;
      }
      filtered.push(s);
    }
 
    return this.runFile(structure, input.file, filtered);
  }
 
//////////////////
 
  private static findStructureForFile(filename: string): IStructure {
// todo, not sure this is the right place for this logic
    if (filename.endsWith(".clas.abap")) {
      return new Structures.ClassGlobal();
    } else if (filename.endsWith(".intf.abap")) {
      return new Structures.InterfaceGlobal();
    } else {
// todo, add a special structure for TYPE-POOLS
      return new Structures.Any();
    }
  }
 
  private static runFile(structure: IStructure, file: IFile, statements: StatementNode[]): {issues: Issue[], node?: StructureNode} {
    const parent = new StructureNode(structure);
    if (this.singletons[structure.constructor.name] === undefined) {
      this.singletons[structure.constructor.name] = structure.getMatcher();
    }
    const result = this.singletons[structure.constructor.name].run(statements, parent);
 
    if (result.error) {
      const issue = Issue.atPosition(file, new Position(1, 1), result.errorDescription, "structure", Severity.Error);
      return {issues: [issue], node: undefined};
    }
    if (result.unmatched.length > 0) {
      const statement = result.unmatched[0];
      const descr = "Unexpected " + statement.get().constructor.name.toUpperCase();
      const issue = Issue.atPosition(file, statement.getStart(), descr, "structure", Severity.Error);
      return {issues: [issue], node: undefined};
    }
 
    return {issues: [], node: parent};
  }
 
}