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

96.73% Statements 89/92
89.18% Branches 33/37
100% Functions 1/1
96.73% Lines 89/92

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 921x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 82x 82x 82x 82x 82x 82x 273x 273x 103x 103x 103x 103x 2x 2x 103x 273x 1x 1x 1x 1x 170x 82x 16x 16x 169x 9x 9x 9x 9x 9x 9x 6x 6x 9x 9x 9x 3x 3x   3x 3x 3x 9x 6x 6x 9x 3x 2x 2x 3x 1x 1x 3x 9x     9x 1x 1x 9x 1x 1x 1x 1x 5x 5x 5x 5x 273x 78x 82x 14x 14x 82x 64x 64x 64x 82x 1x
import * as Expressions from "../../2_statements/expressions";
import * as Statements from "../../2_statements/statements";
import * as Structures from "../../3_structures/structures";
import {StatementNode, StructureNode} from "../../nodes";
import {TypedIdentifier} from "../../types/_typed_identifier";
import * as Basic from "../../types/basic";
import {IStructureComponent} from "../../types/basic";
import {Data as DataSyntax} from "../statements/data";
import {ReferenceType} from "../_reference";
import {CheckSyntaxKey, SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class Data {
  public runSyntax(node: StructureNode, input: SyntaxInput): TypedIdentifier | undefined {
    const name = node.findFirstExpression(Expressions.DefinitionName)!.getFirstToken();
    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 = new 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 typeToken = c.findFirstExpression(Expressions.TypeName)?.getFirstToken();
        const typeName = typeToken?.getStr();
 
        let foundId = input.scope.findType(typeName);
        if (foundId === undefined) {
          foundId = input.scope.findVariable(typeName);
        }
 
        let found = foundId?.getType();
        if (found === undefined) {
          const f = input.scope.getDDIC().lookupTableOrView(typeName).type;
          if (f instanceof TypedIdentifier) {
            found = f.getType();
          } else {
            found = f;
          }
        } else {
          input.scope.addReference(typeToken, foundId, ReferenceType.TypeReference, input.filename);
        }
        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);
          }
        }
        if (found instanceof Basic.UnknownType) {
          return new TypedIdentifier(name, input.filename, new Basic.UnknownType("unknown type, " + typeName));
        }
        if (found instanceof Basic.TableType && found.isWithHeader()) {
          found = found.getRowType();
        }
        if (!(found instanceof Basic.StructureType)) {
          const message = "not structured, " + typeName;
          input.issues.push(syntaxIssue(input, typeToken!, message));
          return new TypedIdentifier(name, input.filename, new Basic.VoidType(CheckSyntaxKey));
        }
        for (const c of found.getComponents()) {
          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);
    }
  }
}