diff --git a/packages/dmn-marshaller/tests/xsdSequence.test.ts b/packages/dmn-marshaller/tests/xsdSequence.test.ts
index ca831d5ffad..c2aefe113b9 100644
--- a/packages/dmn-marshaller/tests/xsdSequence.test.ts
+++ b/packages/dmn-marshaller/tests/xsdSequence.test.ts
@@ -19,15 +19,68 @@
import * as fs from "fs";
import * as path from "path";
-import { getMarshaller } from "@kie-tools/dmn-marshaller";
+import { DmnLatestModel, getMarshaller } from "@kie-tools/dmn-marshaller";
-const files = [
- { path: "../tests-data--manual/other/decisionAndInput.dmn" },
- { path: "../tests-data--manual/other/decisionAndInput_wrongSequenceOrder.dmn" },
-];
+describe("build produces elements respecting the hierarchy of the element type", () => {
+ test("businessKnowledgeSource element", () => {
+ const json: DmnLatestModel = {
+ definitions: {
+ "@_name": "myDmn",
+ "@_namespace": "myDmnNamespace",
+ drgElement: [
+ {
+ __$$element: "businessKnowledgeModel",
+ authorityRequirement: [],
+ "@_name": "myBkm",
+ encapsulatedLogic: {
+ expression: {
+ __$$element: "literalExpression",
+ text: { __$$text: "myBkm literal expression" },
+ extensionElements: {},
+ },
+ },
+ variable: {
+ "@_name": "myBkm var",
+ extensionElements: {},
+ description: { __$$text: "myBkm var description" },
+ },
+ extensionElements: {},
+ description: { __$$text: "myBkm description" },
+ },
+ ],
+ },
+ };
+ expect(
+ getMarshaller(
+ ``,
+ { upgradeTo: "latest" }
+ ).builder.build(json)
+ ).toStrictEqual(`
+
+
+ myBkm description
+
+
+ myBkm var description
+
+
+
+
+
+ myBkm literal expression
+
+
+
+
+`);
+ });
+});
describe("build always produces elements in the same order", () => {
- for (const file of files) {
+ for (const file of [
+ { path: "../tests-data--manual/other/decisionAndInput.dmn" },
+ { path: "../tests-data--manual/other/decisionAndInput_wrongSequenceOrder.dmn" },
+ ]) {
test(path.basename(file.path), () => {
const xml = fs.readFileSync(path.join(__dirname, file.path), "utf-8");
const marshaller = getMarshaller(xml, { upgradeTo: "1.5" });
diff --git a/packages/xml-parser-ts-codegen/src/codegen.ts b/packages/xml-parser-ts-codegen/src/codegen.ts
index eb349425f85..c5054aebc12 100644
--- a/packages/xml-parser-ts-codegen/src/codegen.ts
+++ b/packages/xml-parser-ts-codegen/src/codegen.ts
@@ -575,7 +575,10 @@ function getMetaProperties(
ct: XptcComplexType,
metaTypeName: string
): { anonymousTypes: XptcMetaType[]; needsExtensionType: boolean; metaProperties: XptcMetaTypeProperty[] } {
- const metaProperties: XptcMetaTypeProperty[] = [];
+ /** Accumulates all properties of this complex type (ct). Attributes and elements. */
+ let ctMetaProperties: XptcMetaTypeProperty[] = [];
+
+ /** Accumulates all anonymous types instantiated on this complex type's hierarchy */
const anonymousTypes: XptcMetaType[] = [];
const immediateParentType = ct.childOf
@@ -587,6 +590,7 @@ function getMetaProperties(
let needsExtensionType = ct.needsExtensionType;
while (curParentCt) {
+ const curParentCtMetaProperties: XptcMetaTypeProperty[] = [];
if (curParentCt?.type === "complex") {
const curParentCtMetaTypeName = getTsNameFromNamedType(
curParentCt.declaredAtRelativeLocation,
@@ -608,7 +612,7 @@ function getMetaProperties(
throw new Error(`Can't resolve local type ref ${a.localTypeRef}`);
}
- metaProperties.push({
+ curParentCtMetaProperties.push({
declaredAt: curParentCt.declaredAtRelativeLocation,
fromType: curParentCtMetaTypeName,
elem: undefined,
@@ -638,7 +642,7 @@ function getMetaProperties(
name: anonymousTypeName,
properties: mp.metaProperties,
});
- metaProperties.push({
+ curParentCtMetaProperties.push({
elem: undefined, // REALLY?
declaredAt: curParentCt.declaredAtRelativeLocation,
fromType: curParentCtMetaTypeName,
@@ -655,7 +659,7 @@ function getMetaProperties(
e.typeName
);
- metaProperties.push({
+ curParentCtMetaProperties.push({
declaredAt: curParentCt.declaredAtRelativeLocation,
fromType: curParentCtMetaTypeName,
elem: undefined, // REALLY?
@@ -692,7 +696,7 @@ function getMetaProperties(
annotation: "Anonymous type from element " + referencedElement.name,
};
- metaProperties.push({
+ curParentCtMetaProperties.push({
declaredAt: referencedElement?.declaredAtRelativeLocation,
fromType: ct.isAnonymous ? "" : curParentCtMetaTypeName,
name: referencedElement.name,
@@ -725,6 +729,10 @@ function getMetaProperties(
curParentCt.childOf
)
: undefined;
+
+ // Make sure the inheritance order is respected. Elements should be listed always from the most generic to the most specific type.
+ // Since we're iterating upwards in the hierarchy, we need to invert prepend the array with the props we find on each step of the hierarchy.
+ ctMetaProperties = [...curParentCtMetaProperties, ...ctMetaProperties];
curParentCt = nextParentType ? __NAMED_TYPES_BY_TS_NAME.get(nextParentType.name) : undefined;
} else if (curParentCt?.type === "simple") {
throw new Error("Can't have a non-complex type as parent of another.");
@@ -743,7 +751,7 @@ function getMetaProperties(
a.localTypeRef
);
- metaProperties.push({
+ ctMetaProperties.push({
declaredAt: ct.declaredAtRelativeLocation,
fromType: metaTypeName,
name: `@_${a.name}`,
@@ -777,7 +785,7 @@ function getMetaProperties(
annotation: "Anonymous type from element " + referencedElement.name,
};
- metaProperties.push({
+ ctMetaProperties.push({
declaredAt: referencedElement?.declaredAtRelativeLocation,
fromType: ct.isAnonymous ? "" : metaTypeName,
name: referencedElement.name,
@@ -799,7 +807,7 @@ function getMetaProperties(
});
} else if (e.kind === "ofNamedType") {
const tsType = getTsTypeFromLocalRef(__XSDS, __NAMED_TYPES_BY_TS_NAME, ct.declaredAtRelativeLocation, e.typeName);
- metaProperties.push({
+ ctMetaProperties.push({
declaredAt: ct.declaredAtRelativeLocation,
fromType: metaTypeName,
name: e.name,
@@ -827,7 +835,7 @@ function getMetaProperties(
name: anonymousTypeName,
properties: mp.metaProperties,
});
- metaProperties.push({
+ ctMetaProperties.push({
declaredAt: ct.declaredAtRelativeLocation,
fromType: metaTypeName,
name: e.name,
@@ -843,7 +851,7 @@ function getMetaProperties(
if (ct.isSimpleContent && ct.childOf) {
const t = getTsTypeFromLocalRef(__XSDS, __NAMED_TYPES_BY_TS_NAME, ct.declaredAtRelativeLocation, ct.childOf);
- metaProperties.push({
+ ctMetaProperties.push({
declaredAt: ct.declaredAtRelativeLocation,
fromType: metaTypeName,
name: `__$$text`,
@@ -860,11 +868,11 @@ function getMetaProperties(
if (!(ct.type === "complex" && !ct.isAnonymous && ct.isAbstract)) {
__META_TYPE_MAPPING.set(metaTypeName, {
name: metaTypeName,
- properties: [...metaProperties.reduce((acc, p) => acc.set(p.name, p), new Map()).values()], // Removing duplicates.
+ properties: [...ctMetaProperties.reduce((acc, p) => acc.set(p.name, p), new Map()).values()], // Removing duplicates.
});
}
- return { metaProperties, needsExtensionType, anonymousTypes };
+ return { metaProperties: ctMetaProperties, needsExtensionType, anonymousTypes };
}
function getAnonymousMetaTypeName(elementName: string, metaTypeName: string) {