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

92.68% Statements 38/41
80.77% Branches 21/26
100% Functions 1/1
92.68% Lines 38/41

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    1x 1x 1x 1x   1x 1x     1x               52x 12x     40x   40x   40x 34x 34x 1x   33x 33x 33x 33x 8x   33x     33x 33x   33x 2x 2x 2x     33x 6x 6x 6x 6x 2x   4x     4x 4x 1x           36x      
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");
      }
      const token = node.getFirstToken();
      const name = token.getStr();
      let found: TypedIdentifier | undefined = helper.searchAttributeName(def, name);
      if (found === undefined) {
        found = helper.searchConstantName(def, name);
      }
      Iif (found === undefined) {
        throw new Error("Attribute or constant \"" + name + "\" not found in \"" + def.getName() + "\"");
      }
      Eif (type) {
        scope.addReference(token, found, type, filename);
      }
      if (found && name.includes("~")) {
        const idef = scope.findInterfaceDefinition(name.split("~")[0]);
        Eif (idef) {
          scope.addReference(token, idef, ReferenceType.ObjectOrientedReference, filename);
        }
      }
      ret = found.getType();
    } else Eif (context instanceof DataReference) {
      const sub = context.getType();
      const name = node.getFirstToken().getStr();
      if (name === "*") {
        return sub;
      }
      Iif (!(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;
  }
 
}