@abaplint/core
Version:
abaplint - Core API
152 lines • 8.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateObject = void 0;
const Expressions = require("../../2_statements/expressions");
const source_1 = require("../expressions/source");
const target_1 = require("../expressions/target");
const dynamic_1 = require("../expressions/dynamic");
const _reference_1 = require("../_reference");
const basic_1 = require("../../types/basic");
const types_1 = require("../../types");
const _object_oriented_1 = require("../_object_oriented");
const _type_utils_1 = require("../_type_utils");
const _syntax_input_1 = require("../_syntax_input");
class CreateObject {
runSyntax(node, input) {
var _a;
let cdef = undefined;
// CREATE OBJECT, TYPE
const type = node.findExpressionAfterToken("TYPE");
if (type && type.get() instanceof Expressions.ClassName) {
const token = type.getFirstToken();
const name = token.getStr();
cdef = input.scope.findClassDefinition(name);
if (cdef) {
input.scope.addReference(token, cdef, _reference_1.ReferenceType.ObjectOrientedReference, input.filename);
input.scope.addReference(token, cdef, _reference_1.ReferenceType.ConstructorReference, input.filename, { ooName: cdef.getName() });
if (cdef.isAbstract() === true) {
const message = cdef.getName() + " is abstract, cannot be instantiated";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
}
else if (input.scope.getDDIC().inErrorNamespace(name) === false) {
input.scope.addReference(token, undefined, _reference_1.ReferenceType.ObjectOrientedVoidReference, input.filename, { ooName: name, ooType: "CLAS" });
}
else {
const message = "TYPE \"" + name + "\" not found";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
}
// just recurse
for (const s of node.findDirectExpressions(Expressions.Source)) {
source_1.Source.runSyntax(s, input);
}
for (const t of ((_a = node.findDirectExpression(Expressions.ParameterListExceptions)) === null || _a === void 0 ? void 0 : _a.findAllExpressions(Expressions.Target)) || []) {
target_1.Target.runSyntax(t, input);
}
const t = node.findDirectExpression(Expressions.Target);
let found = undefined;
if (t) {
found = target_1.Target.runSyntax(t, input);
if (found instanceof basic_1.VoidType) {
// do nothing
}
else if (found instanceof basic_1.UnknownType) {
const message = "Target type unknown, " + t.concatTokens();
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
else if (!(found instanceof basic_1.ObjectReferenceType)
&& !(found instanceof basic_1.AnyType)
&& !(found instanceof basic_1.DataType)
&& !(found instanceof basic_1.GenericObjectReferenceType)) {
const message = "Target must be an object reference, " + t.concatTokens();
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
else if (found instanceof basic_1.GenericObjectReferenceType && type === undefined) {
const message = "Generic type, cannot be instantiated";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
else if (found instanceof basic_1.ObjectReferenceType) {
const id = found.getIdentifier();
if (id instanceof types_1.InterfaceDefinition && type === undefined) {
const message = "Interface reference, cannot be instantiated";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
else if (found instanceof basic_1.ObjectReferenceType
&& type === undefined
&& input.scope.findInterfaceDefinition(found.getQualifiedName())) {
const message = "Interface reference, cannot be instantiated";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
else if (id instanceof types_1.ClassDefinition && cdef === undefined) {
cdef = id;
}
if (type === undefined && id instanceof types_1.ClassDefinition && id.isAbstract() === true) {
const message = id.getName() + " is abstract, cannot be instantiated";
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
}
if (found instanceof basic_1.ObjectReferenceType && cdef === undefined) {
cdef = input.scope.findClassDefinition(found.getQualifiedName());
}
}
for (const t of node.findDirectExpressions(Expressions.Dynamic)) {
dynamic_1.Dynamic.runSyntax(t, input);
}
let ooName = cdef === null || cdef === void 0 ? void 0 : cdef.getName();
if (ooName === undefined && found instanceof basic_1.VoidType) {
ooName = found.getVoided();
}
input.scope.addReference(t === null || t === void 0 ? void 0 : t.getFirstToken(), cdef, _reference_1.ReferenceType.ConstructorReference, input.filename, { ooName: ooName });
this.validateParameters(cdef, node, input);
}
validateParameters(cdef, node, input) {
var _a, _b, _c, _d;
if (cdef === undefined) {
const sources = (_a = node.findDirectExpression(Expressions.ParameterListS)) === null || _a === void 0 ? void 0 : _a.findAllExpressions(Expressions.Source);
for (const s of sources || []) {
source_1.Source.runSyntax(s, input);
}
return;
}
const methodDef = new _object_oriented_1.ObjectOriented(input.scope).searchMethodName(cdef, "CONSTRUCTOR");
const methodParameters = (_b = methodDef.method) === null || _b === void 0 ? void 0 : _b.getParameters();
const allImporting = (methodParameters === null || methodParameters === void 0 ? void 0 : methodParameters.getImporting()) || [];
const requiredImporting = new Set(methodParameters === null || methodParameters === void 0 ? void 0 : methodParameters.getRequiredParameters().map(i => i.getName().toUpperCase()));
for (const p of ((_c = node.findDirectExpression(Expressions.ParameterListS)) === null || _c === void 0 ? void 0 : _c.findAllExpressions(Expressions.ParameterS)) || []) {
const name = (_d = p.findDirectExpression(Expressions.ParameterName)) === null || _d === void 0 ? void 0 : _d.concatTokens().toUpperCase();
if (name === undefined) {
continue;
}
const source = p.findDirectExpression(Expressions.Source);
const sourceType = source_1.Source.runSyntax(source, input);
const found = allImporting === null || allImporting === void 0 ? void 0 : allImporting.find(p => p.getName().toUpperCase() === name);
if (found === undefined) {
const message = `constructor parameter "${name}" does not exist`;
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
else if (new _type_utils_1.TypeUtils(input.scope).isAssignableStrict(sourceType, found.getType(), source) === false) {
const message = `constructor parameter "${name}" type not compatible`;
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
requiredImporting.delete(name);
}
for (const r of requiredImporting.values()) {
const message = `constructor parameter "${r}" must be supplied`;
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
return;
}
}
}
exports.CreateObject = CreateObject;
//# sourceMappingURL=create_object.js.map