@abaplint/core
Version:
abaplint - Core API
179 lines • 8.32 kB
JavaScript
"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