@domainlang/language 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/ast-augmentation.d.ts +7 -2
- package/out/diagram/context-map-diagram-generator.d.ts +72 -0
- package/out/diagram/context-map-diagram-generator.js +405 -0
- package/out/diagram/context-map-diagram-generator.js.map +1 -0
- package/out/diagram/context-map-layout-configurator.d.ts +15 -0
- package/out/diagram/context-map-layout-configurator.js +39 -0
- package/out/diagram/context-map-layout-configurator.js.map +1 -0
- package/out/diagram/elk-layout-factory.d.ts +43 -0
- package/out/diagram/elk-layout-factory.js +64 -0
- package/out/diagram/elk-layout-factory.js.map +1 -0
- package/out/domain-lang-module.d.ts +7 -0
- package/out/domain-lang-module.js +11 -2
- package/out/domain-lang-module.js.map +1 -1
- package/out/generated/ast.d.ts +323 -51
- package/out/generated/ast.js +194 -33
- package/out/generated/ast.js.map +1 -1
- package/out/generated/grammar.js +418 -172
- package/out/generated/grammar.js.map +1 -1
- package/out/index.d.ts +3 -0
- package/out/index.js +4 -0
- package/out/index.js.map +1 -1
- package/out/lsp/domain-lang-code-lens-provider.d.ts +8 -0
- package/out/lsp/domain-lang-code-lens-provider.js +48 -0
- package/out/lsp/domain-lang-code-lens-provider.js.map +1 -0
- package/out/lsp/domain-lang-completion.js +39 -15
- package/out/lsp/domain-lang-completion.js.map +1 -1
- package/out/lsp/domain-lang-document-symbol-provider.js +5 -5
- package/out/lsp/domain-lang-document-symbol-provider.js.map +1 -1
- package/out/lsp/domain-lang-formatter.js +32 -0
- package/out/lsp/domain-lang-formatter.js.map +1 -1
- package/out/lsp/domain-lang-index-manager.d.ts +2 -3
- package/out/lsp/domain-lang-index-manager.js +5 -8
- package/out/lsp/domain-lang-index-manager.js.map +1 -1
- package/out/lsp/domain-lang-workspace-manager.d.ts +1 -1
- package/out/lsp/domain-lang-workspace-manager.js +2 -26
- package/out/lsp/domain-lang-workspace-manager.js.map +1 -1
- package/out/lsp/explain.js +9 -3
- package/out/lsp/explain.js.map +1 -1
- package/out/lsp/hover/domain-lang-hover.js +13 -11
- package/out/lsp/hover/domain-lang-hover.js.map +1 -1
- package/out/lsp/hover/domain-lang-keywords.js +29 -26
- package/out/lsp/hover/domain-lang-keywords.js.map +1 -1
- package/out/lsp/tool-handlers.js +63 -57
- package/out/lsp/tool-handlers.js.map +1 -1
- package/out/sdk/ast-augmentation.d.ts +29 -21
- package/out/sdk/ast-augmentation.js +11 -7
- package/out/sdk/ast-augmentation.js.map +1 -1
- package/out/sdk/index.d.ts +2 -2
- package/out/sdk/index.js +1 -1
- package/out/sdk/index.js.map +1 -1
- package/out/sdk/loader-node.js +2 -2
- package/out/sdk/loader-node.js.map +1 -1
- package/out/sdk/patterns.d.ts +50 -61
- package/out/sdk/patterns.js +92 -62
- package/out/sdk/patterns.js.map +1 -1
- package/out/sdk/query.js +54 -43
- package/out/sdk/query.js.map +1 -1
- package/out/sdk/serializers.js +20 -7
- package/out/sdk/serializers.js.map +1 -1
- package/out/sdk/types.d.ts +87 -18
- package/out/sdk/types.js.map +1 -1
- package/out/sdk/validator.js +48 -64
- package/out/sdk/validator.js.map +1 -1
- package/out/services/performance-optimizer.d.ts +3 -3
- package/out/services/performance-optimizer.js +1 -3
- package/out/services/performance-optimizer.js.map +1 -1
- package/out/services/relationship-inference.d.ts +4 -4
- package/out/services/relationship-inference.js +34 -46
- package/out/services/relationship-inference.js.map +1 -1
- package/out/syntaxes/domain-lang.monarch.js +1 -1
- package/out/syntaxes/domain-lang.monarch.js.map +1 -1
- package/out/utils/import-utils.d.ts +6 -20
- package/out/utils/import-utils.js +3 -63
- package/out/utils/import-utils.js.map +1 -1
- package/out/validation/constants.d.ts +23 -6
- package/out/validation/constants.js +24 -7
- package/out/validation/constants.js.map +1 -1
- package/out/validation/maps.js +10 -4
- package/out/validation/maps.js.map +1 -1
- package/out/validation/relationships.d.ts +4 -8
- package/out/validation/relationships.js +96 -48
- package/out/validation/relationships.js.map +1 -1
- package/package.json +5 -2
- package/src/ast-augmentation.ts +7 -2
- package/src/diagram/context-map-diagram-generator.ts +513 -0
- package/src/diagram/context-map-layout-configurator.ts +43 -0
- package/src/diagram/elk-layout-factory.ts +83 -0
- package/src/domain-lang-module.ts +19 -2
- package/src/domain-lang.langium +62 -26
- package/src/generated/ast.ts +413 -63
- package/src/generated/grammar.ts +418 -172
- package/src/index.ts +5 -0
- package/src/lsp/domain-lang-code-lens-provider.ts +54 -0
- package/src/lsp/domain-lang-completion.ts +42 -15
- package/src/lsp/domain-lang-document-symbol-provider.ts +5 -5
- package/src/lsp/domain-lang-formatter.ts +34 -0
- package/src/lsp/domain-lang-index-manager.ts +6 -9
- package/src/lsp/domain-lang-workspace-manager.ts +3 -29
- package/src/lsp/explain.ts +10 -2
- package/src/lsp/hover/domain-lang-hover.ts +10 -8
- package/src/lsp/hover/domain-lang-keywords.ts +27 -24
- package/src/lsp/tool-handlers.ts +61 -47
- package/src/sdk/ast-augmentation.ts +30 -21
- package/src/sdk/index.ts +11 -1
- package/src/sdk/loader-node.ts +2 -2
- package/src/sdk/patterns.ts +114 -76
- package/src/sdk/query.ts +57 -48
- package/src/sdk/serializers.ts +20 -7
- package/src/sdk/types.ts +92 -17
- package/src/sdk/validator.ts +52 -69
- package/src/services/performance-optimizer.ts +4 -6
- package/src/services/relationship-inference.ts +43 -54
- package/src/utils/import-utils.ts +9 -74
- package/src/validation/constants.ts +32 -9
- package/src/validation/maps.ts +12 -4
- package/src/validation/relationships.ts +150 -71
package/src/validation/maps.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ValidationAcceptor } from 'langium';
|
|
2
2
|
import type { ContextMap, DomainMap, Relationship, BoundedContextRef } from '../generated/ast.js';
|
|
3
|
-
import { isThisRef } from '../generated/ast.js';
|
|
3
|
+
import { isDirectionalRelationship, isSymmetricRelationship, isThisRef } from '../generated/ast.js';
|
|
4
4
|
import { ValidationMessages, buildCodeDescription, IssueCodes } from './constants.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -139,9 +139,17 @@ function getRefKey(ref: BoundedContextRef): string {
|
|
|
139
139
|
function buildRelationshipKey(rel: Relationship): string {
|
|
140
140
|
const left = getRefKey(rel.left);
|
|
141
141
|
const right = getRefKey(rel.right);
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
const arrow = rel.arrow ?? '';
|
|
143
|
+
|
|
144
|
+
if (isDirectionalRelationship(rel)) {
|
|
145
|
+
const leftPatterns = rel.leftPatterns.map(p => p.$type).sort().join(',');
|
|
146
|
+
const rightPatterns = rel.rightPatterns.map(p => p.$type).sort().join(',');
|
|
147
|
+
return `[${leftPatterns}]${left}${arrow}[${rightPatterns}]${right}`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Symmetric relationship
|
|
151
|
+
const pattern = isSymmetricRelationship(rel) && rel.pattern ? rel.pattern.$type : '';
|
|
152
|
+
return `[${pattern}]${left}${arrow}${right}`;
|
|
145
153
|
}
|
|
146
154
|
|
|
147
155
|
/**
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { ValidationAcceptor } from 'langium';
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
2
|
+
import type { BoundedContextRef, Relationship } from '../generated/ast.js';
|
|
3
|
+
import {
|
|
4
|
+
isThisRef,
|
|
5
|
+
isDirectionalRelationship,
|
|
6
|
+
isSymmetricRelationship,
|
|
7
|
+
isAntiCorruptionLayer,
|
|
8
|
+
isConformist,
|
|
9
|
+
isOpenHostService,
|
|
10
|
+
isSupplier,
|
|
11
|
+
isCustomer,
|
|
12
|
+
} from '../generated/ast.js';
|
|
4
13
|
import { ValidationMessages, buildCodeDescription } from './constants.js';
|
|
5
14
|
|
|
6
|
-
/**
|
|
7
|
-
* Gets a display name for a BoundedContextRef (handles 'this' and regular refs).
|
|
8
|
-
*/
|
|
9
15
|
function getContextName(ref: BoundedContextRef): string {
|
|
10
16
|
if (isThisRef(ref)) {
|
|
11
17
|
return 'this';
|
|
@@ -14,54 +20,19 @@ function getContextName(ref: BoundedContextRef): string {
|
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
/**
|
|
17
|
-
* Validates that
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @param relationship - The relationship to validate
|
|
21
|
-
* @param accept - The validation acceptor for reporting issues
|
|
22
|
-
*/
|
|
23
|
-
function validateSharedKernelBidirectional(
|
|
24
|
-
relationship: Relationship,
|
|
25
|
-
accept: ValidationAcceptor
|
|
26
|
-
): void {
|
|
27
|
-
// Check if SharedKernel pattern exists on either side
|
|
28
|
-
const hasSharedKernelLeft = relationship.leftPatterns?.some(
|
|
29
|
-
pattern => pattern === 'SK' || pattern === 'SharedKernel'
|
|
30
|
-
);
|
|
31
|
-
const hasSharedKernelRight = relationship.rightPatterns?.some(
|
|
32
|
-
pattern => pattern === 'SK' || pattern === 'SharedKernel'
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
if ((hasSharedKernelLeft || hasSharedKernelRight) && relationship.arrow !== '<->') {
|
|
36
|
-
const leftName = getContextName(relationship.left);
|
|
37
|
-
const rightName = getContextName(relationship.right);
|
|
38
|
-
|
|
39
|
-
accept('warning',
|
|
40
|
-
ValidationMessages.SHARED_KERNEL_MUST_BE_BIDIRECTIONAL(leftName, rightName, relationship.arrow),
|
|
41
|
-
{ node: relationship, property: 'arrow', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Validates that Anti-Corruption Layer (ACL) is on the consuming side.
|
|
48
|
-
* ACL protects downstream context from upstream changes.
|
|
49
|
-
*
|
|
50
|
-
* @param relationship - The relationship to validate
|
|
51
|
-
* @param accept - The validation acceptor for reporting issues
|
|
23
|
+
* Validates that ACL is on the downstream (consuming) side.
|
|
24
|
+
* ACL on upstream side of -> is a warning. ACL on upstream side of <- is also a warning.
|
|
52
25
|
*/
|
|
53
26
|
function validateACLPlacement(
|
|
54
27
|
relationship: Relationship,
|
|
55
28
|
accept: ValidationAcceptor
|
|
56
29
|
): void {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
);
|
|
60
|
-
const hasACLRight = relationship.rightPatterns
|
|
61
|
-
pattern => pattern === 'ACL' || pattern === 'AntiCorruptionLayer'
|
|
62
|
-
);
|
|
30
|
+
if (!isDirectionalRelationship(relationship)) return;
|
|
31
|
+
|
|
32
|
+
const hasACLLeft = relationship.leftPatterns.some(isAntiCorruptionLayer);
|
|
33
|
+
const hasACLRight = relationship.rightPatterns.some(isAntiCorruptionLayer);
|
|
63
34
|
|
|
64
|
-
//
|
|
35
|
+
// For ->, left is upstream. ACL on upstream side is wrong.
|
|
65
36
|
if (hasACLLeft && relationship.arrow === '->') {
|
|
66
37
|
const leftName = getContextName(relationship.left);
|
|
67
38
|
accept('warning',
|
|
@@ -70,7 +41,7 @@ function validateACLPlacement(
|
|
|
70
41
|
);
|
|
71
42
|
}
|
|
72
43
|
|
|
73
|
-
//
|
|
44
|
+
// For <-, right is upstream. ACL on upstream side is wrong.
|
|
74
45
|
if (hasACLRight && relationship.arrow === '<-') {
|
|
75
46
|
const rightName = getContextName(relationship.right);
|
|
76
47
|
accept('warning',
|
|
@@ -81,24 +52,17 @@ function validateACLPlacement(
|
|
|
81
52
|
}
|
|
82
53
|
|
|
83
54
|
/**
|
|
84
|
-
* Validates that
|
|
85
|
-
* Conformist means accepting upstream model without translation.
|
|
86
|
-
*
|
|
87
|
-
* @param relationship - The relationship to validate
|
|
88
|
-
* @param accept - The validation acceptor for reporting issues
|
|
55
|
+
* Validates that CF is on the downstream (consuming) side.
|
|
89
56
|
*/
|
|
90
57
|
function validateConformistPlacement(
|
|
91
58
|
relationship: Relationship,
|
|
92
59
|
accept: ValidationAcceptor
|
|
93
60
|
): void {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
);
|
|
97
|
-
const hasCFRight = relationship.rightPatterns
|
|
98
|
-
pattern => pattern === 'CF' || pattern === 'Conformist'
|
|
99
|
-
);
|
|
61
|
+
if (!isDirectionalRelationship(relationship)) return;
|
|
62
|
+
|
|
63
|
+
const hasCFLeft = relationship.leftPatterns.some(isConformist);
|
|
64
|
+
const hasCFRight = relationship.rightPatterns.some(isConformist);
|
|
100
65
|
|
|
101
|
-
// CF on left side with -> arrow means upstream is conformist (incorrect)
|
|
102
66
|
if (hasCFLeft && relationship.arrow === '->') {
|
|
103
67
|
const leftName = getContextName(relationship.left);
|
|
104
68
|
accept('warning',
|
|
@@ -107,7 +71,6 @@ function validateConformistPlacement(
|
|
|
107
71
|
);
|
|
108
72
|
}
|
|
109
73
|
|
|
110
|
-
// CF on right side with <- arrow means upstream is conformist (incorrect)
|
|
111
74
|
if (hasCFRight && relationship.arrow === '<-') {
|
|
112
75
|
const rightName = getContextName(relationship.right);
|
|
113
76
|
accept('warning',
|
|
@@ -118,18 +81,107 @@ function validateConformistPlacement(
|
|
|
118
81
|
}
|
|
119
82
|
|
|
120
83
|
/**
|
|
121
|
-
* Validates that
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
84
|
+
* Validates that OHS is on the upstream (providing) side.
|
|
85
|
+
*/
|
|
86
|
+
function validateOHSPlacement(
|
|
87
|
+
relationship: Relationship,
|
|
88
|
+
accept: ValidationAcceptor
|
|
89
|
+
): void {
|
|
90
|
+
if (!isDirectionalRelationship(relationship)) return;
|
|
91
|
+
|
|
92
|
+
// For ->, right is downstream. OHS on downstream side is wrong.
|
|
93
|
+
const hasOHSRight = relationship.rightPatterns.some(isOpenHostService);
|
|
94
|
+
if (hasOHSRight && relationship.arrow === '->') {
|
|
95
|
+
const rightName = getContextName(relationship.right);
|
|
96
|
+
accept('warning',
|
|
97
|
+
ValidationMessages.OHS_ON_WRONG_SIDE(rightName, 'right'),
|
|
98
|
+
{ node: relationship, property: 'rightPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// For <-, left is downstream. OHS on downstream side is wrong.
|
|
103
|
+
const hasOHSLeft = relationship.leftPatterns.some(isOpenHostService);
|
|
104
|
+
if (hasOHSLeft && relationship.arrow === '<-') {
|
|
105
|
+
const leftName = getContextName(relationship.left);
|
|
106
|
+
accept('warning',
|
|
107
|
+
ValidationMessages.OHS_ON_WRONG_SIDE(leftName, 'left'),
|
|
108
|
+
{ node: relationship, property: 'leftPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Validates that Supplier is on the upstream side and Customer is on the downstream side.
|
|
115
|
+
* These are errors, not warnings — S/C have fixed placement.
|
|
116
|
+
*/
|
|
117
|
+
function validateCustomerSupplierPlacement(
|
|
118
|
+
relationship: Relationship,
|
|
119
|
+
accept: ValidationAcceptor
|
|
120
|
+
): void {
|
|
121
|
+
if (!isDirectionalRelationship(relationship)) return;
|
|
122
|
+
|
|
123
|
+
// For ->, left is upstream, right is downstream
|
|
124
|
+
// Supplier must be upstream, Customer must be downstream
|
|
125
|
+
if (relationship.arrow === '->') {
|
|
126
|
+
if (relationship.rightPatterns.some(isSupplier)) {
|
|
127
|
+
accept('error',
|
|
128
|
+
ValidationMessages.SUPPLIER_ON_WRONG_SIDE(getContextName(relationship.right), 'right'),
|
|
129
|
+
{ node: relationship, property: 'rightPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (relationship.leftPatterns.some(isCustomer)) {
|
|
133
|
+
accept('error',
|
|
134
|
+
ValidationMessages.CUSTOMER_ON_WRONG_SIDE(getContextName(relationship.left), 'left'),
|
|
135
|
+
{ node: relationship, property: 'leftPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// For <-, right is upstream, left is downstream
|
|
141
|
+
if (relationship.arrow === '<-') {
|
|
142
|
+
if (relationship.leftPatterns.some(isSupplier)) {
|
|
143
|
+
accept('error',
|
|
144
|
+
ValidationMessages.SUPPLIER_ON_WRONG_SIDE(getContextName(relationship.left), 'left'),
|
|
145
|
+
{ node: relationship, property: 'leftPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
if (relationship.rightPatterns.some(isCustomer)) {
|
|
149
|
+
accept('error',
|
|
150
|
+
ValidationMessages.CUSTOMER_ON_WRONG_SIDE(getContextName(relationship.right), 'right'),
|
|
151
|
+
{ node: relationship, property: 'rightPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// <-> is bidirectional — Customer/Supplier is inherently directional and must not appear on a <-> arrow
|
|
157
|
+
if (relationship.arrow === '<->') {
|
|
158
|
+
const allPatterns = [...relationship.leftPatterns, ...relationship.rightPatterns];
|
|
159
|
+
if (allPatterns.some(isSupplier)) {
|
|
160
|
+
accept('error',
|
|
161
|
+
'Supplier [S] cannot be used on a bidirectional (<->) relationship — Customer/Supplier is inherently directional.',
|
|
162
|
+
{ node: relationship, property: relationship.leftPatterns.some(isSupplier) ? 'leftPatterns' : 'rightPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (allPatterns.some(isCustomer)) {
|
|
166
|
+
accept('error',
|
|
167
|
+
'Customer [C] cannot be used on a bidirectional (<->) relationship — Customer/Supplier is inherently directional.',
|
|
168
|
+
{ node: relationship, property: relationship.leftPatterns.some(isCustomer) ? 'leftPatterns' : 'rightPatterns', codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Validates pattern count per side (info if > 3).
|
|
126
176
|
*/
|
|
127
177
|
function validatePatternCount(
|
|
128
178
|
relationship: Relationship,
|
|
129
179
|
accept: ValidationAcceptor
|
|
130
180
|
): void {
|
|
131
|
-
|
|
132
|
-
|
|
181
|
+
if (!isDirectionalRelationship(relationship)) return;
|
|
182
|
+
|
|
183
|
+
const leftCount = relationship.leftPatterns.length;
|
|
184
|
+
const rightCount = relationship.rightPatterns.length;
|
|
133
185
|
|
|
134
186
|
if (leftCount > 3) {
|
|
135
187
|
accept('info',
|
|
@@ -146,9 +198,36 @@ function validatePatternCount(
|
|
|
146
198
|
}
|
|
147
199
|
}
|
|
148
200
|
|
|
149
|
-
|
|
150
|
-
|
|
201
|
+
/**
|
|
202
|
+
* Validates that symmetric relationships with self-reference produce a warning.
|
|
203
|
+
*/
|
|
204
|
+
function validateSelfSymmetric(
|
|
205
|
+
relationship: Relationship,
|
|
206
|
+
accept: ValidationAcceptor
|
|
207
|
+
): void {
|
|
208
|
+
if (!isSymmetricRelationship(relationship)) return;
|
|
209
|
+
|
|
210
|
+
const leftName = getContextName(relationship.left);
|
|
211
|
+
const rightName = getContextName(relationship.right);
|
|
212
|
+
|
|
213
|
+
if (leftName === rightName) {
|
|
214
|
+
accept('warning',
|
|
215
|
+
ValidationMessages.SELF_SYMMETRIC_RELATIONSHIP(leftName),
|
|
216
|
+
{ node: relationship, codeDescription: buildCodeDescription('language.md', 'integration-patterns') }
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* All relationship validation checks.
|
|
223
|
+
* Each function receives a Relationship (DirectionalRelationship | SymmetricRelationship)
|
|
224
|
+
* and guards internally for the correct subtype.
|
|
225
|
+
*/
|
|
226
|
+
export const relationshipChecks: Array<(relationship: Relationship, accept: ValidationAcceptor) => void> = [
|
|
151
227
|
validateACLPlacement,
|
|
152
228
|
validateConformistPlacement,
|
|
153
|
-
|
|
229
|
+
validateOHSPlacement,
|
|
230
|
+
validateCustomerSupplierPlacement,
|
|
231
|
+
validatePatternCount,
|
|
232
|
+
validateSelfSymmetric,
|
|
154
233
|
];
|