componentsjs-generator
Advanced tools
Comparing version 3.0.0-beta.2 to 3.0.0-beta.3
@@ -5,3 +5,3 @@ import type { ClassDeclaration, MethodDefinition } from '@typescript-eslint/types/dist/ts-estree'; | ||
import type { CommentLoader } from './CommentLoader'; | ||
import type { ParameterDataField, ParameterRangeUnresolved } from './ParameterLoader'; | ||
import type { GenericTypeParameterData, ParameterDataField, ParameterRangeUnresolved } from './ParameterLoader'; | ||
/** | ||
@@ -50,2 +50,3 @@ * Loads the constructor data of classes. | ||
export interface ConstructorData<R> { | ||
genericTypeParameters: GenericTypeParameterData<R>[]; | ||
parameters: ParameterDataField<R>[]; | ||
@@ -52,0 +53,0 @@ classLoaded: ClassReferenceLoaded; |
@@ -21,3 +21,3 @@ "use strict"; | ||
// Initialize default value | ||
constructorDataIndex[className] = { parameters: [], classLoaded: classLoadedRoot }; | ||
constructorDataIndex[className] = { genericTypeParameters: [], parameters: [], classLoaded: classLoadedRoot }; | ||
// Fill in constructor data if we're loading a class, and we find a constructor in the inheritance chain. | ||
@@ -24,0 +24,0 @@ if (classLoadedRoot.type === 'class') { |
@@ -18,2 +18,11 @@ import type { Identifier, TSPropertySignature, TSTypeLiteral, TypeElement, TypeNode, TSIndexSignature, TSTypeReference, Parameter } from '@typescript-eslint/types/dist/ts-estree'; | ||
/** | ||
* Load the generic type parameter data from the given generic in a constructor. | ||
* @param classLoaded The loaded class in which the field is defined. | ||
* @param genericTypeParameters The array of generic type parameters that will be appended to. | ||
* @param constructorCommentData Comment data from the constructor. | ||
* @param genericName The generic type name. | ||
* @param genericType The optional generic type range. | ||
*/ | ||
loadConstructorGeneric(classLoaded: ClassReferenceLoaded, genericTypeParameters: GenericTypeParameterData<ParameterRangeUnresolved>[], constructorCommentData: ConstructorCommentData, genericName: string, genericType: TypeNode | undefined): void; | ||
/** | ||
* Load the parameter data from the given field in a constructor. | ||
@@ -52,2 +61,3 @@ * @param classLoaded The loaded class in which the field is defined. | ||
getFieldName(classLoaded: ClassReferenceLoaded, field: Identifier | TSPropertySignature): string; | ||
getErrorIdentifierGeneric(classLoaded: ClassReferenceLoaded, genericName: string): string; | ||
getErrorIdentifierField(classLoaded: ClassReferenceLoaded, field: Identifier | TSPropertySignature): string; | ||
@@ -131,2 +141,16 @@ getErrorIdentifierIndex(): string; | ||
} | ||
export interface GenericTypeParameterData<R> { | ||
/** | ||
* The generic type parameter name. | ||
*/ | ||
name: string; | ||
/** | ||
* The range of the generic type parameter. | ||
*/ | ||
range?: R; | ||
/** | ||
* The human-readable description of this parameter. | ||
*/ | ||
comment?: string; | ||
} | ||
export declare type ParameterRangeUnresolved = { | ||
@@ -144,2 +168,3 @@ type: 'raw'; | ||
value: string; | ||
genericTypeParameterInstantiations: ParameterRangeUnresolved[] | undefined; | ||
/** | ||
@@ -169,2 +194,5 @@ * The place from which the interface was referenced. | ||
value: ParameterRangeUnresolved; | ||
} | { | ||
type: 'genericTypeReference'; | ||
value: string; | ||
}; | ||
@@ -183,2 +211,3 @@ export declare type ParameterRangeResolved = { | ||
value: ClassReferenceLoaded; | ||
genericTypeParameterInstances: ParameterRangeResolved[] | undefined; | ||
} | { | ||
@@ -204,2 +233,9 @@ type: 'nested'; | ||
value: ParameterRangeResolved; | ||
} | { | ||
type: 'genericTypeReference'; | ||
value: string; | ||
/** | ||
* The place in which the generic type was defined. | ||
*/ | ||
origin: ClassReferenceLoaded; | ||
}; | ||
@@ -206,0 +242,0 @@ /** |
@@ -20,2 +20,7 @@ "use strict"; | ||
const constructorCommentData = this.commentLoader.getCommentDataFromConstructor(constructorChain); | ||
// Load all generic type parameters | ||
const genericTypeParameters = []; | ||
for (const [genericName, genericType] of Object.entries(constructorChain[0].classLoaded.generics)) { | ||
this.loadConstructorGeneric(constructorChain[0].classLoaded, genericTypeParameters, constructorCommentData, genericName, genericType.type); | ||
} | ||
// Load all constructor parameters | ||
@@ -26,5 +31,21 @@ const parameters = []; | ||
} | ||
return { parameters, classLoaded: constructorChain[0].classLoaded }; | ||
return { genericTypeParameters, parameters, classLoaded: constructorChain[0].classLoaded }; | ||
} | ||
/** | ||
* Load the generic type parameter data from the given generic in a constructor. | ||
* @param classLoaded The loaded class in which the field is defined. | ||
* @param genericTypeParameters The array of generic type parameters that will be appended to. | ||
* @param constructorCommentData Comment data from the constructor. | ||
* @param genericName The generic type name. | ||
* @param genericType The optional generic type range. | ||
*/ | ||
loadConstructorGeneric(classLoaded, genericTypeParameters, constructorCommentData, genericName, genericType) { | ||
genericTypeParameters.push({ | ||
name: genericName, | ||
...genericType ? | ||
{ range: this.getRangeFromTypeNode(classLoaded, genericType, this.getErrorIdentifierGeneric(classLoaded, genericName)) } : | ||
{}, | ||
}); | ||
} | ||
/** | ||
* Load the parameter data from the given field in a constructor. | ||
@@ -131,2 +152,5 @@ * @param classLoaded The loaded class in which the field is defined. | ||
} | ||
getErrorIdentifierGeneric(classLoaded, genericName) { | ||
return `generic type ${genericName}`; | ||
} | ||
getErrorIdentifierField(classLoaded, field) { | ||
@@ -161,9 +185,8 @@ return `field ${this.getFieldName(classLoaded, field)}`; | ||
default: | ||
// First check if the type is be a generic type | ||
// First check if the type is a direct generic type | ||
if (classLoaded.type !== 'type' && typeNode.typeName.name in classLoaded.generics) { | ||
const genericProperties = classLoaded.generics[typeNode.typeName.name]; | ||
if (!genericProperties.type) { | ||
throw new Error(`Found untyped generic field type at ${errorIdentifier} in ${classLoaded.localName} at ${classLoaded.fileName}`); | ||
} | ||
return this.getRangeFromTypeNode(classLoaded, genericProperties.type, errorIdentifier); | ||
return { | ||
type: 'genericTypeReference', | ||
value: typeNode.typeName.name, | ||
}; | ||
} | ||
@@ -175,4 +198,16 @@ // Check if this node is a predefined type alias | ||
} | ||
// If we have type parameters, determine the generic type param instantiations | ||
// eslint-disable-next-line no-case-declarations | ||
let genericTypeParameterInstantiations; | ||
if (typeNode.typeParameters) { | ||
genericTypeParameterInstantiations = typeNode.typeParameters.params | ||
.map(genericTypeParameter => this.getRangeFromTypeNode(classLoaded, genericTypeParameter, `generic type instantiation on ${classLoaded.localName} in ${classLoaded.fileName}`)); | ||
} | ||
// Otherwise, assume we have an interface/class parameter | ||
return { type: 'interface', value: typeNode.typeName.name, origin: classLoaded }; | ||
return { | ||
type: 'interface', | ||
value: typeNode.typeName.name, | ||
genericTypeParameterInstantiations, | ||
origin: classLoaded, | ||
}; | ||
} | ||
@@ -278,2 +313,3 @@ } | ||
case 'interface': | ||
case 'genericTypeReference': | ||
// Replace these types | ||
@@ -280,0 +316,0 @@ return override; |
@@ -6,3 +6,3 @@ import type { TSTypeLiteral } from '@typescript-eslint/types/dist/ts-estree'; | ||
import type { ConstructorData } from './ConstructorLoader'; | ||
import type { ParameterData, ParameterRangeResolved, ParameterRangeUnresolved } from './ParameterLoader'; | ||
import type { GenericTypeParameterData, ParameterData, ParameterRangeResolved, ParameterRangeUnresolved } from './ParameterLoader'; | ||
export declare class ParameterResolver { | ||
@@ -24,7 +24,15 @@ private readonly classLoader; | ||
/** | ||
* Resolve the given array of generic type parameter data in parallel. | ||
* @param genericTypeParameters An array of unresolved generic type parameters. | ||
* @param owningClass The class in which the given generic type parameters are declared. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
resolveGenericTypeParameterData(genericTypeParameters: GenericTypeParameterData<ParameterRangeUnresolved>[], owningClass: ClassReferenceLoaded, genericTypeRemappings: Record<string, ParameterRangeUnresolved>): Promise<GenericTypeParameterData<ParameterRangeResolved>[]>; | ||
/** | ||
* Resolve the given array of parameter data in parallel. | ||
* @param parameters An array of unresolved parameters. | ||
* @param owningClass The class in which the given parameters are declared. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
resolveParameterData(parameters: ParameterData<ParameterRangeUnresolved>[], owningClass: ClassReferenceLoaded): Promise<ParameterData<ParameterRangeResolved>[]>; | ||
resolveParameterData(parameters: ParameterData<ParameterRangeUnresolved>[], owningClass: ClassReferenceLoaded, genericTypeRemappings: Record<string, ParameterRangeUnresolved>): Promise<ParameterData<ParameterRangeResolved>[]>; | ||
/** | ||
@@ -34,10 +42,16 @@ * Resolve the given parameter range. | ||
* @param owningClass The class this range was defined in. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
resolveRange(range: ParameterRangeUnresolved, owningClass: ClassReferenceLoaded): Promise<ParameterRangeResolved>; | ||
resolveRange(range: ParameterRangeUnresolved, owningClass: ClassReferenceLoaded, genericTypeRemappings: Record<string, ParameterRangeUnresolved>): Promise<ParameterRangeResolved>; | ||
/** | ||
* Resolve a class or interface. | ||
* @param interfaceName A class or interface name. | ||
* @param genericTypeParameterInstances Generic type parameters that were supplied for instantiation. | ||
* Note that these generics are NOT the same as the generics that may be defined | ||
* within the class itself. | ||
* @param owningClass The class this interface was used in. | ||
* @param rootOwningClass The top-level class this interface was used in. Necessary for generic type resolution. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
resolveRangeInterface(interfaceName: string, owningClass: ClassReferenceLoaded): Promise<ParameterRangeResolved>; | ||
resolveRangeInterface(interfaceName: string, genericTypeParameterInstances: ParameterRangeUnresolved[] | undefined, owningClass: ClassReferenceLoaded, rootOwningClass: ClassReferenceLoaded, genericTypeRemappings: Record<string, ParameterRangeUnresolved>): Promise<ParameterRangeResolved>; | ||
/** | ||
@@ -63,4 +77,6 @@ * Check if the given interface should actually be considered a class. | ||
* @param iface A loaded interface. | ||
* @param owningClass The class this hash is declared in. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
getNestedFieldsFromInterface(iface: InterfaceLoaded): Promise<ParameterData<ParameterRangeResolved>[]>; | ||
getNestedFieldsFromInterface(iface: InterfaceLoaded, owningClass: ClassReferenceLoaded, genericTypeRemappings: Record<string, ParameterRangeUnresolved>): Promise<ParameterData<ParameterRangeResolved>[]>; | ||
/** | ||
@@ -70,4 +86,5 @@ * Recursively get all fields from the given hash. | ||
* @param owningClass The class this hash is declared in. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
getNestedFieldsFromHash(hash: TSTypeLiteral, owningClass: ClassReferenceLoaded): Promise<ParameterData<ParameterRangeResolved>[]>; | ||
getNestedFieldsFromHash(hash: TSTypeLiteral, owningClass: ClassReferenceLoaded, genericTypeRemappings: Record<string, ParameterRangeUnresolved>): Promise<ParameterData<ParameterRangeResolved>[]>; | ||
} | ||
@@ -74,0 +91,0 @@ export interface ParameterResolverArgs { |
@@ -33,3 +33,4 @@ "use strict"; | ||
return { | ||
parameters: (await this.resolveParameterData(unresolvedConstructorData.parameters, unresolvedConstructorData.classLoaded)).filter(parameter => parameter.type === 'field'), | ||
genericTypeParameters: await this.resolveGenericTypeParameterData(unresolvedConstructorData.genericTypeParameters, unresolvedConstructorData.classLoaded, {}), | ||
parameters: (await this.resolveParameterData(unresolvedConstructorData.parameters, unresolvedConstructorData.classLoaded, {})).filter(parameter => parameter.type === 'field'), | ||
classLoaded: unresolvedConstructorData.classLoaded, | ||
@@ -39,9 +40,26 @@ }; | ||
/** | ||
* Resolve the given array of generic type parameter data in parallel. | ||
* @param genericTypeParameters An array of unresolved generic type parameters. | ||
* @param owningClass The class in which the given generic type parameters are declared. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
async resolveGenericTypeParameterData(genericTypeParameters, owningClass, genericTypeRemappings) { | ||
return await Promise.all(genericTypeParameters | ||
.map(async (generic) => ({ | ||
...generic, | ||
range: generic.range ? await this.resolveRange(generic.range, owningClass, genericTypeRemappings) : undefined, | ||
}))); | ||
} | ||
/** | ||
* Resolve the given array of parameter data in parallel. | ||
* @param parameters An array of unresolved parameters. | ||
* @param owningClass The class in which the given parameters are declared. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
async resolveParameterData(parameters, owningClass) { | ||
async resolveParameterData(parameters, owningClass, genericTypeRemappings) { | ||
return await Promise.all(parameters | ||
.map(async (parameter) => ({ ...parameter, range: await this.resolveRange(parameter.range, owningClass) }))); | ||
.map(async (parameter) => ({ | ||
...parameter, | ||
range: await this.resolveRange(parameter.range, owningClass, genericTypeRemappings), | ||
}))); | ||
} | ||
@@ -52,4 +70,5 @@ /** | ||
* @param owningClass The class this range was defined in. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
async resolveRange(range, owningClass) { | ||
async resolveRange(range, owningClass, genericTypeRemappings) { | ||
switch (range.type) { | ||
@@ -66,7 +85,7 @@ case 'raw': | ||
} | ||
return await this.resolveRangeInterface(range.value, range.origin); | ||
return await this.resolveRangeInterface(range.value, range.genericTypeParameterInstantiations, range.origin, owningClass, genericTypeRemappings); | ||
case 'hash': | ||
return { | ||
type: 'nested', | ||
value: await this.getNestedFieldsFromHash(range.value, owningClass), | ||
value: await this.getNestedFieldsFromHash(range.value, owningClass, genericTypeRemappings), | ||
}; | ||
@@ -82,3 +101,4 @@ case 'undefined': | ||
type: range.type, | ||
elements: await Promise.all(range.elements.map(child => this.resolveRange(child, owningClass))), | ||
elements: await Promise.all(range.elements | ||
.map(child => this.resolveRange(child, owningClass, genericTypeRemappings))), | ||
}; | ||
@@ -89,4 +109,14 @@ case 'array': | ||
type: range.type, | ||
value: await this.resolveRange(range.value, owningClass), | ||
value: await this.resolveRange(range.value, owningClass, genericTypeRemappings), | ||
}; | ||
case 'genericTypeReference': | ||
// If this generic type was remapped, return that remapped type | ||
if (range.value in genericTypeRemappings) { | ||
return this.resolveRange(genericTypeRemappings[range.value], owningClass, genericTypeRemappings); | ||
} | ||
return { | ||
type: 'genericTypeReference', | ||
value: range.value, | ||
origin: owningClass, | ||
}; | ||
} | ||
@@ -97,5 +127,10 @@ } | ||
* @param interfaceName A class or interface name. | ||
* @param genericTypeParameterInstances Generic type parameters that were supplied for instantiation. | ||
* Note that these generics are NOT the same as the generics that may be defined | ||
* within the class itself. | ||
* @param owningClass The class this interface was used in. | ||
* @param rootOwningClass The top-level class this interface was used in. Necessary for generic type resolution. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
async resolveRangeInterface(interfaceName, owningClass) { | ||
async resolveRangeInterface(interfaceName, genericTypeParameterInstances, owningClass, rootOwningClass, genericTypeRemappings) { | ||
const classOrInterface = await this.loadClassOrInterfacesChain({ | ||
@@ -113,2 +148,7 @@ packageName: owningClass.packageName, | ||
value: classOrInterface, | ||
genericTypeParameterInstances: genericTypeParameterInstances ? | ||
await Promise.all(genericTypeParameterInstances | ||
.map(genericTypeParameter => this | ||
.resolveRange(genericTypeParameter, rootOwningClass, genericTypeRemappings))) : | ||
undefined, | ||
}; | ||
@@ -120,8 +160,16 @@ } | ||
const unresolvedFields = parameterLoader.getRangeFromTypeNode(classOrInterface, classOrInterface.declaration.typeAnnotation, `type alias ${classOrInterface.localName} in ${classOrInterface.fileName}`); | ||
return this.resolveRange(unresolvedFields, classOrInterface); | ||
return this.resolveRange(unresolvedFields, classOrInterface, genericTypeRemappings); | ||
} | ||
// If we find an interface, load it as a hash with nested fields | ||
if (genericTypeParameterInstances) { | ||
// If the interfaces has generic type instantiations, | ||
// map the generic type declarations of the class on the generic types of the interface | ||
const ifaceGenericTypes = Object.keys(classOrInterface.generics); | ||
for (const [i, genericTypeParameterInstance] of genericTypeParameterInstances.entries()) { | ||
genericTypeRemappings[ifaceGenericTypes[i]] = genericTypeParameterInstance; | ||
} | ||
} | ||
return { | ||
type: 'nested', | ||
value: await this.getNestedFieldsFromInterface(classOrInterface), | ||
value: await this.getNestedFieldsFromInterface(classOrInterface, rootOwningClass, genericTypeRemappings), | ||
}; | ||
@@ -192,7 +240,9 @@ } | ||
* @param iface A loaded interface. | ||
* @param owningClass The class this hash is declared in. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
async getNestedFieldsFromInterface(iface) { | ||
async getNestedFieldsFromInterface(iface, owningClass, genericTypeRemappings) { | ||
const parameterLoader = new ParameterLoader_1.ParameterLoader({ commentLoader: this.commentLoader }); | ||
const unresolvedFields = parameterLoader.loadInterfaceFields(iface); | ||
return this.resolveParameterData(unresolvedFields, iface); | ||
return this.resolveParameterData(unresolvedFields, owningClass, genericTypeRemappings); | ||
} | ||
@@ -203,7 +253,8 @@ /** | ||
* @param owningClass The class this hash is declared in. | ||
* @param genericTypeRemappings A remapping of generic type names. | ||
*/ | ||
async getNestedFieldsFromHash(hash, owningClass) { | ||
async getNestedFieldsFromHash(hash, owningClass, genericTypeRemappings) { | ||
const parameterLoader = new ParameterLoader_1.ParameterLoader({ commentLoader: this.commentLoader }); | ||
const unresolvedFields = parameterLoader.loadHashFields(owningClass, hash); | ||
return this.resolveParameterData(unresolvedFields, owningClass); | ||
return this.resolveParameterData(unresolvedFields, owningClass, genericTypeRemappings); | ||
} | ||
@@ -210,0 +261,0 @@ } |
@@ -63,2 +63,3 @@ "use strict"; | ||
case 'undefined': | ||
case 'genericTypeReference': | ||
break; | ||
@@ -65,0 +66,0 @@ case 'class': |
@@ -5,5 +5,5 @@ import type { ContextParser, JsonLdContextNormalized } from 'jsonld-context-parser'; | ||
import type { PackageMetadata } from '../parse/PackageMetadataLoader'; | ||
import type { DefaultNested, DefaultValue, ParameterData, ParameterRangeResolved } from '../parse/ParameterLoader'; | ||
import type { DefaultNested, DefaultValue, GenericTypeParameterData, ParameterData, ParameterRangeResolved } from '../parse/ParameterLoader'; | ||
import type { ExternalComponents } from '../resolution/ExternalModulesLoader'; | ||
import type { ComponentDefinition, ComponentDefinitions, ComponentDefinitionsIndex, ConstructorArgumentDefinition, ConstructorFieldDefinition, DefaultValueDefinition, ParameterDefinition, ParameterDefinitionRange } from './ComponentDefinitions'; | ||
import type { ComponentDefinition, ComponentDefinitions, ComponentDefinitionsIndex, ConstructorArgumentDefinition, ConstructorFieldDefinition, DefaultValueDefinition, ParameterDefinition, ParameterDefinitionRange, GenericTypeParameterDefinition } from './ComponentDefinitions'; | ||
import { ContextConstructor } from './ContextConstructor'; | ||
@@ -56,3 +56,3 @@ /** | ||
*/ | ||
constructComponent(context: JsonLdContextNormalized, externalContextsCallback: ExternalContextCallback, classReference: ClassReferenceLoadedWithoutType, constructorData: ConstructorData<ParameterRangeResolved>): Promise<ComponentDefinition>; | ||
constructComponent(context: JsonLdContextNormalized, externalContextsCallback: ExternalContextCallback, classReference: ClassReferenceLoadedWithoutType, constructorData: ConstructorData<ParameterRangeResolved> | undefined): Promise<ComponentDefinition>; | ||
/** | ||
@@ -81,2 +81,9 @@ * Construct a compacted module IRI. | ||
/** | ||
* Construct a compacted generic name IRI. | ||
* @param context A parsed JSON-LD context. | ||
* @param classReference The class reference. | ||
* @param genericTypeName The name of the generic type. | ||
*/ | ||
genericNameToId(context: JsonLdContextNormalized, classReference: ClassReference, genericTypeName: string): string; | ||
/** | ||
* Construct constructor arguments from the given constructor data. | ||
@@ -88,2 +95,12 @@ * Additionally, parameters will be appended to the parameters array. | ||
* @param classReference Class reference of the class component owning this constructor. | ||
* @param genericTypes Generic types of the class. | ||
*/ | ||
constructGenericTypeParameters(context: JsonLdContextNormalized, externalContextsCallback: ExternalContextCallback, classReference: ClassReferenceLoadedWithoutType, genericTypes: GenericTypeParameterData<ParameterRangeResolved>[]): Promise<GenericTypeParameterDefinition[]>; | ||
/** | ||
* Construct constructor arguments from the given constructor data. | ||
* Additionally, parameters will be appended to the parameters array. | ||
* | ||
* @param context A parsed JSON-LD context. | ||
* @param externalContextsCallback Callback for external contexts. | ||
* @param classReference Class reference of the class component owning this constructor. | ||
* @param constructorData Constructor data of the owning class. | ||
@@ -90,0 +107,0 @@ * @param parameters The array of parameters of the owning class, which will be appended to. |
@@ -119,6 +119,10 @@ "use strict"; | ||
async constructComponent(context, externalContextsCallback, classReference, constructorData) { | ||
// Determine generic type parameters | ||
const genericTypeParameters = constructorData ? | ||
await this.constructGenericTypeParameters(context, externalContextsCallback, classReference, constructorData.genericTypeParameters) : | ||
undefined; | ||
// Fill in parameters and constructor arguments | ||
const parameters = []; | ||
const scopedId = await this.classNameToId(context, externalContextsCallback, classReference); | ||
const constructorArguments = classReference.type === 'class' ? | ||
const constructorArguments = constructorData && classReference.type === 'class' ? | ||
await this.constructParameters(context, externalContextsCallback, classReference, constructorData, parameters) : | ||
@@ -155,2 +159,3 @@ []; | ||
...classReference.comment ? { comment: classReference.comment } : {}, | ||
...genericTypeParameters && genericTypeParameters.length > 0 ? { genericTypeParameters } : {}, | ||
parameters, | ||
@@ -226,2 +231,15 @@ constructorArguments, | ||
/** | ||
* Construct a compacted generic name IRI. | ||
* @param context A parsed JSON-LD context. | ||
* @param classReference The class reference. | ||
* @param genericTypeName The name of the generic type. | ||
*/ | ||
genericNameToId(context, classReference, genericTypeName) { | ||
return this.fieldNameToId(context, classReference, `_generic_${genericTypeName}`, { | ||
parentFieldNames: [], | ||
fieldIdsHash: {}, | ||
defaultNested: [], | ||
}); | ||
} | ||
/** | ||
* Construct constructor arguments from the given constructor data. | ||
@@ -233,2 +251,24 @@ * Additionally, parameters will be appended to the parameters array. | ||
* @param classReference Class reference of the class component owning this constructor. | ||
* @param genericTypes Generic types of the class. | ||
*/ | ||
async constructGenericTypeParameters(context, externalContextsCallback, classReference, genericTypes) { | ||
const definitions = []; | ||
for (const genericType of genericTypes) { | ||
const id = this.genericNameToId(context, classReference, genericType.name); | ||
definitions.push({ | ||
'@id': id, | ||
...genericType.range ? | ||
{ range: await this.constructParameterRange(genericType.range, context, externalContextsCallback, id) } : | ||
{}, | ||
}); | ||
} | ||
return definitions; | ||
} | ||
/** | ||
* Construct constructor arguments from the given constructor data. | ||
* Additionally, parameters will be appended to the parameters array. | ||
* | ||
* @param context A parsed JSON-LD context. | ||
* @param externalContextsCallback Callback for external contexts. | ||
* @param classReference Class reference of the class component owning this constructor. | ||
* @param constructorData Constructor data of the owning class. | ||
@@ -411,3 +451,13 @@ * @param parameters The array of parameters of the owning class, which will be appended to. | ||
case 'class': | ||
return await this.classNameToId(context, externalContextsCallback, range.value); | ||
// eslint-disable-next-line no-case-declarations | ||
const componentId = await this.classNameToId(context, externalContextsCallback, range.value); | ||
if (range.genericTypeParameterInstances) { | ||
return { | ||
'@type': 'ParameterRangeGenericComponent', | ||
component: componentId, | ||
genericTypeInstances: await Promise.all(range.genericTypeParameterInstances | ||
.map(genericType => this.constructParameterRange(genericType, context, externalContextsCallback, fieldId))), | ||
}; | ||
} | ||
return componentId; | ||
case 'nested': | ||
@@ -445,2 +495,7 @@ throw new Error('Composition of nested fields is unsupported'); | ||
}; | ||
case 'genericTypeReference': | ||
return { | ||
'@type': 'ParameterRangeGenericTypeReference', | ||
parameterRangeGenericType: this.genericNameToId(context, range.origin, range.value), | ||
}; | ||
} | ||
@@ -447,0 +502,0 @@ } |
@@ -19,5 +19,10 @@ export declare type ComponentDefinitions = Record<string, { | ||
comment?: string; | ||
genericTypeParameters?: GenericTypeParameterDefinition[]; | ||
parameters: ParameterDefinition[]; | ||
constructorArguments: ConstructorArgumentDefinition[]; | ||
} | ||
export interface GenericTypeParameterDefinition { | ||
'@id': string; | ||
range?: ParameterDefinitionRange; | ||
} | ||
export interface ParameterDefinition { | ||
@@ -56,2 +61,9 @@ '@id': string; | ||
parameterRangeValueLiteral: number | string | boolean; | ||
} | { | ||
'@type': 'ParameterRangeGenericTypeReference'; | ||
parameterRangeGenericType: string; | ||
} | { | ||
'@type': 'ParameterRangeGenericComponent'; | ||
component: string; | ||
genericTypeInstances: ParameterDefinitionRange[]; | ||
}; | ||
@@ -58,0 +70,0 @@ export declare type ConstructorArgumentDefinition = string | { |
{ | ||
"name": "componentsjs-generator", | ||
"version": "3.0.0-beta.2", | ||
"version": "3.0.0-beta.3", | ||
"description": "Automatically generate component files from TypeScript classes for the Components.js dependency injection framework", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -223,3 +223,4 @@ # Components-Generator.js | ||
* Another class, which will be mapped to the component `@id`. | ||
* A record or interface containing key-value pairs where each value matches one of the possible options. Nesting is allowed. | ||
* A record or interface containing key-value pairs where each value matches one of the possible options. Nesting is allowed. | ||
* Reference to a generic type that is defined on the class. | ||
* An array, tuple, union, or intersection over any of the allowed types. | ||
@@ -226,0 +227,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
240851
52
4598
422