componentsjs 4.5.0 → 5.0.0-beta.3
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/CHANGELOG.md +261 -0
- package/README.md +16 -0
- package/components/context.jsonld +87 -2
- package/lib/ComponentsManager.js +3 -5
- package/lib/construction/ConfigConstructor.js +7 -14
- package/lib/construction/argument/ArgumentConstructorHandlerHash.js +3 -2
- package/lib/construction/strategy/ConstructionStrategyCommonJsString.js +3 -0
- package/lib/construction/strategy/IConstructionStrategy.d.ts +2 -2
- package/lib/loading/ComponentRegistry.js +1 -1
- package/lib/loading/ComponentRegistryFinalizer.js +25 -4
- package/lib/preprocess/ConfigPreprocessorComponent.d.ts +3 -1
- package/lib/preprocess/ConfigPreprocessorComponent.js +34 -12
- package/lib/preprocess/ConfigPreprocessorComponentMapped.d.ts +4 -3
- package/lib/preprocess/ConfigPreprocessorComponentMapped.js +17 -18
- package/lib/preprocess/GenericsContext.d.ts +74 -0
- package/lib/preprocess/GenericsContext.js +326 -0
- package/lib/preprocess/ParameterHandler.d.ts +6 -2
- package/lib/preprocess/ParameterHandler.js +23 -21
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerCollectEntries.d.ts +3 -2
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerCollectEntries.js +24 -10
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerElements.d.ts +2 -1
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerElements.js +8 -5
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerFields.d.ts +2 -1
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerFields.js +16 -9
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerKeyValue.d.ts +4 -3
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerKeyValue.js +12 -12
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerList.d.ts +2 -1
- package/lib/preprocess/constructorargumentsmapping/ConstructorArgumentsElementMappingHandlerList.js +9 -22
- package/lib/preprocess/constructorargumentsmapping/IConstructorArgumentsElementMappingHandler.d.ts +5 -2
- package/lib/preprocess/constructorargumentsmapping/IConstructorArgumentsMapper.d.ts +5 -2
- package/lib/preprocess/parameterproperty/IParameterPropertyHandler.d.ts +5 -2
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefault.d.ts +6 -3
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefault.js +20 -3
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefaultScoped.d.ts +2 -2
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerDefaultScoped.js +16 -5
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerFixed.d.ts +5 -3
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerFixed.js +25 -2
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerLazy.d.ts +2 -2
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerLazy.js +10 -3
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.d.ts +38 -4
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.js +412 -31
- package/lib/rdf/RdfParser.d.ts +1 -1
- package/lib/rdf/RdfParser.js +16 -4
- package/lib/rdf/RdfStreamIncluder.js +1 -1
- package/lib/util/ErrorResourcesContext.d.ts +11 -14
- package/lib/util/ErrorResourcesContext.js +44 -22
- package/package.json +2 -2
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRequired.d.ts +0 -11
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerRequired.js +0 -23
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerUnique.d.ts +0 -12
- package/lib/preprocess/parameterproperty/ParameterPropertyHandlerUnique.js +0 -34
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ConfigPreprocessorComponent = void 0;
|
|
4
4
|
const Iris_1 = require("../rdf/Iris");
|
|
5
5
|
const ErrorResourcesContext_1 = require("../util/ErrorResourcesContext");
|
|
6
|
+
const GenericsContext_1 = require("./GenericsContext");
|
|
6
7
|
/**
|
|
7
8
|
* Handles config that refer to a component as type.
|
|
8
9
|
* The component may have parameters that can be applied on the config.
|
|
@@ -82,34 +83,55 @@ class ConfigPreprocessorComponent {
|
|
|
82
83
|
if (requireElement) {
|
|
83
84
|
configRaw.property.requireElement = requireElement;
|
|
84
85
|
}
|
|
85
|
-
configRaw.
|
|
86
|
+
configRaw.property.arguments = this.transformConstructorArguments(config, handleResponse);
|
|
86
87
|
// Validate the input config
|
|
87
88
|
this.validateConfig(config, handleResponse);
|
|
88
89
|
return configRaw;
|
|
89
90
|
}
|
|
91
|
+
createGenericsContext(handleResponse, config) {
|
|
92
|
+
// Create a new generics context for the component's generic type parameters
|
|
93
|
+
const genericsContext = new GenericsContext_1.GenericsContext(this.objectLoader, handleResponse.component.properties.genericTypeParameters);
|
|
94
|
+
// If the config has a genericTypeInstancesComponentScope, it will also have genericTypeInstances.
|
|
95
|
+
// In that case, we bind these instances to the component's generic type parameters within the context.
|
|
96
|
+
// (these values may have been set during generic param type-checking in
|
|
97
|
+
// ParameterPropertyHandlerRange#hasParamValueValidType)
|
|
98
|
+
if (config.property.genericTypeInstancesComponentScope &&
|
|
99
|
+
handleResponse.component.value === config.property.genericTypeInstancesComponentScope.value) {
|
|
100
|
+
genericsContext.bindComponentGenericTypes(handleResponse.component, config.properties.genericTypeInstances, { config }, (subType, superType) => this.parameterHandler.parameterPropertyHandlerRange
|
|
101
|
+
.hasType(subType, superType, genericsContext, config.property.genericTypeInstancesComponentScope, config.properties.genericTypeInstances, { config }));
|
|
102
|
+
}
|
|
103
|
+
return genericsContext;
|
|
104
|
+
}
|
|
90
105
|
/**
|
|
91
106
|
* Determine the constructor arguments of the given config.
|
|
92
107
|
* @param config A config.
|
|
93
108
|
* @param handleResponse Return value of the {#canHandle}.
|
|
94
109
|
*/
|
|
95
110
|
transformConstructorArguments(config, handleResponse) {
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
// Hack to enforce ArgumentConstructorHandlerHash
|
|
99
|
-
hasFields: '"true"',
|
|
100
|
-
});
|
|
111
|
+
const entries = [];
|
|
112
|
+
const genericsContext = this.createGenericsContext(handleResponse, config);
|
|
101
113
|
for (const fieldData of handleResponse.component.properties.parameters) {
|
|
102
114
|
const field = this.objectLoader.createCompactedResource({});
|
|
103
115
|
field.property.key = this.objectLoader.createCompactedResource(`"${fieldData.term.value}"`);
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
const value = this.parameterHandler
|
|
117
|
+
.applyParameterValues(handleResponse.component, fieldData, config, genericsContext);
|
|
118
|
+
if (value) {
|
|
119
|
+
field.property.value = value;
|
|
106
120
|
}
|
|
107
|
-
|
|
121
|
+
entries.push(field);
|
|
108
122
|
}
|
|
123
|
+
// Create a single-arg hash constructor, and add all params as key-value pairs
|
|
124
|
+
const param0 = this.objectLoader.createCompactedResource({
|
|
125
|
+
fields: {
|
|
126
|
+
list: entries,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
109
129
|
// Create constructor arguments list
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
130
|
+
return this.objectLoader.createCompactedResource({
|
|
131
|
+
list: [
|
|
132
|
+
param0,
|
|
133
|
+
],
|
|
134
|
+
});
|
|
113
135
|
}
|
|
114
136
|
/**
|
|
115
137
|
* Let this config inherit parameter values from previously instantiated configs.
|
|
@@ -2,6 +2,7 @@ import type { Resource } from 'rdf-object';
|
|
|
2
2
|
import type { IComponentConfigPreprocessorHandleResponse } from './ConfigPreprocessorComponent';
|
|
3
3
|
import { ConfigPreprocessorComponent } from './ConfigPreprocessorComponent';
|
|
4
4
|
import type { IConstructorArgumentsMapper } from './constructorargumentsmapping/IConstructorArgumentsMapper';
|
|
5
|
+
import type { GenericsContext } from './GenericsContext';
|
|
5
6
|
/**
|
|
6
7
|
* Handles config that refer to a component as type.
|
|
7
8
|
* The component may have parameters that can be applied on the config.
|
|
@@ -10,7 +11,7 @@ import type { IConstructorArgumentsMapper } from './constructorargumentsmapping/
|
|
|
10
11
|
export declare class ConfigPreprocessorComponentMapped extends ConfigPreprocessorComponent implements IConstructorArgumentsMapper {
|
|
11
12
|
private readonly mappingHandlers;
|
|
12
13
|
canHandle(config: Resource): IComponentConfigPreprocessorHandleResponse | undefined;
|
|
13
|
-
transformConstructorArguments(config: Resource, handleResponse: IComponentConfigPreprocessorHandleResponse): Resource
|
|
14
|
-
applyConstructorArgumentsParameters(configRoot: Resource, constructorArgs: Resource, configElement: Resource): Resource
|
|
15
|
-
getParameterValue(configRoot: Resource, parameter: Resource, configElement: Resource, rawValue: boolean): Resource
|
|
14
|
+
transformConstructorArguments(config: Resource, handleResponse: IComponentConfigPreprocessorHandleResponse): Resource;
|
|
15
|
+
applyConstructorArgumentsParameters(configRoot: Resource, constructorArgs: Resource, configElement: Resource, genericsContext: GenericsContext): Resource;
|
|
16
|
+
getParameterValue(configRoot: Resource, parameter: Resource, configElement: Resource, rawValue: boolean, genericsContext: GenericsContext): Resource | undefined;
|
|
16
17
|
}
|
|
@@ -33,39 +33,38 @@ class ConfigPreprocessorComponentMapped extends ConfigPreprocessorComponent_1.Co
|
|
|
33
33
|
}
|
|
34
34
|
transformConstructorArguments(config, handleResponse) {
|
|
35
35
|
const constructorArgs = handleResponse.component.property.constructorArguments;
|
|
36
|
-
|
|
36
|
+
const genericsContext = this.createGenericsContext(handleResponse, config);
|
|
37
|
+
return this.applyConstructorArgumentsParameters(config, constructorArgs, config, genericsContext);
|
|
37
38
|
}
|
|
38
|
-
applyConstructorArgumentsParameters(configRoot, constructorArgs, configElement) {
|
|
39
|
+
applyConstructorArgumentsParameters(configRoot, constructorArgs, configElement, genericsContext) {
|
|
39
40
|
// Check if this constructor args resource can be handled by one of the built-in handlers.
|
|
40
41
|
for (const handler of this.mappingHandlers) {
|
|
41
|
-
if (handler.canHandle(configRoot, constructorArgs, configElement, this)) {
|
|
42
|
-
return handler.handle(configRoot, constructorArgs, configElement, this);
|
|
42
|
+
if (handler.canHandle(configRoot, constructorArgs, configElement, this, genericsContext)) {
|
|
43
|
+
return handler.handle(configRoot, constructorArgs, configElement, this, genericsContext);
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
// Fallback to original constructor args
|
|
46
|
-
return
|
|
47
|
+
return constructorArgs;
|
|
47
48
|
}
|
|
48
|
-
getParameterValue(configRoot, parameter, configElement, rawValue) {
|
|
49
|
-
var _a;
|
|
49
|
+
getParameterValue(configRoot, parameter, configElement, rawValue, genericsContext) {
|
|
50
50
|
let valueOut;
|
|
51
51
|
if (parameter.type === 'NamedNode' && parameter.value === Iris_1.IRIS_RDF.subject) {
|
|
52
|
-
valueOut =
|
|
53
|
-
valueOut[0].property.unique = this.objectLoader.createCompactedResource('"true"');
|
|
52
|
+
valueOut = this.objectLoader.createCompactedResource(`"${configElement.value}"`);
|
|
54
53
|
}
|
|
55
|
-
else if (parameter.type === 'NamedNode') {
|
|
56
|
-
valueOut = this.parameterHandler
|
|
54
|
+
else if (parameter.type === 'NamedNode' && !parameter.property.fields) {
|
|
55
|
+
valueOut = this.parameterHandler
|
|
56
|
+
.applyParameterValues(configRoot, parameter, configElement, genericsContext);
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
valueOut = this.applyConstructorArgumentsParameters(configRoot, parameter, configElement);
|
|
59
|
+
valueOut = this.applyConstructorArgumentsParameters(configRoot, parameter, configElement, genericsContext);
|
|
60
60
|
}
|
|
61
61
|
// If the referenced IRI should become a plain string
|
|
62
62
|
if (rawValue) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
63
|
+
valueOut = (valueOut === null || valueOut === void 0 ? void 0 : valueOut.list) ?
|
|
64
|
+
this.objectLoader.createCompactedResource({
|
|
65
|
+
list: valueOut.list.map(valueOutSub => `"${valueOutSub.value}"`),
|
|
66
|
+
}) :
|
|
67
|
+
this.objectLoader.createCompactedResource(`"${valueOut ? valueOut.value : 'undefined'}"`);
|
|
69
68
|
}
|
|
70
69
|
return valueOut;
|
|
71
70
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type * as RDF from '@rdfjs/types';
|
|
2
|
+
import type { Resource, RdfObjectLoader } from 'rdf-object';
|
|
3
|
+
import type { IParamValueConflict } from './parameterproperty/ParameterPropertyHandlerRange';
|
|
4
|
+
/**
|
|
5
|
+
* Context for binding generic types to a concrete range value.
|
|
6
|
+
*/
|
|
7
|
+
export declare class GenericsContext {
|
|
8
|
+
private static readonly XSD_INHERITANCE_TABLE;
|
|
9
|
+
private readonly objectLoader;
|
|
10
|
+
/**
|
|
11
|
+
* Set of generic type ids.
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
genericTypeIds: Record<string, boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Mapping of generic type id to the resolved range.
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
bindings: Record<string, Resource>;
|
|
20
|
+
constructor(objectLoader: RdfObjectLoader, genericTypeParameters: Resource[]);
|
|
21
|
+
/**
|
|
22
|
+
* Try to to bind the given value to the given generic.
|
|
23
|
+
* @param genericTypeId IRI of the generic to bind.
|
|
24
|
+
* @param value The value to bind to.
|
|
25
|
+
* @param valueTypeValidator Callback for validating values against types.
|
|
26
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
27
|
+
* @return boolean True if the binding was valid and took place.
|
|
28
|
+
*/
|
|
29
|
+
bindGenericTypeToValue(genericTypeId: string, value: Resource | undefined, valueTypeValidator: (subValue: Resource | undefined, subType: Resource) => IParamValueConflict | undefined, typeTypeValidator: (subValue: Resource, subType: Resource) => IParamValueConflict | undefined): IParamValueConflict | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Try to bind the given range to the given generic.
|
|
32
|
+
* @param genericTypeId IRI of the generic to bind.
|
|
33
|
+
* @param range The range to bind to.
|
|
34
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
35
|
+
* @return boolean True if the binding was valid and took place.
|
|
36
|
+
*/
|
|
37
|
+
bindGenericTypeToRange(genericTypeId: string, range: Resource, typeTypeValidator: (subType: Resource, superType: Resource) => IParamValueConflict | undefined): IParamValueConflict | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Infer the parameter range of the given value.
|
|
40
|
+
* @param value A value.
|
|
41
|
+
*/
|
|
42
|
+
inferValueRange(value: Resource | undefined): Resource | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Merge the given ranges into a new range.
|
|
45
|
+
* This will return undefined in the ranges are incompatible.
|
|
46
|
+
*
|
|
47
|
+
* If one type is more specific than the other, it will return the narrowest type.
|
|
48
|
+
*
|
|
49
|
+
* @param rangeA A first range.
|
|
50
|
+
* @param rangeB A second range.
|
|
51
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
52
|
+
*/
|
|
53
|
+
mergeRanges(rangeA: Resource, rangeB: Resource, typeTypeValidator: (subType: Resource, superType: Resource) => IParamValueConflict | undefined): Resource | undefined;
|
|
54
|
+
protected mergeUnion(rangeUnion: Resource, rangeOther: Resource, typeValidator: (subType: Resource, superType: Resource) => IParamValueConflict | undefined): Resource | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Check if the given type is a subtype of the given super type.
|
|
57
|
+
* @param type A type node.
|
|
58
|
+
* @param potentialSuperType A potential super type node.
|
|
59
|
+
*/
|
|
60
|
+
isXsdSubType(type: RDF.Term, potentialSuperType: RDF.Term): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Apply the give generic type instances for the given component's generic type parameters.
|
|
63
|
+
*
|
|
64
|
+
* This will throw if the number of passed instances does not match with
|
|
65
|
+
* the number of generic type parameters on the component.
|
|
66
|
+
*
|
|
67
|
+
* @param component The component
|
|
68
|
+
* @param genericTypeInstances The generic type instances to apply.
|
|
69
|
+
* @param errorContext The context for error reporting.
|
|
70
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
71
|
+
* @return boolean False if the application failed due to a binding error. True otherwise
|
|
72
|
+
*/
|
|
73
|
+
bindComponentGenericTypes(component: Resource, genericTypeInstances: Resource[], errorContext: Record<string, Resource | Resource[] | string>, typeTypeValidator: (subValue: Resource, subType: Resource) => IParamValueConflict | undefined): IParamValueConflict | undefined;
|
|
74
|
+
}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GenericsContext = void 0;
|
|
4
|
+
const ErrorResourcesContext_1 = require("../util/ErrorResourcesContext");
|
|
5
|
+
const ParameterPropertyHandlerRange_1 = require("./parameterproperty/ParameterPropertyHandlerRange");
|
|
6
|
+
/**
|
|
7
|
+
* Context for binding generic types to a concrete range value.
|
|
8
|
+
*/
|
|
9
|
+
class GenericsContext {
|
|
10
|
+
constructor(objectLoader, genericTypeParameters) {
|
|
11
|
+
this.objectLoader = objectLoader;
|
|
12
|
+
this.genericTypeIds = Object.fromEntries(genericTypeParameters
|
|
13
|
+
.map(genericTypeParameter => [genericTypeParameter.value, true]));
|
|
14
|
+
this.bindings = {};
|
|
15
|
+
for (const genericTypeParameter of genericTypeParameters) {
|
|
16
|
+
if (genericTypeParameter.property.range) {
|
|
17
|
+
this.bindings[genericTypeParameter.value] = genericTypeParameter.property.range;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Try to to bind the given value to the given generic.
|
|
23
|
+
* @param genericTypeId IRI of the generic to bind.
|
|
24
|
+
* @param value The value to bind to.
|
|
25
|
+
* @param valueTypeValidator Callback for validating values against types.
|
|
26
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
27
|
+
* @return boolean True if the binding was valid and took place.
|
|
28
|
+
*/
|
|
29
|
+
bindGenericTypeToValue(genericTypeId, value, valueTypeValidator, typeTypeValidator) {
|
|
30
|
+
// Fail if an unknown generic type is referenced
|
|
31
|
+
if (!(genericTypeId in this.genericTypeIds)) {
|
|
32
|
+
return {
|
|
33
|
+
description: `unknown generic <${genericTypeId}> is being referenced`,
|
|
34
|
+
context: { value },
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// If the generic was already bound to a range, validate it
|
|
38
|
+
const existingRange = this.bindings[genericTypeId];
|
|
39
|
+
if (existingRange) {
|
|
40
|
+
const subConflict = valueTypeValidator(value, existingRange);
|
|
41
|
+
if (subConflict) {
|
|
42
|
+
return {
|
|
43
|
+
description: `generic <${genericTypeId}> with existing range "${ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange.rangeToDisplayString(existingRange, this)}" can not contain the given value`,
|
|
44
|
+
context: { existingRange, value },
|
|
45
|
+
causes: [subConflict],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Infer type of value
|
|
50
|
+
const valueRange = this.inferValueRange(value);
|
|
51
|
+
if (!valueRange) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Save inferred type
|
|
55
|
+
return this.bindGenericTypeToRange(genericTypeId, valueRange, typeTypeValidator);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Try to bind the given range to the given generic.
|
|
59
|
+
* @param genericTypeId IRI of the generic to bind.
|
|
60
|
+
* @param range The range to bind to.
|
|
61
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
62
|
+
* @return boolean True if the binding was valid and took place.
|
|
63
|
+
*/
|
|
64
|
+
bindGenericTypeToRange(genericTypeId, range, typeTypeValidator) {
|
|
65
|
+
// Fail if an unknown generic type is referenced
|
|
66
|
+
if (!(genericTypeId in this.genericTypeIds)) {
|
|
67
|
+
return {
|
|
68
|
+
description: `unknown generic <${genericTypeId}> is being referenced`,
|
|
69
|
+
context: {},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// If we already had a range, check if they match
|
|
73
|
+
if (this.bindings[genericTypeId]) {
|
|
74
|
+
const mergedRange = this.mergeRanges(this.bindings[genericTypeId], range, typeTypeValidator);
|
|
75
|
+
if (!mergedRange) {
|
|
76
|
+
return {
|
|
77
|
+
description: `generic <${genericTypeId}> with existing range "${ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange.rangeToDisplayString(this.bindings[genericTypeId], this)}" can not be bound to range "${ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange.rangeToDisplayString(range, this)}"`,
|
|
78
|
+
context: {
|
|
79
|
+
existingRange: this.bindings[genericTypeId],
|
|
80
|
+
newRange: range,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
range = mergedRange;
|
|
85
|
+
}
|
|
86
|
+
this.bindings[genericTypeId] = range;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Infer the parameter range of the given value.
|
|
90
|
+
* @param value A value.
|
|
91
|
+
*/
|
|
92
|
+
inferValueRange(value) {
|
|
93
|
+
// Value is undefined
|
|
94
|
+
if (!value) {
|
|
95
|
+
return this.objectLoader.createCompactedResource({ '@type': 'ParameterRangeUndefined' });
|
|
96
|
+
}
|
|
97
|
+
// Value is a literal
|
|
98
|
+
if (value.term.termType === 'Literal') {
|
|
99
|
+
return this.objectLoader.createCompactedResource(value.term.datatype);
|
|
100
|
+
}
|
|
101
|
+
// Value is a named node
|
|
102
|
+
const types = value.properties.type;
|
|
103
|
+
if (types.length > 1) {
|
|
104
|
+
return this.objectLoader.createCompactedResource({
|
|
105
|
+
'@type': 'ParameterRangeUnion',
|
|
106
|
+
parameterRangeElements: types,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return types[0];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Merge the given ranges into a new range.
|
|
113
|
+
* This will return undefined in the ranges are incompatible.
|
|
114
|
+
*
|
|
115
|
+
* If one type is more specific than the other, it will return the narrowest type.
|
|
116
|
+
*
|
|
117
|
+
* @param rangeA A first range.
|
|
118
|
+
* @param rangeB A second range.
|
|
119
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
120
|
+
*/
|
|
121
|
+
mergeRanges(rangeA, rangeB, typeTypeValidator) {
|
|
122
|
+
var _a, _b;
|
|
123
|
+
// Check if one is a subtype of the other (and return the most specific type)
|
|
124
|
+
if (!typeTypeValidator(rangeA, rangeB)) {
|
|
125
|
+
return rangeA;
|
|
126
|
+
}
|
|
127
|
+
if (!typeTypeValidator(rangeB, rangeA)) {
|
|
128
|
+
return rangeB;
|
|
129
|
+
}
|
|
130
|
+
// Check XSD inheritance relationship
|
|
131
|
+
if (this.isXsdSubType(rangeA.term, rangeB.term)) {
|
|
132
|
+
return rangeA;
|
|
133
|
+
}
|
|
134
|
+
if (this.isXsdSubType(rangeB.term, rangeA.term)) {
|
|
135
|
+
return rangeB;
|
|
136
|
+
}
|
|
137
|
+
// If a range is a wildcard, return the other type
|
|
138
|
+
if (rangeA.isA('ParameterRangeWildcard')) {
|
|
139
|
+
return rangeB;
|
|
140
|
+
}
|
|
141
|
+
if (rangeB.isA('ParameterRangeWildcard')) {
|
|
142
|
+
return rangeA;
|
|
143
|
+
}
|
|
144
|
+
// Ranges always match with generic references
|
|
145
|
+
if (rangeA.isA('ParameterRangeGenericTypeReference')) {
|
|
146
|
+
return rangeB;
|
|
147
|
+
}
|
|
148
|
+
if (rangeB.isA('ParameterRangeGenericTypeReference')) {
|
|
149
|
+
return rangeA;
|
|
150
|
+
}
|
|
151
|
+
// Check parameter range types
|
|
152
|
+
if ((_a = rangeA.property.type) === null || _a === void 0 ? void 0 : _a.term.equals((_b = rangeB.property.type) === null || _b === void 0 ? void 0 : _b.term)) {
|
|
153
|
+
// Check sub-value for specific param range cases
|
|
154
|
+
if (rangeA.isA('ParameterRangeArray') ||
|
|
155
|
+
rangeA.isA('ParameterRangeRest') ||
|
|
156
|
+
rangeA.isA('ParameterRangeKeyof')) {
|
|
157
|
+
const valueA = rangeA.property.parameterRangeValue;
|
|
158
|
+
const valueB = rangeB.property.parameterRangeValue;
|
|
159
|
+
const merged = this.mergeRanges(valueA, valueB, typeTypeValidator);
|
|
160
|
+
if (!merged) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
return this.objectLoader.createCompactedResource({
|
|
164
|
+
'@type': rangeA.property.type,
|
|
165
|
+
parameterRangeValue: merged,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
// Check sub-values for specific param range cases
|
|
169
|
+
if (rangeA.isA('ParameterRangeUnion') ||
|
|
170
|
+
rangeA.isA('ParameterRangeIntersection') ||
|
|
171
|
+
rangeA.isA('ParameterRangeTuple')) {
|
|
172
|
+
const valuesA = rangeA.properties.parameterRangeElements;
|
|
173
|
+
const valuesB = rangeB.properties.parameterRangeElements;
|
|
174
|
+
if (valuesA.length !== valuesB.length) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const merged = valuesA.map((valueA, i) => this.mergeRanges(valueA, valuesB[i], typeTypeValidator));
|
|
178
|
+
if (merged.some(subValue => !subValue)) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
return this.objectLoader.createCompactedResource({
|
|
182
|
+
'@type': rangeA.property.type,
|
|
183
|
+
parameterRangeElements: merged,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
// Check sub-values for generic components
|
|
187
|
+
if (rangeA.isA('ParameterRangeGenericComponent')) {
|
|
188
|
+
const mergedComponent = this.mergeRanges(rangeA.property.component, rangeB.property.component, typeTypeValidator);
|
|
189
|
+
if (!mergedComponent) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const valuesA = rangeA.properties.genericTypeInstances;
|
|
193
|
+
const valuesB = rangeB.properties.genericTypeInstances;
|
|
194
|
+
if (valuesA.length !== valuesB.length) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const merged = valuesA.map((valueA, i) => this.mergeRanges(valueA, valuesB[i], typeTypeValidator));
|
|
198
|
+
if (merged.some(subValue => !subValue)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
return this.objectLoader.createCompactedResource({
|
|
202
|
+
'@type': 'ParameterRangeGenericComponent',
|
|
203
|
+
component: mergedComponent,
|
|
204
|
+
genericTypeInstances: merged,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return rangeA;
|
|
208
|
+
}
|
|
209
|
+
// Handle left or right being a union
|
|
210
|
+
if (rangeA.isA('ParameterRangeUnion')) {
|
|
211
|
+
return this.mergeUnion(rangeA, rangeB, typeTypeValidator);
|
|
212
|
+
}
|
|
213
|
+
if (rangeB.isA('ParameterRangeUnion')) {
|
|
214
|
+
return this.mergeUnion(rangeB, rangeA, typeTypeValidator);
|
|
215
|
+
}
|
|
216
|
+
// Check if the range refers to a component with a generic type
|
|
217
|
+
// TODO: somehow pass the range's component and genericTypeInstances (like in ParameterPropertyHandlerRange)?
|
|
218
|
+
if (rangeA.isA('ParameterRangeGenericComponent')) {
|
|
219
|
+
return this.mergeRanges(rangeA.property.component, rangeB, typeTypeValidator);
|
|
220
|
+
}
|
|
221
|
+
if (rangeB.isA('ParameterRangeGenericComponent')) {
|
|
222
|
+
return this.mergeRanges(rangeB.property.component, rangeA, typeTypeValidator);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
mergeUnion(rangeUnion, rangeOther, typeValidator) {
|
|
226
|
+
const elements = rangeUnion.properties.parameterRangeElements;
|
|
227
|
+
const mergedValues = elements
|
|
228
|
+
.map(element => this.mergeRanges(rangeOther, element, typeValidator))
|
|
229
|
+
.filter(Boolean);
|
|
230
|
+
if (mergedValues.length === 0) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (mergedValues.length === 1) {
|
|
234
|
+
return mergedValues[0];
|
|
235
|
+
}
|
|
236
|
+
return this.objectLoader.createCompactedResource({
|
|
237
|
+
'@type': 'ParameterRangeUnion',
|
|
238
|
+
parameterRangeElements: mergedValues,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Check if the given type is a subtype of the given super type.
|
|
243
|
+
* @param type A type node.
|
|
244
|
+
* @param potentialSuperType A potential super type node.
|
|
245
|
+
*/
|
|
246
|
+
isXsdSubType(type, potentialSuperType) {
|
|
247
|
+
const values = GenericsContext.XSD_INHERITANCE_TABLE[potentialSuperType.value];
|
|
248
|
+
return values && values.has(type.value);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Apply the give generic type instances for the given component's generic type parameters.
|
|
252
|
+
*
|
|
253
|
+
* This will throw if the number of passed instances does not match with
|
|
254
|
+
* the number of generic type parameters on the component.
|
|
255
|
+
*
|
|
256
|
+
* @param component The component
|
|
257
|
+
* @param genericTypeInstances The generic type instances to apply.
|
|
258
|
+
* @param errorContext The context for error reporting.
|
|
259
|
+
* @param typeTypeValidator Callback for validating sub-types against super-types.
|
|
260
|
+
* @return boolean False if the application failed due to a binding error. True otherwise
|
|
261
|
+
*/
|
|
262
|
+
bindComponentGenericTypes(component, genericTypeInstances, errorContext, typeTypeValidator) {
|
|
263
|
+
const genericTypeParameters = component.properties.genericTypeParameters;
|
|
264
|
+
// Don't do anything if no generic type instances are passed.
|
|
265
|
+
if (genericTypeInstances.length === 0) {
|
|
266
|
+
return {
|
|
267
|
+
description: `no generic type instances are passed`,
|
|
268
|
+
context: errorContext,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
// Throw if an unexpected number of generic type instances are passed.
|
|
272
|
+
if (genericTypeParameters.length !== genericTypeInstances.length) {
|
|
273
|
+
throw new ErrorResourcesContext_1.ErrorResourcesContext(`Invalid generic type instantiation: a different amount of generic types are passed (${genericTypeInstances.length}) than are defined on the component (${genericTypeParameters.length}).`, Object.assign({ passedGenerics: genericTypeInstances, definedGenerics: genericTypeParameters, component }, errorContext));
|
|
274
|
+
}
|
|
275
|
+
// Populate with manually defined generic type bindings
|
|
276
|
+
for (const [i, genericTypeInstance] of genericTypeInstances.entries()) {
|
|
277
|
+
// Remap generic type IRI to inner generic type IRI
|
|
278
|
+
const genericTypeIdInner = genericTypeParameters[i].value;
|
|
279
|
+
if (genericTypeInstance.property.parameterRangeGenericBindings) {
|
|
280
|
+
const subConflict = this.bindGenericTypeToRange(genericTypeIdInner, genericTypeInstance.property.parameterRangeGenericBindings, typeTypeValidator);
|
|
281
|
+
if (subConflict) {
|
|
282
|
+
return {
|
|
283
|
+
description: `invalid binding for generic <${genericTypeIdInner}>`,
|
|
284
|
+
context: errorContext,
|
|
285
|
+
causes: [subConflict],
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
this.genericTypeIds[genericTypeIdInner] = true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
exports.GenericsContext = GenericsContext;
|
|
294
|
+
GenericsContext.XSD_INHERITANCE_TABLE = {
|
|
295
|
+
'http://www.w3.org/2001/XMLSchema#number': new Set([
|
|
296
|
+
'http://www.w3.org/2001/XMLSchema#integer',
|
|
297
|
+
'http://www.w3.org/2001/XMLSchema#long',
|
|
298
|
+
'http://www.w3.org/2001/XMLSchema#int',
|
|
299
|
+
'http://www.w3.org/2001/XMLSchema#byte',
|
|
300
|
+
'http://www.w3.org/2001/XMLSchema#short',
|
|
301
|
+
'http://www.w3.org/2001/XMLSchema#negativeInteger',
|
|
302
|
+
'http://www.w3.org/2001/XMLSchema#nonNegativeInteger',
|
|
303
|
+
'http://www.w3.org/2001/XMLSchema#nonPositiveInteger',
|
|
304
|
+
'http://www.w3.org/2001/XMLSchema#positiveInteger',
|
|
305
|
+
'http://www.w3.org/2001/XMLSchema#unsignedByte',
|
|
306
|
+
'http://www.w3.org/2001/XMLSchema#unsignedInt',
|
|
307
|
+
'http://www.w3.org/2001/XMLSchema#unsignedLong',
|
|
308
|
+
'http://www.w3.org/2001/XMLSchema#unsignedShort',
|
|
309
|
+
'http://www.w3.org/2001/XMLSchema#double',
|
|
310
|
+
'http://www.w3.org/2001/XMLSchema#decimal',
|
|
311
|
+
'http://www.w3.org/2001/XMLSchema#float',
|
|
312
|
+
]),
|
|
313
|
+
'http://www.w3.org/2001/XMLSchema#string': new Set([
|
|
314
|
+
'http://www.w3.org/2001/XMLSchema#normalizedString',
|
|
315
|
+
'http://www.w3.org/2001/XMLSchema#anyURI',
|
|
316
|
+
'http://www.w3.org/2001/XMLSchema#base64Binary',
|
|
317
|
+
'http://www.w3.org/2001/XMLSchema#language',
|
|
318
|
+
'http://www.w3.org/2001/XMLSchema#Name',
|
|
319
|
+
'http://www.w3.org/2001/XMLSchema#NCName',
|
|
320
|
+
'http://www.w3.org/2001/XMLSchema#NMTOKEN',
|
|
321
|
+
'http://www.w3.org/2001/XMLSchema#token',
|
|
322
|
+
'http://www.w3.org/2001/XMLSchema#hexBinary',
|
|
323
|
+
'http://www.w3.org/2001/XMLSchema#langString',
|
|
324
|
+
]),
|
|
325
|
+
};
|
|
326
|
+
//# sourceMappingURL=GenericsContext.js.map
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import type { RdfObjectLoader, Resource } from 'rdf-object';
|
|
2
|
+
import type { GenericsContext } from './GenericsContext';
|
|
3
|
+
import { ParameterPropertyHandlerRange } from './parameterproperty/ParameterPropertyHandlerRange';
|
|
2
4
|
/**
|
|
3
5
|
* Handles component parameters in the context of a config.
|
|
4
6
|
*/
|
|
5
7
|
export declare class ParameterHandler {
|
|
6
8
|
private readonly objectLoader;
|
|
7
9
|
private readonly parameterPropertyHandlers;
|
|
10
|
+
readonly parameterPropertyHandlerRange: ParameterPropertyHandlerRange;
|
|
8
11
|
constructor(options: IParameterHandlerOptions);
|
|
9
12
|
/**
|
|
10
13
|
* Obtain the values of the given parameter in the context of the given config.
|
|
11
14
|
* @param configRoot The root config resource that we are working in.
|
|
12
15
|
* @param parameter The parameter resource to get the value for.
|
|
13
16
|
* @param configElement Part of the config resource to look for parameter instantiations as predicates.
|
|
14
|
-
* @
|
|
17
|
+
* @param genericsContext Context for generic types.
|
|
18
|
+
* @return - The parameter value
|
|
15
19
|
*/
|
|
16
|
-
applyParameterValues(configRoot: Resource, parameter: Resource, configElement: Resource): Resource
|
|
20
|
+
applyParameterValues(configRoot: Resource, parameter: Resource, configElement: Resource, genericsContext: GenericsContext): Resource | undefined;
|
|
17
21
|
}
|
|
18
22
|
export interface IParameterHandlerOptions {
|
|
19
23
|
objectLoader: RdfObjectLoader;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ParameterHandler = void 0;
|
|
4
|
+
const ErrorResourcesContext_1 = require("../util/ErrorResourcesContext");
|
|
4
5
|
const ParameterPropertyHandlerDefault_1 = require("./parameterproperty/ParameterPropertyHandlerDefault");
|
|
5
6
|
const ParameterPropertyHandlerDefaultScoped_1 = require("./parameterproperty/ParameterPropertyHandlerDefaultScoped");
|
|
6
7
|
const ParameterPropertyHandlerFixed_1 = require("./parameterproperty/ParameterPropertyHandlerFixed");
|
|
7
8
|
const ParameterPropertyHandlerLazy_1 = require("./parameterproperty/ParameterPropertyHandlerLazy");
|
|
8
9
|
const ParameterPropertyHandlerRange_1 = require("./parameterproperty/ParameterPropertyHandlerRange");
|
|
9
|
-
const ParameterPropertyHandlerRequired_1 = require("./parameterproperty/ParameterPropertyHandlerRequired");
|
|
10
|
-
const ParameterPropertyHandlerUnique_1 = require("./parameterproperty/ParameterPropertyHandlerUnique");
|
|
11
10
|
/**
|
|
12
11
|
* Handles component parameters in the context of a config.
|
|
13
12
|
*/
|
|
@@ -16,11 +15,9 @@ class ParameterHandler {
|
|
|
16
15
|
this.objectLoader = options.objectLoader;
|
|
17
16
|
this.parameterPropertyHandlers = [
|
|
18
17
|
new ParameterPropertyHandlerDefaultScoped_1.ParameterPropertyHandlerDefaultScoped(this.objectLoader),
|
|
19
|
-
new ParameterPropertyHandlerDefault_1.ParameterPropertyHandlerDefault(),
|
|
20
|
-
new
|
|
21
|
-
new
|
|
22
|
-
new ParameterPropertyHandlerUnique_1.ParameterPropertyHandlerUnique(this.objectLoader),
|
|
23
|
-
new ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange(this.objectLoader),
|
|
18
|
+
new ParameterPropertyHandlerDefault_1.ParameterPropertyHandlerDefault(this.objectLoader),
|
|
19
|
+
new ParameterPropertyHandlerFixed_1.ParameterPropertyHandlerFixed(this.objectLoader),
|
|
20
|
+
this.parameterPropertyHandlerRange = new ParameterPropertyHandlerRange_1.ParameterPropertyHandlerRange(this.objectLoader),
|
|
24
21
|
new ParameterPropertyHandlerLazy_1.ParameterPropertyHandlerLazy(),
|
|
25
22
|
];
|
|
26
23
|
}
|
|
@@ -29,25 +26,30 @@ class ParameterHandler {
|
|
|
29
26
|
* @param configRoot The root config resource that we are working in.
|
|
30
27
|
* @param parameter The parameter resource to get the value for.
|
|
31
28
|
* @param configElement Part of the config resource to look for parameter instantiations as predicates.
|
|
32
|
-
* @
|
|
29
|
+
* @param genericsContext Context for generic types.
|
|
30
|
+
* @return - The parameter value
|
|
33
31
|
*/
|
|
34
|
-
applyParameterValues(configRoot, parameter, configElement) {
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
applyParameterValues(configRoot, parameter, configElement, genericsContext) {
|
|
33
|
+
// Make sure that we always have a single value with list elements in it.
|
|
34
|
+
const values = configElement.properties[parameter.value];
|
|
35
|
+
let value;
|
|
36
|
+
if (values.length === 1) {
|
|
37
|
+
value = values[0];
|
|
38
|
+
}
|
|
39
|
+
else if (values.length > 0) {
|
|
40
|
+
if (values.some(subValue => !subValue.list)) {
|
|
41
|
+
throw new ErrorResourcesContext_1.ErrorResourcesContext(`Detected multiple values for parameter ${parameter.value}. RDF lists should be used for defining multiple values.`, {
|
|
42
|
+
arguments: values,
|
|
43
|
+
});
|
|
45
44
|
}
|
|
45
|
+
value = this.objectLoader.createCompactedResource({
|
|
46
|
+
list: values.flatMap(subValue => subValue.list),
|
|
47
|
+
});
|
|
46
48
|
}
|
|
47
49
|
// Run the value through all applicable parameters property handlers.
|
|
48
50
|
for (const handler of this.parameterPropertyHandlers) {
|
|
49
|
-
if (handler.canHandle(value, configRoot, parameter, configElement)) {
|
|
50
|
-
value = handler.handle(value, configRoot, parameter, configElement);
|
|
51
|
+
if (handler.canHandle(value, configRoot, parameter, configElement, genericsContext)) {
|
|
52
|
+
value = handler.handle(value, configRoot, parameter, configElement, genericsContext);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
return value;
|