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

71.66% Statements 43/60
14.28% Branches 1/7
100% Functions 1/1
71.66% Lines 43/60

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 601x 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 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 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 new VoidType(CheckSyntaxKey);
    }
 
    const children = node.getChildren().slice();
    const first = children[0];
    if (!(first.get() instanceof AttributeName)) {
      input.issues.push(syntaxIssue(input, node.getFirstToken(), "AttributeChain, unexpected first child"));
      return new VoidType(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 new VoidType(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 new VoidType(CheckSyntaxKey);
    }
    for (const t of type) {
      input.scope.addReference(nameToken, context, t, input.filename);
    }
 
// todo, loop, handle ArrowOrDash, ComponentName, TableExpression
 
    return context.getType();
  }
 
}