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

83.05% Statements 49/59
68.18% Branches 15/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 11x 11x 11x 12x 12x 12x 12x 3x 12x 9x 9x 9x     12x 12x 1x 1x 11x 11x 10x 10x 11x 11x 11x 3x 3x 3x       3x 3x 3x 3x 3x           11x 2x 2x 11x 11x 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.found === true && found.id) {
        scope.addReference(token, found.id, found.type, 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 && found.found === true && 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);
    }
 
  }
}