All files / src/cds/expressions cds_function.ts

100% Statements 94/94
100% Branches 1/1
100% Functions 1/1
100% Lines 94/94

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 941x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x
import {CDSFunctionInput, CDSName, CDSType} from ".";
import {altPrio, Expression, regex, seq, starPrio} from "../../abap/2_statements/combi";
import {IStatementRunnable} from "../../abap/2_statements/statement_runnable";
 
export class CDSFunction extends Expression {
  public getRunnable(): IStatementRunnable {
    const coalesce = seq("COALESCE", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const concat = seq("CONCAT", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const concat_with_space = seq("CONCAT_WITH_SPACE", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const dats_add_days = seq("DATS_ADD_DAYS", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const dats_add_months = seq("DATS_ADD_MONTHS", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const dats_days_between = seq("DATS_DAYS_BETWEEN", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const dats_is_valid = seq("DATS_IS_VALID", "(", CDSFunctionInput, ")");
    const tims_is_valid = seq("TIMS_IS_VALID", "(", CDSFunctionInput, ")");
    const substring = seq("SUBSTRING", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const bintohex = seq("BINTOHEX", "(", CDSFunctionInput, ")");
    const hextobin = seq("HEXTOBIN", "(", CDSFunctionInput, ")");
 
    const upper = seq("UPPER", "(", CDSFunctionInput, ")");
    const lower = seq("LOWER", "(", CDSFunctionInput, ")");
 
    const abs = seq("ABS", "(", CDSFunctionInput, ")");
    const ceil = seq("CEIL", "(", CDSFunctionInput, ")");
    const floor = seq("FLOOR", "(", CDSFunctionInput, ")");
    const round = seq("ROUND", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const div = seq("DIV", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const division = seq("DIVISION", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const tstmp_to_dats = seq("TSTMP_TO_DATS", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const tstmp_to_tims = seq("TSTMP_TO_TIMS", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const tstmp_to_dst = seq("TSTMP_TO_DST", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const dats_tims_to_tstmp = seq("DATS_TIMS_TO_TSTMP", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const tstmp_is_valid = seq("TSTMP_IS_VALID", "(", CDSFunctionInput, ")");
    const tstmp_current_utctimestamp = seq("TSTMP_CURRENT_UTCTIMESTAMP", "(", ")");
    const utcl_current = seq("UTCL_CURRENT", "(", ")");
    const tstmp_seconds_between = seq("TSTMP_SECONDS_BETWEEN", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const tstmp_add_seconds = seq("TSTMP_ADD_SECONDS", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const abap_system_timezone = seq("ABAP_SYSTEM_TIMEZONE", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const abap_user_timezone = seq("ABAP_USER_TIMEZONE", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const mod = seq("MOD", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const replace = seq("REPLACE", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const lpad = seq("LPAD", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const rpad = seq("RPAD", "(", CDSFunctionInput, ",", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const instr = seq("INSTR", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const length = seq("LENGTH", "(", CDSFunctionInput, ")");
 
    const ltrim = seq("LTRIM", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const rtrim = seq("RTRIM", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const left = seq("LEFT", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
    const right = seq("RIGHT", "(", CDSFunctionInput, ",", CDSFunctionInput, ")");
 
    const fltp_to_dec = seq("FLTP_TO_DEC", "(", CDSFunctionInput, "AS", CDSType, ")");
 
    const curr_to_decfloat_amount = seq("CURR_TO_DECFLOAT_AMOUNT", "(", CDSFunctionInput, ")");
 
    const conversionInput = seq(CDSName, "=", ">", CDSFunctionInput);
    const conversionInputs = seq(conversionInput, starPrio(seq(",", conversionInput)));
    const unitConversion = seq("UNIT_CONVERSION", "(", conversionInputs, ")");
    const currencyConversion = seq("CURRENCY_CONVERSION", "(", conversionInputs, ")");
    const decimalShift = seq("DECIMAL_SHIFT", "(", conversionInputs, ")");
    const ratioOf = seq("RATIO_OF", "(", conversionInputs, ")");
    const replaceRegexpr = seq("REPLACE_REGEXPR", "(", conversionInputs, ")");
    const matchesRegexpr = seq("MATCHES_REGEXPR", "(", conversionInputs, ")");
    const occurrencesRegexpr = seq("OCCURRENCES_REGEXPR", "(", conversionInputs, ")");
    const substrRegexpr = seq("SUBSTR_REGEXPR", "(", conversionInputs, ")");
    const locateRegexpr = seq("LOCATE_REGEXPR", "(", conversionInputs, ")");
 
    // Generic fallback: user-defined/extension functions like GET_NUMERIC_VALUE(arg).
    // Use a regex that excludes CDS keywords that would otherwise be matched by CDSName.
    // Must contain at least one underscore to distinguish from keywords (e.g. GET_NUMERIC_VALUE).
    const extFuncName = regex(/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/i);
    const genericArgs = seq(CDSFunctionInput, starPrio(seq(",", CDSFunctionInput)));
    const genericFunc = seq(extFuncName, "(", genericArgs, ")");
 
    return altPrio(substring, coalesce, tstmp_to_dats, concat, tstmp_to_tims,
                   upper, lower, abs, ceil, floor, round, div, division,
                   concat_with_space, dats_is_valid, tims_is_valid, dats_days_between, tstmp_add_seconds,
                   tstmp_seconds_between, tstmp_current_utctimestamp, tstmp_is_valid, utcl_current,
                   abap_system_timezone, abap_user_timezone, bintohex, hextobin,
                   dats_add_days, dats_add_months, tstmp_to_dst, dats_tims_to_tstmp, mod,
                   left, right, lpad, rpad, instr, length, ltrim, rtrim, replace,
                   unitConversion, currencyConversion, decimalShift, fltp_to_dec, ratioOf,
                   replaceRegexpr, matchesRegexpr, occurrencesRegexpr, substrRegexpr, locateRegexpr,
                   curr_to_decfloat_amount,
                   genericFunc);
  }
}