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

91.66% Statements 66/72
83.33% Branches 15/18
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 101x 101x 101x 101x 101x 101x 101x 20x 20x 81x 81x 81x 81x 81x 101x 59x 59x 2x 2x 57x 57x 57x 59x 28x 28x 59x 13x 13x 44x 44x 44x 59x 3x 3x 3x 3x 3x 44x 101x 22x 22x 22x     22x     22x 22x 1x 1x 22x     65x 65x 65x 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 an object reference, attribute name");
    }
 
    return ret;
  }
 
}