@lionweb/json-utils 0.7.0-beta.8 → 0.7.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/dist/LionWebJsonChunkWrapper.d.ts.map +1 -1
- package/dist/LionWebJsonChunkWrapper.js +3 -2
- package/dist/LionWebJsonChunkWrapper.js.map +1 -1
- package/package.json +31 -30
- package/src/ChunkUtils.ts +49 -0
- package/src/JsonContext.ts +31 -0
- package/src/LionWebJson.ts +13 -0
- package/src/LionWebJsonChunkWrapper.ts +137 -0
- package/src/M3definitions.ts +178 -0
- package/src/NodeUtils.ts +76 -0
- package/src/index.ts +6 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LionWebJsonChunkWrapper.d.ts","sourceRoot":"","sources":["../src/LionWebJsonChunkWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,SAAS,EACT,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACvB,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"LionWebJsonChunkWrapper.d.ts","sourceRoot":"","sources":["../src/LionWebJsonChunkWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,SAAS,EACT,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACvB,MAAM,eAAe,CAAA;AAKtB;;;;GAIG;AACH,qBAAa,uBAAuB;IAChC,SAAS,EAAE,gBAAgB,CAAA;IAC3B;;;OAGG;IACH,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,CAAwC;IAE7F;;;OAGG;gBACS,KAAK,EAAE,gBAAgB;IAKnC;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,gBAAgB;IAMtC,OAAO,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe,GAAG,SAAS;IAInD,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,EAAE;IAIzE;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,oBAAoB,GAAG,SAAS;IAe5D;;;OAGG;IACH,kBAAkB,CAAC,WAAW,EAAE,sBAAsB,GAAG,SAAS;IAclE,QAAQ,IAAI,MAAM;IAUlB,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,MAAM;CAGjB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isEqualMetaPointer } from "@lionweb/json";
|
|
2
|
+
import { asMinimalJsonString } from "@lionweb/ts-utils";
|
|
2
3
|
import { MetaPointers } from "./M3definitions.js";
|
|
3
4
|
import { NodeUtils } from "./NodeUtils.js";
|
|
4
5
|
/**
|
|
@@ -91,7 +92,7 @@ export class LionWebJsonChunkWrapper {
|
|
|
91
92
|
result += this.indent(depth + 1) + "*Annotations*" + "\n";
|
|
92
93
|
node.annotations.forEach(ann => {
|
|
93
94
|
result += this.recursiveToString(this.getNode(ann), depth + 1);
|
|
94
|
-
// result += this.indent(depth) + "[[" +
|
|
95
|
+
// result += this.indent(depth) + "[[" + asMinimalJsonString(ann) + "]]\n"
|
|
95
96
|
});
|
|
96
97
|
}
|
|
97
98
|
node.properties
|
|
@@ -100,7 +101,7 @@ export class LionWebJsonChunkWrapper {
|
|
|
100
101
|
result += this.indent(depth + 1) + "*property* " + property.property.key + ": " + property.value + "\n";
|
|
101
102
|
});
|
|
102
103
|
node.references.forEach(ref => {
|
|
103
|
-
result += this.indent(depth + 1) + "*" + ref.reference.key + "*: " +
|
|
104
|
+
result += this.indent(depth + 1) + "*" + ref.reference.key + "*: " + asMinimalJsonString(ref.targets) + "\n";
|
|
104
105
|
});
|
|
105
106
|
node.containments.forEach(cont => {
|
|
106
107
|
if (cont.children.length !== 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LionWebJsonChunkWrapper.js","sourceRoot":"","sources":["../src/LionWebJsonChunkWrapper.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"LionWebJsonChunkWrapper.js","sourceRoot":"","sources":["../src/LionWebJsonChunkWrapper.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
2
|
+
"name": "@lionweb/json-utils",
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "Utilities for LionWeb JSON",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"typings": "dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/LionWeb-io/lionweb-typescript.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/LionWeb-io/lionweb-typescript/issues"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"clean": "npx rimraf dist node_modules -g lionweb-json-utils-*.tgz",
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"lint": "eslint src",
|
|
21
|
+
"prep:pre-release": "npm run clean && npm install && npm run build",
|
|
22
|
+
"prerelease-alpha": "npm run prep:pre-release",
|
|
23
|
+
"release-alpha": "npm publish --tag alpha",
|
|
24
|
+
"prerelease-beta": "npm run prep:pre-release",
|
|
25
|
+
"release-beta": "npm publish --tag beta",
|
|
26
|
+
"prerelease": "npm run prep:pre-release",
|
|
27
|
+
"release": "npm publish"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@lionweb/json": "0.7.0",
|
|
31
|
+
"@lionweb/ts-utils": "0.7.0"
|
|
32
|
+
}
|
|
32
33
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { LionWebId, LionWebJsonChunk, LionWebJsonNode, LionWebJsonUsedLanguage, LionWebKey } from "@lionweb/json"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Utility functions for LionWeb chunks
|
|
5
|
+
*/
|
|
6
|
+
export class ChunkUtils {
|
|
7
|
+
/**
|
|
8
|
+
* Find a used language in `chunk` with `key`.
|
|
9
|
+
* @param chunk
|
|
10
|
+
* @param key
|
|
11
|
+
*/
|
|
12
|
+
static findLwUsedLanguage(chunk: LionWebJsonChunk, key: LionWebKey): LionWebJsonUsedLanguage | null {
|
|
13
|
+
for (const language of chunk.languages) {
|
|
14
|
+
if (language.key === key) {
|
|
15
|
+
return language
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Find a used language in `chunk` with `key` and 'version'.
|
|
23
|
+
* @param chunk
|
|
24
|
+
* @param key
|
|
25
|
+
* @param version
|
|
26
|
+
*/
|
|
27
|
+
static findLwUsedLanguageWithVersion(chunk: LionWebJsonChunk, key: LionWebKey, version: string): LionWebJsonUsedLanguage | null {
|
|
28
|
+
for (const language of chunk.languages) {
|
|
29
|
+
if (language.key === key && language.version === version) {
|
|
30
|
+
return language
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Find node with id equals `id` in `chunk`.
|
|
38
|
+
* @param chunk
|
|
39
|
+
* @param id
|
|
40
|
+
*/
|
|
41
|
+
static findNode(chunk: LionWebJsonChunk, id: LionWebId): LionWebJsonNode | null {
|
|
42
|
+
for (const node of chunk.nodes) {
|
|
43
|
+
if (node.id === id) {
|
|
44
|
+
return node
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type JsonPath = (string | number)[]
|
|
2
|
+
|
|
3
|
+
export class JsonContext {
|
|
4
|
+
private parent: JsonContext | null
|
|
5
|
+
private local_path: JsonPath
|
|
6
|
+
|
|
7
|
+
concat(...items: JsonPath): JsonContext {
|
|
8
|
+
return new JsonContext(this, items)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
path(): JsonPath {
|
|
12
|
+
return this.parent === null ? this.local_path : this.parent.path().concat(this.local_path)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
constructor(parent: JsonContext | null, path: JsonPath) {
|
|
16
|
+
this.parent = parent
|
|
17
|
+
this.local_path = path
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
toString(): string {
|
|
21
|
+
let result = ""
|
|
22
|
+
this.path().forEach((part, index) => {
|
|
23
|
+
if (typeof part === "string") {
|
|
24
|
+
result += (index === 0 ? "" : ".") + part
|
|
25
|
+
} else if (typeof part === "number") {
|
|
26
|
+
result += "[" + part + "]"
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
return result
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LionWebJsonUsedLanguage } from "@lionweb/json"
|
|
2
|
+
import { LION_CORE_M3_KEY, LION_CORE_M3_VERSION } from "./M3definitions.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The types defining the structure of the LionWeb JSON format.
|
|
6
|
+
* @see https://lionweb-io.github.io/specification/serialization/serialization.html
|
|
7
|
+
* We use types instead of classes, because the purpose is to define the Lionweb JSON to be sent over the line.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export function isLionWebM3Language(language: LionWebJsonUsedLanguage): boolean {
|
|
12
|
+
return language.key === LION_CORE_M3_KEY && language.version === LION_CORE_M3_VERSION
|
|
13
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isEqualMetaPointer,
|
|
3
|
+
LionWebId,
|
|
4
|
+
LionWebJsonChunk,
|
|
5
|
+
LionWebJsonContainment,
|
|
6
|
+
LionWebJsonMetaPointer,
|
|
7
|
+
LionWebJsonNode,
|
|
8
|
+
LionWebJsonReference
|
|
9
|
+
} from "@lionweb/json"
|
|
10
|
+
import { asMinimalJsonString } from "@lionweb/ts-utils"
|
|
11
|
+
import { MetaPointers } from "./M3definitions.js"
|
|
12
|
+
import { NodeUtils } from "./NodeUtils.js"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Wraps around a LionWebJsonChunk, providing access to information inside, might be using caches to improve performance.
|
|
16
|
+
* NB Make sure that the contents of the chunk are not changed after creating the wrapper!
|
|
17
|
+
* NB BE aware that with `pushChunk(...)` the original chunk will be changed.
|
|
18
|
+
*/
|
|
19
|
+
export class LionWebJsonChunkWrapper {
|
|
20
|
+
jsonChunk: LionWebJsonChunk
|
|
21
|
+
/**
|
|
22
|
+
* Map to get quick access to nodes by id.
|
|
23
|
+
* @protected
|
|
24
|
+
*/
|
|
25
|
+
protected nodesIdMap: Map<LionWebId, LionWebJsonNode> = new Map<LionWebId, LionWebJsonNode>()
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a wrapper with `chunk` as its chunk
|
|
29
|
+
* @param chunk
|
|
30
|
+
*/
|
|
31
|
+
constructor(chunk: LionWebJsonChunk) {
|
|
32
|
+
this.jsonChunk = chunk
|
|
33
|
+
this.prepareNodeIds(chunk)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Put all nodes in a map, validate that there are no two nodes with the same id.
|
|
37
|
+
* The check should logically be in LionWebReferenceValidator, but the created map is needed here.
|
|
38
|
+
*/
|
|
39
|
+
prepareNodeIds(chunk: LionWebJsonChunk) {
|
|
40
|
+
chunk.nodes.forEach(node => {
|
|
41
|
+
this.nodesIdMap.set(node.id, node)
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getNode(id: LionWebId): LionWebJsonNode | undefined {
|
|
46
|
+
return this.nodesIdMap.get(id)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
findNodesOfClassifier(concept: LionWebJsonMetaPointer): LionWebJsonNode[] {
|
|
50
|
+
return this.jsonChunk.nodes.filter(node => isEqualMetaPointer(node.classifier, concept))
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Return the target nodes inside `reference` as a list of actual nodes (LionWebJsonNode[])
|
|
55
|
+
* @param reference
|
|
56
|
+
*/
|
|
57
|
+
getReferredNodes(reference: LionWebJsonReference | undefined) {
|
|
58
|
+
if (reference === undefined) {
|
|
59
|
+
return []
|
|
60
|
+
}
|
|
61
|
+
const result = reference.targets.flatMap(target => {
|
|
62
|
+
if (target.reference === null) {
|
|
63
|
+
return []
|
|
64
|
+
} else {
|
|
65
|
+
const referredNode = this.getNode(target.reference)
|
|
66
|
+
return referredNode === undefined ? [] : [referredNode]
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
return result
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Return the target nodes inside `reference` as a list of actual nodes (LionWebJsonNode[])
|
|
74
|
+
* @param reference
|
|
75
|
+
*/
|
|
76
|
+
getChildrenAsNodes(containment: LionWebJsonContainment | undefined) {
|
|
77
|
+
if (containment === undefined) {
|
|
78
|
+
return []
|
|
79
|
+
}
|
|
80
|
+
const result: LionWebJsonNode[] = []
|
|
81
|
+
containment.children.forEach(ch => {
|
|
82
|
+
const childNode = this.getNode(ch)
|
|
83
|
+
if (childNode !== undefined) {
|
|
84
|
+
result.push(childNode)
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
return result
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
asString(): string {
|
|
91
|
+
let result = ""
|
|
92
|
+
const partitions = this.jsonChunk.nodes.filter(n => n.parent === null)
|
|
93
|
+
partitions.forEach(partition => {
|
|
94
|
+
const pString = this.recursiveToString(partition, 1)
|
|
95
|
+
result += pString
|
|
96
|
+
})
|
|
97
|
+
return result
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private recursiveToString(node: LionWebJsonNode | undefined, depth: number): string {
|
|
101
|
+
if (node === undefined) {
|
|
102
|
+
return ""
|
|
103
|
+
}
|
|
104
|
+
let result: string = ""
|
|
105
|
+
const nameProperty = NodeUtils.findProperty(node, MetaPointers.INamedName)
|
|
106
|
+
const name = nameProperty === undefined ? "" : " " + nameProperty.value
|
|
107
|
+
result += this.indent(depth) + "(" + node.id + ")" + name + "\n"
|
|
108
|
+
if (node.annotations !== undefined && node.annotations.length !== 0) {
|
|
109
|
+
result += this.indent(depth + 1) + "*Annotations*" + "\n"
|
|
110
|
+
node.annotations.forEach(ann => {
|
|
111
|
+
result += this.recursiveToString(this.getNode(ann), depth + 1)
|
|
112
|
+
// result += this.indent(depth) + "[[" + asMinimalJsonString(ann) + "]]\n"
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
node.properties
|
|
116
|
+
.filter(p => p !== nameProperty)
|
|
117
|
+
.forEach(property => {
|
|
118
|
+
result += this.indent(depth + 1) + "*property* " + property.property.key + ": " + property.value + "\n"
|
|
119
|
+
})
|
|
120
|
+
node.references.forEach(ref => {
|
|
121
|
+
result += this.indent(depth + 1) + "*" + ref.reference.key + "*: " + asMinimalJsonString(ref.targets) + "\n"
|
|
122
|
+
})
|
|
123
|
+
node.containments.forEach(cont => {
|
|
124
|
+
if (cont.children.length !== 0) {
|
|
125
|
+
result += this.indent(depth + 1) + "*" + cont.containment.key + "*" + "\n"
|
|
126
|
+
cont.children.forEach(ch => {
|
|
127
|
+
result += this.recursiveToString(this.getNode(ch), depth + 1)
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
return result
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private indent(depth: number): string {
|
|
135
|
+
return Array(depth).join(" ")
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file contains LionWeb defined M3 keys and identifications.
|
|
3
|
+
*/
|
|
4
|
+
export const LION_CORE_BUILTINS_INAMED_NAME = "LionCore-builtins-INamed-name"
|
|
5
|
+
export const LION_CORE_BUILTINS_KEY = "LionCore-builtins"
|
|
6
|
+
|
|
7
|
+
export const LION_CORE_M3_KEY = "LionCore-M3"
|
|
8
|
+
export const LION_CORE_M3_NAME = "LionCore_M3"
|
|
9
|
+
|
|
10
|
+
export const LION_CORE_M3_VERSION = "2023.1"
|
|
11
|
+
|
|
12
|
+
// built-in data types:
|
|
13
|
+
export const LIONWEB_BOOLEAN_TYPE = "LionCore-builtins-Boolean"
|
|
14
|
+
export const LIONWEB_JSON_TYPE = "LionCore-builtins-JSON"
|
|
15
|
+
export const LIONWEB_INTEGER_TYPE = "LionCore-builtins-Integer"
|
|
16
|
+
export const LIONWEB_STRING_TYPE = "LionCore-builtins-String"
|
|
17
|
+
|
|
18
|
+
export const M3_Keys = {
|
|
19
|
+
Property: "Property",
|
|
20
|
+
Reference: "Reference",
|
|
21
|
+
Concept: "Concept",
|
|
22
|
+
conceptExtends: "Concept-extends",
|
|
23
|
+
conceptImplements: "Concept-implements",
|
|
24
|
+
concept2: {
|
|
25
|
+
key: "Concept",
|
|
26
|
+
extends: { key: "Concept-extends" },
|
|
27
|
+
implements: { key: "Concept-implements" }
|
|
28
|
+
},
|
|
29
|
+
conceptAbstract: "Concept-abstract",
|
|
30
|
+
conceptPartition: "Concept-partition",
|
|
31
|
+
classifierFeatures: "Classifier-features",
|
|
32
|
+
Interface: "Interface",
|
|
33
|
+
InterfaceExtends: "Interface-extends",
|
|
34
|
+
Containment: "Containment",
|
|
35
|
+
Language: "Language",
|
|
36
|
+
languageVersion: "Language-version",
|
|
37
|
+
IKeyedKey: "IKeyed-key",
|
|
38
|
+
PropertyType: "Property-type",
|
|
39
|
+
Enumeration: "Enumeration",
|
|
40
|
+
EnumerationLiterals: "Enumeration-literals",
|
|
41
|
+
EnumerationLiteral: "EnumerationLiteral",
|
|
42
|
+
INamed: "LionCore-builtins-INamed",
|
|
43
|
+
INamedName: "LionCore-builtins-INamed-name",
|
|
44
|
+
Annotation: "Annotation",
|
|
45
|
+
AnnotationAnnotates: "Annotation-annotates",
|
|
46
|
+
AnnotationExtends: "Annotation-extends",
|
|
47
|
+
AnnotationImplements: "Annotation-implements",
|
|
48
|
+
Node: "LionCore-builtins-Node"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const MetaPointers = {
|
|
52
|
+
Language: {
|
|
53
|
+
version: LION_CORE_M3_VERSION,
|
|
54
|
+
language: LION_CORE_M3_KEY,
|
|
55
|
+
key: M3_Keys.Language
|
|
56
|
+
},
|
|
57
|
+
LanguageVersion: {
|
|
58
|
+
version: LION_CORE_M3_VERSION,
|
|
59
|
+
language: LION_CORE_M3_KEY,
|
|
60
|
+
key: M3_Keys.languageVersion
|
|
61
|
+
},
|
|
62
|
+
ClassifierFeatures: {
|
|
63
|
+
version: LION_CORE_M3_VERSION,
|
|
64
|
+
language: LION_CORE_M3_KEY,
|
|
65
|
+
key: M3_Keys.classifierFeatures
|
|
66
|
+
},
|
|
67
|
+
Concept: {
|
|
68
|
+
version: LION_CORE_M3_VERSION,
|
|
69
|
+
language: LION_CORE_M3_KEY,
|
|
70
|
+
key: M3_Keys.concept2.key
|
|
71
|
+
},
|
|
72
|
+
ConceptAbstract: {
|
|
73
|
+
version: LION_CORE_M3_VERSION,
|
|
74
|
+
language: LION_CORE_M3_KEY,
|
|
75
|
+
key: M3_Keys.conceptAbstract
|
|
76
|
+
},
|
|
77
|
+
ConceptPartition: {
|
|
78
|
+
version: LION_CORE_M3_VERSION,
|
|
79
|
+
language: LION_CORE_M3_KEY,
|
|
80
|
+
key: M3_Keys.conceptPartition
|
|
81
|
+
},
|
|
82
|
+
ConceptExtends: {
|
|
83
|
+
version: LION_CORE_M3_VERSION,
|
|
84
|
+
language: LION_CORE_M3_KEY,
|
|
85
|
+
key: M3_Keys.concept2.extends.key
|
|
86
|
+
},
|
|
87
|
+
ConceptImplements: {
|
|
88
|
+
version: LION_CORE_M3_VERSION,
|
|
89
|
+
language: LION_CORE_M3_KEY,
|
|
90
|
+
key: M3_Keys.concept2.implements.key
|
|
91
|
+
},
|
|
92
|
+
Annotation: {
|
|
93
|
+
version: LION_CORE_M3_VERSION,
|
|
94
|
+
language: LION_CORE_M3_KEY,
|
|
95
|
+
key: M3_Keys.Annotation
|
|
96
|
+
},
|
|
97
|
+
AnnotationAnnotates: {
|
|
98
|
+
version: LION_CORE_M3_VERSION,
|
|
99
|
+
language: LION_CORE_M3_KEY,
|
|
100
|
+
key: M3_Keys.AnnotationAnnotates
|
|
101
|
+
},
|
|
102
|
+
AnnotationExtends: {
|
|
103
|
+
version: LION_CORE_M3_VERSION,
|
|
104
|
+
language: LION_CORE_M3_KEY,
|
|
105
|
+
key: M3_Keys.AnnotationExtends
|
|
106
|
+
},
|
|
107
|
+
AnnotationImplements: {
|
|
108
|
+
version: LION_CORE_M3_VERSION,
|
|
109
|
+
language: LION_CORE_M3_KEY,
|
|
110
|
+
key: M3_Keys.AnnotationImplements
|
|
111
|
+
},
|
|
112
|
+
Interface: {
|
|
113
|
+
version: LION_CORE_M3_VERSION,
|
|
114
|
+
language: LION_CORE_M3_KEY,
|
|
115
|
+
key: M3_Keys.Interface
|
|
116
|
+
},
|
|
117
|
+
InterfaceExtends: {
|
|
118
|
+
version: LION_CORE_M3_VERSION,
|
|
119
|
+
language: LION_CORE_M3_KEY,
|
|
120
|
+
key: M3_Keys.InterfaceExtends
|
|
121
|
+
},
|
|
122
|
+
Enumeration: {
|
|
123
|
+
version: LION_CORE_M3_VERSION,
|
|
124
|
+
language: LION_CORE_M3_KEY,
|
|
125
|
+
key: M3_Keys.Enumeration
|
|
126
|
+
},
|
|
127
|
+
EnumerationLiteral: {
|
|
128
|
+
version: LION_CORE_M3_VERSION,
|
|
129
|
+
language: LION_CORE_M3_KEY,
|
|
130
|
+
key: M3_Keys.EnumerationLiteral
|
|
131
|
+
},
|
|
132
|
+
EnumerationLiterals: {
|
|
133
|
+
version: LION_CORE_M3_VERSION,
|
|
134
|
+
language: LION_CORE_M3_KEY,
|
|
135
|
+
key: M3_Keys.EnumerationLiterals
|
|
136
|
+
},
|
|
137
|
+
Containment: {
|
|
138
|
+
version: LION_CORE_M3_VERSION,
|
|
139
|
+
language: LION_CORE_M3_KEY,
|
|
140
|
+
key: M3_Keys.Containment
|
|
141
|
+
},
|
|
142
|
+
Property: {
|
|
143
|
+
version: LION_CORE_M3_VERSION,
|
|
144
|
+
language: LION_CORE_M3_KEY,
|
|
145
|
+
key: M3_Keys.Property
|
|
146
|
+
},
|
|
147
|
+
PropertyType: {
|
|
148
|
+
version: LION_CORE_M3_VERSION,
|
|
149
|
+
language: LION_CORE_M3_KEY,
|
|
150
|
+
key: M3_Keys.PropertyType
|
|
151
|
+
},
|
|
152
|
+
Reference: {
|
|
153
|
+
version: LION_CORE_M3_VERSION,
|
|
154
|
+
language: LION_CORE_M3_KEY,
|
|
155
|
+
key: M3_Keys.Reference
|
|
156
|
+
},
|
|
157
|
+
IKeyedKey: {
|
|
158
|
+
language: LION_CORE_M3_KEY,
|
|
159
|
+
version: LION_CORE_M3_VERSION,
|
|
160
|
+
key: M3_Keys.IKeyedKey
|
|
161
|
+
},
|
|
162
|
+
// Builtins:
|
|
163
|
+
Node: {
|
|
164
|
+
language: LION_CORE_BUILTINS_KEY,
|
|
165
|
+
version: LION_CORE_M3_VERSION,
|
|
166
|
+
key: M3_Keys.Node
|
|
167
|
+
},
|
|
168
|
+
INamed: {
|
|
169
|
+
language: LION_CORE_BUILTINS_KEY,
|
|
170
|
+
version: LION_CORE_M3_VERSION,
|
|
171
|
+
key: M3_Keys.INamed
|
|
172
|
+
},
|
|
173
|
+
INamedName: {
|
|
174
|
+
language: LION_CORE_BUILTINS_KEY,
|
|
175
|
+
version: LION_CORE_M3_VERSION,
|
|
176
|
+
key: M3_Keys.INamedName
|
|
177
|
+
}
|
|
178
|
+
}
|
package/src/NodeUtils.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isEqualMetaPointer,
|
|
3
|
+
isEqualReferenceTarget, LionWebId,
|
|
4
|
+
LionWebJsonContainment,
|
|
5
|
+
LionWebJsonMetaPointer,
|
|
6
|
+
LionWebJsonNode,
|
|
7
|
+
LionWebJsonProperty,
|
|
8
|
+
LionWebJsonReference,
|
|
9
|
+
LionWebJsonReferenceTarget, LionWebKey
|
|
10
|
+
} from "@lionweb/json"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Utility functions for LionWebJsonNode's
|
|
14
|
+
*/
|
|
15
|
+
export class NodeUtils {
|
|
16
|
+
/**
|
|
17
|
+
* Find property with key equals `key` in `node`.
|
|
18
|
+
* @param node
|
|
19
|
+
* @param key
|
|
20
|
+
*/
|
|
21
|
+
static findProperty(node: LionWebJsonNode, property: LionWebJsonMetaPointer): LionWebJsonProperty | undefined {
|
|
22
|
+
if (node === undefined) {
|
|
23
|
+
return undefined
|
|
24
|
+
}
|
|
25
|
+
return node.properties.find(
|
|
26
|
+
prop => isEqualMetaPointer(prop.property, property)
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Find containment child with key equals `key` in `node`.
|
|
32
|
+
* @param node
|
|
33
|
+
* @param key
|
|
34
|
+
*/
|
|
35
|
+
static findChild(node: LionWebJsonNode, key: LionWebKey): LionWebJsonContainment | undefined {
|
|
36
|
+
if (node === undefined) {
|
|
37
|
+
return undefined
|
|
38
|
+
}
|
|
39
|
+
for (const containment of node.containments) {
|
|
40
|
+
if (containment.containment.key === key) {
|
|
41
|
+
return containment
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return undefined
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static findContainment(node: LionWebJsonNode, containment: LionWebJsonMetaPointer): LionWebJsonContainment | undefined {
|
|
48
|
+
if (node === undefined) {
|
|
49
|
+
return undefined
|
|
50
|
+
}
|
|
51
|
+
return node.containments.find(cont => isEqualMetaPointer(cont.containment, containment))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static findReference(node: LionWebJsonNode, reference: LionWebJsonMetaPointer): LionWebJsonReference | undefined {
|
|
55
|
+
if (node === undefined) {
|
|
56
|
+
return undefined
|
|
57
|
+
}
|
|
58
|
+
return node.references.find(ref => isEqualMetaPointer(ref.reference, reference))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static findReferenceTarget(
|
|
62
|
+
referenceTargets: LionWebJsonReferenceTarget[],
|
|
63
|
+
target: LionWebJsonReferenceTarget,
|
|
64
|
+
): LionWebJsonReferenceTarget | undefined {
|
|
65
|
+
for (const refTarget of referenceTargets) {
|
|
66
|
+
if (isEqualReferenceTarget(refTarget, target)) {
|
|
67
|
+
return refTarget
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return undefined
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static findContainmentContainingChild(containments: LionWebJsonContainment[], childId: LionWebId): LionWebJsonContainment | undefined {
|
|
74
|
+
return containments.find(cont => cont.children.includes(childId))
|
|
75
|
+
}
|
|
76
|
+
}
|