mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-22 01:22:54 +00:00
refactor: build system
This commit is contained in:
8
packages/easy-ast/README.md
Normal file
8
packages/easy-ast/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# What is Easy AST?
|
||||
|
||||
Easy [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) is a "wrapper" around the TypeScript Compiler API. The TS Compiler API is built for many
|
||||
much more complex things than just accessing type declarations, and thus comes with a ton of
|
||||
bloat that makes it really difficult to work with.
|
||||
|
||||
This is why we built the Easy AST, which converts the TS representation to a really easy and
|
||||
lightweight structure, that removes a lot of the stuff you wouldn't really need.
|
||||
61
packages/easy-ast/package.json
Normal file
61
packages/easy-ast/package.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"name": "@openstapps/easy-ast",
|
||||
"description": "Tool to easily handle TypeScript AST",
|
||||
"version": "2.1.0",
|
||||
"type": "module",
|
||||
"license": "GPL-3.0-only",
|
||||
"repository": "git@gitlab.com:openstapps/core-tools.git",
|
||||
"author": "Thea Schöbl <dev@theaninova.de>",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsup --dts",
|
||||
"format": "prettier .",
|
||||
"format:fix": "prettier --write .",
|
||||
"lint": "eslint --ext .ts src/",
|
||||
"lint:fix": "eslint --fix --ext .ts src/",
|
||||
"test": "nyc mocha 'test/**/*.spec.ts'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@openstapps/collection-utils": "workspace:*",
|
||||
"@openstapps/logger": "workspace:*",
|
||||
"typescript": "4.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@openstapps/eslint-config": "workspace:*",
|
||||
"@openstapps/nyc-config": "workspace:*",
|
||||
"@openstapps/prettier-config": "workspace:*",
|
||||
"@openstapps/tsconfig": "workspace:*",
|
||||
"@testdeck/mocha": "0.3.3",
|
||||
"@types/chai": "4.3.4",
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"@types/mocha": "10.0.1",
|
||||
"@types/node": "18.15.3",
|
||||
"mocha": "10.2.0",
|
||||
"nock": "13.3.0",
|
||||
"tsup": "6.7.0"
|
||||
},
|
||||
"tsup": {
|
||||
"entry": [
|
||||
"src/app.ts",
|
||||
"src/index.ts"
|
||||
],
|
||||
"sourcemap": true,
|
||||
"clean": true,
|
||||
"format": "esm",
|
||||
"outDir": "lib"
|
||||
},
|
||||
"prettier": "@openstapps/prettier-config",
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"@openstapps"
|
||||
]
|
||||
},
|
||||
"eslintIgnore": [
|
||||
"resources",
|
||||
"openapi"
|
||||
],
|
||||
"nyc": {
|
||||
"extends": "@openstapps/nyc-config"
|
||||
}
|
||||
}
|
||||
117
packages/easy-ast/src/ast-internal-util.ts
Normal file
117
packages/easy-ast/src/ast-internal-util.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
import {cleanupEmpty} from './util.js';
|
||||
import {LightweightComment} from './types/lightweight-comment.js';
|
||||
|
||||
/** @internal */
|
||||
export function extractComment(node: ts.Node): LightweightComment | undefined {
|
||||
const jsDocuments =
|
||||
// @ts-expect-error jsDoc exists in reality
|
||||
node.jsDoc as
|
||||
| Array<{
|
||||
comment?: string;
|
||||
tags?: Array<{comment?: string; tagName?: {escapedText?: string}}>;
|
||||
}>
|
||||
| undefined;
|
||||
const jsDocument = jsDocuments?.[jsDocuments.length - 1];
|
||||
const comment = jsDocument?.comment?.split('\n\n');
|
||||
|
||||
return jsDocument === undefined
|
||||
? undefined
|
||||
: cleanupEmpty({
|
||||
shortSummary: comment?.[0],
|
||||
description: comment?.[comment.length - 1],
|
||||
tags: jsDocument?.tags?.map(tag =>
|
||||
cleanupEmpty({
|
||||
name: tag.tagName?.escapedText ?? 'UNRESOLVED_NAME',
|
||||
parameters: tag.comment?.split(' '),
|
||||
}),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isProperty(
|
||||
node: ts.ClassElement | ts.TypeElement,
|
||||
): node is ts.PropertyDeclaration | ts.PropertySignature {
|
||||
return ts.isPropertyDeclaration(node) || ts.isPropertySignature(node);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function filterNodeTo<T extends ts.Node, S extends T>(
|
||||
node: ts.NodeArray<T>,
|
||||
check: (node: T) => node is S,
|
||||
): S[] {
|
||||
return node.filter(check);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function filterChildrenTo<T extends ts.Node>(node: ts.Node, check: (node: ts.Node) => node is T): T[] {
|
||||
const out: T[] = [];
|
||||
node.forEachChild(child => {
|
||||
if (check(child)) {
|
||||
out.push(child);
|
||||
}
|
||||
});
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getModifiers(text: string, kind: string): string[] {
|
||||
return [
|
||||
...text
|
||||
.split(kind)[0]
|
||||
.split(/\s+/)
|
||||
.filter(it => it !== ''),
|
||||
kind,
|
||||
];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function resolvePropertyName(name?: ts.PropertyName): string | undefined {
|
||||
return name === undefined
|
||||
? undefined
|
||||
: ts.isComputedPropertyName(name)
|
||||
? 'UNSUPPORTED_IDENTIFIER_TYPE'
|
||||
: name.getText();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function resolveTypeName(type?: ts.TypeNode): string | undefined {
|
||||
// @ts-expect-error typeName exists in reality
|
||||
return type?.typeName?.escapedText ?? type?.typeName?.right?.escapedText;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isArrayLikeType(typeNode?: ts.TypeNode): typeNode is ts.ArrayTypeNode | ts.TypeReferenceNode {
|
||||
return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || isArrayReference(typeNode));
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isArrayReference(typeNode: ts.TypeNode): boolean {
|
||||
return ts.isTypeReferenceNode(typeNode) && (typeNode.typeName as ts.Identifier).escapedText === 'Array';
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isClassLikeNode(node: ts.Node): node is ts.ClassDeclaration | ts.InterfaceDeclaration {
|
||||
return ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isEnumLikeNode(node: ts.Node): node is ts.EnumDeclaration | ts.TypeAliasDeclaration {
|
||||
return ts.isEnumDeclaration(node) || ts.isTypeAliasDeclaration(node);
|
||||
}
|
||||
83
packages/easy-ast/src/ast-util.ts
Normal file
83
packages/easy-ast/src/ast-util.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import ts from 'typescript';
|
||||
import {LightweightAliasDefinition} from './types/lightweight-alias-definition.js';
|
||||
import {LightweightClassDefinition} from './types/lightweight-class-definition.js';
|
||||
import {LightweightDefinition} from './types/lightweight-definition.js';
|
||||
import {LightweightDefinitionKind} from './types/lightweight-definition-kind.js';
|
||||
import {LightweightProject} from './types/lightweight-project.js';
|
||||
import {LightweightType} from './types/lightweight-type.js';
|
||||
import {keyBy} from '@openstapps/collection-utils';
|
||||
|
||||
/**
|
||||
* Creates a printable name of a type
|
||||
*/
|
||||
export function expandTypeValue(type: LightweightType): string | undefined {
|
||||
if (type.isArray) {
|
||||
return `${type.value}[]`;
|
||||
}
|
||||
if (isStringLiteralType(type)) {
|
||||
return `'${type.value}'`;
|
||||
}
|
||||
if (isUnionOrIntersectionType(type)) {
|
||||
return type.specificationTypes?.map(expandTypeValue).join(isUnionType(type) ? ' | ' : ' & ');
|
||||
}
|
||||
if (type.genericsTypes?.length === 0) {
|
||||
return `${type.value}<${type.genericsTypes?.map(expandTypeValue).join(', ')}>`;
|
||||
}
|
||||
|
||||
return type.value?.toString();
|
||||
}
|
||||
|
||||
export function definitionsOf(project: LightweightProject): Record<string, LightweightDefinition> {
|
||||
return keyBy(Object.values(project).flatMap(Object.values), it => it.name);
|
||||
}
|
||||
|
||||
export function isPrimitiveType(type: {flags: ts.TypeFlags}): boolean {
|
||||
return (type.flags & ts.TypeFlags.NonPrimitive) === 0;
|
||||
}
|
||||
|
||||
export function isLiteralType(type: {flags: ts.TypeFlags}): boolean {
|
||||
return (type.flags & ts.TypeFlags.Literal) !== 0;
|
||||
}
|
||||
|
||||
export function isEnumLiteralType(type: {flags: ts.TypeFlags}): boolean {
|
||||
return (type.flags & ts.TypeFlags.EnumLiteral) !== 0;
|
||||
}
|
||||
|
||||
export function isStringLiteralType(type: {flags: ts.TypeFlags}): boolean {
|
||||
return (type.flags & ts.TypeFlags.StringLiteral) !== 0;
|
||||
}
|
||||
|
||||
export function isUnionOrIntersectionType(type: {flags: ts.TypeFlags}): boolean {
|
||||
return (type.flags & ts.TypeFlags.UnionOrIntersection) !== 0;
|
||||
}
|
||||
|
||||
export function isUnionType(type: {flags: ts.TypeFlags}): boolean {
|
||||
return (type.flags & ts.TypeFlags.Union) !== 0;
|
||||
}
|
||||
|
||||
export function isLightweightClass(node?: LightweightDefinition): node is LightweightClassDefinition {
|
||||
return node?.kind === LightweightDefinitionKind.CLASS_LIKE;
|
||||
}
|
||||
|
||||
export function isLightweightEnum(node?: LightweightDefinition): node is LightweightAliasDefinition {
|
||||
return node?.kind === LightweightDefinitionKind.ALIAS_LIKE;
|
||||
}
|
||||
|
||||
export function isTypeVariable(type: {flags: ts.TypeFlags}): boolean {
|
||||
return (type.flags & ts.TypeFlags.TypeVariable) !== 0;
|
||||
}
|
||||
255
packages/easy-ast/src/easy-ast.ts
Normal file
255
packages/easy-ast/src/easy-ast.ts
Normal file
@@ -0,0 +1,255 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import ts from 'typescript';
|
||||
import {cleanupEmpty, mapNotNil, rejectNil, expandPathToFilesSync} from './util.js';
|
||||
import {
|
||||
extractComment,
|
||||
filterChildrenTo,
|
||||
filterNodeTo,
|
||||
getModifiers,
|
||||
isArrayLikeType,
|
||||
isClassLikeNode,
|
||||
isEnumLikeNode,
|
||||
isProperty,
|
||||
resolvePropertyName,
|
||||
resolveTypeName,
|
||||
} from './ast-internal-util.js';
|
||||
import {isEnumLiteralType, isTypeVariable} from './ast-util.js';
|
||||
import {LightweightAliasDefinition} from './types/lightweight-alias-definition.js';
|
||||
import {LightweightClassDefinition} from './types/lightweight-class-definition.js';
|
||||
import {LightweightDefinition} from './types/lightweight-definition.js';
|
||||
import {LightweightDefinitionKind} from './types/lightweight-definition-kind.js';
|
||||
import {LightweightProject} from './types/lightweight-project.js';
|
||||
import {LightweightType} from './types/lightweight-type.js';
|
||||
import path from 'path';
|
||||
import {LightweightProperty} from './types/lightweight-property.js';
|
||||
import {mapValues, groupBy, keyBy} from '@openstapps/collection-utils';
|
||||
|
||||
/**
|
||||
* Convert a TypeScript project to a lightweight Type-AST representation of the project
|
||||
*
|
||||
* @param sourcePath either a directory or a set of input files
|
||||
* @param includeComments if comments should be included (default true)
|
||||
*/
|
||||
export function lightweightProjectFromPath(
|
||||
sourcePath: string | string[],
|
||||
includeComments = true,
|
||||
): LightweightProject {
|
||||
return new LightweightDefinitionBuilder(sourcePath, includeComments).convert();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a TypeScript project to a set of lightweight definition ASTs
|
||||
*
|
||||
* @param sourcePath either a directory or a set of input files
|
||||
* @param includeComments if comments should be included (default true)
|
||||
*/
|
||||
export function lightweightDefinitionsFromPath(
|
||||
sourcePath: string | string[],
|
||||
includeComments = true,
|
||||
): LightweightDefinition[] {
|
||||
return rejectNil(new LightweightDefinitionBuilder(sourcePath, includeComments).convertToList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the reflection model and converts it into a flatter, easier to handle model
|
||||
*/
|
||||
class LightweightDefinitionBuilder {
|
||||
readonly program: ts.Program;
|
||||
|
||||
readonly sourceFiles: readonly ts.SourceFile[];
|
||||
|
||||
readonly typeChecker: ts.TypeChecker;
|
||||
|
||||
constructor(sourcePath: string | string[], readonly includeComments: boolean) {
|
||||
const rootNames = Array.isArray(sourcePath)
|
||||
? sourcePath
|
||||
: expandPathToFilesSync(path.resolve(sourcePath), file => file.endsWith('ts'));
|
||||
|
||||
this.program = ts.createProgram({
|
||||
rootNames: rootNames,
|
||||
options: {
|
||||
alwaysStrict: true,
|
||||
charset: 'utf8',
|
||||
declaration: true,
|
||||
esModuleInterop: true,
|
||||
experimentalDecorators: true,
|
||||
inlineSourceMap: true,
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
strict: true,
|
||||
target: ts.ScriptTarget.ES2015,
|
||||
},
|
||||
});
|
||||
|
||||
this.typeChecker = this.program.getTypeChecker();
|
||||
this.sourceFiles = mapNotNil(this.program.getRootFileNames(), it => this.program.getSourceFile(it));
|
||||
}
|
||||
|
||||
private convertAliasLike(
|
||||
enumLike: ts.EnumDeclaration | ts.TypeAliasDeclaration,
|
||||
): LightweightAliasDefinition {
|
||||
return cleanupEmpty({
|
||||
comment: this.includeComments ? extractComment(enumLike) : undefined,
|
||||
name: enumLike.name.getText() ?? 'ERROR',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: getModifiers(enumLike.getText(), ts.isEnumDeclaration(enumLike) ? 'enum' : 'type'),
|
||||
type: ts.isEnumDeclaration(enumLike)
|
||||
? enumLike.members.length > 0
|
||||
? {
|
||||
flags: 1_048_576,
|
||||
specificationTypes: enumLike.members.map(it => this.lightweightTypeAtNode(it)),
|
||||
}
|
||||
: undefined
|
||||
: this.lightweightTypeFromType(this.typeChecker.getTypeFromTypeNode(enumLike.type), enumLike.type),
|
||||
});
|
||||
}
|
||||
|
||||
private convertClassLike(
|
||||
classLike: ts.ClassDeclaration | ts.InterfaceDeclaration,
|
||||
): LightweightClassDefinition {
|
||||
const heritages = mapValues(
|
||||
groupBy([...classLike.heritageClauses!], it => it.token.toString()),
|
||||
heritages => heritages.flatMap(it => it.types),
|
||||
);
|
||||
|
||||
return cleanupEmpty({
|
||||
comment: this.includeComments ? extractComment(classLike) : undefined,
|
||||
name: classLike.name?.escapedText ?? 'ERROR',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: getModifiers(classLike.getText(), ts.isClassDeclaration(classLike) ? 'class' : 'interface'),
|
||||
extendedDefinitions: heritages[ts.SyntaxKind.ExtendsKeyword]?.map(it => this.lightweightTypeAtNode(it)),
|
||||
implementedDefinitions: heritages[ts.SyntaxKind.ImplementsKeyword]?.map(it =>
|
||||
this.lightweightTypeAtNode(it),
|
||||
),
|
||||
indexSignatures: keyBy(
|
||||
filterNodeTo(
|
||||
classLike.members as ts.NodeArray<ts.ClassElement | ts.TypeElement>,
|
||||
ts.isIndexSignatureDeclaration,
|
||||
).map(indexSignature =>
|
||||
cleanupEmpty({
|
||||
name:
|
||||
this.typeChecker.getSignatureFromDeclaration(indexSignature)?.parameters?.[0]?.escapedName ??
|
||||
'UNRESOLVED_INDEX_SIGNATURE',
|
||||
type: this.lightweightTypeFromType(
|
||||
this.typeChecker.getTypeFromTypeNode(indexSignature.type),
|
||||
indexSignature.type,
|
||||
),
|
||||
indexSignatureType: this.lightweightTypeFromType(
|
||||
this.typeChecker.getTypeFromTypeNode(indexSignature.parameters[0].type!),
|
||||
indexSignature.parameters[0].type!,
|
||||
),
|
||||
}),
|
||||
),
|
||||
it => it.name,
|
||||
),
|
||||
typeParameters: classLike.typeParameters?.map(it => it.name.getText()),
|
||||
properties: this.collectProperties(classLike.members),
|
||||
});
|
||||
}
|
||||
|
||||
collectProperties(
|
||||
members: ts.NodeArray<ts.ClassElement | ts.TypeElement>,
|
||||
): Record<string, LightweightProperty> {
|
||||
return keyBy(
|
||||
filterNodeTo(members as ts.NodeArray<ts.ClassElement | ts.TypeElement>, isProperty).map(property =>
|
||||
cleanupEmpty({
|
||||
comment: this.includeComments ? extractComment(property) : undefined,
|
||||
name: resolvePropertyName(property.name) ?? property.getText(),
|
||||
type: this.lightweightTypeAtNode(property),
|
||||
properties: this.collectProperties((property.type as ts.TypeLiteralNode)?.members),
|
||||
optional: ts.isPropertyDeclaration(property)
|
||||
? property.questionToken === undefined
|
||||
? undefined
|
||||
: true
|
||||
: undefined,
|
||||
}),
|
||||
),
|
||||
it => it.name,
|
||||
);
|
||||
}
|
||||
|
||||
private lightweightTypeAtNode(node: ts.Node): LightweightType {
|
||||
const type = this.typeChecker.getTypeAtLocation(node);
|
||||
|
||||
return this.lightweightTypeFromType(type, this.typeChecker.typeToTypeNode(type, node, undefined));
|
||||
}
|
||||
|
||||
private lightweightTypeFromType(type: ts.Type, typeNode?: ts.TypeNode): LightweightType {
|
||||
if (typeNode?.kind === ts.SyntaxKind.ConditionalType) {
|
||||
return {value: 'UNSUPPORTED_CONDITIONAL_TYPE', flags: ts.TypeFlags.Unknown};
|
||||
}
|
||||
if (isArrayLikeType(typeNode)) {
|
||||
const elementType = ts.isArrayTypeNode(typeNode) ? typeNode.elementType : typeNode.typeArguments?.[0]!;
|
||||
const out = this.lightweightTypeFromType(
|
||||
this.typeChecker.getTypeFromTypeNode(elementType),
|
||||
elementType,
|
||||
);
|
||||
out.isArray = true;
|
||||
|
||||
return out;
|
||||
}
|
||||
const isReference =
|
||||
typeNode !== undefined && ts.isTypeReferenceNode(typeNode) && !isEnumLiteralType(type);
|
||||
const isTypeLiteral = typeNode !== undefined && ts.isTypeLiteralNode(typeNode);
|
||||
// @ts-expect-error intrinsic name & value exist
|
||||
const intrinsicName = (type.intrinsicName ?? type.value) as string | undefined;
|
||||
|
||||
return cleanupEmpty({
|
||||
value: intrinsicName,
|
||||
referenceName: isTypeLiteral
|
||||
? undefined
|
||||
: resolveTypeName(typeNode) ?? (type.symbol?.escapedName as string | undefined),
|
||||
flags: type.flags,
|
||||
genericsTypes: isTypeVariable(type)
|
||||
? undefined
|
||||
: this.typeChecker
|
||||
.getApparentType(type)
|
||||
// @ts-expect-error resolvedTypeArguments exits
|
||||
?.resolvedTypeArguments?.filter(it => !it.isThisType)
|
||||
?.map((it: ts.Type) => this.lightweightTypeFromType(it)),
|
||||
specificationTypes:
|
||||
type.isUnionOrIntersection() && !isReference
|
||||
? type.types.map(it =>
|
||||
this.lightweightTypeFromType(it, this.typeChecker.typeToTypeNode(it, undefined, undefined)),
|
||||
)
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the conversion process
|
||||
*/
|
||||
convert(): LightweightProject {
|
||||
return mapValues(
|
||||
keyBy([...this.sourceFiles], it => it.fileName),
|
||||
file =>
|
||||
keyBy(
|
||||
[
|
||||
...filterChildrenTo(file, isClassLikeNode).map(it => this.convertClassLike(it)),
|
||||
...filterChildrenTo(file, isEnumLikeNode).map(it => this.convertAliasLike(it)),
|
||||
],
|
||||
it => it.name,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as conversion, but generates a simple list of all definitions.
|
||||
*/
|
||||
convertToList(): LightweightDefinition[] {
|
||||
return Object.values(this.convert()).flatMap(it => it.values);
|
||||
}
|
||||
}
|
||||
25
packages/easy-ast/src/index.ts
Normal file
25
packages/easy-ast/src/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export * from './easy-ast.js'
|
||||
export * from './ast-util.js'
|
||||
|
||||
export * from './types/lightweight-alias-definition.js'
|
||||
export * from './types/lightweight-class-definition.js'
|
||||
export * from './types/lightweight-comment.js'
|
||||
export * from './types/lightweight-definition.js'
|
||||
export * from './types/lightweight-definition-kind.js'
|
||||
export * from './types/lightweight-project.js'
|
||||
export * from './types/lightweight-property.js'
|
||||
export * from './types/lightweight-type.js'
|
||||
32
packages/easy-ast/src/types/lightweight-alias-definition.ts
Normal file
32
packages/easy-ast/src/types/lightweight-alias-definition.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {LightweightDefinitionBase} from './lightweight-definition.js';
|
||||
import {LightweightDefinitionKind} from './lightweight-definition-kind.js';
|
||||
import {LightweightType} from './lightweight-type.js';
|
||||
/**
|
||||
* Represents an enum definition
|
||||
*/
|
||||
export interface LightweightAliasDefinition extends LightweightDefinitionBase {
|
||||
/**
|
||||
* Kind
|
||||
*/
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE;
|
||||
|
||||
/**
|
||||
* Enumeration or union values
|
||||
*/
|
||||
type?: LightweightType;
|
||||
}
|
||||
54
packages/easy-ast/src/types/lightweight-class-definition.ts
Normal file
54
packages/easy-ast/src/types/lightweight-class-definition.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {LightweightDefinitionBase} from './lightweight-definition.js';
|
||||
import {LightweightDefinitionKind} from './lightweight-definition-kind.js';
|
||||
import {LightweightIndexSignature, LightweightProperty} from './lightweight-property.js';
|
||||
import {LightweightType} from './lightweight-type.js';
|
||||
|
||||
/**
|
||||
* Represents a class definition
|
||||
*/
|
||||
export interface LightweightClassDefinition extends LightweightDefinitionBase {
|
||||
/**
|
||||
* String values of the extended definitions
|
||||
*/
|
||||
extendedDefinitions?: LightweightType[];
|
||||
|
||||
/**
|
||||
* String values of the implemented definitions
|
||||
*/
|
||||
implementedDefinitions?: LightweightType[];
|
||||
|
||||
/**
|
||||
* Index signatures
|
||||
*/
|
||||
indexSignatures?: Record<string, LightweightIndexSignature>;
|
||||
|
||||
/**
|
||||
* Kind
|
||||
*/
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE;
|
||||
|
||||
/**
|
||||
* Properties of the definition
|
||||
*/
|
||||
properties?: Record<string, LightweightProperty>;
|
||||
|
||||
/**
|
||||
* Generic type parameters of this class
|
||||
*/
|
||||
typeParameters?: string[];
|
||||
}
|
||||
48
packages/easy-ast/src/types/lightweight-comment.ts
Normal file
48
packages/easy-ast/src/types/lightweight-comment.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* Represents a Comment
|
||||
*/
|
||||
export interface LightweightComment {
|
||||
/**
|
||||
* Description of the comment
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
/**
|
||||
* Short summary of the comment
|
||||
*/
|
||||
shortSummary?: string;
|
||||
|
||||
/**
|
||||
* Tags of the comment
|
||||
*/
|
||||
tags?: LightweightCommentTag[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Lightweight comment tag
|
||||
*/
|
||||
export interface LightweightCommentTag {
|
||||
/**
|
||||
* The name of the tag
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* The parameters of the tag
|
||||
*/
|
||||
parameters?: string[];
|
||||
}
|
||||
19
packages/easy-ast/src/types/lightweight-definition-kind.ts
Normal file
19
packages/easy-ast/src/types/lightweight-definition-kind.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export enum LightweightDefinitionKind {
|
||||
CLASS_LIKE = 'class-like',
|
||||
ALIAS_LIKE = 'alias-like',
|
||||
}
|
||||
46
packages/easy-ast/src/types/lightweight-definition.ts
Normal file
46
packages/easy-ast/src/types/lightweight-definition.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {LightweightDefinitionKind} from './lightweight-definition-kind.js';
|
||||
import {LightweightComment} from './lightweight-comment.js';
|
||||
import {LightweightClassDefinition} from './lightweight-class-definition.js';
|
||||
import {LightweightAliasDefinition} from './lightweight-alias-definition.js';
|
||||
|
||||
export type LightweightDefinition = LightweightClassDefinition | LightweightAliasDefinition;
|
||||
|
||||
/**
|
||||
* Represents any definition without specifics
|
||||
*/
|
||||
export interface LightweightDefinitionBase {
|
||||
/**
|
||||
* The comment of the definition
|
||||
*/
|
||||
comment?: LightweightComment;
|
||||
|
||||
/**
|
||||
* Kind of the definition
|
||||
*/
|
||||
kind: LightweightDefinitionKind;
|
||||
|
||||
/**
|
||||
* The definition type
|
||||
* e.g. [`abstract`, `class`] or [`enum`] or [`export`, `type`]
|
||||
*/
|
||||
modifiers?: string[];
|
||||
|
||||
/**
|
||||
* Name of the definition
|
||||
*/
|
||||
name: string;
|
||||
}
|
||||
101
packages/easy-ast/src/types/lightweight-project.ts
Normal file
101
packages/easy-ast/src/types/lightweight-project.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {mapNotNil} from '../util.js';
|
||||
import {definitionsOf, isLightweightClass} from '../ast-util.js';
|
||||
import {lightweightProjectFromPath} from '../easy-ast.js';
|
||||
import {LightweightClassDefinition} from './lightweight-class-definition.js';
|
||||
import {LightweightDefinition} from './lightweight-definition.js';
|
||||
|
||||
/**
|
||||
* Build an index for a lightweight project
|
||||
*/
|
||||
function buildIndex(project: LightweightProject): Record<string, string> {
|
||||
return Object.fromEntries(
|
||||
Object.values(project).flatMap((definitions, file) =>
|
||||
Object.keys(definitions).map(definition => [definition, file.toString()]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A lightweight definition class for more advanced use cases
|
||||
*/
|
||||
export class LightweightProjectWithIndex {
|
||||
/**
|
||||
* All definitions
|
||||
*/
|
||||
readonly definitions: Record<string, LightweightDefinition>;
|
||||
|
||||
/**
|
||||
* Project
|
||||
*/
|
||||
readonly files: LightweightProject;
|
||||
|
||||
/**
|
||||
* Index of all definitions to their respective files
|
||||
*/
|
||||
readonly index: {
|
||||
[definitionName: string]: string;
|
||||
};
|
||||
|
||||
constructor(project: LightweightProject | string) {
|
||||
this.files = typeof project === 'string' ? lightweightProjectFromPath(project) : project;
|
||||
this.index = buildIndex(this.files);
|
||||
this.definitions = definitionsOf(this.files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply inherited classes; default deeply
|
||||
*/
|
||||
applyInheritance(classLike: LightweightClassDefinition, deep?: boolean): LightweightDefinition {
|
||||
return Object.assign(
|
||||
mapNotNil(
|
||||
[...(classLike.implementedDefinitions ?? []), ...(classLike.extendedDefinitions ?? [])],
|
||||
extension => {
|
||||
const object = this.definitions[extension.referenceName ?? ''];
|
||||
|
||||
return (deep ?? true) && isLightweightClass(object)
|
||||
? this.applyInheritance(object)
|
||||
: JSON.parse(JSON.stringify(object));
|
||||
},
|
||||
),
|
||||
JSON.parse(JSON.stringify(classLike)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a definition
|
||||
*
|
||||
* Requires the program to be run with `--require ts-node/register`
|
||||
*/
|
||||
async instantiateDefinitionByName<T>(name: string, findCompiledModule = true): Promise<T | undefined> {
|
||||
const fsPath = this.index[name];
|
||||
if (fsPath === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const module = await import(findCompiledModule ? `${fsPath.replace(/\.d\.ts$/, '')}.js` : fsPath);
|
||||
|
||||
return new module[name]() as T;
|
||||
}
|
||||
}
|
||||
|
||||
export interface LightweightFile {
|
||||
[definitionName: string]: LightweightDefinition;
|
||||
}
|
||||
|
||||
export interface LightweightProject {
|
||||
[sourcePath: string]: LightweightFile;
|
||||
}
|
||||
53
packages/easy-ast/src/types/lightweight-property.ts
Normal file
53
packages/easy-ast/src/types/lightweight-property.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {LightweightComment} from './lightweight-comment.js';
|
||||
import {LightweightType} from './lightweight-type.js';
|
||||
|
||||
/**
|
||||
* Represents a property definition
|
||||
*/
|
||||
export interface LightweightProperty {
|
||||
/**
|
||||
* The comment of the property
|
||||
*/
|
||||
comment?: LightweightComment;
|
||||
|
||||
/**
|
||||
* Name of the property
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Is the property marked as optional
|
||||
*/
|
||||
optional?: true;
|
||||
|
||||
/**
|
||||
* A record of properties if the property happens to be a type literal
|
||||
*/
|
||||
properties?: Record<string, LightweightProperty>;
|
||||
|
||||
/**
|
||||
* Type of the property
|
||||
*/
|
||||
type: LightweightType;
|
||||
}
|
||||
|
||||
export interface LightweightIndexSignature extends LightweightProperty {
|
||||
/**
|
||||
* Type of the index signature, if it is an index signature
|
||||
*/
|
||||
indexSignatureType: LightweightType;
|
||||
}
|
||||
58
packages/easy-ast/src/types/lightweight-type.ts
Normal file
58
packages/easy-ast/src/types/lightweight-type.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {TypeFlags} from 'typescript';
|
||||
|
||||
/**
|
||||
* Describes an easy to use type definition.
|
||||
*/
|
||||
export interface LightweightType {
|
||||
/**
|
||||
* Type Flags
|
||||
*/
|
||||
flags: TypeFlags;
|
||||
|
||||
/**
|
||||
* Contains all types inside of <> brackets
|
||||
*/
|
||||
genericsTypes?: LightweightType[];
|
||||
|
||||
/**
|
||||
* If it is an array(-like) type
|
||||
*/
|
||||
isArray?: true;
|
||||
|
||||
/**
|
||||
* If it is a type parameter
|
||||
*/
|
||||
isTypeParameter?: true;
|
||||
|
||||
/**
|
||||
* The name of the type that is referenced. Enum members have reference names that lead no where.
|
||||
*/
|
||||
referenceName?: string;
|
||||
|
||||
/**
|
||||
* Type specifications, if the type is combined by either an array, union or a typeOperator
|
||||
*/
|
||||
specificationTypes?: LightweightType[];
|
||||
|
||||
/**
|
||||
* Value of the type
|
||||
*
|
||||
* Literal types have their value here, non-literals their type name (for example 'string')
|
||||
*/
|
||||
value?: string | number | boolean;
|
||||
}
|
||||
61
packages/easy-ast/src/util.ts
Normal file
61
packages/easy-ast/src/util.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import path from "path";
|
||||
import {readdirSync, statSync} from "fs";
|
||||
|
||||
/**
|
||||
* Filters only defined elements
|
||||
*/
|
||||
export function rejectNil<T>(array: Array<T | undefined | null>): T[] {
|
||||
// eslint-disable-next-line unicorn/no-null
|
||||
return array.filter(it => it == null) as T[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Map elements that are not null
|
||||
*/
|
||||
export function mapNotNil<T, S>(array: readonly T[], transform: (element: T) => S | undefined | null): S[] {
|
||||
return rejectNil(array.map(transform));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all properties with the value 'undefined', [] or {}
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function cleanupEmpty<T extends object>(object: T): T {
|
||||
const out = {} as T;
|
||||
for (const key in object) {
|
||||
const value = object[key];
|
||||
// eslint-disable-next-line unicorn/no-null
|
||||
if (value != null && (typeof value !== 'object' || Object.values(value).length > 0)) {
|
||||
out[key] = value;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand a path to a list of all files deeply contained in it
|
||||
*/
|
||||
export function expandPathToFilesSync(sourcePath: string, accept: (fileName: string) => boolean): string[] {
|
||||
const fullPath = path.resolve(sourcePath);
|
||||
const directory = statSync(fullPath);
|
||||
|
||||
return directory.isDirectory()
|
||||
? readdirSync(fullPath).flatMap(fragment =>
|
||||
expandPathToFilesSync(path.resolve(sourcePath, fragment), accept),
|
||||
)
|
||||
: [fullPath].filter(accept);
|
||||
}
|
||||
68
packages/easy-ast/test/alias-like.ast-test.ts
Normal file
68
packages/easy-ast/test/alias-like.ast-test.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
type TestTypeAlias = number | string;
|
||||
|
||||
enum TestEnum {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve alias-likes`,
|
||||
expected: {
|
||||
TestTypeAlias: {
|
||||
name: 'TestTypeAlias',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['type'],
|
||||
type: {
|
||||
flags: 1_048_576,
|
||||
specificationTypes: [
|
||||
{
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
},
|
||||
{
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
TestEnum: {
|
||||
name: 'TestEnum',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['enum'],
|
||||
type: {
|
||||
flags: 1_048_576,
|
||||
specificationTypes: [
|
||||
{
|
||||
referenceName: 'Foo',
|
||||
value: 0,
|
||||
flags: 1280,
|
||||
},
|
||||
{
|
||||
referenceName: 'Bar',
|
||||
value: 1,
|
||||
flags: 1280,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
75
packages/easy-ast/test/array-like.ast-test.ts
Normal file
75
packages/easy-ast/test/array-like.ast-test.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-interface */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface Random {}
|
||||
|
||||
type TestArrayGeneric = Array<string>;
|
||||
type TestArrayLiteral = number[];
|
||||
type TestArrayReferenceGeneric = Array<Random>;
|
||||
type TestArrayReferenceLiteral = Random[];
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve array-likes`,
|
||||
expected: {
|
||||
TestArrayGeneric: {
|
||||
name: 'TestArrayGeneric',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['type'],
|
||||
type: {
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
isArray: true,
|
||||
},
|
||||
},
|
||||
TestArrayLiteral: {
|
||||
name: 'TestArrayLiteral',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['type'],
|
||||
type: {
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
isArray: true,
|
||||
},
|
||||
},
|
||||
TestArrayReferenceGeneric: {
|
||||
name: 'TestArrayReferenceGeneric',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['type'],
|
||||
type: {
|
||||
referenceName: 'Random',
|
||||
flags: 524_288,
|
||||
isArray: true,
|
||||
},
|
||||
},
|
||||
TestArrayReferenceLiteral: {
|
||||
name: 'TestArrayReferenceLiteral',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['type'],
|
||||
type: {
|
||||
referenceName: 'Random',
|
||||
flags: 524_288,
|
||||
isArray: true,
|
||||
},
|
||||
},
|
||||
Random: {
|
||||
name: 'Random',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
},
|
||||
},
|
||||
};
|
||||
59
packages/easy-ast/test/class-like.ast-test.ts
Normal file
59
packages/easy-ast/test/class-like.ast-test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-inferrable-types */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface TestInterface {
|
||||
foo: number;
|
||||
}
|
||||
|
||||
class TestClass {
|
||||
bar: string = 'test';
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve class-likes`,
|
||||
expected: {
|
||||
TestInterface: {
|
||||
name: 'TestInterface',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
properties: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: {
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TestClass: {
|
||||
name: 'TestClass',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['class'],
|
||||
properties: {
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: {
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
161
packages/easy-ast/test/comment.ast-test.ts
Normal file
161
packages/easy-ast/test/comment.ast-test.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars,jsdoc/check-tag-names */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
/**
|
||||
* Class comment
|
||||
*
|
||||
* Class description
|
||||
*
|
||||
* More description
|
||||
*
|
||||
* @classTag classParameter1 classParameter2
|
||||
*/
|
||||
interface TestInterface {
|
||||
/**
|
||||
* Property comment
|
||||
*
|
||||
* Property description
|
||||
*
|
||||
* More description
|
||||
*
|
||||
* @propertyTag propertyParameter1 propertyParameter2
|
||||
*/
|
||||
foo: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class comment
|
||||
*
|
||||
* Class description
|
||||
*
|
||||
* More description
|
||||
*
|
||||
* @classTag classParameter1 classParameter2
|
||||
*/
|
||||
class TestClass {
|
||||
/**
|
||||
* Property comment
|
||||
*
|
||||
* Property description
|
||||
*
|
||||
* More description
|
||||
*
|
||||
* @propertyTag propertyParameter1 propertyParameter2
|
||||
*/
|
||||
foo = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum comment
|
||||
*
|
||||
* Enum description
|
||||
*
|
||||
* More description
|
||||
*
|
||||
* @enumTag enumParameter1
|
||||
*/
|
||||
enum TestAlias {}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve comments`,
|
||||
expected: {
|
||||
TestInterface: {
|
||||
comment: {
|
||||
shortSummary: 'Class comment',
|
||||
description: 'Class description\n\nMore description',
|
||||
tags: [
|
||||
{
|
||||
name: 'classTag',
|
||||
parameters: ['classParameter1', 'classParameter2'],
|
||||
},
|
||||
],
|
||||
},
|
||||
name: 'TestInterface',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
properties: {
|
||||
foo: {
|
||||
comment: {
|
||||
shortSummary: 'Property comment',
|
||||
description: 'Property description\n\nMore description',
|
||||
tags: [
|
||||
{
|
||||
name: 'propertyTag',
|
||||
parameters: ['propertyParameter1', 'propertyParameter2'],
|
||||
},
|
||||
],
|
||||
},
|
||||
name: 'foo',
|
||||
type: {
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TestClass: {
|
||||
comment: {
|
||||
shortSummary: 'Class comment',
|
||||
description: 'Class description\n\nMore description',
|
||||
tags: [
|
||||
{
|
||||
name: 'classTag',
|
||||
parameters: ['classParameter1', 'classParameter2'],
|
||||
},
|
||||
],
|
||||
},
|
||||
name: 'TestClass',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['class'],
|
||||
properties: {
|
||||
foo: {
|
||||
comment: {
|
||||
shortSummary: 'Property comment',
|
||||
description: 'Property description\n\nMore description',
|
||||
tags: [
|
||||
{
|
||||
name: 'propertyTag',
|
||||
parameters: ['propertyParameter1', 'propertyParameter2'],
|
||||
},
|
||||
],
|
||||
},
|
||||
name: 'foo',
|
||||
type: {
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TestAlias: {
|
||||
comment: {
|
||||
shortSummary: 'Enum comment',
|
||||
description: 'Enum description\n\nMore description',
|
||||
tags: [
|
||||
{
|
||||
name: 'enumTag',
|
||||
parameters: ['enumParameter1'],
|
||||
},
|
||||
],
|
||||
},
|
||||
name: 'TestAlias',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['enum'],
|
||||
},
|
||||
},
|
||||
};
|
||||
66
packages/easy-ast/test/default-generics.ast-test.ts
Normal file
66
packages/easy-ast/test/default-generics.ast-test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface Test1<T = number> {
|
||||
foo: T;
|
||||
}
|
||||
|
||||
interface Test2 {
|
||||
bar: Test1;
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve default generics`,
|
||||
expected: {
|
||||
Test1: {
|
||||
name: 'Test1',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
typeParameters: ['T'],
|
||||
properties: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: {
|
||||
referenceName: 'T',
|
||||
flags: 262_144,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Test2: {
|
||||
name: 'Test2',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
properties: {
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: {
|
||||
referenceName: 'Test1',
|
||||
flags: 524_288,
|
||||
genericsTypes: [
|
||||
{
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
20
packages/easy-ast/test/easy-ast-spec-type.ts
Normal file
20
packages/easy-ast/test/easy-ast-spec-type.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {LightweightFile} from '../../src/easy-ast/types/lightweight-project.js';
|
||||
|
||||
export interface EasyAstSpecType {
|
||||
testName: string;
|
||||
expected: LightweightFile;
|
||||
}
|
||||
73
packages/easy-ast/test/enum-specified-value.ast-test.ts
Normal file
73
packages/easy-ast/test/enum-specified-value.ast-test.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
enum TestAuto {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
enum TestSpecified {
|
||||
YES = 'yes',
|
||||
NO = 'no',
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve auto and specified enums`,
|
||||
expected: {
|
||||
TestAuto: {
|
||||
name: 'TestAuto',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['enum'],
|
||||
type: {
|
||||
flags: 1_048_576,
|
||||
specificationTypes: [
|
||||
{
|
||||
referenceName: 'Foo',
|
||||
value: 0,
|
||||
flags: 1280,
|
||||
},
|
||||
{
|
||||
referenceName: 'Bar',
|
||||
value: 1,
|
||||
flags: 1280,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
TestSpecified: {
|
||||
name: 'TestSpecified',
|
||||
kind: LightweightDefinitionKind.ALIAS_LIKE,
|
||||
modifiers: ['enum'],
|
||||
type: {
|
||||
flags: 1_048_576,
|
||||
specificationTypes: [
|
||||
{
|
||||
referenceName: 'YES',
|
||||
value: 'yes',
|
||||
flags: 1152,
|
||||
},
|
||||
{
|
||||
referenceName: 'NO',
|
||||
value: 'no',
|
||||
flags: 1152,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
80
packages/easy-ast/test/generics.ast-test.ts
Normal file
80
packages/easy-ast/test/generics.ast-test.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface $Random {}
|
||||
|
||||
interface Generics {
|
||||
baz: Foo<number, $Random>;
|
||||
}
|
||||
|
||||
interface Foo<T, S> {
|
||||
foo: T;
|
||||
bar: S;
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve generics`,
|
||||
expected: {
|
||||
Generics: {
|
||||
name: 'Generics',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
properties: {
|
||||
baz: {
|
||||
name: 'baz',
|
||||
type: {
|
||||
referenceName: 'Foo',
|
||||
flags: 524_288,
|
||||
genericsTypes: [
|
||||
{
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
{
|
||||
referenceName: '$Random',
|
||||
flags: 524_288,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Foo: {
|
||||
name: 'Foo',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
typeParameters: ['T', 'S'],
|
||||
properties: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: {
|
||||
referenceName: 'T',
|
||||
flags: 262_144,
|
||||
},
|
||||
},
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: {
|
||||
referenceName: 'S',
|
||||
flags: 262_144,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
69
packages/easy-ast/test/index-signature.ast-test.ts
Normal file
69
packages/easy-ast/test/index-signature.ast-test.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface $Random {}
|
||||
|
||||
interface IndexSignatureObject {
|
||||
[key: string]: $Random;
|
||||
}
|
||||
|
||||
interface IndexSignaturePrimitive {
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should resolve index signatures`,
|
||||
expected: {
|
||||
IndexSignatureObject: {
|
||||
name: 'IndexSignatureObject',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
indexSignatures: {
|
||||
key: {
|
||||
name: 'key',
|
||||
indexSignatureType: {
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
},
|
||||
type: {
|
||||
referenceName: '$Random',
|
||||
flags: 524_288,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IndexSignaturePrimitive: {
|
||||
name: 'IndexSignaturePrimitive',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
indexSignatures: {
|
||||
key: {
|
||||
name: 'key',
|
||||
indexSignatureType: {
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
},
|
||||
type: {
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
35
packages/easy-ast/test/index.ts
Normal file
35
packages/easy-ast/test/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {expandPathToFilesSync, toUnixPath} from '../src/util.js';
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {lightweightProjectFromPath} from '../src/easy-ast.js';
|
||||
import {expect} from 'chai';
|
||||
|
||||
describe('Easy AST', async () => {
|
||||
const project = lightweightProjectFromPath('./test/easy-ast', true);
|
||||
for (const file of expandPathToFilesSync('./test/easy-ast', file => file.endsWith('ast-test.ts'))) {
|
||||
try {
|
||||
const test = (await import(file))['testConfig'] as EasyAstSpecType;
|
||||
|
||||
it(test.testName, () => {
|
||||
expect(omitBy(project[toUnixPath(file)], (_value, key) => key.startsWith('$'))).to.be.deep.equal(
|
||||
test.expected,
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
82
packages/easy-ast/test/ineritance.ast-test.ts
Normal file
82
packages/easy-ast/test/ineritance.ast-test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-inferrable-types */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface $BaseInterface<T> {
|
||||
foo: T;
|
||||
}
|
||||
|
||||
interface $BaseInterface2 {
|
||||
bar: string;
|
||||
}
|
||||
|
||||
class $BaseClass {}
|
||||
|
||||
class InheritingClass extends $BaseClass implements $BaseInterface<number>, $BaseInterface2 {
|
||||
bar: string = '';
|
||||
|
||||
foo: number = 1;
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `inheritance`,
|
||||
expected: {
|
||||
InheritingClass: {
|
||||
name: 'InheritingClass',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['class'],
|
||||
implementedDefinitions: [
|
||||
{
|
||||
referenceName: '$BaseInterface',
|
||||
genericsTypes: [
|
||||
{
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
],
|
||||
flags: 524_288,
|
||||
},
|
||||
{
|
||||
referenceName: '$BaseInterface2',
|
||||
flags: 524_288,
|
||||
},
|
||||
],
|
||||
extendedDefinitions: [
|
||||
{
|
||||
referenceName: '$BaseClass',
|
||||
flags: 524_288,
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: {
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
},
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: {
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
61
packages/easy-ast/test/nested.ast-test.ts
Normal file
61
packages/easy-ast/test/nested.ast-test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface,@typescript-eslint/no-unused-vars */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface NestedObject {
|
||||
nested: {
|
||||
deeplyNested: {
|
||||
aNumber: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should handle nested/type literals`,
|
||||
expected: {
|
||||
NestedObject: {
|
||||
name: 'NestedObject',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
properties: {
|
||||
nested: {
|
||||
name: 'nested',
|
||||
type: {
|
||||
flags: 524_288,
|
||||
},
|
||||
properties: {
|
||||
deeplyNested: {
|
||||
name: 'deeplyNested',
|
||||
type: {
|
||||
flags: 524_288,
|
||||
},
|
||||
properties: {
|
||||
aNumber: {
|
||||
name: 'aNumber',
|
||||
type: {
|
||||
flags: 8,
|
||||
value: 'number',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
99
packages/easy-ast/test/primitive-types.ast-test.ts
Normal file
99
packages/easy-ast/test/primitive-types.ast-test.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-explicit-any */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface Test {
|
||||
number_type: number;
|
||||
string_type: string;
|
||||
boolean_type: boolean;
|
||||
any_type: any;
|
||||
unknown_type: unknown;
|
||||
null_type: null;
|
||||
undefined_type: undefined;
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should interpret primitive types correctly`,
|
||||
expected: {
|
||||
Test: {
|
||||
name: 'Test',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
properties: {
|
||||
number_type: {
|
||||
name: 'number_type',
|
||||
type: {
|
||||
value: 'number',
|
||||
flags: 8,
|
||||
},
|
||||
},
|
||||
string_type: {
|
||||
name: 'string_type',
|
||||
type: {
|
||||
value: 'string',
|
||||
flags: 4,
|
||||
},
|
||||
},
|
||||
boolean_type: {
|
||||
name: 'boolean_type',
|
||||
type: {
|
||||
value: 'boolean',
|
||||
flags: 1_048_592,
|
||||
specificationTypes: [
|
||||
{
|
||||
value: 'false',
|
||||
flags: 512,
|
||||
},
|
||||
{
|
||||
value: 'true',
|
||||
flags: 512,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
any_type: {
|
||||
name: 'any_type',
|
||||
type: {
|
||||
value: 'any',
|
||||
flags: 1,
|
||||
},
|
||||
},
|
||||
unknown_type: {
|
||||
name: 'unknown_type',
|
||||
type: {
|
||||
value: 'unknown',
|
||||
flags: 2,
|
||||
},
|
||||
},
|
||||
null_type: {
|
||||
name: 'null_type',
|
||||
type: {
|
||||
value: 'null',
|
||||
flags: 65_536,
|
||||
},
|
||||
},
|
||||
undefined_type: {
|
||||
name: 'undefined_type',
|
||||
type: {
|
||||
value: 'undefined',
|
||||
flags: 32_768,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
61
packages/easy-ast/test/stack-overflow.ast-test.ts
Normal file
61
packages/easy-ast/test/stack-overflow.ast-test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-explicit-any */
|
||||
/*
|
||||
* Copyright (C) 2021 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {EasyAstSpecType} from './easy-ast-spec-type.js';
|
||||
import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js';
|
||||
|
||||
interface Foo<T extends Bar<string>> {
|
||||
bar: T;
|
||||
}
|
||||
|
||||
interface Bar<T> {
|
||||
foo: T;
|
||||
}
|
||||
|
||||
export const testConfig: EasyAstSpecType = {
|
||||
testName: `should ignore type constraints`,
|
||||
expected: {
|
||||
Foo: {
|
||||
name: 'Foo',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
typeParameters: ['T'],
|
||||
properties: {
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: {
|
||||
referenceName: 'T',
|
||||
flags: 262_144,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Bar: {
|
||||
name: 'Bar',
|
||||
kind: LightweightDefinitionKind.CLASS_LIKE,
|
||||
modifiers: ['interface'],
|
||||
typeParameters: ['T'],
|
||||
properties: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: {
|
||||
referenceName: 'T',
|
||||
flags: 262_144,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
3
packages/easy-ast/tsconfig.json
Normal file
3
packages/easy-ast/tsconfig.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "@openstapps/tsconfig"
|
||||
}
|
||||
Reference in New Issue
Block a user