All files / src/abap/5_syntax/structures data.ts

91.4% Statements 117/128
90.74% Branches 49/54
100% Functions 2/2
91.4% Lines 117/128

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 1281x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 107x 107x 107x 8x 8x 8x 99x 99x 99x 107x 1x 1x 99x 99x 99x 99x 107x 326x 326x 117x 117x 117x 117x 2x 2x 117x 326x 1x 1x 1x 1x 209x 99x 21x 21x 208x 17x 17x 17x 7x 3x 3x 7x 4x 4x 17x     10x 17x 13x 13x 10x 326x 92x 107x 18x 18x 107x 74x 74x 74x 107x 1x 1x 8x 24x 24x 2x 2x 2x 2x 24x         22x 1x 1x 1x 1x 22x 1x 1x 1x 1x 21x 1x 1x 1x 1x 20x 1x 19x 1x 18x 1x 17x           24x 8x 1x
import {SyntaxInput} from "../_syntax_input";
import {Data as DataSyntax} from "../statements/data";
import {IStructureComponent} from "../../types/basic";
import {StatementNode, StructureNode, TokenNode} from "../../nodes";
import {Identifier as TokenIdentifier} from "../../1_lexer/tokens/identifier";
import {Type} from "../statements/type";
import {TypedIdentifier} from "../../types/_typed_identifier";
import {Types} from "./types";
import * as Basic from "../../types/basic";
import * as Expressions from "../../2_statements/expressions";
import * as Statements from "../../2_statements/statements";
import * as Structures from "../../3_structures/structures";
import {IncludeType} from "../statements/include_type";
import {Constant} from "../statements/constant";
import {Constants} from "./constants";
import {Ranges} from "../statements/ranges";
import {SelectOption} from "../statements/selectoption";
import {Parameter} from "../statements/parameter";
 
export class Data {
  public static runSyntax(node: StructureNode, input: SyntaxInput): TypedIdentifier | undefined {
    const fouth = node.getFirstChild()?.getChildren()[3];
    const isCommonPart = fouth instanceof TokenNode && fouth.concatTokens().toUpperCase() === "COMMON";
    if (isCommonPart) {
      this.runCommonPartSyntax(node, input);
      return undefined;
    }
 
    const nameExpr = node.findFirstExpression(Expressions.DefinitionName)!;
    let name = nameExpr.getFirstToken();
    if (nameExpr.countTokens() > 1) { // workaround for names with dashes
      name = new TokenIdentifier(name.getStart(), nameExpr.concatTokens());
    }
    let table: boolean = false;
    const values: {[index: string]: string} = {};
 
    const components: IStructureComponent[] = [];
    for (const c of node.getChildren()) {
      const ctyp = c.get();
      if (c instanceof StatementNode && ctyp instanceof Statements.Data) {
        const found = new DataSyntax().runSyntax(c, input);
        if (found) {
          components.push({name: found.getName(), type: found.getType()});
          if (found.getValue() !== undefined) {
            values[found.getName()] = found.getValue() as string;
          }
        }
      } else if (c instanceof StructureNode && ctyp instanceof Structures.Data) {
        const found = Data.runSyntax(c, input);
        if (found) {
          components.push({name: found.getName(), type: found.getType()});
        }
      } else if (c instanceof StatementNode && ctyp instanceof Statements.DataBegin) {
        if (c.findDirectTokenByText("OCCURS")) {
          table = true;
        }
      } else if (c instanceof StatementNode && ctyp instanceof Statements.IncludeType) {
        // INCLUDES
        const found = new IncludeType().runSyntax(c, input);
        if (found instanceof Basic.VoidType) {
          if (table === true) {
            const ttyp = new Basic.TableType(found, {withHeader: true, keyType: Basic.TableKeyType.default});
            return new TypedIdentifier(name, input.filename, ttyp);
          } else {
            return new TypedIdentifier(name, input.filename, found);
          }
        } else if (found instanceof Basic.UnknownType) {
          return new TypedIdentifier(name, input.filename, found);
        }
 
        for (const c of found) {
          components.push(c);
        }
      }
    }
 
    if (table === true) {
      return new TypedIdentifier(name, input.filename, new Basic.TableType(
        new Basic.StructureType(components), {withHeader: true, keyType: Basic.TableKeyType.default}));
    } else {
      const val = Object.keys(values).length > 0 ? values : undefined;
      return new TypedIdentifier(name, input.filename, new Basic.StructureType(components), undefined, val);
    }
  }
 
  private static runCommonPartSyntax(node: StructureNode, input: SyntaxInput): void {
    for (const c of node.getChildren()) {
      const ctyp = c.get();
      if (c instanceof StatementNode && ctyp instanceof Statements.Data) {
        const found = new DataSyntax().runSyntax(c, input);
        if (found) {
          input.scope.addIdentifier(found);
        }
      } else if (c instanceof StructureNode && ctyp instanceof Structures.Data) {
        const found = Data.runSyntax(c, input);
        if (found) {
          input.scope.addIdentifier(found);
        }
      } else if (c instanceof StatementNode && ctyp instanceof Statements.Type) {
        const found = new Type().runSyntax(c, input);
        if (found) {
          input.scope.addType(found);
        }
      } else if (c instanceof StructureNode && ctyp instanceof Structures.Types) {
        const found = new Types().runSyntax(c, input);
        if (found) {
          input.scope.addType(found);
        }
      } else if (c instanceof StatementNode && ctyp instanceof Statements.Constant) {
        const found = new Constant().runSyntax(c, input);
        if (found) {
          input.scope.addIdentifier(found);
        }
      } else if (c instanceof StatementNode && ctyp instanceof Statements.Ranges) {
        new Ranges().runSyntax(c, input);
      } else if (c instanceof StatementNode && ctyp instanceof Statements.SelectOption) {
        new SelectOption().runSyntax(c, input);
      } else if (c instanceof StatementNode && ctyp instanceof Statements.Parameter) {
        new Parameter().runSyntax(c, input);
      } else if (c instanceof StructureNode && ctyp instanceof Structures.Constants) {
        const {type: found, values: _} = new Constants().runSyntax(c, input);
        if (found) {
          input.scope.addIdentifier(found);
        }
      }
    }
  }
}