componentjs-generator
Advanced tools
Comparing version
@@ -37,4 +37,7 @@ #!/usr/bin/env node | ||
.generateComponents() | ||
.catch((error) => process.stderr.write(`${error.message}\n`)); | ||
.catch((error) => { | ||
process.stderr.write(`${error.message}\n`); | ||
process.exit(1); | ||
}); | ||
} | ||
//# sourceMappingURL=GenerateRunner.js.map |
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
<a name="v1.1.0"></a> | ||
## [v1.1.0](https://github.com/LinkedSoftwareDependencies/Components-Generator.js/compare/v1.0.1...v1.1.0) - 2020-09-07 | ||
### Added | ||
* [Handle generically typed parameters](https://github.com/LinkedSoftwareDependencies/Components-Generator.js/commit/3344ea9ff1d023a9a14efaac330d79097ac444d9) | ||
### Fixed | ||
* [Fix exiting with code 0 on error](https://github.com/LinkedSoftwareDependencies/Components-Generator.js/commit/157a9f5f52f16eb4b1f8a943b4111ef4f7923353) | ||
<a name="v1.0.1"></a> | ||
@@ -5,0 +14,0 @@ ## [v1.0.1](https://github.com/LinkedSoftwareDependencies/Components-Generator.js/compare/v1.0.0...v1.0.1) - 2020-08-28 |
@@ -1,2 +0,2 @@ | ||
import { ClassDeclaration, TSInterfaceDeclaration } from '@typescript-eslint/types/dist/ts-estree'; | ||
import { ClassDeclaration, TSInterfaceDeclaration, TypeNode } from '@typescript-eslint/types/dist/ts-estree'; | ||
import { AST, TSESTreeOptions } from '@typescript-eslint/typescript-estree'; | ||
@@ -32,4 +32,13 @@ /** | ||
comment?: string; | ||
generics: GenericTypes; | ||
} | ||
/** | ||
* A hash of generic type name to its properties. | ||
*/ | ||
export interface GenericTypes { | ||
[name: string]: { | ||
type?: TypeNode; | ||
}; | ||
} | ||
/** | ||
* A loaded interface with a full interface declaration. | ||
@@ -45,2 +54,3 @@ */ | ||
comment?: string; | ||
generics: GenericTypes; | ||
} |
import { ClassDeclaration, TSInterfaceDeclaration } from '@typescript-eslint/types/dist/ts-estree'; | ||
import { AST, TSESTreeOptions } from '@typescript-eslint/typescript-estree'; | ||
import { ResolutionContext } from '../resolution/ResolutionContext'; | ||
import { ClassLoaded, ClassReference, ClassReferenceLoaded, InterfaceLoaded } from './ClassIndex'; | ||
import { ClassLoaded, ClassReference, ClassReferenceLoaded, GenericTypes, InterfaceLoaded } from './ClassIndex'; | ||
/** | ||
@@ -33,2 +33,7 @@ * Loads typescript classes from class references. | ||
/** | ||
* Create a hash of generic types in the given class declaration. | ||
* @param classDeclaration A class or interface declaration. | ||
*/ | ||
collectGenericTypes(classDeclaration: ClassDeclaration | TSInterfaceDeclaration): GenericTypes; | ||
/** | ||
* Annotate the given loaded class or interface with a comment if it is present on the declaration. | ||
@@ -35,0 +40,0 @@ * @param classLoaded A loaded class or interface. |
@@ -74,7 +74,11 @@ "use strict"; | ||
if (classReference.localName in exportedClasses) { | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'class' }, classReference), { declaration: exportedClasses[classReference.localName], ast, abstract: exportedClasses[classReference.localName].abstract })); | ||
const declaration = exportedClasses[classReference.localName]; | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'class' }, classReference), { declaration, | ||
ast, abstract: declaration.abstract, generics: this.collectGenericTypes(declaration) })); | ||
} | ||
// If the class has been declared in this file, return directly | ||
if (classReference.localName in declaredClasses) { | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'class' }, classReference), { declaration: declaredClasses[classReference.localName], ast, abstract: declaredClasses[classReference.localName].abstract })); | ||
const declaration = declaredClasses[classReference.localName]; | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'class' }, classReference), { declaration, | ||
ast, abstract: declaration.abstract, generics: this.collectGenericTypes(declaration) })); | ||
} | ||
@@ -85,7 +89,11 @@ // Only consider interfaces if explicitly enabled | ||
if (classReference.localName in exportedInterfaces) { | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'interface' }, classReference), { declaration: exportedInterfaces[classReference.localName], ast })); | ||
const declaration = exportedInterfaces[classReference.localName]; | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'interface' }, classReference), { declaration, | ||
ast, generics: this.collectGenericTypes(declaration) })); | ||
} | ||
// If the interface has been declared in this file, return directly | ||
if (classReference.localName in declaredInterfaces) { | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'interface' }, classReference), { declaration: declaredInterfaces[classReference.localName], ast })); | ||
const declaration = declaredInterfaces[classReference.localName]; | ||
return this.enhanceLoadedWithComment(Object.assign(Object.assign({ type: 'interface' }, classReference), { declaration, | ||
ast, generics: this.collectGenericTypes(declaration) })); | ||
} | ||
@@ -114,2 +122,15 @@ } | ||
/** | ||
* Create a hash of generic types in the given class declaration. | ||
* @param classDeclaration A class or interface declaration. | ||
*/ | ||
collectGenericTypes(classDeclaration) { | ||
const genericTypes = {}; | ||
if (classDeclaration.typeParameters) { | ||
for (const param of classDeclaration.typeParameters.params) { | ||
genericTypes[param.name.name] = { type: param.constraint }; | ||
} | ||
} | ||
return genericTypes; | ||
} | ||
/** | ||
* Annotate the given loaded class or interface with a comment if it is present on the declaration. | ||
@@ -116,0 +137,0 @@ * @param classLoaded A loaded class or interface. |
@@ -136,2 +136,11 @@ "use strict"; | ||
default: | ||
// First check if the type is be a generic type | ||
if (typeNode.typeName.name in this.classLoaded.generics) { | ||
const genericProperties = this.classLoaded.generics[typeNode.typeName.name]; | ||
if (!genericProperties.type) { | ||
throw new Error(`Found untyped generic field type at ${this.getFieldName(field)} in ${this.classLoaded.localName} at ${this.classLoaded.fileName}`); | ||
} | ||
return this.getRangeFromTypeNode(genericProperties.type, field); | ||
} | ||
// Otherwise, assume we have an interface/class parameter | ||
return { type: 'interface', value: typeNode.typeName.name }; | ||
@@ -138,0 +147,0 @@ } |
{ | ||
"name": "componentjs-generator", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Automatically generate component files from TypeScript classes for the Components.js dependency injection framework", | ||
@@ -74,3 +74,3 @@ "main": "index.js", | ||
"@types/lru-cache": "^5.1.0", | ||
"@typescript-eslint/typescript-estree": "^3.10.1", | ||
"@typescript-eslint/typescript-estree": "^4.0.0", | ||
"comment-parser": "^0.7.6", | ||
@@ -93,3 +93,3 @@ "jsonld-context-parser": "^2.0.2", | ||
"eslint-plugin-import": "^2.22.0", | ||
"eslint-plugin-jest": "^23.18.0", | ||
"eslint-plugin-jest": "^24.0.0", | ||
"eslint-plugin-tsdoc": "^0.2.6", | ||
@@ -96,0 +96,0 @@ "eslint-plugin-unused-imports": "^0.1.3", |
121939
2.2%2462
1.99%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed