UNPKG

@abaplint/core

Version:
84 lines 4.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StringTemplate = void 0; const nodes_1 = require("../../nodes"); const basic_1 = require("../../types/basic"); const Expressions = require("../../2_statements/expressions"); const source_1 = require("./source"); const _type_utils_1 = require("../_type_utils"); const _syntax_input_1 = require("../_syntax_input"); const Tokens = require("../../1_lexer/tokens"); class StringTemplate { static runSyntax(node, input) { const typeUtils = new _type_utils_1.TypeUtils(input.scope); const ret = basic_1.StringType.get(); for (const child of node.getChildren()) { if (child instanceof nodes_1.ExpressionNode && child.get() instanceof Expressions.StringTemplateSource) { const s = child.findDirectExpression(Expressions.Source); const type = source_1.Source.runSyntax(s, input, ret); if (type === undefined) { const message = "No target type determined"; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } else if ((typeUtils.isCharLike(type) === false && typeUtils.isHexLike(type) === false && !(type instanceof basic_1.UTCLongType)) || type instanceof basic_1.StructureType) { const message = "String template, not character like, " + type.constructor.name; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } const format = child.findDirectExpression(Expressions.StringTemplateFormatting); const formatConcat = format === null || format === void 0 ? void 0 : format.concatTokens(); for (const formatSource of (format === null || format === void 0 ? void 0 : format.findAllExpressions(Expressions.Source)) || []) { source_1.Source.runSyntax(formatSource, input); } if (format && (formatConcat === null || formatConcat === void 0 ? void 0 : formatConcat.includes("ALPHA = ")) && !(type instanceof basic_1.UnknownType) && !(type instanceof basic_1.VoidType) && !(type instanceof basic_1.StringType) && !(type instanceof basic_1.CLikeType) && !(type instanceof basic_1.CharacterType) && !(type instanceof basic_1.NumericGenericType) && !(type instanceof basic_1.NumericType) && !(type instanceof basic_1.AnyType)) { const message = `Cannot apply ALPHA to this type (${type.constructor.name})`; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, format.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } } else if (child instanceof nodes_1.TokenNode) { const token = child.get(); if (token instanceof Tokens.StringTemplate || token instanceof Tokens.StringTemplateBegin || token instanceof Tokens.StringTemplateMiddle || token instanceof Tokens.StringTemplateEnd) { const issue = this.validateEscapeSequences(token.getStr(), input, child); if (issue) { input.issues.push(issue); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } } } } return ret; } static validateEscapeSequences(str, input, node) { // Valid escape sequences in ABAP string templates: \|, \{, \}, \\, \n, \r, \t const validEscapes = new Set(["\\|", "\\{", "\\}", "\\\\", "\\n", "\\r", "\\t"]); for (let i = 0; i < str.length; i++) { if (str[i] === "\\") { const escape = str.substring(i, i + 2); if (!validEscapes.has(escape)) { return (0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), `Invalid escape sequence "${escape}" in string template`); } i++; // skip the next character as it's part of the escape sequence } } return undefined; } } exports.StringTemplate = StringTemplate; //# sourceMappingURL=string_template.js.map