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

100% Statements 34/34
100% Branches 15/15
100% Functions 3/3
100% Lines 34/34

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     5105x   5105x 5105x 12731x 12731x 422x   12309x     5105x             5105x 274x 4831x 60x     4771x         5105x 5105x 3x   5105x   5105x 358x 358x   4747x 140x 140x 140x 140x     4607x      
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};
  }
 
}