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

90.24% Statements 74/82
76.47% Branches 13/17
100% Functions 1/1
90.24% Lines 74/82

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 821x 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 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 {CurrentScope} from "../_current_scope";
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";
 
export class TypeEnum {
  public runSyntax(node: StructureNode, scope: CurrentScope, filename: string): {values: TypedIdentifier[], types: TypedIdentifier[]} {
    let values: TypedIdentifier[] = [];
    const types: TypedIdentifier[] = [];
 
    if (!(node.get() instanceof Structures.TypeEnum)) {
      throw new Error("TypeEnum, unexpected type");
    }
 
    const begin = node.findDirectStatement(Statements.TypeEnumBegin);
    if (begin === undefined) {
      throw new Error("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, 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, filename, IntegerType.get()));
    }
 
    const baseType = begin.findExpressionAfterToken("TYPE")?.getFirstToken();
    const baseName = baseType?.getStr();
    if (baseType && baseName) {
      const found = scope.findType(baseName);
      if (found) {
        scope.addReference(baseType, found, ReferenceType.TypeReference, filename);
      }
    }
 
    const name = begin.findFirstExpression(Expressions.NamespaceSimpleName);
    if (name) {
      let qualifiedName = name.concatTokens();
      if (scope.getType() === ScopeType.ClassDefinition
          || scope.getType() === ScopeType.Interface) {
        qualifiedName = scope.getName() + "=>" + qualifiedName;
      }
      const id = new TypedIdentifier(name.getFirstToken(), filename, new EnumType({qualifiedName: qualifiedName}), [IdentifierMeta.Enum]);
      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(), filename, new StructureType(components), [IdentifierMeta.Enum]);
      values.push(id);
    }
 
    return {values, types};
  }
}