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

85.93% Statements 55/64
50% Branches 5/10
100% Functions 1/1
85.93% Lines 55/64

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 641x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 7x       7x     7x 7x 2x 2x 2x 2x 2x 5x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x   1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 7x       5x 5x 5x 5x 5x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {TypedIdentifier} from "../../types/_typed_identifier";
import {UnknownType, TableType, StructureType, CharacterType, VoidType, TableKeyType} from "../../types/basic";
import {BasicTypes} from "../basic_types";
import {Dynamic} from "../expressions/dynamic";
import {StatementSyntax} from "../_statement_syntax";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
import {Identifier} from "../../1_lexer/tokens";
 
export class SelectOption implements StatementSyntax {
  public runSyntax(node: StatementNode, input: SyntaxInput): void {
    const nameToken = node.findFirstExpression(Expressions.FieldSub)?.getFirstToken();
 
    if (nameToken && nameToken.getStr().length > 8) {
      const message = "Select-option name too long, " + nameToken.getStr();
      input.issues.push(syntaxIssue(input, nameToken, message));
      return;
    } else if (nameToken === undefined) {
      return;
    }
 
    for (const d of node.findDirectExpressions(Expressions.Dynamic)) {
      Dynamic.runSyntax(d, input);
      input.scope.addIdentifier(
        new TypedIdentifier(nameToken, input.filename, VoidType.get("DYNAMIC_SELECT_OPTION")));
      return;
    }
 
    const nameExpression = node.findFirstExpression(Expressions.FieldChain);
    let found = new BasicTypes(input).resolveLikeName(nameExpression);
    if (found) {
      if (found instanceof StructureType) {
        let length = 0;
        for (const c of found.getComponents()) {
          if (c.type instanceof CharacterType) {
            length += c.type.getLength();
          }
        }
        if (length === 0) {
          found = VoidType.get("Selectoption, fallback");
        } else {
          found = new CharacterType(length);
        }
      }
 
      const stru = new StructureType([
        {name: "SIGN", type: new CharacterType(1)},
        {name: "OPTION", type: new CharacterType(2)},
        {name: "LOW", type: found},
        {name: "HIGH", type: found},
      ]);
      input.scope.addIdentifier(
        new TypedIdentifier(nameToken, input.filename, new TableType(stru, {withHeader: true, keyType: TableKeyType.default})));
    } else {
      input.scope.addIdentifier(
        new TypedIdentifier(nameToken, input.filename, new UnknownType("Select option, fallback")));
    }
 
    const magicName = "%_" + nameToken.getStr() + "_%_app_%";
    const magicToken = new Identifier(nameToken.getStart(), magicName);
    input.scope.addIdentifier(new TypedIdentifier(magicToken, input.filename, VoidType.get("SELECT-OPTION magic")));
  }
}