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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11x 11x 11x 11x 11x 11x 1x 1x 1x 1x 24x 24x 24x 24x 14x 14x 10x 10x 24x 5x 5x 5x 24x 24x 24x 2x 2x 3x 3x 24x 24x 1x 1x 1x 1x 1x 2x 2x 2x 2x | import * as Expressions from "../../2_statements/expressions";
import {ExpressionNode, StatementNode} from "../../nodes";
import {Source} from "../expressions/source";
import {StatementSyntax} from "../_statement_syntax";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
import {BuiltIn} from "../_builtin";
import {ObjectOriented} from "../_object_oriented";
import {ObjectReferenceType} from "../../types/basic";
import {LanguageVersion, Release, releaseAtLeast} from "../../../version";
export class Case implements StatementSyntax {
public runSyntax(node: StatementNode, input: SyntaxInput): void {
// just recurse
for (const s of node.findDirectExpressions(Expressions.Source)) {
Source.runSyntax(s, input);
checkCaseOperand(s, input);
}
}
}
// Before 7.40 SP02 the operands of CASE and WHEN are enhanced functional operand positions: besides
// data objects and functional methods, only built-in functions with exactly one unnamed argument are allowed
export function checkCaseOperand(source: ExpressionNode, input: SyntaxInput): void {
if (releaseAtLeast(input.scope.getRelease(), Release.v740sp02)
|| input.scope.getLanguageVersion() === LanguageVersion.Cloud
|| input.scope.getOpenABAP()) {
return;
}
const chain = source.findDirectExpression(Expressions.MethodCallChain);
if (chain === undefined || source.getChildren().length !== 1 || chain.getChildren().length !== 1) {
return;
}
const call = chain.findDirectExpression(Expressions.MethodCall);
const nameToken = call?.findDirectExpression(Expressions.MethodName)?.getFirstToken();
const name = nameToken?.getStr();
if (nameToken === undefined || BuiltIn.searchBuiltin(name) === undefined || BuiltIn.hasUnnamedArgument(name)) {
return;
}
// a method of the enclosing class takes precedence over the built-in function
const meType = input.scope.findVariable("me")?.getType();
if (meType instanceof ObjectReferenceType) {
const def = input.scope.findObjectDefinition(meType.getIdentifierName());
if (new ObjectOriented(input.scope).searchMethodName(def, name).method !== undefined) {
return;
}
}
const message = "Built-in function " + name + " not allowed as CASE/WHEN operand before v740sp02";
input.issues.push(syntaxIssue(input, nameToken, message));
}
|