Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(map): add Map support as a type #228

Merged
merged 5 commits into from
Feb 8, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
},
"FunctionExpression": {
"parameters": "first"
}
},
"SwitchCase": 1
}
],
"@typescript-eslint/interface-name-prefix": "off",
Expand Down
1 change: 1 addition & 0 deletions config/modules/transformer/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const base = require("../base/webpack.base");
module.exports = merge(base({
tsConfigFile: 'config/modules/transformer/tsconfig.json'
}), {
devtool: 'cheap-module-eval-source-map',
uittorio marked this conversation as resolved.
Show resolved Hide resolved
target: "node",
node: {
__dirname: false
Expand Down
196 changes: 97 additions & 99 deletions src/transformer/descriptor/descriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,104 +40,102 @@ import { GetUnionDescriptor } from './union/union';

export function GetDescriptor(node: ts.Node, scope: Scope): ts.Expression {
switch (node.kind) {
case ts.SyntaxKind.TypeAliasDeclaration:
return GetTypeAliasDescriptor(node as ts.TypeAliasDeclaration, scope);
case ts.SyntaxKind.TypeReference:
return GetTypeReferenceDescriptor(node as ts.TypeReferenceNode, scope);
case ts.SyntaxKind.TypeLiteral:
return GetTypeLiteralDescriptor(node as ts.TypeLiteralNode, scope);
case ts.SyntaxKind.InterfaceDeclaration:
return GetInterfaceDeclarationDescriptor(node as ts.InterfaceDeclaration, scope);
case ts.SyntaxKind.ClassDeclaration:
return GetClassDeclarationDescriptor(node as ts.ClassDeclaration, scope);
case ts.SyntaxKind.PropertySignature:
case ts.SyntaxKind.PropertyAssignment:
return GetPropertyDescriptor(node as ts.PropertySignature, scope);
case ts.SyntaxKind.PropertyDeclaration:
return GetPropertyDescriptor(node as ts.PropertyDeclaration, scope);
case ts.SyntaxKind.LiteralType:
return GetLiteralDescriptor(node as ts.LiteralTypeNode, scope);
case ts.SyntaxKind.ExpressionWithTypeArguments:
return GetExpressionWithTypeArgumentsDescriptor(node as ts.ExpressionWithTypeArguments, scope);
case ts.SyntaxKind.Identifier:
return GetIdentifierDescriptor(node as ts.Identifier, scope);
case ts.SyntaxKind.ThisType:
return GetMockFactoryCallForThis(scope.currentMockKey);
case ts.SyntaxKind.ImportSpecifier:
return GetImportDescriptor(node as ts.ImportSpecifier, scope);
case ts.SyntaxKind.TypeParameter:
return GetTypeParameterDescriptor(node as ts.TypeParameterDeclaration, scope);
case ts.SyntaxKind.ImportClause:
return GetImportDescriptor(node as ts.ImportClause, scope);
case ts.SyntaxKind.MethodSignature:
return GetMethodSignatureDescriptor(node as ts.MethodSignature, scope);
case ts.SyntaxKind.FunctionDeclaration:
return GetMethodDeclarationDescriptor(node as ts.FunctionDeclaration, scope);
case ts.SyntaxKind.MethodDeclaration:
return GetMethodDeclarationDescriptor(node as ts.MethodDeclaration, scope);
case ts.SyntaxKind.FunctionType:
return GetFunctionTypeDescriptor(node as ts.FunctionTypeNode, scope);
case ts.SyntaxKind.ConstructSignature:
return GetFunctionTypeDescriptor(node as ts.ConstructSignatureDeclaration, scope);
case ts.SyntaxKind.CallSignature:
return GetFunctionTypeDescriptor(node as ts.CallSignatureDeclaration, scope);
case ts.SyntaxKind.ArrowFunction:
case ts.SyntaxKind.FunctionExpression:
return GetFunctionAssignmentDescriptor(node as ts.ArrowFunction, scope);
case ts.SyntaxKind.ConstructorType:
return GetConstructorTypeDescriptor(node as ts.ConstructorTypeNode, scope);
case ts.SyntaxKind.TypeQuery:
return GetTypeQueryDescriptor(node as ts.TypeQueryNode, scope);
case ts.SyntaxKind.UnionType:
return GetUnionDescriptor(node as ts.UnionTypeNode, scope);
case ts.SyntaxKind.IntersectionType:
return GetIntersectionDescriptor(node as ts.IntersectionTypeNode, scope);
case ts.SyntaxKind.EnumDeclaration:
return GetEnumDeclarationDescriptor(node as ts.EnumDeclaration);
case ts.SyntaxKind.MappedType:
return GetMappedDescriptor(node as ts.MappedTypeNode, scope);
case ts.SyntaxKind.ParenthesizedType:
return GetParenthesizedDescriptor(node as ts.ParenthesizedTypeNode, scope);
case ts.SyntaxKind.ArrayType:
case ts.SyntaxKind.TupleType:
return GetArrayDescriptor();
case ts.SyntaxKind.StringKeyword:
return GetStringDescriptor();
case ts.SyntaxKind.NumberKeyword:
return GetNumberDescriptor();
case ts.SyntaxKind.TrueKeyword:
return GetBooleanTrueDescriptor();
case ts.SyntaxKind.FalseKeyword:
return GetBooleanFalseDescriptor();
case ts.SyntaxKind.NumericLiteral:
case ts.SyntaxKind.StringLiteral:
return GetLiteralDescriptor(node as ts.LiteralTypeNode, scope);
case ts.SyntaxKind.ObjectLiteralExpression:
return GetObjectLiteralDescriptor(node as ts.ObjectLiteralExpression, scope);
case ts.SyntaxKind.IndexedAccessType:
return GetIndexedAccessTypeDescriptor(node as ts.IndexedAccessTypeNode, scope);
case ts.SyntaxKind.BooleanKeyword:
case ts.SyntaxKind.TypePredicate:
case ts.SyntaxKind.FirstTypeNode:
return GetBooleanDescriptor();
case ts.SyntaxKind.ObjectKeyword:
return GetMockPropertiesFromSymbol([], [], scope);
case ts.SyntaxKind.NullKeyword:
return GetNullDescriptor();
case ts.SyntaxKind.ImportEqualsDeclaration:
return GetImportEqualsDescriptor(node as ts.ImportEqualsDeclaration, scope);
case ts.SyntaxKind.BigIntKeyword:
return GetBigIntDescriptor();
case ts.SyntaxKind.AnyKeyword:
case ts.SyntaxKind.NeverKeyword:
case ts.SyntaxKind.UnknownKeyword:
case ts.SyntaxKind.UndefinedKeyword:
case ts.SyntaxKind.VoidKeyword:
return GetUndefinedDescriptor();
case ts.SyntaxKind.CallExpression:
return node as ts.CallExpression;
default:
TransformerLogger().typeNotSupported(ts.SyntaxKind[node.kind]);
return GetNullDescriptor();
case ts.SyntaxKind.TypeAliasDeclaration:
return GetTypeAliasDescriptor(node as ts.TypeAliasDeclaration, scope);
case ts.SyntaxKind.TypeReference:
return GetTypeReferenceDescriptor(node as ts.TypeReferenceNode, scope);
case ts.SyntaxKind.TypeLiteral:
return GetTypeLiteralDescriptor(node as ts.TypeLiteralNode, scope);
case ts.SyntaxKind.InterfaceDeclaration:
return GetInterfaceDeclarationDescriptor(node as ts.InterfaceDeclaration, scope);
case ts.SyntaxKind.ClassDeclaration:
return GetClassDeclarationDescriptor(node as ts.ClassDeclaration, scope);
case ts.SyntaxKind.PropertySignature:
case ts.SyntaxKind.PropertyAssignment:
return GetPropertyDescriptor(node as ts.PropertySignature, scope);
case ts.SyntaxKind.PropertyDeclaration:
return GetPropertyDescriptor(node as ts.PropertyDeclaration, scope);
case ts.SyntaxKind.LiteralType:
return GetLiteralDescriptor(node as ts.LiteralTypeNode, scope);
case ts.SyntaxKind.ExpressionWithTypeArguments:
return GetExpressionWithTypeArgumentsDescriptor(node as ts.ExpressionWithTypeArguments, scope);
case ts.SyntaxKind.Identifier:
return GetIdentifierDescriptor(node as ts.Identifier, scope);
case ts.SyntaxKind.ThisType:
return GetMockFactoryCallForThis(scope.currentMockKey);
case ts.SyntaxKind.ImportSpecifier:
return GetImportDescriptor(node as ts.ImportSpecifier, scope);
case ts.SyntaxKind.TypeParameter:
return GetTypeParameterDescriptor(node as ts.TypeParameterDeclaration, scope);
case ts.SyntaxKind.ImportClause:
return GetImportDescriptor(node as ts.ImportClause, scope);
case ts.SyntaxKind.MethodSignature:
return GetMethodSignatureDescriptor(node as ts.MethodSignature, scope);
case ts.SyntaxKind.FunctionDeclaration:
return GetMethodDeclarationDescriptor(node as ts.FunctionDeclaration, scope);
case ts.SyntaxKind.MethodDeclaration:
return GetMethodDeclarationDescriptor(node as ts.MethodDeclaration, scope);
case ts.SyntaxKind.FunctionType:
return GetFunctionTypeDescriptor(node as ts.FunctionTypeNode, scope);
case ts.SyntaxKind.ConstructSignature:
return GetFunctionTypeDescriptor(node as ts.ConstructSignatureDeclaration, scope);
case ts.SyntaxKind.CallSignature:
return GetFunctionTypeDescriptor(node as ts.CallSignatureDeclaration, scope);
case ts.SyntaxKind.ArrowFunction:
case ts.SyntaxKind.FunctionExpression:
return GetFunctionAssignmentDescriptor(node as ts.ArrowFunction, scope);
case ts.SyntaxKind.ConstructorType:
return GetConstructorTypeDescriptor(node as ts.ConstructorTypeNode, scope);
case ts.SyntaxKind.TypeQuery:
return GetTypeQueryDescriptor(node as ts.TypeQueryNode, scope);
case ts.SyntaxKind.UnionType:
return GetUnionDescriptor(node as ts.UnionTypeNode, scope);
case ts.SyntaxKind.IntersectionType:
return GetIntersectionDescriptor(node as ts.IntersectionTypeNode, scope);
case ts.SyntaxKind.EnumDeclaration:
return GetEnumDeclarationDescriptor(node as ts.EnumDeclaration);
case ts.SyntaxKind.MappedType:
return GetMappedDescriptor(node as ts.MappedTypeNode, scope);
case ts.SyntaxKind.ParenthesizedType:
return GetParenthesizedDescriptor(node as ts.ParenthesizedTypeNode, scope);
case ts.SyntaxKind.ArrayType:
case ts.SyntaxKind.TupleType:
return GetArrayDescriptor();
case ts.SyntaxKind.StringKeyword:
return GetStringDescriptor();
case ts.SyntaxKind.NumberKeyword:
return GetNumberDescriptor();
case ts.SyntaxKind.TrueKeyword:
return GetBooleanTrueDescriptor();
case ts.SyntaxKind.FalseKeyword:
return GetBooleanFalseDescriptor();
case ts.SyntaxKind.NumericLiteral:
case ts.SyntaxKind.StringLiteral:
return GetLiteralDescriptor(node as ts.LiteralTypeNode, scope);
case ts.SyntaxKind.ObjectLiteralExpression:
return GetObjectLiteralDescriptor(node as ts.ObjectLiteralExpression, scope);
case ts.SyntaxKind.IndexedAccessType:
return GetIndexedAccessTypeDescriptor(node as ts.IndexedAccessTypeNode, scope);
case ts.SyntaxKind.BooleanKeyword:
case ts.SyntaxKind.TypePredicate:
case ts.SyntaxKind.FirstTypeNode:
return GetBooleanDescriptor();
case ts.SyntaxKind.ObjectKeyword:
return GetMockPropertiesFromSymbol([], [], scope);
case ts.SyntaxKind.NullKeyword:
return GetNullDescriptor();
case ts.SyntaxKind.ImportEqualsDeclaration:
return GetImportEqualsDescriptor(node as ts.ImportEqualsDeclaration, scope);
case ts.SyntaxKind.BigIntKeyword:
return GetBigIntDescriptor();
case ts.SyntaxKind.AnyKeyword:
case ts.SyntaxKind.NeverKeyword:
case ts.SyntaxKind.UnknownKeyword:
case ts.SyntaxKind.UndefinedKeyword:
case ts.SyntaxKind.VoidKeyword:
return GetUndefinedDescriptor();
default:
TransformerLogger().typeNotSupported(ts.SyntaxKind[node.kind]);
return GetNullDescriptor();
}
}
34 changes: 17 additions & 17 deletions src/transformer/descriptor/indexedAccess/indexedAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,28 @@ export function GetIndexedAccessTypeDescriptor(node: ts.IndexedAccessTypeNode, s
let propertyName: string | null = null;

switch (node.indexType.kind) {
case ts.SyntaxKind.TypeReference:
const declaration: ts.Declaration = TypescriptHelper.GetDeclarationFromNode((node.indexType as ts.TypeReferenceNode).typeName);
case ts.SyntaxKind.TypeReference:
const declaration: ts.Declaration = TypescriptHelper.GetDeclarationFromNode((node.indexType as ts.TypeReferenceNode).typeName);

switch (declaration.kind) {
case ts.SyntaxKind.TypeParameter:
const propertyNameIdentifier: ts.PropertyName = PropertySignatureCache.instance.get();
propertyName = (propertyNameIdentifier as ts.Identifier).escapedText as string;
switch (declaration.kind) {
case ts.SyntaxKind.TypeParameter:
const propertyNameIdentifier: ts.PropertyName = PropertySignatureCache.instance.get();
propertyName = (propertyNameIdentifier as ts.Identifier).escapedText as string;
break;
case ts.SyntaxKind.TypeAliasDeclaration:
propertyName = (((declaration as ts.TypeAliasDeclaration).type as ts.LiteralTypeNode).literal as ts.StringLiteral).text;
break;
default:
TransformerLogger().typeNotSupported('IndexedAccess of TypeReference of ' + ts.SyntaxKind[declaration.kind]);
break;
}
break;
case ts.SyntaxKind.TypeAliasDeclaration:
propertyName = (((declaration as ts.TypeAliasDeclaration).type as ts.LiteralTypeNode).literal as ts.StringLiteral).text;
case ts.SyntaxKind.LiteralType:
propertyName = ((node.indexType as ts.LiteralTypeNode).literal as ts.StringLiteral).text;
break;
default:
TransformerLogger().typeNotSupported('IndexedAccess of TypeReference of ' + ts.SyntaxKind[declaration.kind]);
TransformerLogger().typeNotSupported('IndexedAccess of ' + ts.SyntaxKind[node.indexType.kind]);
break;
}
break;
case ts.SyntaxKind.LiteralType:
propertyName = ((node.indexType as ts.LiteralTypeNode).literal as ts.StringLiteral).text;
break;
default:
TransformerLogger().typeNotSupported('IndexedAccess of ' + ts.SyntaxKind[node.indexType.kind]);
break;
}

if (propertyName !== null) {
Expand Down
15 changes: 9 additions & 6 deletions src/transformer/descriptor/method/bodyReturnType.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import * as ts from 'typescript';
import { Scope } from '../../scope/scope';
import { GetDescriptor } from '../descriptor';
import { GetNullDescriptor } from '../null/null';

export function GetReturnTypeFromBody(node: ts.ArrowFunction | ts.FunctionExpression | ts.MethodDeclaration | ts.FunctionDeclaration, scope: Scope): ts.Expression {
let returnValue: ts.Expression;
export function GetReturnTypeFromBodyDescriptor(node: ts.ArrowFunction | ts.FunctionExpression | ts.MethodDeclaration | ts.FunctionDeclaration, scope: Scope): ts.Expression {
return GetDescriptor(GetReturnNodeFromBody(node), scope);
}

export function GetReturnNodeFromBody(node: ts.ArrowFunction | ts.FunctionExpression | ts.MethodDeclaration | ts.FunctionDeclaration): ts.Node {
let returnValue: ts.Node;

const functionBody: ts.FunctionBody = node.body as ts.FunctionBody;
uittorio marked this conversation as resolved.
Show resolved Hide resolved

if (functionBody.statements) {
const returnStatement: ts.ReturnStatement = GetReturnStatement(functionBody);

if (returnStatement) {
returnValue = GetDescriptor(returnStatement.expression, scope);
returnValue = returnStatement.expression;
} else {
returnValue = GetNullDescriptor();
returnValue = ts.createNull();
uittorio marked this conversation as resolved.
Show resolved Hide resolved
}
} else {
returnValue = GetDescriptor(node.body, scope);
returnValue = node.body;
}

return returnValue;
Expand Down
4 changes: 2 additions & 2 deletions src/transformer/descriptor/method/functionAssignment.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as ts from 'typescript';
import { Scope } from '../../scope/scope';
import { PropertySignatureCache } from '../property/cache';
import { GetReturnTypeFromBody } from './bodyReturnType';
import { GetReturnTypeFromBodyDescriptor } from './bodyReturnType';
import { GetMethodDescriptor } from './method';

type functionAssignment = ts.ArrowFunction | ts.FunctionExpression;

export function GetFunctionAssignmentDescriptor(node: functionAssignment, scope: Scope): ts.Expression {
const property: ts.PropertyName = PropertySignatureCache.instance.get();
const returnValue: ts.Expression = GetReturnTypeFromBody(node, scope);
const returnValue: ts.Expression = GetReturnTypeFromBodyDescriptor(node, scope);

return GetMethodDescriptor(property, returnValue);
}
4 changes: 2 additions & 2 deletions src/transformer/descriptor/method/methodDeclaration.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ts from 'typescript';
import { Scope } from '../../scope/scope';
import { GetDescriptor } from '../descriptor';
import { GetReturnTypeFromBody } from './bodyReturnType';
import { GetReturnTypeFromBodyDescriptor } from './bodyReturnType';
import { GetMethodDescriptor } from './method';

export function GetMethodDeclarationDescriptor(node: ts.MethodDeclaration | ts.FunctionDeclaration, scope: Scope): ts.Expression {
Expand All @@ -10,7 +10,7 @@ export function GetMethodDeclarationDescriptor(node: ts.MethodDeclaration | ts.F
if (node.type) {
returnType = GetDescriptor(node.type, scope);
} else {
returnType = GetReturnTypeFromBody(node, scope);
returnType = GetReturnTypeFromBodyDescriptor(node, scope);
}

return GetMethodDescriptor(node.name, returnType);
Expand Down
23 changes: 13 additions & 10 deletions src/transformer/descriptor/module/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { Scope } from '../../scope/scope';
import { TypeChecker } from '../../typeChecker/typeChecker';
import { TypescriptHelper } from '../helper/helper';
import { GetMockPropertiesFromDeclarations } from '../mock/mockProperties';
import { PropertyLike } from '../mock/propertyLike';
import { GetTypeQueryDescriptorFromDeclaration } from '../typeQuery/typeQuery';

type ExternalSource = ts.SourceFile | ts.ModuleDeclaration;

export function GetModuleDescriptor(node: ts.NamedDeclaration, scope: Scope): ts.Expression {
Expand All @@ -16,7 +16,7 @@ export function GetModuleDescriptor(node: ts.NamedDeclaration, scope: Scope): ts
const externalModuleDeclaration: ts.NamedDeclaration = symbol.declarations[0];

if (isExternalSource(externalModuleDeclaration)) {
return GetPropertiesFromSourceFileOrModuleDeclaration(externalModuleDeclaration, symbol, scope);
return GetPropertiesFromSourceFileOrModuleDeclarationDescriptor(externalModuleDeclaration, symbol, scope);
}

return GetTypeQueryDescriptorFromDeclaration(externalModuleDeclaration, scope);
Expand All @@ -26,29 +26,32 @@ function isExternalSource(declaration: ts.Node): declaration is ExternalSource {
return ts.isSourceFile(declaration) || ts.isModuleDeclaration(declaration);
}

function GetPropertiesFromSourceFileOrModuleDeclaration(sourceFile: ExternalSource, symbol: ts.Symbol, scope: Scope): ts.Expression {
function GetPropertiesFromSourceFileOrModuleDeclarationDescriptor(sourceFile: ExternalSource, symbol: ts.Symbol, scope: Scope): ts.Expression {
return GetMockPropertiesFromDeclarations(GetPropertiesFromSourceFileOrModuleDeclaration(sourceFile, symbol, scope), [], scope);
}

function GetPropertiesFromSourceFileOrModuleDeclaration(sourceFile: ExternalSource, symbol: ts.Symbol, scope: Scope): ts.PropertySignature[] {
const typeChecker: ts.TypeChecker = TypeChecker();
const moduleExports: ts.Symbol[] = typeChecker.getExportsOfModule(symbol);

const properties: PropertyLike[] = moduleExports.map((prop: ts.Symbol): PropertyLike => {
return moduleExports.map((prop: ts.Symbol): ts.PropertySignature => {
const originalSymbol: ts.Symbol = TypescriptHelper.GetAliasedSymbolSafe(prop);
const originalDeclaration: ts.NamedDeclaration = originalSymbol.declarations[0];
const declaration: ts.Declaration = prop.declarations[0];

if (ts.isExportAssignment(declaration)) {
return TypescriptCreator.createProperty('default', ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
return TypescriptCreator.createPropertySignature('default', ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
}

if (ts.isExportSpecifier(declaration) && ts.isSourceFile(originalDeclaration)) {
const exportSpecifierSymbol: ts.Symbol = typeChecker.getSymbolAtLocation(declaration.name);
const exportSpecifierAliasSymbol: ts.Symbol = typeChecker.getAliasedSymbol(exportSpecifierSymbol);
const exportSpecifierProperties: ts.Expression = GetPropertiesFromSourceFileOrModuleDeclaration(originalDeclaration, exportSpecifierAliasSymbol, scope);
const exportSpecifierProperties: ts.PropertySignature[] = GetPropertiesFromSourceFileOrModuleDeclaration(originalDeclaration, exportSpecifierAliasSymbol, scope);
const propertyType: ts.TypeNode = ts.createTypeLiteralNode(exportSpecifierProperties);

return TypescriptCreator.createPropertyWitInitializer(declaration.name, exportSpecifierProperties);
return TypescriptCreator.createPropertySignature(declaration.name, propertyType);
}

return TypescriptCreator.createProperty(originalDeclaration.name as ts.Identifier, ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
return TypescriptCreator.createPropertySignature(originalDeclaration.name as ts.Identifier, ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
});

return GetMockPropertiesFromDeclarations(properties, [], scope);
}
Loading