UNPKG

@abaplint/core

Version:
179 lines • 8.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Procedural = void 0; const Expressions = require("../2_statements/expressions"); const Statements = require("../2_statements/statements"); const Structures = require("../3_structures/structures"); const types_1 = require("../types"); const _current_scope_1 = require("./_current_scope"); const _scope_type_1 = require("./_scope_type"); const objects_1 = require("../../objects"); const _typed_identifier_1 = require("../types/_typed_identifier"); const basic_1 = require("../types/basic"); const ddic_1 = require("../../ddic"); const _object_oriented_1 = require("./_object_oriented"); const _reference_1 = require("./_reference"); class Procedural { constructor(reg, scope) { this.scope = scope; this.reg = reg; } addAllFormDefinitions(file, obj) { const structure = file.getStructure(); if (structure) { const input = { scope: _current_scope_1.CurrentScope.buildDefault(this.reg, obj), filename: file.getFilename(), issues: [], }; for (const found of structure.findAllStructures(Structures.Form)) { this.scope.addFormDefinitions([new types_1.FormDefinition(found, input)]); } } const stru = file.getStructure(); if (stru === undefined) { return; } const includes = stru.findAllStatements(Statements.Include); for (const node of includes) { const found = this.findInclude(node, obj); if (found) { this.addAllFormDefinitions(found, obj); } } } findInclude(node, obj) { // assumption: no cyclic includes, includes not found are reported by rule "check_include" // todo: how to make sure code is not duplicated here and in rule "check_include" / include graph? const expr = node.findFirstExpression(Expressions.IncludeName); if (expr === undefined) { return undefined; } const name = expr.getFirstToken().getStr(); // look in the current function group if (obj instanceof objects_1.FunctionGroup) { const incl = obj.getInclude(name); if (incl !== undefined) { return incl; } } const prog = this.reg.getObject("PROG", name); if (prog !== undefined) { return prog.getABAPFiles()[0]; } // todo, this is slow, try determining the FUGR name from the include name for (const fugr of this.reg.getObjectsByType("FUGR")) { if (fugr instanceof objects_1.FunctionGroup) { const found = fugr.getInclude(name); if (found) { return found; } } } return undefined; } findFunctionScope(obj, node, filename) { var _a, _b, _c, _d, _e; if (!(obj instanceof objects_1.FunctionGroup)) { throw new Error("findFunctionScope, expected function group input"); } const nameToken = node.findFirstExpression(Expressions.Field).getFirstToken(); const name = nameToken.getStr(); this.scope.push(_scope_type_1.ScopeType.FunctionModule, name, node.getFirstToken().getStart(), filename); const definition = obj.getModule(name); if (definition === undefined) { throw new Error("Function module definition \"" + name + "\" not found"); } const ddic = new ddic_1.DDIC(this.reg); const allNames = new Set(); for (const param of definition.getParameters()) { let found = undefined; if (param.type === undefined || param.type === "") { found = basic_1.AnyType.get(); } else if (param.type.includes("=>")) { // then its a type from global INTF or CLAS const [clas, name] = param.type.split("=>"); const def = this.scope.findObjectDefinition(clas); if (def) { const type = def.getTypeDefinitions().getByName(name); if (type) { this.scope.addReference(nameToken, type, _reference_1.ReferenceType.TypeReference, filename); found = type.getType(); } } } if (found === undefined) { found = ddic.lookup(param.type).type; } if (param.direction === types_1.FunctionModuleParameterDirection.tables) { if (found instanceof basic_1.TableType) { found = new basic_1.TableType(found.getRowType(), { withHeader: true, keyType: basic_1.TableKeyType.default }); } else { found = new basic_1.TableType(found, { withHeader: true, keyType: basic_1.TableKeyType.default }); } } if ((found instanceof basic_1.UnknownType || found instanceof basic_1.VoidType) && ((_a = param.type) === null || _a === void 0 ? void 0 : _a.includes("-"))) { const [name, field] = param.type.split("-"); const f = ddic.lookupTableOrView(name).type; if (f && f instanceof basic_1.StructureType) { const c = f.getComponentByName(field); if (c) { found = c; } } if (found === undefined || found instanceof basic_1.UnknownType || found instanceof basic_1.VoidType) { const f = (_b = this.scope.findType(name)) === null || _b === void 0 ? void 0 : _b.getType(); if (f && f instanceof basic_1.StructureType) { const c = f.getComponentByName(field); if (c) { found = c; } } } } else if ((found instanceof basic_1.UnknownType || found instanceof basic_1.VoidType) && ((_c = param.type) === null || _c === void 0 ? void 0 : _c.includes("=>"))) { const [name, field] = param.type.split("=>"); const def = this.scope.findObjectDefinition(name); const c = new _object_oriented_1.ObjectOriented(this.scope).searchTypeName(def, field); if (c) { found = c.getType(); } } if ((found instanceof basic_1.UnknownType || found instanceof basic_1.VoidType) && param.type) { const f = ddic.lookupBuiltinType(param.type); if (f) { found = f; } if (found === undefined || found instanceof basic_1.UnknownType || found instanceof basic_1.VoidType) { const f = (_d = this.scope.findType(param.type)) === null || _d === void 0 ? void 0 : _d.getType(); if (f) { found = f; } } if (found === undefined || found instanceof basic_1.UnknownType || found instanceof basic_1.VoidType) { const f = (_e = this.scope.findTypePoolType(param.type)) === null || _e === void 0 ? void 0 : _e.getType(); if (f) { found = f; } } } if (found instanceof basic_1.UnknownType && new ddic_1.DDIC(this.reg).inErrorNamespace(param.type) === false) { found = basic_1.VoidType.get(param.type); } if (allNames.has(param.name.toUpperCase())) { // yea, IMPORTING and EXPORTING can have the same name // workaround to avoid false postivies, can be improved continue; } else { const type = new _typed_identifier_1.TypedIdentifier(nameToken, filename, found); this.scope.addNamedIdentifier(param.name, type); allNames.add(param.name.toUpperCase()); } } } } exports.Procedural = Procedural; //# sourceMappingURL=_procedural.js.map