UNPKG

@abaplint/core

Version:
162 lines • 9.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MethodSource = void 0; const Expressions = require("../../2_statements/expressions"); const nodes_1 = require("../../nodes"); const dynamic_1 = require("./dynamic"); const basic_1 = require("../../types/basic"); const _reference_1 = require("../_reference"); const _object_oriented_1 = require("../_object_oriented"); const _abstract_type_1 = require("../../types/basic/_abstract_type"); const source_field_symbol_1 = require("./source_field_symbol"); const source_field_1 = require("./source_field"); const tokens_1 = require("../../1_lexer/tokens"); const attribute_name_1 = require("./attribute_name"); const component_name_1 = require("./component_name"); const version_1 = require("../../../version"); const _syntax_input_1 = require("../_syntax_input"); const assert_error_1 = require("../assert_error"); class MethodSource { static runSyntax(node, input) { var _a, _b, _c; const helper = new _object_oriented_1.ObjectOriented(input.scope); const children = node.getChildren().slice(); const first = children.shift(); if (first === undefined) { throw new assert_error_1.AssertError("MethodSource, first child expected"); } let context = this.findTop(first, input, children); if (context === undefined) { context = (_a = input.scope.findVariable("me")) === null || _a === void 0 ? void 0 : _a.getType(); children.unshift(first); } if (input.scope.getVersion() === version_1.Version.Cloud && first.get() instanceof Expressions.Dynamic && first instanceof nodes_1.ExpressionNode && ((_b = children[0]) === null || _b === void 0 ? void 0 : _b.concatTokens()) === "=>") { const name = (_c = first.findDirectExpression(Expressions.Constant)) === null || _c === void 0 ? void 0 : _c.concatTokens().replace(/'/g, "").replace(/`/g, ""); if (name !== undefined && input.scope.findClassDefinition(name) === undefined) { const message = `Class "${name}" not found/released`; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } } if (context instanceof basic_1.VoidType) { while (children.length > 0) { const current = children.shift(); if (current instanceof nodes_1.ExpressionNode && current.get() instanceof Expressions.Dynamic) { dynamic_1.Dynamic.runSyntax(current, input); } } return context; } while (children.length > 0) { const current = children.shift(); if (current === undefined) { break; } if (current.get() instanceof tokens_1.Dash) { if (context instanceof basic_1.UnknownType) { const message = "Not a structure, type unknown, MethodSource"; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } else if (!(context instanceof basic_1.StructureType)) { const message = "Not a structure, MethodSource"; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } } else if (current.get() instanceof tokens_1.InstanceArrow || current.get() instanceof tokens_1.StaticArrow) { // todo, handling static vs instance } else if (current.get() instanceof Expressions.AttributeName || current.get() instanceof Expressions.SourceField) { if (context instanceof _abstract_type_1.AbstractType) { const attr = attribute_name_1.AttributeName.runSyntax(context, current, input, _reference_1.ReferenceType.DataReadReference, false); const isSyntaxError = attr instanceof basic_1.VoidType && attr.getVoided() === _syntax_input_1.CheckSyntaxKey; if (isSyntaxError === false) { context = attr; continue; } } // try looking for method name const className = context instanceof basic_1.ObjectReferenceType ? context.getIdentifierName() : undefined; const methodToken = current.getFirstToken(); const methodName = methodToken === null || methodToken === void 0 ? void 0 : methodToken.getStr(); const def = input.scope.findObjectDefinition(className); // eslint-disable-next-line prefer-const let { method, def: foundDef } = helper.searchMethodName(def, methodName); if (method === undefined && (methodName === null || methodName === void 0 ? void 0 : methodName.toUpperCase()) === "CONSTRUCTOR") { context = basic_1.VoidType.get("CONSTRUCTOR"); // todo, this is a workaround, constructors always exists } else if (method === undefined && !(context instanceof basic_1.VoidType)) { const message = "Method or attribute \"" + methodName + "\" not found, MethodSource"; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } else if (method) { const extra = helper.methodReferenceExtras(foundDef, className); input.scope.addReference(methodToken, method, _reference_1.ReferenceType.MethodReference, input.filename, extra); context = method; } } else if (current.get() instanceof Expressions.ComponentName && context instanceof _abstract_type_1.AbstractType) { if (context instanceof basic_1.TableType && context.isWithHeader()) { context = context.getRowType(); } context = component_name_1.ComponentName.runSyntax(context, current, input); } else if (current instanceof nodes_1.ExpressionNode && current.get() instanceof Expressions.Dynamic) { dynamic_1.Dynamic.runSyntax(current, input); context = basic_1.VoidType.get("Dynamic"); } } if (context instanceof _abstract_type_1.AbstractType && !(context instanceof basic_1.VoidType)) { const message = "Not a method, MethodSource"; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } else if (context === undefined) { const message = "Not found, MethodSource"; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } return context; } ////////////////////////////////////// static findTop(first, input, children) { if (first.get() instanceof Expressions.ClassName) { // todo, refactor this part to new expression handler, const token = first.getFirstToken(); const className = token.getStr(); const classDefinition = input.scope.findObjectDefinition(className); if (classDefinition === undefined && input.scope.getDDIC().inErrorNamespace(className) === false) { const extra = { ooName: className, ooType: "Void" }; input.scope.addReference(token, undefined, _reference_1.ReferenceType.ObjectOrientedVoidReference, input.filename, extra); return basic_1.VoidType.get(className); } else if (classDefinition === undefined) { const message = "Class " + className + " not found"; input.issues.push((0, _syntax_input_1.syntaxIssue)(input, first.getFirstToken(), message)); return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey); } input.scope.addReference(first.getFirstToken(), classDefinition, _reference_1.ReferenceType.ObjectOrientedReference, input.filename); return new basic_1.ObjectReferenceType(classDefinition); } else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.SourceField && children.length > 0) { return source_field_1.SourceField.runSyntax(first, input, _reference_1.ReferenceType.DataReadReference); } else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.SourceFieldSymbol) { return source_field_symbol_1.SourceFieldSymbol.runSyntax(first, input); } else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.Dynamic) { dynamic_1.Dynamic.runSyntax(first, input); return basic_1.VoidType.get("Dynamic"); } return undefined; } } exports.MethodSource = MethodSource; //# sourceMappingURL=method_source.js.map