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

71.18% Statements 42/59
14.28% Branches 1/7
100% Functions 1/1
71.18% Lines 42/59

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 591x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x   4x       4x 4x 4x       4x 4x 4x         4x 4x 4x 4x 4x 4x     4x         4x 4x 4x 4x 4x 4x 4x 4x 1x 1x
import {INode} from "../../nodes/_inode";
import {AbstractType} from "../../types/basic/_abstract_type";
import {VoidType} from "../../types/basic/void_type";
import {ObjectReferenceType} from "../../types/basic/object_reference_type";
import {ObjectOriented} from "../_object_oriented";
import {ReferenceType} from "../_reference";
import {TypedIdentifier} from "../../types/_typed_identifier";
import {AttributeName} from "../../2_statements/expressions";
import {CheckSyntaxKey, SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class AttributeChain {
  public static runSyntax(
    inputContext: AbstractType | undefined,
    node: INode,
    input: SyntaxInput,
    type: ReferenceType[]): AbstractType | undefined {
 
    if (inputContext instanceof VoidType) {
      return inputContext;
    } else if (!(inputContext instanceof ObjectReferenceType)) {
      input.issues.push(syntaxIssue(input, node.getFirstToken(), "Not an object reference(AttributeChain)"));
      return VoidType.get(CheckSyntaxKey);
    }
 
    const first = node.getChildren()[0];
    if (!(first.get() instanceof AttributeName)) {
      input.issues.push(syntaxIssue(input, node.getFirstToken(), "AttributeChain, unexpected first child"));
      return VoidType.get(CheckSyntaxKey);
    }
 
    const def = input.scope.findObjectDefinition(inputContext.getIdentifierName());
    if (def === undefined) {
      const message = "Definition for \"" + inputContext.getIdentifierName() + "\" not found in scope(AttributeChain)";
      input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
      return VoidType.get(CheckSyntaxKey);
    }
    const nameToken = first.getFirstToken();
    const name = nameToken.getStr();
    const helper = new ObjectOriented(input.scope);
 
    let context: TypedIdentifier | undefined = helper.searchAttributeName(def, name);
    if (context === undefined) {
      context = helper.searchConstantName(def, name);
    }
    if (context === undefined) {
      const message = "Attribute or constant \"" + name + "\" not found in \"" + def.getName() + "\"";
      input.issues.push(syntaxIssue(input, nameToken, message));
      return VoidType.get(CheckSyntaxKey);
    }
    for (const t of type) {
      input.scope.addReference(nameToken, context, t, input.filename);
    }
 
// todo, loop, handle ArrowOrDash, ComponentName, TableExpression
 
    return context.getType();
  }
 
}