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

80.95% Statements 51/63
72.72% Branches 16/22
100% Functions 1/1
80.95% Lines 51/63

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 631x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 12x 12x 12x 13x 13x 13x 13x 4x 13x 9x 9x 9x         13x 13x 1x 1x 1x 1x 12x 12x 11x 11x 12x 12x 12x 4x 4x 4x       4x 4x 4x 4x 4x           12x 3x 3x 12x 12x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
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";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class Catch implements StatementSyntax {
  public runSyntax(node: StatementNode, input: SyntaxInput): 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 = input.scope.existsObject(className);
      if (found?.id) {
        input.scope.addReference(token, found.id, ReferenceType.ObjectOrientedReference, input.filename);
      } else if (input.scope.getDDIC().inErrorNamespace(className) === false) {
        const extra: IReferenceExtras = {ooName: className, ooType: "Void"};
        input.scope.addReference(token, undefined, ReferenceType.ObjectOrientedVoidReference, input.filename, extra);
      } else {
        const message = "CATCH, unknown class " + className;
        input.issues.push(syntaxIssue(input, token, message));
        return;
      }
 
      if (names.has(className)) {
        const message = "Duplicate class name in CATCH: " + className;
        input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
        return;
      }
      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 = input.scope.existsObject(firstClassName);
      if (token && firstClassName && found?.id) {
        const identifier = new TypedIdentifier(token, input.filename, new ObjectReferenceType(found.id), [IdentifierMeta.InlineDefinition]);
        input.scope.addIdentifier(identifier);
        input.scope.addReference(token, identifier, ReferenceType.DataWriteReference, input.filename);
      } else if (token && input.scope.getDDIC().inErrorNamespace(firstClassName) === false) {
        const identifier = new TypedIdentifier(token, input.filename, VoidType.get(firstClassName), [IdentifierMeta.InlineDefinition]);
        input.scope.addIdentifier(identifier);
        input.scope.addReference(token, identifier, ReferenceType.DataWriteReference, input.filename);
      } else if (token) {
        const message = "Catch, could not determine type for \"" + token.getStr() + "\"";
        const identifier = new TypedIdentifier(token, input.filename, new UnknownType(message), [IdentifierMeta.InlineDefinition]);
        input.scope.addIdentifier(identifier);
        input.scope.addReference(token, identifier, ReferenceType.DataWriteReference, input.filename);
      }
    } else if (target) {
      Target.runSyntax(target, input);
    }
 
  }
}