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

91.67% Statements 66/72
85% Branches 17/20
100% Functions 1/1
91.67% 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 56x 56x 56x 56x 56x 56x 56x 12x 12x 44x 44x 44x 44x 44x 56x 37x 37x 2x 2x 35x 35x 35x 37x 10x 10x 37x     35x 35x 35x 37x 2x 2x 2x 2x 2x 35x 56x 7x 7x 7x 2x 2x 7x     5x 7x 1x 1x 7x     39x 39x 39x 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;
  }
 
}