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

90.47% Statements 76/84
76.47% Branches 13/17
100% Functions 1/1
90.47% Lines 76/84

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 841x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 14x 14x 14x 14x     14x 14x 14x     14x 14x 14x 14x     14x 14x 14x 14x 14x 9x 9x     9x 9x 9x 9x 14x 14x 14x 14x 4x 4x 3x 3x 4x 14x 14x 14x 14x 14x 14x 5x 5x 14x 14x 14x 14x 14x 14x 14x 14x 6x 6x 13x 13x 13x 13x 13x 6x 6x 6x 6x 14x 14x 14x 1x
import * as Expressions from "../../2_statements/expressions";
import * as Statements from "../../2_statements/statements";
import * as Structures from "../../3_structures/structures";
import {StructureNode} from "../../nodes";
import {IntegerType, IStructureComponent, StructureType} from "../../types/basic";
import {IdentifierMeta, TypedIdentifier} from "../../types/_typed_identifier";
import {ReferenceType} from "../_reference";
import {EnumType} from "../../types/basic/enum_type";
import {ScopeType} from "../_scope_type";
import {SyntaxInput} from "../_syntax_input";
import {AssertError} from "../assert_error";
 
export class TypeEnum {
  public runSyntax(node: StructureNode, input: SyntaxInput): {values: TypedIdentifier[], types: TypedIdentifier[]} {
    let values: TypedIdentifier[] = [];
    const types: TypedIdentifier[] = [];
 
    if (!(node.get() instanceof Structures.TypeEnum)) {
      throw new AssertError("TypeEnum, unexpected type");
    }
 
    const begin = node.findDirectStatement(Statements.TypeEnumBegin);
    if (begin === undefined) {
      throw new AssertError("TypeEnum, unexpected type, begin");
    }
 
    for (const type of node.findDirectStatements(Statements.Type)) {
      const expr = type.findFirstExpression(Expressions.NamespaceSimpleName);
      if (expr === undefined) {
        continue;
      }
      const token = expr.getFirstToken();
      // integer is default if BASE TYPE is not specified
      values.push(new TypedIdentifier(token, input.filename, IntegerType.get()));
    }
    for (const type of node.findDirectStatements(Statements.TypeEnum)) {
      const expr = type.findFirstExpression(Expressions.NamespaceSimpleName);
      if (expr === undefined) {
        continue;
      }
      const token = expr.getFirstToken();
      // integer is default if BASE TYPE is not specified
      values.push(new TypedIdentifier(token, input.filename, IntegerType.get()));
    }
 
    const baseType = begin.findExpressionAfterToken("TYPE")?.getFirstToken();
    const baseName = baseType?.getStr();
    if (baseType && baseName) {
      const found = input.scope.findType(baseName);
      if (found) {
        input.scope.addReference(baseType, found, ReferenceType.TypeReference, input.filename);
      }
    }
 
    const name = begin.findFirstExpression(Expressions.NamespaceSimpleName);
    if (name) {
      let qualifiedName = name.concatTokens();
      if (input.scope.getType() === ScopeType.ClassDefinition
          || input.scope.getType() === ScopeType.Interface) {
        qualifiedName = input.scope.getName() + "=>" + qualifiedName;
      }
      const etype = new EnumType({qualifiedName: qualifiedName});
      const id = new TypedIdentifier(name.getFirstToken(), input.filename, etype, [IdentifierMeta.Enum]);
      input.scope.addType(id);
      types.push(id);
    }
 
    const stru = begin.findExpressionAfterToken("STRUCTURE");
    if (stru) {
      const components: IStructureComponent[] = [];
      for (const r of values) {
        components.push({
          name: r.getName(),
          type: r.getType(),
        });
      }
      values = [];
      const id = new TypedIdentifier(stru.getFirstToken(), input.filename, new StructureType(components), [IdentifierMeta.Enum]);
      values.push(id);
    }
 
    return {values, types};
  }
}