@lionweb/validation 0.6.0-beta.3 → 0.6.0-beta.5
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/dist/diff/LionWebJsonDiff.d.ts +1 -1
- package/dist/diff/LionWebJsonDiff.d.ts.map +1 -1
- package/dist/diff/LionWebJsonDiff.js +70 -21
- package/dist/diff/LionWebJsonDiff.js.map +1 -1
- package/dist/diff/changes/Change.d.ts +21 -3
- package/dist/diff/changes/Change.d.ts.map +1 -1
- package/dist/diff/changes/Change.js +21 -2
- package/dist/diff/changes/Change.js.map +1 -1
- package/dist/diff/changes/ChunkChange.d.ts +5 -5
- package/dist/diff/changes/ChunkChange.d.ts.map +1 -1
- package/dist/diff/changes/ChunkChange.js +5 -5
- package/dist/diff/changes/ChunkChange.js.map +1 -1
- package/dist/diff/changes/ContainmentChange.d.ts +9 -10
- package/dist/diff/changes/ContainmentChange.d.ts.map +1 -1
- package/dist/diff/changes/ContainmentChange.js +12 -12
- package/dist/diff/changes/ContainmentChange.js.map +1 -1
- package/dist/diff/changes/NodeChange.d.ts +21 -2
- package/dist/diff/changes/NodeChange.d.ts.map +1 -1
- package/dist/diff/changes/NodeChange.js +32 -2
- package/dist/diff/changes/NodeChange.js.map +1 -1
- package/dist/diff/changes/PropertyChange.d.ts +7 -6
- package/dist/diff/changes/PropertyChange.d.ts.map +1 -1
- package/dist/diff/changes/PropertyChange.js +5 -4
- package/dist/diff/changes/PropertyChange.js.map +1 -1
- package/dist/diff/changes/ReferenceChange.d.ts +13 -7
- package/dist/diff/changes/ReferenceChange.d.ts.map +1 -1
- package/dist/diff/changes/ReferenceChange.js +17 -8
- package/dist/diff/changes/ReferenceChange.js.map +1 -1
- package/dist/json/LionWebJson.d.ts +6 -0
- package/dist/json/LionWebJson.d.ts.map +1 -1
- package/dist/json/LionWebJson.js +8 -0
- package/dist/json/LionWebJson.js.map +1 -1
- package/dist/json/LionWebJsonChunkWrapper.d.ts +2 -3
- package/dist/json/LionWebJsonChunkWrapper.d.ts.map +1 -1
- package/dist/json/LionWebJsonChunkWrapper.js +16 -16
- package/dist/json/LionWebJsonChunkWrapper.js.map +1 -1
- package/dist/json/LionWebLanguageDefinition.d.ts.map +1 -1
- package/dist/json/LionWebLanguageDefinition.js.map +1 -1
- package/dist/json/NodeUtils.d.ts +3 -1
- package/dist/json/NodeUtils.d.ts.map +1 -1
- package/dist/json/NodeUtils.js +8 -1
- package/dist/json/NodeUtils.js.map +1 -1
- package/package.json +1 -1
- package/src/diff/LionWebJsonDiff.ts +81 -26
- package/src/diff/changes/Change.ts +27 -3
- package/src/diff/changes/ChunkChange.ts +5 -5
- package/src/diff/changes/ContainmentChange.ts +10 -12
- package/src/diff/changes/NodeChange.ts +33 -2
- package/src/diff/changes/PropertyChange.ts +8 -6
- package/src/diff/changes/ReferenceChange.ts +18 -8
- package/src/json/LionWebJson.ts +9 -0
- package/src/json/LionWebJsonChunkWrapper.ts +17 -24
- package/src/json/LionWebLanguageDefinition.ts +1 -0
- package/src/json/NodeUtils.ts +19 -4
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { JsonContext } from "../issues/index.js"
|
|
2
2
|
import {
|
|
3
3
|
ChunkUtils,
|
|
4
|
-
isEqualMetaPointer,
|
|
5
|
-
LionWebJsonContainment,
|
|
4
|
+
isEqualMetaPointer, isEqualReferenceTarget,
|
|
6
5
|
LionWebJsonChunk,
|
|
6
|
+
LionWebJsonContainment,
|
|
7
7
|
LionWebJsonNode,
|
|
8
8
|
LionWebJsonProperty,
|
|
9
9
|
LionWebJsonReference,
|
|
10
|
+
LionWebJsonReferenceTarget,
|
|
10
11
|
LwJsonUsedLanguage,
|
|
11
|
-
NodeUtils
|
|
12
|
+
NodeUtils
|
|
12
13
|
} from "../json/index.js"
|
|
13
|
-
import { Change, GenericChange } from "./changes/Change.js"
|
|
14
|
+
import { Change, GenericChange, Missing } from "./changes/Change.js"
|
|
14
15
|
import { LanguageAdded, LanguageRemoved, NodeAdded, NodeRemoved, SerializationFormatChange } from "./changes/ChunkChange.js"
|
|
15
|
-
import { ChildAdded, ChildRemoved } from "./changes/ContainmentChange.js"
|
|
16
|
-
import { TargetAdded, TargetRemoved } from "./changes/index.js"
|
|
17
|
-
import { DiffResult } from "./DiffResult.js"
|
|
16
|
+
import { ChildAdded, ChildRemoved, ChildOrderChanged } from "./changes/ContainmentChange.js"
|
|
17
|
+
import { AnnotationAdded, AnnotationOrderChanged, AnnotationRemoved, TargetAdded, TargetOrderChanged, TargetRemoved } from "./changes/index.js"
|
|
18
18
|
import { NodeClassifierChanged, ParentChanged } from "./changes/NodeChange.js"
|
|
19
19
|
import { PropertyValueChanged } from "./changes/PropertyChange.js"
|
|
20
|
+
import { DiffResult } from "./DiffResult.js"
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Comparing LionWeb JSON chunks and find all differences
|
|
@@ -42,9 +43,7 @@ export class LionWebJsonDiff {
|
|
|
42
43
|
*/
|
|
43
44
|
diffLwNode(ctx: JsonContext, beforeNode: LionWebJsonNode, afterNode: LionWebJsonNode): void {
|
|
44
45
|
if (!isEqualMetaPointer(beforeNode.classifier, afterNode.classifier)) {
|
|
45
|
-
this.change(
|
|
46
|
-
new NodeClassifierChanged(ctx.concat("classifier"), beforeNode, beforeNode.classifier, afterNode.classifier),
|
|
47
|
-
)
|
|
46
|
+
this.change(new NodeClassifierChanged(ctx.concat("classifier"), beforeNode, beforeNode.classifier, afterNode.classifier))
|
|
48
47
|
}
|
|
49
48
|
if (beforeNode.parent !== afterNode.parent) {
|
|
50
49
|
this.change(new ParentChanged(ctx, beforeNode, beforeNode.parent, afterNode.parent))
|
|
@@ -60,7 +59,8 @@ export class LionWebJsonDiff {
|
|
|
60
59
|
beforeNode.id,
|
|
61
60
|
beforeProperty.property,
|
|
62
61
|
beforeProperty.value,
|
|
63
|
-
|
|
62
|
+
null,
|
|
63
|
+
Missing.MissingAfter
|
|
64
64
|
),
|
|
65
65
|
)
|
|
66
66
|
} else {
|
|
@@ -76,8 +76,9 @@ export class LionWebJsonDiff {
|
|
|
76
76
|
ctx.concat("properties", index),
|
|
77
77
|
beforeNode.id,
|
|
78
78
|
afterProperty.property,
|
|
79
|
-
|
|
79
|
+
null,
|
|
80
80
|
afterProperty.value,
|
|
81
|
+
Missing.MissingBefore
|
|
81
82
|
),
|
|
82
83
|
)
|
|
83
84
|
}
|
|
@@ -90,7 +91,7 @@ export class LionWebJsonDiff {
|
|
|
90
91
|
// NB No containment is considered equivalent to a containment with empty _children_
|
|
91
92
|
if (beforeContainment.children.length !== 0) {
|
|
92
93
|
beforeContainment.children.forEach(childId => {
|
|
93
|
-
this.change(new ChildRemoved(ctx.concat("containments", index), beforeNode, beforeContainment.containment, childId))
|
|
94
|
+
this.change(new ChildRemoved(ctx.concat("containments", index), beforeNode, beforeContainment.containment, afterContainment, childId, Missing.MissingAfter))
|
|
94
95
|
})
|
|
95
96
|
}
|
|
96
97
|
} else {
|
|
@@ -103,7 +104,7 @@ export class LionWebJsonDiff {
|
|
|
103
104
|
if (beforeContainment === null) {
|
|
104
105
|
if (afterContainment.children.length !== 0) {
|
|
105
106
|
afterContainment.children.forEach(childId => {
|
|
106
|
-
this.change(new ChildAdded(ctx.concat("containments", index), afterNode, afterContainment.containment, childId))
|
|
107
|
+
this.change(new ChildAdded(ctx.concat("containments", index), afterNode, afterContainment.containment, afterContainment, childId, Missing.MissingBefore))
|
|
107
108
|
})
|
|
108
109
|
}
|
|
109
110
|
}
|
|
@@ -115,7 +116,7 @@ export class LionWebJsonDiff {
|
|
|
115
116
|
if (afterReference === null) {
|
|
116
117
|
if (beforeReference.targets.length !== 0) {
|
|
117
118
|
beforeReference.targets.forEach(target => {
|
|
118
|
-
this.change(new TargetRemoved(ctx.concat("references", index), afterNode, beforeReference
|
|
119
|
+
this.change(new TargetRemoved(ctx.concat("references", index), afterNode, beforeReference, afterReference, target, Missing.MissingAfter))
|
|
119
120
|
})
|
|
120
121
|
}
|
|
121
122
|
} else {
|
|
@@ -128,11 +129,34 @@ export class LionWebJsonDiff {
|
|
|
128
129
|
if (beforeReference === null) {
|
|
129
130
|
if (afterReference.targets.length !== 0) {
|
|
130
131
|
afterReference.targets.forEach(target => {
|
|
131
|
-
this.change(new TargetAdded(ctx.concat("references", index), afterNode, afterReference
|
|
132
|
+
this.change(new TargetAdded(ctx.concat("references", index), afterNode, beforeReference, afterReference, target, Missing.MissingBefore))
|
|
132
133
|
})
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
})
|
|
137
|
+
if (beforeNode.annotations !== undefined && afterNode.annotations !== undefined) {
|
|
138
|
+
let annotationDiffFound = false
|
|
139
|
+
beforeNode.annotations.forEach((beforeAnn: string, index: number) => {
|
|
140
|
+
if (!afterNode.annotations.includes(beforeAnn)) {
|
|
141
|
+
annotationDiffFound = true
|
|
142
|
+
this.change(new AnnotationRemoved(ctx, beforeNode, afterNode, beforeAnn, index))
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
afterNode.annotations.forEach((afterAnn: string, index: number) => {
|
|
146
|
+
if (!beforeNode.annotations.includes(afterAnn)) {
|
|
147
|
+
annotationDiffFound = true
|
|
148
|
+
this.change(new AnnotationAdded(ctx, beforeNode, afterNode, afterAnn, index))
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
if (!annotationDiffFound) {
|
|
152
|
+
for (let i: number = 0; i < afterNode.annotations.length; i++) {
|
|
153
|
+
if (afterNode.annotations[i] !== beforeNode.annotations[i]) {
|
|
154
|
+
this.change(new AnnotationOrderChanged(ctx.concat("annotations"), beforeNode, afterNode, "", i))
|
|
155
|
+
break
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
136
160
|
}
|
|
137
161
|
|
|
138
162
|
diffLwChunk(beforeChunk: LionWebJsonChunk, afterChunk: LionWebJsonChunk): void {
|
|
@@ -197,14 +221,25 @@ export class LionWebJsonDiff {
|
|
|
197
221
|
}
|
|
198
222
|
// Check whether children exist in both objects (two for loops)
|
|
199
223
|
// TODO Also check for the order that can be changed!!!
|
|
224
|
+
let changeFound = false
|
|
200
225
|
for (const childId1 of beforeContainment.children) {
|
|
201
226
|
if (!afterContainment.children.includes(childId1)) {
|
|
202
|
-
|
|
227
|
+
changeFound = true
|
|
228
|
+
this.change(new ChildRemoved(ctx, node, beforeContainment.containment, afterContainment, childId1))
|
|
203
229
|
}
|
|
204
230
|
}
|
|
205
231
|
for (const childId2 of afterContainment.children) {
|
|
206
232
|
if (!beforeContainment.children.includes(childId2)) {
|
|
207
|
-
|
|
233
|
+
changeFound = true
|
|
234
|
+
this.change(new ChildAdded(ctx, node, beforeContainment.containment, afterContainment, childId2))
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (!changeFound) {
|
|
238
|
+
for (let i: number = 0; i < afterContainment.children.length; i++) {
|
|
239
|
+
if (afterContainment.children[i] !== beforeContainment.children[i]) {
|
|
240
|
+
this.change(new ChildOrderChanged(ctx.concat("children"), node, afterContainment.containment, afterContainment, ""))
|
|
241
|
+
break
|
|
242
|
+
}
|
|
208
243
|
}
|
|
209
244
|
}
|
|
210
245
|
}
|
|
@@ -214,21 +249,41 @@ export class LionWebJsonDiff {
|
|
|
214
249
|
console.error("diffContainment: MetaPointers of containments should be identical")
|
|
215
250
|
this.diff(ctx, `Reference has concept ${JSON.stringify(beforeRef.reference)} vs ${JSON.stringify(afterRef.reference)}`)
|
|
216
251
|
}
|
|
252
|
+
let diffFound = false;
|
|
217
253
|
beforeRef.targets.forEach((beforeTarget: LionWebJsonReferenceTarget, index: number) => {
|
|
218
254
|
const afterTarget = NodeUtils.findLwReferenceTarget(afterRef.targets, beforeTarget)
|
|
219
255
|
if (afterTarget === null) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
this.change(new TargetRemoved(ctx.concat("targets", index), node, beforeRef.reference, beforeTarget.reference))
|
|
256
|
+
this.change(new TargetRemoved(ctx.concat("targets", index), node, beforeRef, afterRef, beforeTarget))
|
|
257
|
+
diffFound = true
|
|
223
258
|
} else {
|
|
224
|
-
if (beforeTarget
|
|
225
|
-
this.diff(
|
|
259
|
+
if (!isEqualReferenceTarget(beforeTarget, afterTarget)) {
|
|
260
|
+
this.diff(
|
|
261
|
+
ctx.concat("targets", index),
|
|
262
|
+
`ERROR: reference target ${JSON.stringify(beforeTarget)} vs ${JSON.stringify(afterTarget)}`,
|
|
263
|
+
)
|
|
226
264
|
}
|
|
227
265
|
}
|
|
228
266
|
})
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
267
|
+
afterRef.targets.forEach((afterTarget: LionWebJsonReferenceTarget, index: number) => {
|
|
268
|
+
const beforeTarget = NodeUtils.findLwReferenceTarget(beforeRef.targets, afterTarget)
|
|
269
|
+
if (beforeTarget === null) {
|
|
270
|
+
this.change(new TargetAdded(ctx.concat("targets", index), node, beforeRef, afterRef, afterTarget))
|
|
271
|
+
diffFound = true
|
|
272
|
+
} else {
|
|
273
|
+
if (!isEqualReferenceTarget(beforeTarget, afterTarget)) {
|
|
274
|
+
this.diff(
|
|
275
|
+
ctx.concat("targets", index),
|
|
276
|
+
`ERROR: reference target ${JSON.stringify(beforeTarget)} vs ${JSON.stringify(afterTarget)}`,
|
|
277
|
+
)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
})
|
|
281
|
+
if (!diffFound) {
|
|
282
|
+
for (let i: number = 0; i < beforeRef.targets.length; i++) {
|
|
283
|
+
if (!isEqualReferenceTarget(beforeRef.targets[i], afterRef.targets[i])) {
|
|
284
|
+
this.change(new TargetOrderChanged(ctx.concat("targets"), node, beforeRef, afterRef, beforeRef.targets[i]))
|
|
285
|
+
break
|
|
286
|
+
}
|
|
232
287
|
}
|
|
233
288
|
}
|
|
234
289
|
}
|
|
@@ -20,9 +20,33 @@ export type ChangeType =
|
|
|
20
20
|
| "TargetRemoved"
|
|
21
21
|
| "ReferenceRemoved"
|
|
22
22
|
| "ReferenceAdded"
|
|
23
|
+
| "AnnotationRemoved"
|
|
24
|
+
| "AnnotationAdded"
|
|
25
|
+
| "ChildOrderChanged"
|
|
26
|
+
| "AnnotationOrderChanged"
|
|
27
|
+
| "TargetOrderChanged"
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Additionbal property in property, contauinment and reference changes to state
|
|
31
|
+
* that the whole property/ containment / reference definition is missing.
|
|
32
|
+
*/
|
|
33
|
+
export enum Missing {
|
|
34
|
+
/**
|
|
35
|
+
* Both before and after have a definition for the property / containment / reference
|
|
36
|
+
*/
|
|
37
|
+
NotMissing,
|
|
38
|
+
/**
|
|
39
|
+
* The definition is missing _before_ for the property / containment / reference
|
|
40
|
+
*/
|
|
41
|
+
MissingBefore,
|
|
42
|
+
/**
|
|
43
|
+
* The definition is missing _after_ for the property / containment / reference
|
|
44
|
+
*/
|
|
45
|
+
MissingAfter
|
|
46
|
+
}
|
|
23
47
|
|
|
24
48
|
export abstract class Change {
|
|
25
|
-
abstract readonly
|
|
49
|
+
abstract readonly changeType: ChangeType
|
|
26
50
|
context: JsonContext
|
|
27
51
|
|
|
28
52
|
constructor(context: JsonContext) {
|
|
@@ -32,12 +56,12 @@ export abstract class Change {
|
|
|
32
56
|
protected abstract msg(): string
|
|
33
57
|
|
|
34
58
|
public changeMsg(): string {
|
|
35
|
-
return `${this.
|
|
59
|
+
return `${this.changeType}: ${this.msg()} at ${this.context.toString()} `
|
|
36
60
|
}
|
|
37
61
|
}
|
|
38
62
|
|
|
39
63
|
export class GenericChange extends Change {
|
|
40
|
-
readonly
|
|
64
|
+
readonly changeType = "GenericChange"
|
|
41
65
|
|
|
42
66
|
constructor(
|
|
43
67
|
context: JsonContext,
|
|
@@ -9,7 +9,7 @@ export abstract class ChunkChange extends Change {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export class SerializationFormatChange extends ChunkChange {
|
|
12
|
-
readonly
|
|
12
|
+
readonly changeType = "SerializationFormatChange"
|
|
13
13
|
|
|
14
14
|
constructor(
|
|
15
15
|
public context: JsonContext,
|
|
@@ -23,7 +23,7 @@ export class SerializationFormatChange extends ChunkChange {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export class NodeRemoved extends ChunkChange {
|
|
26
|
-
readonly
|
|
26
|
+
readonly changeType = "NodeRemoved"
|
|
27
27
|
|
|
28
28
|
constructor(
|
|
29
29
|
public context: JsonContext,
|
|
@@ -36,7 +36,7 @@ export class NodeRemoved extends ChunkChange {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export class NodeAdded extends ChunkChange {
|
|
39
|
-
readonly
|
|
39
|
+
readonly changeType = "NodeAdded"
|
|
40
40
|
|
|
41
41
|
constructor(
|
|
42
42
|
public context: JsonContext,
|
|
@@ -58,11 +58,11 @@ export abstract class LanguageChange extends ChunkChange {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export class LanguageRemoved extends LanguageChange {
|
|
61
|
-
readonly
|
|
61
|
+
readonly changeType = "LanguageRemoved"
|
|
62
62
|
protected msg = () => `Language with key ${this.language.key} and version ${this.language.version} is removed`
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
export class LanguageAdded extends LanguageChange {
|
|
66
|
-
readonly
|
|
66
|
+
readonly changeType = "LanguageAdded"
|
|
67
67
|
protected msg = () => `Language with key ${this.language.key} and version ${this.language.version} is added`
|
|
68
68
|
}
|
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
import { JsonContext } from "../../issues/index.js"
|
|
2
|
-
import { LionWebJsonMetaPointer, LionWebJsonNode } from "../../json/index.js"
|
|
3
|
-
import { Change } from "./Change.js"
|
|
2
|
+
import { LionWebJsonContainment, LionWebJsonMetaPointer, LionWebJsonNode } from "../../json/index.js"
|
|
3
|
+
import { Change, Missing } from "./Change.js"
|
|
4
4
|
|
|
5
5
|
export abstract class ContainmentChange extends Change {
|
|
6
6
|
constructor(
|
|
7
7
|
public context: JsonContext,
|
|
8
8
|
public parentNode: LionWebJsonNode,
|
|
9
9
|
public containment: LionWebJsonMetaPointer,
|
|
10
|
+
public afterContainment: LionWebJsonContainment | null,
|
|
10
11
|
public childId: string,
|
|
12
|
+
public missing = Missing.NotMissing
|
|
11
13
|
) {
|
|
12
14
|
super(context)
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export class ChildAdded extends ContainmentChange {
|
|
17
|
-
readonly
|
|
19
|
+
readonly changeType = "ChildAdded"
|
|
18
20
|
protected msg = () => `Node "${this.parentNode.id}" added child "${this.childId}" to containment ${this.containment.key}`
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export class ChildRemoved extends ContainmentChange {
|
|
22
|
-
readonly
|
|
23
|
-
protected msg = () => `Node "${this.parentNode.id}" removed child "${this.childId}"`
|
|
24
|
+
readonly changeType = "ChildRemoved"
|
|
25
|
+
protected msg = () => `Node "${this.parentNode.id}" removed child "${this.childId}" from containment "${this.containment.key}"`
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
export class
|
|
27
|
-
readonly
|
|
28
|
-
|
|
29
|
-
super(ctx)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
protected msg = () => `Node "${this.node.id}" containment added: "${JSON.stringify(this.containment)}"`
|
|
28
|
+
export class ChildOrderChanged extends ContainmentChange {
|
|
29
|
+
readonly changeType = "ChildOrderChanged"
|
|
30
|
+
protected msg = () => `Node "${this.parentNode.id}" changed order of children in containment "${this.containment.key}"`
|
|
33
31
|
}
|
|
34
32
|
|
|
@@ -3,7 +3,7 @@ import { LionWebJsonMetaPointer, LionWebJsonNode } from "../../json/index.js"
|
|
|
3
3
|
import { Change, ChangeType } from "./Change.js"
|
|
4
4
|
|
|
5
5
|
export class NodeClassifierChanged extends Change {
|
|
6
|
-
readonly
|
|
6
|
+
readonly changeType: ChangeType = "NodeClassifierChanged"
|
|
7
7
|
|
|
8
8
|
constructor(
|
|
9
9
|
public context: JsonContext,
|
|
@@ -13,11 +13,12 @@ export class NodeClassifierChanged extends Change {
|
|
|
13
13
|
) {
|
|
14
14
|
super(context)
|
|
15
15
|
}
|
|
16
|
+
|
|
16
17
|
protected msg = () => `Object ${this.node.id} has classifier changed from ${this.oldClassifier.key} to ${this.newClassifier.key}`
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export class ParentChanged extends Change {
|
|
20
|
-
readonly
|
|
21
|
+
readonly changeType = "ParentChanged"
|
|
21
22
|
|
|
22
23
|
constructor(
|
|
23
24
|
public context: JsonContext,
|
|
@@ -30,3 +31,33 @@ export class ParentChanged extends Change {
|
|
|
30
31
|
|
|
31
32
|
protected msg = () => `Node "${this.node.id}" changed parent from "${this.beforeParentId}" to "${this.afterParentId}`
|
|
32
33
|
}
|
|
34
|
+
|
|
35
|
+
export abstract class AnnotationChange extends Change {
|
|
36
|
+
constructor(
|
|
37
|
+
ctx: JsonContext,
|
|
38
|
+
public nodeBefore: LionWebJsonNode,
|
|
39
|
+
public nodeAfter: LionWebJsonNode,
|
|
40
|
+
public annotationId: string,
|
|
41
|
+
public index: number
|
|
42
|
+
) {
|
|
43
|
+
super(ctx)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class AnnotationRemoved extends AnnotationChange {
|
|
48
|
+
readonly changeType = "AnnotationRemoved"
|
|
49
|
+
|
|
50
|
+
protected msg = () => `Node "${this.nodeBefore.id}" removed annotation "${this.annotationId}"`
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class AnnotationAdded extends AnnotationChange {
|
|
54
|
+
readonly changeType = "AnnotationAdded"
|
|
55
|
+
|
|
56
|
+
protected msg = () => `Node "${this.nodeAfter.id}" added annotation "${this.annotationId}"`
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
export class AnnotationOrderChanged extends AnnotationChange {
|
|
61
|
+
readonly changeType = "AnnotationOrderChanged"
|
|
62
|
+
protected msg = () => `Node "${this.nodeAfter.id}" changed order of annotations`
|
|
63
|
+
}
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import { JsonContext } from "../../issues/index.js"
|
|
2
2
|
import { LionWebJsonMetaPointer, LionWebJsonNode } from "../../json/index.js"
|
|
3
|
-
import { Change } from "./Change.js"
|
|
3
|
+
import { Change, Missing } from "./Change.js"
|
|
4
|
+
|
|
4
5
|
|
|
5
6
|
export abstract class PropertyChange extends Change {
|
|
6
7
|
constructor(
|
|
7
8
|
public context: JsonContext,
|
|
8
9
|
public nodeId: string,
|
|
9
10
|
public property: LionWebJsonMetaPointer,
|
|
10
|
-
public oldValue: string |
|
|
11
|
-
public newValue: string |
|
|
11
|
+
public oldValue: string | null,
|
|
12
|
+
public newValue: string | null,
|
|
13
|
+
public missing: Missing = Missing.NotMissing
|
|
12
14
|
) {
|
|
13
|
-
super(context)
|
|
15
|
+
super(context)
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export class PropertyValueChanged extends PropertyChange {
|
|
18
|
-
readonly
|
|
20
|
+
readonly changeType = "PropertyValueChanged"
|
|
19
21
|
protected msg = () => `Node "${this.nodeId} changed value of property "${this.property.key}" from "${this.oldValue}" to "${this.newValue}"`
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
export class PropertyAdded extends Change {
|
|
23
|
-
readonly
|
|
25
|
+
readonly changeType = "PropertyAdded";
|
|
24
26
|
constructor(ctx: JsonContext, public node: LionWebJsonNode, public property: LionWebJsonMetaPointer) {
|
|
25
27
|
super(ctx)
|
|
26
28
|
}
|
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
import { JsonContext } from "../../issues/index.js"
|
|
2
|
-
import {
|
|
3
|
-
import { Change } from "./Change.js"
|
|
2
|
+
import { LionWebJsonNode, LionWebJsonReference, LionWebJsonReferenceTarget } from "../../json/index.js"
|
|
3
|
+
import { Change, Missing } from "./Change.js"
|
|
4
4
|
|
|
5
5
|
export abstract class ReferenceChange extends Change {
|
|
6
6
|
constructor(
|
|
7
7
|
public context: JsonContext,
|
|
8
8
|
public node: LionWebJsonNode,
|
|
9
|
-
public
|
|
10
|
-
public
|
|
9
|
+
public beforeReference: LionWebJsonReference | null,
|
|
10
|
+
public afterReference: LionWebJsonReference | null,
|
|
11
|
+
public target: LionWebJsonReferenceTarget,
|
|
12
|
+
public missing = Missing.NotMissing
|
|
11
13
|
) {
|
|
12
14
|
super(context)
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export class TargetAdded extends ReferenceChange {
|
|
17
|
-
readonly
|
|
18
|
-
protected msg = () =>
|
|
19
|
+
readonly changeType = "TargetAdded"
|
|
20
|
+
protected msg = () =>
|
|
21
|
+
`Node "${this.node.id}" added target "${this.target.reference}" to reference "${this?.afterReference?.reference?.key}"`
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
export class TargetRemoved extends ReferenceChange {
|
|
22
|
-
readonly
|
|
23
|
-
protected msg = () =>
|
|
25
|
+
readonly changeType = "TargetRemoved"
|
|
26
|
+
protected msg = () =>
|
|
27
|
+
`Node "${this.node.id}" removed target "${this.target.reference}" from reference "${this?.beforeReference?.reference?.key}"`
|
|
24
28
|
}
|
|
29
|
+
|
|
30
|
+
export class TargetOrderChanged extends ReferenceChange {
|
|
31
|
+
readonly changeType = "TargetOrderChanged"
|
|
32
|
+
protected msg = () => `Node "${this.node.id}" changed order of targets in reference "${this.afterReference?.reference?.key}"`
|
|
33
|
+
}
|
|
34
|
+
|
package/src/json/LionWebJson.ts
CHANGED
|
@@ -14,6 +14,11 @@ export const LIONWEB_JSON_TYPE = "LionCore-builtins-JSON"
|
|
|
14
14
|
export const LIONWEB_INTEGER_TYPE = "LionCore-builtins-Integer"
|
|
15
15
|
export const LIONWEB_STRING_TYPE = "LionCore-builtins-String"
|
|
16
16
|
|
|
17
|
+
export const LIONWEB_M3_INAMED_PROPERTY = {
|
|
18
|
+
language: LION_CORE_BUILTINS_KEY,
|
|
19
|
+
version: LION_CORE_M3_VERSION,
|
|
20
|
+
key: LION_CORE_BUILTINS_INAMED_NAME
|
|
21
|
+
}
|
|
17
22
|
export type LionWebId = string
|
|
18
23
|
|
|
19
24
|
export type LionWebJsonMetaPointer = {
|
|
@@ -26,6 +31,10 @@ export function isEqualMetaPointer(p1: LionWebJsonMetaPointer, p2: LionWebJsonMe
|
|
|
26
31
|
return p1.key === p2.key && p1.version === p2.version && p1.language === p2.language
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
export function isEqualReferenceTarget(first: LionWebJsonReferenceTarget, second: LionWebJsonReferenceTarget): boolean {
|
|
35
|
+
return first.reference === second.reference && first.resolveInfo === second.resolveInfo
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
export type LionWebJsonChunk = {
|
|
30
39
|
serializationFormatVersion: string
|
|
31
40
|
languages: LwJsonUsedLanguage[]
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
LIONWEB_M3_INAMED_PROPERTY,
|
|
3
3
|
LionWebId,
|
|
4
4
|
LionWebJsonChunk,
|
|
5
|
-
LionWebJsonContainment,
|
|
6
|
-
LionWebJsonMetaPointer,
|
|
7
5
|
LionWebJsonNode,
|
|
8
6
|
LionWebJsonProperty
|
|
9
7
|
} from "./LionWebJson.js"
|
|
@@ -41,18 +39,6 @@ export class LionWebJsonChunkWrapper {
|
|
|
41
39
|
return this.nodesIdMap.get(id)
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
findContainment(node: LionWebJsonNode, containment: LionWebJsonMetaPointer): LionWebJsonContainment | undefined {
|
|
45
|
-
return node.containments.find(
|
|
46
|
-
cont => isEqualMetaPointer(cont.containment, containment)
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
findProperty(node: LionWebJsonNode, property: LionWebJsonMetaPointer): LionWebJsonProperty | undefined {
|
|
51
|
-
return node.properties.find(
|
|
52
|
-
prop => isEqualMetaPointer(prop.property, property)
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
42
|
findNodesOfConcept(conceptKey: string): LionWebJsonNode[] {
|
|
57
43
|
return this.jsonChunk.nodes.filter(node => node.classifier.key === conceptKey)
|
|
58
44
|
}
|
|
@@ -88,22 +74,25 @@ export class LionWebJsonChunkWrapper {
|
|
|
88
74
|
return "";
|
|
89
75
|
}
|
|
90
76
|
let result: string = ""
|
|
91
|
-
const nameProperty =
|
|
92
|
-
language: LION_CORE_BUILTINS_KEY,
|
|
93
|
-
version: LION_CORE_M3_VERSION,
|
|
94
|
-
key: LION_CORE_BUILTINS_INAMED_NAME,
|
|
95
|
-
})
|
|
77
|
+
const nameProperty = NodeUtils.findProperty(node, LIONWEB_M3_INAMED_PROPERTY)
|
|
96
78
|
const name = nameProperty === undefined ? "" : " " + nameProperty.value
|
|
97
|
-
result +=
|
|
79
|
+
result += this.indent(depth) + "(" + node.id + ")" + name + "\n"
|
|
80
|
+
if (node.annotations !== undefined && node.annotations.length !== 0) {
|
|
81
|
+
result += this.indent(depth + 1) + "*Annotations*" + "\n"
|
|
82
|
+
node.annotations.forEach(ann => {
|
|
83
|
+
result += this.recursiveToString(this.getNode(ann), depth + 1)
|
|
84
|
+
// result += this.indent(depth) + "[[" + JSON.stringify(ann) + "]]\n"
|
|
85
|
+
})
|
|
86
|
+
}
|
|
98
87
|
node.properties.filter(p => p !== nameProperty).forEach(property => {
|
|
99
|
-
result +=
|
|
88
|
+
result += this.indent(depth + 1) + "*property* " + property.property.key + ": " + property.value + "\n"
|
|
100
89
|
})
|
|
101
90
|
node.references.forEach(ref => {
|
|
102
|
-
result +=
|
|
91
|
+
result += this.indent(depth + 1) + "*" + ref.reference.key + "*: " + JSON.stringify(ref.targets) + "\n"
|
|
103
92
|
})
|
|
104
93
|
node.containments.forEach(cont => {
|
|
105
94
|
if (cont.children.length !== 0) {
|
|
106
|
-
result +=
|
|
95
|
+
result += this.indent(depth + 1) + "*" + cont.containment.key + "*" + "\n"
|
|
107
96
|
cont.children.forEach(ch => {
|
|
108
97
|
result += this.recursiveToString(this.getNode(ch), depth + 1)
|
|
109
98
|
})
|
|
@@ -111,4 +100,8 @@ export class LionWebJsonChunkWrapper {
|
|
|
111
100
|
})
|
|
112
101
|
return result
|
|
113
102
|
}
|
|
103
|
+
|
|
104
|
+
private indent(depth: number): string {
|
|
105
|
+
return Array(depth).join(" ")
|
|
106
|
+
}
|
|
114
107
|
}
|
|
@@ -17,6 +17,7 @@ export const LIONWEB_M3_LANGUAGE_KEY = "Language"
|
|
|
17
17
|
export const LIONWEB_M3_LANGUAGE_VERSION_KEY = "Language-version"
|
|
18
18
|
export const LIONWEB_M3_IKEYED_KEY_KEY = "IKeyed-key"
|
|
19
19
|
export const LIONWEB_M3_PROPERTY_TYPE_KEY = "Property-type"
|
|
20
|
+
|
|
20
21
|
/**
|
|
21
22
|
* Collection of language definitions
|
|
22
23
|
*/
|
package/src/json/NodeUtils.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
isEqualMetaPointer,
|
|
3
|
+
isEqualReferenceTarget,
|
|
4
|
+
LionWebJsonContainment, LionWebJsonMetaPointer,
|
|
3
5
|
LionWebJsonNode,
|
|
4
6
|
LionWebJsonProperty,
|
|
5
7
|
LionWebJsonReference,
|
|
6
|
-
LionWebJsonReferenceTarget
|
|
8
|
+
LionWebJsonReferenceTarget
|
|
7
9
|
} from "./LionWebJson.js"
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -24,6 +26,12 @@ export class NodeUtils {
|
|
|
24
26
|
return null
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
static findProperty(node: LionWebJsonNode, property: LionWebJsonMetaPointer): LionWebJsonProperty | undefined {
|
|
30
|
+
return node.properties.find(
|
|
31
|
+
prop => isEqualMetaPointer(prop.property, property)
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
/**
|
|
28
36
|
* Find containment child with key equals `key` in `node`.
|
|
29
37
|
* @param node
|
|
@@ -38,6 +46,13 @@ export class NodeUtils {
|
|
|
38
46
|
return null
|
|
39
47
|
}
|
|
40
48
|
|
|
49
|
+
static findContainment(node: LionWebJsonNode, containment: LionWebJsonMetaPointer): LionWebJsonContainment | undefined {
|
|
50
|
+
return node.containments.find(
|
|
51
|
+
cont => isEqualMetaPointer(cont.containment, containment)
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
41
56
|
static findLwReference(node: LionWebJsonNode, key: string): LionWebJsonReference | null {
|
|
42
57
|
for (const reference of node.references) {
|
|
43
58
|
if (reference.reference.key === key) {
|
|
@@ -52,13 +67,13 @@ export class NodeUtils {
|
|
|
52
67
|
target: LionWebJsonReferenceTarget,
|
|
53
68
|
): LionWebJsonReferenceTarget | null {
|
|
54
69
|
for (const refTarget of lwReferenceTargets) {
|
|
55
|
-
if (refTarget
|
|
70
|
+
if (isEqualReferenceTarget(refTarget, target)) {
|
|
56
71
|
return refTarget
|
|
57
72
|
}
|
|
58
73
|
}
|
|
59
74
|
return null
|
|
60
75
|
}
|
|
61
|
-
|
|
76
|
+
|
|
62
77
|
/**
|
|
63
78
|
* Get all nodes that are children for _node_: both the containment and annotation children
|
|
64
79
|
* @param node
|