All files / src/abap/5_syntax/expressions attribute_name.ts

91.66% Statements 66/72
85% Branches 17/20
100% Functions 1/1
91.66% Lines 66/72

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 721x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 85x 85x 85x 85x 85x 85x 85x 19x 19x 66x 66x 66x 66x 66x 85x 43x 43x 2x 2x 41x 41x 41x 43x 14x 14x 43x     41x 41x 41x 43x 3x 3x 3x 3x 3x 41x 85x 23x 23x 23x 1x 1x 23x     22x 23x 1x 1x 23x     62x 62x 62x 1x 1x
import {INode} from "../../nodes/_inode";
import {AbstractType} from "../../types/basic/_abstract_type";
import {VoidType} from "../../types/basic/void_type";
import {StructureType} from "../../types/basic/structure_type";
import {ObjectReferenceType} from "../../types/basic/object_reference_type";
import {ObjectOriented} from "../_object_oriented";
import {CurrentScope} from "../_current_scope";
import {DataReference} from "../../types/basic/data_reference_type";
import {ReferenceType} from "../_reference";
import {TypedIdentifier} from "../../types/_typed_identifier";
 
export class AttributeName {
  public runSyntax(
    context: AbstractType | undefined,
    node: INode,
    scope: CurrentScope,
    filename: string,
    type?: ReferenceType | undefined): AbstractType | undefined {
 
    if (context instanceof VoidType) {
      return context;
    }
 
    const helper = new ObjectOriented(scope);
 
    let ret: AbstractType | undefined = undefined;
 
    if (context instanceof ObjectReferenceType) {
      const def = scope.findObjectDefinition(context.getIdentifierName());
      if (def === undefined) {
        throw new Error("Definition for \"" + context.getIdentifierName() + "\" not found in scope(AttributeName)");
      }
      const token = node.getFirstToken();
      const name = token.getStr();
      let found: TypedIdentifier | undefined = helper.searchAttributeName(def, name);
      if (found === undefined) {
        found = helper.searchConstantName(def, name);
      }
      if (found === undefined) {
        throw new Error("Attribute or constant \"" + name + "\" not found in \"" + def.getName() + "\"");
      }
      if (type) {
        scope.addReference(token, found, type, filename);
      }
      if (found && name.includes("~")) {
        const idef = scope.findInterfaceDefinition(name.split("~")[0]);
        if (idef) {
          scope.addReference(token, idef, ReferenceType.ObjectOrientedReference, filename);
        }
      }
      ret = found.getType();
    } else if (context instanceof DataReference) {
      const sub = context.getType();
      const name = node.getFirstToken().getStr();
      if (name === "*") {
        return sub;
      }
      if (!(sub instanceof StructureType)) {
        throw new Error("Data reference not structured");
      }
      ret = sub.getComponentByName(name);
      if (ret === undefined) {
        throw new Error("Component \"" + name + "\" not found in data reference structure");
      }
    } else {
      throw new Error("Not a object reference, attribute name");
    }
 
    return ret;
  }
 
}