All files / src/abap/5_syntax/statements catch.ts

83.05% Statements 49/59
72.72% Branches 16/22
100% Functions 1/1
83.05% Lines 49/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 13x 13x 13x 14x 14x 14x 14x 4x 14x 10x 10x 10x     14x 14x 1x 1x 13x 13x 12x 12x 13x 13x 13x 3x 3x 3x       3x 3x 3x 3x 3x           13x 3x 3x 13x 13x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {TypedIdentifier, IdentifierMeta} from "../../types/_typed_identifier";
import {UnknownType} from "../../types/basic/unknown_type";
import {ObjectReferenceType, VoidType} from "../../types/basic";
import {Target} from "../expressions/target";
import {IReferenceExtras, ReferenceType} from "../_reference";
import {StatementSyntax} from "../_statement_syntax";
 
export class Catch implements StatementSyntax {
  public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void {
 
    const names = new Set<string>();
    for (const c of node.findDirectExpressions(Expressions.ClassName)) {
      const token = c.getFirstToken();
      const className = token.getStr().toUpperCase();
      const found = scope.existsObject(className);
      if (found?.id) {
        scope.addReference(token, found.id, ReferenceType.ObjectOrientedReference, filename);
      } else if (scope.getDDIC().inErrorNamespace(className) === false) {
        const extra: IReferenceExtras = {ooName: className, ooType: "Void"};
        scope.addReference(token, undefined, ReferenceType.ObjectOrientedVoidReference, filename, extra);
      } else {
        throw new Error("CATCH, unknown class " + className);
      }
 
      if (names.has(className)) {
        throw new Error("Duplicate class name in CATCH: " + className);
      }
      names.add(className);
    }
 
    const target = node.findDirectExpression(Expressions.Target);
    const firstClassName = node.findDirectExpression(Expressions.ClassName)?.getFirstToken().getStr();
 
    if (target?.findDirectExpression(Expressions.InlineData)) {
      const token = target.findFirstExpression(Expressions.TargetField)?.getFirstToken();
      const found = scope.existsObject(firstClassName);
      if (token && firstClassName && found?.id) {
        const identifier = new TypedIdentifier(token, filename, new ObjectReferenceType(found.id), [IdentifierMeta.InlineDefinition]);
        scope.addIdentifier(identifier);
        scope.addReference(token, identifier, ReferenceType.DataWriteReference, filename);
      } else if (token && scope.getDDIC().inErrorNamespace(firstClassName) === false) {
        const identifier = new TypedIdentifier(token, filename, new VoidType(firstClassName), [IdentifierMeta.InlineDefinition]);
        scope.addIdentifier(identifier);
        scope.addReference(token, identifier, ReferenceType.DataWriteReference, filename);
      } else if (token) {
        const message = "Catch, could not determine type for \"" + token.getStr() + "\"";
        const identifier = new TypedIdentifier(token, filename, new UnknownType(message), [IdentifierMeta.InlineDefinition]);
        scope.addIdentifier(identifier);
        scope.addReference(token, identifier, ReferenceType.DataWriteReference, filename);
      }
    } else if (target) {
      new Target().runSyntax(target, scope, filename);
    }
 
  }
}