@lionweb/validation 0.6.1-beta.0 → 0.6.1-beta.1
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.map +1 -1
- package/dist/diff/LionWebJsonDiff.js +18 -23
- package/dist/diff/LionWebJsonDiff.js.map +1 -1
- package/dist/diff/changes/ContainmentChange.d.ts +2 -2
- package/dist/diff/changes/ContainmentChange.d.ts.map +1 -1
- package/dist/diff/changes/ContainmentChange.js.map +1 -1
- package/dist/diff/changes/ReferenceChange.d.ts +3 -3
- package/dist/diff/changes/ReferenceChange.d.ts.map +1 -1
- package/dist/diff/changes/ReferenceChange.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/issues/LanguageIssues.d.ts +37 -13
- package/dist/issues/LanguageIssues.d.ts.map +1 -1
- package/dist/issues/LanguageIssues.js +49 -13
- package/dist/issues/LanguageIssues.js.map +1 -1
- package/dist/issues/ReferenceIssues.d.ts +6 -6
- package/dist/issues/ReferenceIssues.d.ts.map +1 -1
- package/dist/issues/ReferenceIssues.js +6 -6
- package/dist/issues/ReferenceIssues.js.map +1 -1
- package/dist/issues/SyntaxIssues.d.ts +9 -9
- package/dist/issues/SyntaxIssues.d.ts.map +1 -1
- package/dist/issues/SyntaxIssues.js +9 -9
- package/dist/issues/SyntaxIssues.js.map +1 -1
- package/dist/issues/ValidationIssue.d.ts +7 -1
- package/dist/issues/ValidationIssue.d.ts.map +1 -1
- package/dist/issues/ValidationIssue.js +9 -1
- package/dist/issues/ValidationIssue.js.map +1 -1
- package/dist/json/LionWebJson.d.ts +1 -14
- package/dist/json/LionWebJson.d.ts.map +1 -1
- package/dist/json/LionWebJson.js +4 -14
- package/dist/json/LionWebJson.js.map +1 -1
- package/dist/json/LionWebJsonChunkWrapper.d.ts +20 -8
- package/dist/json/LionWebJsonChunkWrapper.d.ts.map +1 -1
- package/dist/json/LionWebJsonChunkWrapper.js +50 -22
- package/dist/json/LionWebJsonChunkWrapper.js.map +1 -1
- package/dist/json/M3definitions.d.ts +176 -0
- package/dist/json/M3definitions.d.ts.map +1 -0
- package/dist/json/M3definitions.js +174 -0
- package/dist/json/M3definitions.js.map +1 -0
- package/dist/json/NodeUtils.d.ts +3 -9
- package/dist/json/NodeUtils.d.ts.map +1 -1
- package/dist/json/NodeUtils.js +18 -31
- package/dist/json/NodeUtils.js.map +1 -1
- package/dist/json/index.d.ts +1 -2
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js +1 -2
- package/dist/json/index.js.map +1 -1
- package/dist/languages/CompositeLionWebLanguageWrapper.d.ts +24 -0
- package/dist/languages/CompositeLionWebLanguageWrapper.d.ts.map +1 -0
- package/dist/languages/CompositeLionWebLanguageWrapper.js +56 -0
- package/dist/languages/CompositeLionWebLanguageWrapper.js.map +1 -0
- package/dist/languages/LanguageRegistry.d.ts +19 -0
- package/dist/languages/LanguageRegistry.d.ts.map +1 -0
- package/dist/languages/LanguageRegistry.js +37 -0
- package/dist/languages/LanguageRegistry.js.map +1 -0
- package/dist/languages/LanguageUtils.d.ts +35 -0
- package/dist/languages/LanguageUtils.d.ts.map +1 -0
- package/dist/languages/LanguageUtils.js +52 -0
- package/dist/languages/LanguageUtils.js.map +1 -0
- package/dist/languages/LionCore-M3.json +2356 -0
- package/{src/json/std-builtins-copy.json → dist/languages/LionCore-builtins.json} +57 -52
- package/dist/languages/LionWebLanguageWrapper.d.ts +31 -0
- package/dist/languages/LionWebLanguageWrapper.d.ts.map +1 -0
- package/dist/languages/LionWebLanguageWrapper.js +69 -0
- package/dist/languages/LionWebLanguageWrapper.js.map +1 -0
- package/dist/languages/MetaPointerMap.d.ts +11 -0
- package/dist/languages/MetaPointerMap.d.ts.map +1 -0
- package/dist/languages/MetaPointerMap.js +39 -0
- package/dist/languages/MetaPointerMap.js.map +1 -0
- package/dist/languages/index.d.ts +3 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +3 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/runners/FileUtils.d.ts +4 -4
- package/dist/runners/FileUtils.d.ts.map +1 -1
- package/dist/runners/FileUtils.js +8 -32
- package/dist/runners/FileUtils.js.map +1 -1
- package/dist/runners/RunCheckFolder.js +3 -1
- package/dist/runners/RunCheckFolder.js.map +1 -1
- package/dist/runners/RunCheckFolderWithLanguage.js +7 -3
- package/dist/runners/RunCheckFolderWithLanguage.js.map +1 -1
- package/dist/runners/RunCheckOneFile.js +3 -1
- package/dist/runners/RunCheckOneFile.js.map +1 -1
- package/dist/runners/RunCheckOneFileWithLanguage.js +12 -3
- package/dist/runners/RunCheckOneFileWithLanguage.js.map +1 -1
- package/dist/runners/Utils.d.ts.map +1 -1
- package/dist/runners/Utils.js +0 -1
- package/dist/runners/Utils.js.map +1 -1
- package/dist/util/graphs.d.ts +18 -0
- package/dist/util/graphs.d.ts.map +1 -0
- package/dist/util/graphs.js +27 -0
- package/dist/util/graphs.js.map +1 -0
- package/dist/validators/LionWebLanguageReferenceValidator.d.ts +5 -4
- package/dist/validators/LionWebLanguageReferenceValidator.d.ts.map +1 -1
- package/dist/validators/LionWebLanguageReferenceValidator.js +96 -34
- package/dist/validators/LionWebLanguageReferenceValidator.js.map +1 -1
- package/dist/validators/LionWebLanguageValidator.d.ts +15 -3
- package/dist/validators/LionWebLanguageValidator.d.ts.map +1 -1
- package/dist/validators/LionWebLanguageValidator.js +54 -21
- package/dist/validators/LionWebLanguageValidator.js.map +1 -1
- package/dist/validators/LionWebReferenceValidator.d.ts.map +1 -1
- package/dist/validators/LionWebReferenceValidator.js +0 -5
- package/dist/validators/LionWebReferenceValidator.js.map +1 -1
- package/dist/validators/LionWebSyntaxValidator.d.ts +1 -1
- package/dist/validators/LionWebSyntaxValidator.js +1 -1
- package/dist/validators/LionWebValidator.d.ts +3 -3
- package/dist/validators/LionWebValidator.d.ts.map +1 -1
- package/dist/validators/LionWebValidator.js +5 -8
- package/dist/validators/LionWebValidator.js.map +1 -1
- package/package.json +5 -5
- package/src/diff/LionWebJsonDiff.ts +18 -23
- package/src/diff/changes/ContainmentChange.ts +1 -1
- package/src/diff/changes/ReferenceChange.ts +2 -2
- package/src/index.ts +2 -0
- package/src/issues/LanguageIssues.ts +49 -14
- package/src/issues/ReferenceIssues.ts +6 -6
- package/src/issues/SyntaxIssues.ts +9 -9
- package/src/issues/ValidationIssue.ts +12 -2
- package/src/json/LionCore_M3.json +2320 -0
- package/src/json/LionCore_builtins.json +231 -0
- package/src/json/LionWebJson.ts +5 -14
- package/src/json/LionWebJsonChunkWrapper.ts +59 -30
- package/src/json/M3definitions.ts +177 -0
- package/src/json/NodeUtils.ts +21 -39
- package/src/json/index.ts +1 -2
- package/src/languages/CompositeLionWebLanguageWrapper.ts +57 -0
- package/src/languages/LanguageRegistry.ts +44 -0
- package/src/languages/LanguageUtils.ts +61 -0
- package/src/languages/LionCore-M3.json +2356 -0
- package/src/languages/LionCore-builtins.json +372 -0
- package/src/languages/LionWebLanguageWrapper.ts +95 -0
- package/src/languages/MetaPointerMap.ts +40 -0
- package/src/languages/index.ts +2 -0
- package/src/runners/FileUtils.ts +9 -36
- package/src/runners/RunCheckFolder.ts +3 -1
- package/src/runners/RunCheckFolderWithLanguage.ts +7 -7
- package/src/runners/RunCheckOneFile.ts +3 -1
- package/src/runners/RunCheckOneFileWithLanguage.ts +12 -7
- package/src/runners/Utils.ts +0 -1
- package/src/tmp.json +574 -0
- package/src/tryout.js +21 -0
- package/src/util/graphs.ts +36 -0
- package/src/validators/LionWebLanguageReferenceValidator.ts +110 -48
- package/src/validators/LionWebLanguageValidator.ts +62 -21
- package/src/validators/LionWebReferenceValidator.ts +0 -5
- package/src/validators/LionWebSyntaxValidator.ts +2 -2
- package/src/validators/LionWebValidator.ts +5 -9
- package/structure.puml +25 -0
- package/dist/json/LanguageUtils.d.ts +0 -9
- package/dist/json/LanguageUtils.d.ts.map +0 -1
- package/dist/json/LanguageUtils.js +0 -30
- package/dist/json/LanguageUtils.js.map +0 -1
- package/dist/json/LionWebLanguageDefinition.d.ts +0 -48
- package/dist/json/LionWebLanguageDefinition.d.ts.map +0 -1
- package/dist/json/LionWebLanguageDefinition.js +0 -126
- package/dist/json/LionWebLanguageDefinition.js.map +0 -1
- package/src/json/LanguageUtils.ts +0 -52
- package/src/json/LionWebLanguageDefinition.ts +0 -144
|
@@ -1,30 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Language_ContainmentMetaPointerNotInClass_Issue,
|
|
3
|
+
Language_IncorrectPropertyMetaPointer_Issue, Language_PropertyMetaPointerNotInClass_Issue,
|
|
4
|
+
Language_PropertyValue_Issue, Language_ReferenceMetaPointerNotInClass_Issue,
|
|
5
|
+
Language_UnknownConcept_Issue
|
|
6
|
+
} from "../issues/index.js"
|
|
1
7
|
import {
|
|
2
8
|
Language_IncorrectContainmentMetaPointer_Issue,
|
|
3
|
-
Language_IncorrectPropertyMetaPointer_Issue,
|
|
4
9
|
Language_IncorrectReferenceMetaPointer_Issue,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Language_UnknownProperty_Issue,
|
|
8
|
-
Language_UnknownReference_Issue,
|
|
10
|
+
Language_UnknownContainment_Issue, Language_UnknownProperty_Issue,
|
|
11
|
+
Language_UnknownReference_Issue
|
|
9
12
|
} from "../issues/LanguageIssues.js"
|
|
13
|
+
import { isEqualMetaPointer, LionWebJsonNode, MetaPointers, NodeUtils } from "../json/index.js"
|
|
10
14
|
import { JsonContext } from "../json/JsonContext.js"
|
|
11
15
|
import {
|
|
12
|
-
LION_CORE_BUILTINS_INAMED_NAME,
|
|
13
|
-
LIONWEB_BOOLEAN_TYPE,
|
|
14
|
-
LIONWEB_INTEGER_TYPE,
|
|
15
|
-
LIONWEB_JSON_TYPE,
|
|
16
|
-
LIONWEB_STRING_TYPE,
|
|
17
16
|
LionWebJsonContainment,
|
|
18
17
|
LionWebJsonProperty,
|
|
19
18
|
LionWebJsonReference,
|
|
20
19
|
} from "../json/LionWebJson.js"
|
|
21
20
|
import { LionWebJsonChunkWrapper } from "../json/LionWebJsonChunkWrapper.js"
|
|
21
|
+
// import {
|
|
22
|
+
// KnownLanguages, LanguageRegistry
|
|
23
|
+
// } from "../languages/LanguageRegistry.js"
|
|
22
24
|
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
LION_CORE_BUILTINS_INAMED_NAME,
|
|
26
|
+
LIONWEB_BOOLEAN_TYPE,
|
|
27
|
+
LIONWEB_INTEGER_TYPE,
|
|
28
|
+
LIONWEB_JSON_TYPE,
|
|
29
|
+
LIONWEB_STRING_TYPE,
|
|
30
|
+
M3_Keys
|
|
31
|
+
} from "../json/M3definitions.js"
|
|
32
|
+
import { LanguageRegistry } from "../languages/index.js"
|
|
28
33
|
import { SimpleFieldValidator } from "./SimpleFieldValidator.js"
|
|
29
34
|
import { ValidationResult } from "./ValidationResult.js"
|
|
30
35
|
|
|
@@ -33,12 +38,10 @@ import { ValidationResult } from "./ValidationResult.js"
|
|
|
33
38
|
*/
|
|
34
39
|
export class LionWebLanguageReferenceValidator {
|
|
35
40
|
validationResult: ValidationResult
|
|
36
|
-
language: LionWebLanguageDefinition
|
|
37
41
|
simpleFieldValidator: SimpleFieldValidator
|
|
38
42
|
|
|
39
|
-
constructor(validationResult: ValidationResult,
|
|
43
|
+
constructor(validationResult: ValidationResult, private registry: LanguageRegistry) {
|
|
40
44
|
this.validationResult = validationResult
|
|
41
|
-
this.language = lang
|
|
42
45
|
this.simpleFieldValidator = new SimpleFieldValidator(this.validationResult)
|
|
43
46
|
}
|
|
44
47
|
|
|
@@ -48,52 +51,65 @@ export class LionWebLanguageReferenceValidator {
|
|
|
48
51
|
|
|
49
52
|
// TODO test reference and children implementation
|
|
50
53
|
validate(obj: LionWebJsonChunkWrapper): void {
|
|
51
|
-
if (this.language === undefined || this.language === null) {
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
54
|
obj.jsonChunk.nodes.forEach((node, nodeIndex) => {
|
|
55
55
|
const nodeContext = new JsonContext(null, ["node", nodeIndex])
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
56
|
+
const nodeConcept = this.registry.getNodeByMetaPointer(node.classifier)
|
|
57
|
+
if (nodeConcept === undefined && nodeContext !== undefined) {
|
|
58
58
|
this.validationResult.issue(new Language_UnknownConcept_Issue(nodeContext, node.classifier))
|
|
59
59
|
return
|
|
60
60
|
}
|
|
61
61
|
node.properties.forEach((property, propIndex) => {
|
|
62
|
-
this.validateProperty(property, nodeContext.concat("properties", propIndex))
|
|
62
|
+
this.validateProperty(node, nodeConcept, property, nodeContext.concat("properties", propIndex))
|
|
63
63
|
})
|
|
64
64
|
node.containments.forEach((containment, childIndex) => {
|
|
65
|
-
this.validateContainment(containment, nodeContext.concat("containments", childIndex))
|
|
65
|
+
this.validateContainment(node, nodeConcept, containment, nodeContext.concat("containments", childIndex))
|
|
66
66
|
})
|
|
67
67
|
node.references.forEach((reference, refIndex) => {
|
|
68
|
-
this.validateReference(reference, nodeContext.concat("references", refIndex))
|
|
68
|
+
this.validateReference(node, nodeConcept, reference, nodeContext.concat("references", refIndex))
|
|
69
69
|
})
|
|
70
70
|
})
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
private validateContainment(
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
76
|
-
this.validationResult.issue(new Language_UnknownContainment_Issue(context,
|
|
73
|
+
private validateContainment(node: LionWebJsonNode, nodeConcept: LionWebJsonNode | undefined, containment: LionWebJsonContainment, context: JsonContext) {
|
|
74
|
+
const metaConcept = this.registry.getNodeByMetaPointer(containment.containment)
|
|
75
|
+
if (metaConcept === null || metaConcept === undefined) {
|
|
76
|
+
this.validationResult.issue(new Language_UnknownContainment_Issue(context, containment.containment))
|
|
77
77
|
return
|
|
78
78
|
}
|
|
79
|
-
if (
|
|
80
|
-
this.validationResult.issue(new Language_IncorrectContainmentMetaPointer_Issue(context,
|
|
79
|
+
if (metaConcept.classifier.key !== M3_Keys.Containment) {
|
|
80
|
+
this.validationResult.issue(new Language_IncorrectContainmentMetaPointer_Issue(context, containment.containment, metaConcept.classifier.key))
|
|
81
|
+
}
|
|
82
|
+
if (nodeConcept !== undefined) {
|
|
83
|
+
const cons = this.registry.languages.allContainments(nodeConcept)
|
|
84
|
+
if (!cons.includes(metaConcept)) {
|
|
85
|
+
this.validationResult.issue(new Language_ContainmentMetaPointerNotInClass_Issue(context, containment.containment, nodeConcept))
|
|
86
|
+
return
|
|
87
|
+
}
|
|
81
88
|
}
|
|
82
89
|
// TODO check type of children
|
|
83
90
|
}
|
|
84
91
|
|
|
85
|
-
private validateReference(ref: LionWebJsonReference, context: JsonContext) {
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
92
|
+
private validateReference(node: LionWebJsonNode, nodeConcept: LionWebJsonNode | undefined, ref: LionWebJsonReference, context: JsonContext) {
|
|
93
|
+
const referenceDefinition = this.registry.getNodeByMetaPointer(ref.reference)
|
|
94
|
+
if (referenceDefinition === null || referenceDefinition === undefined) {
|
|
88
95
|
this.validationResult.issue(new Language_UnknownReference_Issue(context, ref.reference))
|
|
89
96
|
return
|
|
90
97
|
}
|
|
91
|
-
if (
|
|
92
|
-
this.validationResult.issue(new Language_IncorrectReferenceMetaPointer_Issue(context, ref.reference,
|
|
98
|
+
if (referenceDefinition.classifier.key !== M3_Keys.Reference) {
|
|
99
|
+
this.validationResult.issue(new Language_IncorrectReferenceMetaPointer_Issue(context, ref.reference, referenceDefinition.classifier.key))
|
|
100
|
+
}
|
|
101
|
+
if (nodeConcept !== undefined) {
|
|
102
|
+
const refs = this.registry.languages.allReferenceDefinitions(nodeConcept)
|
|
103
|
+
if (!refs.includes(referenceDefinition)) {
|
|
104
|
+
this.validationResult.issue(new Language_ReferenceMetaPointerNotInClass_Issue(context, ref.reference, nodeConcept))
|
|
105
|
+
return
|
|
106
|
+
}
|
|
93
107
|
}
|
|
108
|
+
|
|
94
109
|
// TODO Check type of reference (if possible)
|
|
95
110
|
|
|
96
111
|
// TODO Check for duplicate targets?
|
|
112
|
+
// No, already done without language check
|
|
97
113
|
// If so, what to check because there can be either or both a `resolveInfo` and a `reference`
|
|
98
114
|
}
|
|
99
115
|
|
|
@@ -101,28 +117,35 @@ export class LionWebLanguageReferenceValidator {
|
|
|
101
117
|
* Checks wwhether the value of `prop1` is correct in relation with its property definition in the referred language.
|
|
102
118
|
* @param prop
|
|
103
119
|
*/
|
|
104
|
-
validateProperty(prop: LionWebJsonProperty, context: JsonContext): void {
|
|
120
|
+
validateProperty(node: LionWebJsonNode, nodeConcept: LionWebJsonNode | undefined, prop: LionWebJsonProperty, context: JsonContext): void {
|
|
105
121
|
if (prop.value === null) {
|
|
106
122
|
return
|
|
107
123
|
}
|
|
108
|
-
const
|
|
109
|
-
if (
|
|
124
|
+
const propertyDefinition = this.registry.getNodeByMetaPointer(prop.property)
|
|
125
|
+
if ( propertyDefinition === undefined) {
|
|
110
126
|
this.validationResult.issue(new Language_UnknownProperty_Issue(context, prop.property))
|
|
111
127
|
return
|
|
112
128
|
}
|
|
113
|
-
if (
|
|
114
|
-
this.validationResult.issue(new Language_IncorrectPropertyMetaPointer_Issue(context, prop.property,
|
|
129
|
+
if (propertyDefinition.classifier.key !== M3_Keys.Property) {
|
|
130
|
+
this.validationResult.issue(new Language_IncorrectPropertyMetaPointer_Issue(context, prop.property, propertyDefinition.classifier.key))
|
|
115
131
|
return
|
|
116
132
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
if (nodeConcept !== undefined) {
|
|
134
|
+
const props = this.registry.languages.allProperties(nodeConcept)
|
|
135
|
+
if (!props.includes(propertyDefinition)) {
|
|
136
|
+
this.validationResult.issue(new Language_PropertyMetaPointerNotInClass_Issue(context, prop.property, nodeConcept))
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const refType = NodeUtils.findReference(propertyDefinition, MetaPointers.PropertyType)
|
|
142
|
+
// const refType = propertyDefinition.references.find(ref => isEqualMetaPointer(ref.reference, MetaPointers.PropertyType))
|
|
143
|
+
const propertyName = propertyDefinition.properties.find(p => p.property.key === LION_CORE_BUILTINS_INAMED_NAME)?.value
|
|
122
144
|
// console.log("Fount type should be " + refType.targets[0].reference);
|
|
123
145
|
if (propertyName !== undefined) {
|
|
124
146
|
if (refType !== null && refType !== undefined) {
|
|
125
|
-
|
|
147
|
+
const typeReferenceId = refType.targets[0].reference
|
|
148
|
+
switch (typeReferenceId) {
|
|
126
149
|
case LIONWEB_BOOLEAN_TYPE:
|
|
127
150
|
this.simpleFieldValidator.validateBoolean(prop, propertyName, context)
|
|
128
151
|
break
|
|
@@ -130,10 +153,49 @@ export class LionWebLanguageReferenceValidator {
|
|
|
130
153
|
this.simpleFieldValidator.validateInteger(prop, propertyName, context)
|
|
131
154
|
break
|
|
132
155
|
case LIONWEB_STRING_TYPE:
|
|
156
|
+
// Each string is correct and having another JSOn type is already captured
|
|
133
157
|
break
|
|
134
158
|
case LIONWEB_JSON_TYPE:
|
|
135
159
|
this.simpleFieldValidator.validateJSON(prop, propertyName, context)
|
|
136
160
|
break
|
|
161
|
+
default: {
|
|
162
|
+
// Check for enumeration
|
|
163
|
+
// console.log("validateProperty: 0")
|
|
164
|
+
const propTypeReference = NodeUtils.findReference(propertyDefinition, MetaPointers.PropertyType)
|
|
165
|
+
if (propTypeReference === undefined) {
|
|
166
|
+
// console.log("validateProperty: 1")
|
|
167
|
+
break
|
|
168
|
+
}
|
|
169
|
+
const propType = this.registry.findNode(propTypeReference.targets[0].reference)
|
|
170
|
+
if (propType === undefined) {
|
|
171
|
+
// console.log("validateProperty: 1.4 for " + prop.value + " ==> " + propTypeReference.targets[0].reference)
|
|
172
|
+
break
|
|
173
|
+
}
|
|
174
|
+
let match = false
|
|
175
|
+
if (isEqualMetaPointer(propType.classifier, MetaPointers.Enumeration)) {
|
|
176
|
+
const literalsContainment = NodeUtils.findContainment(propType, MetaPointers.EnumerationLiterals)
|
|
177
|
+
if (literalsContainment === undefined) {
|
|
178
|
+
// console.log("validateProperty: 2")
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
const literals = literalsContainment.children.map(child => this.registry.findNode(child))
|
|
182
|
+
match = literals.some(lit => {
|
|
183
|
+
if (lit === undefined) {
|
|
184
|
+
// console.log("validateProperty: 3")
|
|
185
|
+
return false
|
|
186
|
+
}
|
|
187
|
+
const litKeyProp = NodeUtils.findProperty(lit, MetaPointers.IKeyedKey)
|
|
188
|
+
if (litKeyProp === undefined) {
|
|
189
|
+
// console.log("validateProperty: 4")
|
|
190
|
+
return false
|
|
191
|
+
}
|
|
192
|
+
return prop.value === litKeyProp.value
|
|
193
|
+
})
|
|
194
|
+
}
|
|
195
|
+
if (!match) {
|
|
196
|
+
this.validationResult.issue(new Language_PropertyValue_Issue(context, prop.property.key, prop.value, propType.classifier.key))
|
|
197
|
+
}
|
|
198
|
+
}
|
|
137
199
|
}
|
|
138
200
|
} else {
|
|
139
201
|
// TODO refType not found, but
|
|
@@ -1,39 +1,80 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericIssue } from "../issues/index.js"
|
|
2
|
+
import { MissingM3Language_Issue } from "../issues/LanguageIssues.js"
|
|
3
|
+
import { isEqualMetaPointer, LionWebJsonNode, MetaPointers } from "../json/index.js"
|
|
2
4
|
import { JsonContext } from "../json/JsonContext.js"
|
|
3
|
-
import { LionWebJsonChunk } from "../json/LionWebJson.js"
|
|
5
|
+
import { isLionWebM3Language, LionWebJsonChunk } from "../json/LionWebJson.js"
|
|
4
6
|
import { LionWebJsonChunkWrapper } from "../json/LionWebJsonChunkWrapper.js"
|
|
7
|
+
import { isConcept, LanguageRegistry } from "../languages/index.js"
|
|
5
8
|
import { ValidationResult } from "./ValidationResult.js"
|
|
6
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Validates whether a chunk is a valid language definition
|
|
12
|
+
*/
|
|
7
13
|
export class LionWebLanguageValidator {
|
|
8
14
|
validationResult: ValidationResult
|
|
15
|
+
chunkWrapper: LionWebJsonChunkWrapper | undefined
|
|
16
|
+
// availableLanguages: LionWebLanguageDefinition[] = []
|
|
9
17
|
|
|
10
|
-
constructor() {
|
|
11
|
-
this.validationResult =
|
|
18
|
+
constructor(validationResult: ValidationResult, private registry: LanguageRegistry) {
|
|
19
|
+
this.validationResult = validationResult
|
|
20
|
+
this.chunkWrapper = undefined
|
|
12
21
|
}
|
|
13
22
|
|
|
14
23
|
/**
|
|
15
|
-
*
|
|
24
|
+
* Check whether the metamodel is a Language.
|
|
25
|
+
* Assumption is that _chunk_ is already validated as a correct :LionWebJsonChunk
|
|
16
26
|
* @param obj
|
|
17
27
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.validationResult.issue(new
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
const usedLanguage = chunk.languages[0]
|
|
26
|
-
if (usedLanguage.key !== "LionCore-M3") {
|
|
27
|
-
this.validationResult.issue(new NotLionCoreLanguageKey_Issue(new JsonContext(null, ["languages", 0]), usedLanguage.key))
|
|
28
|
-
}
|
|
29
|
-
if (usedLanguage.version !== "1") {
|
|
30
|
-
this.validationResult.issue(new IncorrectLionCoreVersion_Issue(new JsonContext(null, ["languages", 0]), usedLanguage.version))
|
|
28
|
+
validateLanguage(chunk: LionWebJsonChunk) {
|
|
29
|
+
this.chunkWrapper = new LionWebJsonChunkWrapper(chunk)
|
|
30
|
+
const usedM3Language = chunk.languages.find(lang => isLionWebM3Language(lang))
|
|
31
|
+
if (usedM3Language === undefined) {
|
|
32
|
+
this.validationResult.issue(new MissingM3Language_Issue(new JsonContext(null, ["languages"])))
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
const languageNodes = chunkWrapper.
|
|
34
|
+
|
|
35
|
+
const languageNodes = this.chunkWrapper.findNodesOfClassifier(MetaPointers.Language)
|
|
34
36
|
if (languageNodes.length !== 1) {
|
|
35
37
|
// TODO Better error handling.
|
|
36
|
-
console.error("
|
|
38
|
+
console.error("Error: xpected exactly one Language node, found " + languageNodes.length + " => " + JSON.stringify(languageNodes))
|
|
37
39
|
}
|
|
40
|
+
chunk.nodes.forEach((node, index) => {
|
|
41
|
+
if (!isConcept(node)) {
|
|
42
|
+
this.validationResult.issue(new GenericIssue(new JsonContext(null, ["nodes", index]), `node ${node.id} is not a concept`))
|
|
43
|
+
} else {
|
|
44
|
+
this.validateConcept(node)
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
validateConcept(node: LionWebJsonNode): void {
|
|
50
|
+
node.properties.forEach(prop => {
|
|
51
|
+
const properties = this.chunkWrapper?.findNodesOfClassifier(MetaPointers.Property)
|
|
52
|
+
const matchedProperty = properties?.find(p => isEqualMetaPointer(p.classifier, prop.property))
|
|
53
|
+
// DUMMY
|
|
54
|
+
return matchedProperty !== undefined
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
validateNode(node: LionWebJsonNode): void {
|
|
59
|
+
const classifier = this.registry.getNodeByMetaPointer(node.classifier)
|
|
60
|
+
if (classifier === undefined) {
|
|
61
|
+
this.validationResult.issue(
|
|
62
|
+
new GenericIssue(new JsonContext(null, ["nodes"]), `Classifier ${node.classifier.key} not found for node ${node.id}`)
|
|
63
|
+
)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
this.validateProperties(node, classifier)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
validateProperties(node: LionWebJsonNode, classifier: LionWebJsonNode): void {
|
|
70
|
+
node.properties.forEach(actualProp => {
|
|
71
|
+
const propClassifier = this.registry.getNodeByMetaPointer(actualProp.property)
|
|
72
|
+
if (propClassifier === undefined) {
|
|
73
|
+
this.validationResult.issue(
|
|
74
|
+
new GenericIssue(new JsonContext(null, ["nodes", "properties"]),
|
|
75
|
+
`Property ${actualProp.property.key} not found for classifier ${classifier.id}`)
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
})
|
|
38
79
|
}
|
|
39
80
|
}
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
import { JsonContext } from "../json/JsonContext.js"
|
|
10
10
|
import { ChunkUtils } from "../json/ChunkUtils.js"
|
|
11
11
|
import {
|
|
12
|
-
LION_CORE_BUILTINS_KEY,
|
|
13
12
|
LionWebJsonContainment,
|
|
14
13
|
LionWebJsonChunk,
|
|
15
14
|
LionWebJsonMetaPointer,
|
|
@@ -106,10 +105,6 @@ export class LionWebReferenceValidator {
|
|
|
106
105
|
*/
|
|
107
106
|
validateLanguageReference(chunk: LionWebJsonChunkWrapper, metaPointer: LionWebJsonMetaPointer, context: JsonContext) {
|
|
108
107
|
const lang = ChunkUtils.findLwUsedLanguageWithVersion(chunk.jsonChunk, metaPointer.language, metaPointer.version)
|
|
109
|
-
if (metaPointer.language === LION_CORE_BUILTINS_KEY) {
|
|
110
|
-
// Ok, builtin
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
108
|
if (lang === undefined || lang === null) {
|
|
114
109
|
this.validationResult.issue(new Reference_LanguageUnknown_Issue(context, metaPointer))
|
|
115
110
|
} else {
|
|
@@ -41,7 +41,7 @@ const MAY_BE_NULL = true
|
|
|
41
41
|
const NOT_NULL = false
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* LionWebCheck can
|
|
44
|
+
* LionWebCheck can check whether objects are structurally LionWeb JSON objects.
|
|
45
45
|
* The check can be on a single object, or recursively on an object and its children.
|
|
46
46
|
*/
|
|
47
47
|
export class LionWebSyntaxValidator {
|
|
@@ -62,7 +62,7 @@ export class LionWebSyntaxValidator {
|
|
|
62
62
|
/**
|
|
63
63
|
* Check whether `obj` is a JSON object that conforms to the serialization syntax of LionCore.
|
|
64
64
|
* All errors found will be pushed into the `errors` array, if its length is not 0, the check has failed.
|
|
65
|
-
* @param obj
|
|
65
|
+
* @param obj
|
|
66
66
|
*/
|
|
67
67
|
validate(obj: unknown) {
|
|
68
68
|
this.validateLwChunk(obj, new JsonContext(null, ["$"]))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LionWebJsonChunk } from "../json/LionWebJson.js"
|
|
2
2
|
import { LionWebJsonChunkWrapper } from "../json/LionWebJsonChunkWrapper.js"
|
|
3
|
-
import {
|
|
3
|
+
import { LanguageRegistry } from "../languages/index.js"
|
|
4
4
|
import { LionWebLanguageReferenceValidator } from "./LionWebLanguageReferenceValidator.js"
|
|
5
5
|
import { LionWebReferenceValidator } from "./LionWebReferenceValidator.js"
|
|
6
6
|
import { LionWebSyntaxValidator } from "./LionWebSyntaxValidator.js"
|
|
@@ -12,7 +12,6 @@ import { ValidationResult } from "./ValidationResult.js"
|
|
|
12
12
|
*/
|
|
13
13
|
export class LionWebValidator {
|
|
14
14
|
object: unknown
|
|
15
|
-
language: LionWebLanguageDefinition | null = null
|
|
16
15
|
|
|
17
16
|
chunk: unknown
|
|
18
17
|
validationResult: ValidationResult
|
|
@@ -21,9 +20,8 @@ export class LionWebValidator {
|
|
|
21
20
|
syntaxCorrect: boolean = false
|
|
22
21
|
referencesCorrect: boolean = false
|
|
23
22
|
|
|
24
|
-
constructor(json: unknown,
|
|
23
|
+
constructor(json: unknown, private registry: LanguageRegistry) {
|
|
25
24
|
this.object = json
|
|
26
|
-
this.language = lang
|
|
27
25
|
this.validationResult = new ValidationResult()
|
|
28
26
|
this.syntaxValidator = new LionWebSyntaxValidator(this.validationResult)
|
|
29
27
|
this.referenceValidator = new LionWebReferenceValidator(this.validationResult)
|
|
@@ -63,11 +61,9 @@ export class LionWebValidator {
|
|
|
63
61
|
// console.log("validateForLanguage not executed because there are reference errors.")
|
|
64
62
|
return
|
|
65
63
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
languageReferenceValidator.validate(this.chunk as LionWebJsonChunkWrapper)
|
|
70
|
-
}
|
|
64
|
+
const languageReferenceValidator = new LionWebLanguageReferenceValidator(this.validationResult, this.registry)
|
|
65
|
+
// when syntax is correct we know the chunk is actually a chunk!
|
|
66
|
+
languageReferenceValidator.validate(this.chunk as LionWebJsonChunkWrapper)
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
// setLanguage(json: LionwebLanguageDefinition) {
|
package/structure.puml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
@startuml
|
|
2
|
+
skinparam linetype ortho
|
|
3
|
+
|
|
4
|
+
class LionWebChunkWrapper {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class LionWebLanguageWrapper {
|
|
8
|
+
superClassifiers(...): Classifier[]
|
|
9
|
+
allSuperClassifiers(...): Classifier[]
|
|
10
|
+
properties(...): Property[]
|
|
11
|
+
allProperties(...): Property[]
|
|
12
|
+
...()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class CompositeLionWebLanguageWrapper {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class LanguageRegistry {
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
LionWebChunkWrapper <|-- LionWebLanguageWrapper
|
|
22
|
+
LionWebLanguageWrapper <|-- CompositeLionWebLanguageWrapper
|
|
23
|
+
CompositeLionWebLanguageWrapper --> "0..*" LionWebLanguageWrapper
|
|
24
|
+
LanguageRegistry --> "1" CompositeLionWebLanguageWrapper
|
|
25
|
+
@enduml
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { LionWebJsonChunk } from "./LionWebJson.js";
|
|
2
|
-
import { LionWebJsonChunkWrapper } from "./LionWebJsonChunkWrapper.js";
|
|
3
|
-
/**
|
|
4
|
-
* Contains methods for getting information from a LionWebJsonChunk representing a language.
|
|
5
|
-
*/
|
|
6
|
-
export declare class LanguageWrapper extends LionWebJsonChunkWrapper {
|
|
7
|
-
constructor(languageJson: LionWebJsonChunk);
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=LanguageUtils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageUtils.d.ts","sourceRoot":"","sources":["../../src/json/LanguageUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAEtE;;GAEG;AACH,qBAAa,eAAgB,SAAQ,uBAAuB;gBAC5C,YAAY,EAAE,gBAAgB;CAuB7C"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { LionWebJsonChunkWrapper } from "./LionWebJsonChunkWrapper.js";
|
|
2
|
-
/**
|
|
3
|
-
* Contains methods for getting information from a LionWebJsonChunk representing a language.
|
|
4
|
-
*/
|
|
5
|
-
export class LanguageWrapper extends LionWebJsonChunkWrapper {
|
|
6
|
-
constructor(languageJson) {
|
|
7
|
-
super(languageJson);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
//
|
|
11
|
-
// function isLionCoreLanguage(node: LionWebJsonNode) {
|
|
12
|
-
// return node.classifier.language === LION_CORE_M3_KEY
|
|
13
|
-
// && node.classifier.version === "2023.1";
|
|
14
|
-
// }
|
|
15
|
-
//
|
|
16
|
-
// const isConcept = (node: LionWebJsonNode): boolean => {
|
|
17
|
-
// return isLionCoreLanguage(node)
|
|
18
|
-
// && node.classifier.key === LIONWEB_M3_CONCEPT_KEY;
|
|
19
|
-
// }
|
|
20
|
-
//
|
|
21
|
-
// const isAnnotation = (node: LionWebJsonNode): boolean => {
|
|
22
|
-
// return isLionCoreLanguage(node)
|
|
23
|
-
// && node.classifier.key === LIONWEB_M3_ANNOTATION_KEY;
|
|
24
|
-
// }
|
|
25
|
-
//
|
|
26
|
-
// const isInterface = (node: LionWebJsonNode): boolean => {
|
|
27
|
-
// return isLionCoreLanguage(node)
|
|
28
|
-
// && node.classifier.key === LIONWEB_M3_INTERFACE_KEY;
|
|
29
|
-
// }
|
|
30
|
-
//# sourceMappingURL=LanguageUtils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageUtils.js","sourceRoot":"","sources":["../../src/json/LanguageUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAEtE;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,uBAAuB;IACxD,YAAY,YAA8B;QACtC,KAAK,CAAC,YAAY,CAAC,CAAA;IACvB,CAAC;CAqBJ;AAED,EAAE;AACF,uDAAuD;AACvD,2DAA2D;AAC3D,mDAAmD;AACnD,IAAI;AACJ,EAAE;AACF,0DAA0D;AAC1D,sCAAsC;AACtC,6DAA6D;AAC7D,IAAI;AACJ,EAAE;AACF,6DAA6D;AAC7D,sCAAsC;AACtC,gEAAgE;AAChE,IAAI;AACJ,EAAE;AACF,4DAA4D;AAC5D,sCAAsC;AACtC,+DAA+D;AAC/D,IAAI"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { LionWebJsonMetaPointer, LionWebJsonNode } from "./LionWebJson.js";
|
|
2
|
-
import { LionWebJsonChunkWrapper } from "./LionWebJsonChunkWrapper.js";
|
|
3
|
-
type LanguageId = {
|
|
4
|
-
name?: string;
|
|
5
|
-
version?: string;
|
|
6
|
-
key?: string;
|
|
7
|
-
};
|
|
8
|
-
export declare const LIONWEB_M3_PROPERTY_KEY = "Property";
|
|
9
|
-
export declare const LIONWEB_M3_CONCEPT_KEY = "Concept";
|
|
10
|
-
export declare const LIONWEB_M3_INTERFACE_KEY = "Interface";
|
|
11
|
-
export declare const LIONWEB_M3_ANNOTATION_KEY = "Annotation";
|
|
12
|
-
export declare const LIONWEB_M3_REFERENCE_KEY = "Reference";
|
|
13
|
-
export declare const LIONWEB_M3_LANGUAGE_KEY = "Language";
|
|
14
|
-
export declare const LIONWEB_M3_LANGUAGE_VERSION_KEY = "Language-version";
|
|
15
|
-
export declare const LIONWEB_M3_IKEYED_KEY_KEY = "IKeyed-key";
|
|
16
|
-
export declare const LIONWEB_M3_PROPERTY_TYPE_KEY = "Property-type";
|
|
17
|
-
/**
|
|
18
|
-
* Collection of language definitions
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* Represents a LionWeb serialiation chunk which represents a language definition / metamodel
|
|
22
|
-
*/
|
|
23
|
-
export declare class LionWebLanguageDefinition {
|
|
24
|
-
languageId: LanguageId | null;
|
|
25
|
-
/**
|
|
26
|
-
* All nodes in the language
|
|
27
|
-
*/
|
|
28
|
-
nodeKeymap: Map<string, LionWebJsonNode>;
|
|
29
|
-
languageChunkWrapper: LionWebJsonChunkWrapper;
|
|
30
|
-
/**
|
|
31
|
-
* Assume chunk represents a language metamodel according to Lionweb M3.
|
|
32
|
-
* @param chunk
|
|
33
|
-
*/
|
|
34
|
-
constructor(chunk: LionWebJsonChunkWrapper);
|
|
35
|
-
protected setLanguage(languageNode: LionWebJsonNode): void;
|
|
36
|
-
/**
|
|
37
|
-
* Store the node `node` under `key`.
|
|
38
|
-
* @param key
|
|
39
|
-
* @param node
|
|
40
|
-
*/
|
|
41
|
-
setNodeByKey(key: string, node: LionWebJsonNode): void;
|
|
42
|
-
getNodeByKey(key: string): LionWebJsonNode | undefined;
|
|
43
|
-
getNodeByMetaPointer(metaPointer: LionWebJsonMetaPointer): LionWebJsonNode | undefined;
|
|
44
|
-
getPropertyByKey(key: string): LionWebJsonNode | undefined;
|
|
45
|
-
getConceptByKey(key: string): LionWebJsonNode | undefined;
|
|
46
|
-
}
|
|
47
|
-
export {};
|
|
48
|
-
//# sourceMappingURL=LionWebLanguageDefinition.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LionWebLanguageDefinition.d.ts","sourceRoot":"","sources":["../../src/json/LionWebLanguageDefinition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,sBAAsB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC1G,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAGtE,KAAK,UAAU,GAAG;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,eAAO,MAAM,uBAAuB,aAAa,CAAA;AACjD,eAAO,MAAM,sBAAsB,YAAY,CAAA;AAC/C,eAAO,MAAM,wBAAwB,cAAc,CAAA;AACnD,eAAO,MAAM,yBAAyB,eAAe,CAAA;AACrD,eAAO,MAAM,wBAAwB,cAAc,CAAA;AACnD,eAAO,MAAM,uBAAuB,aAAa,CAAA;AACjD,eAAO,MAAM,+BAA+B,qBAAqB,CAAA;AACjE,eAAO,MAAM,yBAAyB,eAAe,CAAA;AACrD,eAAO,MAAM,4BAA4B,kBAAkB,CAAA;AAE3D;;GAEG;AA8BH;;GAEG;AACH,qBAAa,yBAAyB;IAClC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAO;IACpC;;OAEG;IACH,UAAU,+BAAqC;IAC/C,oBAAoB,EAAE,uBAAuB,CAAA;IAE7C;;;OAGG;gBACS,KAAK,EAAE,uBAAuB;IAa1C,SAAS,CAAC,WAAW,CAAC,YAAY,EAAE,eAAe;IAYnD;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI;IAItD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAItD,oBAAoB,CAAC,WAAW,EAAE,sBAAsB,GAAG,eAAe,GAAG,SAAS;IAetF,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAY1D,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;CAW5D"}
|