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

98.13% Statements 105/107
94.91% Branches 56/59
100% Functions 1/1
98.13% Lines 105/107

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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 1071x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 68x 68x 68x 68x 68x 68x 68x 68x 68x 1x 1x 1x 67x 68x 68x 68x 54x 54x 20x 20x 20x 20x 54x 28x 28x 28x 34x 6x 6x 6x 6x 48x 54x 18x 18x 54x 61x 61x 68x 13x 13x 5x 13x 1x 1x 8x 7x 7x 7x 7x 13x 54x 68x 1x 1x 54x 54x 54x 68x 4x 4x 54x 68x 2x 2x 54x 68x 12x 12x 68x     54x 68x 5x 5x 54x 68x 68x 68x 52x 52x 2x 2x 52x 68x 4x 4x 4x 68x 68x 1x
import * as Expressions from "../../2_statements/expressions";
import {ExpressionNode, StatementNode} from "../../nodes";
import {Source} from "../expressions/source";
import {IReferenceExtras, ReferenceType} from "../_reference";
import {ObjectReferenceType, VoidType} from "../../types/basic";
import {StatementSyntax} from "../_statement_syntax";
import {MessageSource} from "../expressions/message_source";
import {RaiseWith} from "../expressions/raise_with";
import {ObjectOriented} from "../_object_oriented";
import {IMethodDefinition} from "../../types/_method_definition";
import {MethodParameters} from "../expressions/method_parameters";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class Raise implements StatementSyntax {
  public runSyntax(node: StatementNode, input: SyntaxInput): void {
 
// todo
 
    const helper = new ObjectOriented(input.scope);
    let method: IMethodDefinition | VoidType | undefined;
 
    const exceptionName = node.findDirectExpression(Expressions.ExceptionName);
    const classicMessage = exceptionName ? helper.checkClassicException() : undefined;
    if (exceptionName && classicMessage) {
      input.issues.push(syntaxIssue(input, exceptionName.getFirstToken(), classicMessage));
      return;
    }
 
    const classTok = node.findDirectExpression(Expressions.ClassName)?.getFirstToken();
    const className = classTok?.getStr();
    if (classTok && className) {
      const found = input.scope.existsObject(className);
      if (found?.id) {
        input.scope.addReference(classTok, found.id, ReferenceType.ObjectOrientedReference, input.filename);
 
        const def = input.scope.findObjectDefinition(className);
        method = helper.searchMethodName(def, "CONSTRUCTOR")?.method;
      } else if (input.scope.getDDIC().inErrorNamespace(className) === false) {
        const extra: IReferenceExtras = {ooName: className, ooType: "Void"};
        input.scope.addReference(classTok, undefined, ReferenceType.ObjectOrientedVoidReference, input.filename, extra);
        method = VoidType.get(className);
      } else {
        const message = "RAISE, unknown class " + className;
        input.issues.push(syntaxIssue(input, classTok, message));
        return;
      }
 
      if (method === undefined) {
        method = VoidType.get(className);
      }
    }
 
    const c = node.findExpressionAfterToken("EXCEPTION");
    if (c instanceof ExpressionNode && (c.get() instanceof Expressions.SimpleSource2 || c.get() instanceof Expressions.Source)) {
      const type = Source.runSyntax(c, input);
      if (type instanceof VoidType) {
        method = type;
      } else if (type instanceof ObjectReferenceType) {
        const def = input.scope.findObjectDefinition(type.getIdentifierName());
        method = helper.searchMethodName(def, "CONSTRUCTOR")?.method;
      } else if (type !== undefined) {
        const message = "RAISE EXCEPTION, must be object reference, got " + type.constructor.name;
        input.issues.push(syntaxIssue(input, c.getFirstToken(), message));
        return;
      }
    }
 
    if (method === undefined) {
      method = VoidType.get("Exception");
    }
 
    // check parameters vs constructor
    const param = node.findDirectExpression(Expressions.ParameterListS);
    if (param) {
      new MethodParameters().checkExporting(param, input, method, true);
    }
 
    for (const s of node.findDirectExpressions(Expressions.RaiseWith)) {
      RaiseWith.runSyntax(s, input);
    }
 
    for (const s of node.findDirectExpressions(Expressions.Source)) {
      Source.runSyntax(s, input);
    }
    for (const s of node.findDirectExpressions(Expressions.SimpleSource2)) {
      Source.runSyntax(s, input);
    }
 
    for (const s of node.findDirectExpressions(Expressions.MessageSource)) {
      MessageSource.runSyntax(s, input);
    }
 
    const id = node.findExpressionAfterToken("ID")?.concatTokens();
    let number = node.findDirectExpression(Expressions.MessageNumber)?.concatTokens();
    if (number === undefined) {
      const num = node.findExpressionAfterToken("NUMBER")?.concatTokens();
      if (num?.startsWith("'")) {
        number = num.substring(1, num.length - 1).toUpperCase();
      }
    }
    if (id?.startsWith("'") && number) {
      const messageClass = id.substring(1, id.length - 1).toUpperCase();
      input.scope.getMSAGReferences().addUsing(input.filename, node.getFirstToken(), messageClass, number);
    }
 
  }
}