@abaplint/core
Version:
abaplint - Core API
162 lines • 9.59 kB
JavaScript
;
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