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

79.31% Statements 46/58
50% Branches 4/8
100% Functions 1/1
79.31% Lines 46/58

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 591x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 12x 12x     12x 12x 12x 12x       12x 12x         12x 12x 2x 2x 2x 2x 2x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 12x       10x 10x 10x 10x 10x 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 nameExpression = node.findFirstExpression(Expressions.FieldSub);
    if (nameExpression === undefined) {
      return;
    }
 
    let nameToken = nameExpression.getFirstToken();
    // FieldSub can include dashes and optional length, eg s-matnr or s_name(10).
    if (nameExpression.getChildren().length > 1) {
      const fullName = nameExpression.concatTokens().replace(/\(.+$/, "").replace(/\[\]$/, "");
      nameToken = new Identifier(nameToken.getStart(), fullName);
    }
 
    if (nameToken && nameToken.getStr().length > 8) {
      const message = "Select-option name too long, " + nameToken.getStr();
      input.issues.push(syntaxIssue(input, nameToken, message));
      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 nameChain = node.findFirstExpression(Expressions.FieldChain);
    const found = new BasicTypes(input).resolveLikeName(nameChain);
    if (found) {
      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")));
  }
}