All files / src/abap/5_syntax/statements include_type.ts

84.09% Statements 74/88
82.75% Branches 24/29
100% Functions 1/1
84.09% Lines 74/88

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 881x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 39x 39x 39x 39x     39x 39x 39x 39x 39x 39x 12x 12x 7x 7x 7x 12x 39x 39x 39x 9x 9x 9x 9x 9x 39x 2x 2x 39x 12x 39x     27x 39x 1x 1x 1x 1x 26x 39x 39x 5x 5x 10x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 26x 26x 26x 39x     39x 26x 26x                 26x 26x 26x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {IStructureComponent, StructureType, TableType, UnknownType, VoidType} from "../../types/basic";
import {BasicTypes} from "../basic_types";
import {TypedIdentifier} from "../../types/_typed_identifier";
import {CheckSyntaxKey, SyntaxInput, syntaxIssue} from "../_syntax_input";
import {AssertError} from "../assert_error";
import {ReferenceType} from "../_reference";
 
export class IncludeType {
  public runSyntax(node: StatementNode, input: SyntaxInput): IStructureComponent[] | VoidType | UnknownType {
    const components: IStructureComponent[] = [];
 
    const iname = node.findFirstExpression(Expressions.TypeName);
    if (iname === undefined) {
      throw new AssertError("IncludeType, unexpected node structure");
    }
    const firstToken = iname.getFirstToken();
    const name = firstToken.getStr();
    const isStructure = node.findDirectTokenByText("STRUCTURE") !== undefined;
 
    let ityp = new BasicTypes(input).parseType(iname);
    if ((ityp instanceof VoidType && isStructure) || ityp instanceof UnknownType) {
      const found = input.scope.findVariable(name);
      if (found) {
        input.scope.addReference(firstToken, found, ReferenceType.DataReadReference, input.filename);
        ityp = found.getType();
      }
    }
 
    const as = node.findExpressionAfterToken("AS")?.concatTokens();
    if (as && ityp instanceof StructureType) {
      ityp = new StructureType(ityp.getComponents().concat([{
        name: as,
        type: ityp,
        asInclude: true,
      }]));
    } else if (ityp instanceof TableType && isStructure) {
      ityp = ityp.getRowType();
    }
    if (ityp instanceof VoidType) {
      return ityp;
    } else if (ityp instanceof UnknownType) {
      return ityp;
    }
 
    if (!(ityp instanceof StructureType)) {
      const message = "not structured, " + name;
      input.issues.push(syntaxIssue(input, iname.getFirstToken(), message));
      return VoidType.get(CheckSyntaxKey);
    }
 
    const suffix = node.findExpressionAfterToken("SUFFIX")?.concatTokens();
    if (suffix && ityp instanceof StructureType) {
      const components: IStructureComponent[] = [];
      for (const c of ityp.getComponents()) {
        if (c.name === as) {
          components.push({...c, suffix: suffix, asInclude: c.asInclude});
          continue;
        }
        components.push({
          name: c.name + suffix,
          type: c.type,
        });
      }
      ityp = new StructureType(components);
    }
 
    if (ityp
        && ityp instanceof TypedIdentifier
        && ityp.getType() instanceof StructureType) {
      const stru = ityp.getType() as StructureType;
      components.push(...stru.getComponents());
    } else if (ityp && ityp instanceof StructureType) {
      components.push(...ityp.getComponents());
    } else if (ityp && ityp instanceof VoidType) {
      return ityp;
    } else if (input.scope.getDDIC().inErrorNamespace(name) === false) {
      return VoidType.get(name);
    } else {
      const message = "IncludeType, type not found \"" + iname.concatTokens() + "\"";
      input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
      return VoidType.get(CheckSyntaxKey);
    }
 
    return components;
  }
}