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

90.38% Statements 47/52
88.88% Branches 24/27
100% Functions 1/1
90.38% Lines 47/52

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 521x 1x 1x 1x 1x 1x 1x 1x 1x 1x 179x 179x 179x 179x 49x 49x 49x       49x 49x 3x 3x 3x 3x 46x 46x 49x 49x     46x 46x 49x 49x 49x 49x 49x 49x 49x 49x 49x 1x 1x 1x 1x 49x 175x 175x 175x 1x
import {ExpressionNode} from "../../nodes";
import {AnyType, CLikeType, CharacterType, NumericGenericType, NumericType, StringType, StructureType, UnknownType, VoidType} from "../../types/basic";
import {AbstractType} from "../../types/basic/_abstract_type";
import * as Expressions from "../../2_statements/expressions";
import {Source} from "./source";
import {TypeUtils} from "../_type_utils";
import {CheckSyntaxKey, SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class StringTemplate {
  public runSyntax(node: ExpressionNode, input: SyntaxInput): AbstractType {
    const typeUtils = new TypeUtils(input.scope);
    const ret = StringType.get();
 
    for (const templateSource of node.findAllExpressions(Expressions.StringTemplateSource)) {
      const s = templateSource.findDirectExpression(Expressions.Source);
      const type = new Source().runSyntax(s, input, ret);
      if (type === undefined) {
        const message = "No target type determined";
        input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
        return new VoidType(CheckSyntaxKey);
      } else if ((typeUtils.isCharLike(type) === false && typeUtils.isHexLike(type) === false)
          || type instanceof StructureType) {
        const message = "String template, not character like, " + type.constructor.name;
        input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
        return new VoidType(CheckSyntaxKey);
      }
 
      const format = templateSource.findDirectExpression(Expressions.StringTemplateFormatting);
      const formatConcat = format?.concatTokens();
      for (const formatSource of format?.findAllExpressions(Expressions.Source) || []) {
        new Source().runSyntax(formatSource, input);
      }
 
      if (format
          && formatConcat?.includes("ALPHA = ")
          && !(type instanceof UnknownType)
          && !(type instanceof VoidType)
          && !(type instanceof StringType)
          && !(type instanceof CLikeType)
          && !(type instanceof CharacterType)
          && !(type instanceof NumericGenericType)
          && !(type instanceof NumericType)
          && !(type instanceof AnyType)) {
        const message = `Cannot apply ALPHA to this type (${type.constructor.name})`;
        input.issues.push(syntaxIssue(input, format.getFirstToken(), message));
        return new VoidType(CheckSyntaxKey);
      }
    }
 
    return ret;
  }
}