UNPKG

@cosmology/ast

Version:
237 lines (215 loc) 7.53 kB
import * as t from '@babel/types'; import { makeCommentBlock } from './utils'; // TODO move to @cosmology/utils package export const commentBlock = (value: string): t.CommentBlock => { return { type: 'CommentBlock', value, start: null, end: null, loc: null }; }; export const commentLine = (value: string): t.CommentLine => { return { type: 'CommentLine', value, start: null, end: null, loc: null }; }; export function tsMethodSignature( key: t.Expression, typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, parameters: Array<t.Identifier | t.RestElement>, typeAnnotation: t.TSTypeAnnotation | null = null, trailingComments?: t.Comment[], leadingComments?: t.Comment[] ): t.TSMethodSignature { const obj = t.tsMethodSignature( key, typeParameters, parameters, typeAnnotation ); obj.kind = 'method'; if (trailingComments && trailingComments.length) { obj.trailingComments = trailingComments; } if (leadingComments && leadingComments.length) { obj.leadingComments = leadingComments; } return obj; } export const classMethod = ( kind: "get" | "set" | "method" | "constructor" | undefined, key: t.Identifier | t.StringLiteral | t.NumericLiteral | t.Expression, params: Array<t.Identifier | t.Pattern | t.RestElement | t.TSParameterProperty>, body: t.BlockStatement, returnType?: t.TSTypeAnnotation, leadingComments: t.CommentLine[] | t.CommentBlock[] = [], computed: boolean = false, _static: boolean = false, generator: boolean = false, async: boolean = false, ) => { const obj = t.classMethod(kind, key, params, body, computed, _static, generator, async) if (returnType) { obj.returnType = returnType; } if (leadingComments) { obj.leadingComments = leadingComments; } return obj; }; export const tsEnumMember = ( id: t.Identifier | t.StringLiteral, initializer?: t.Expression, leadingComments?: any[] ) => { const obj = t.tsEnumMember(id, initializer); obj.leadingComments = leadingComments; return obj; }; export const tsPropertySignature = ( key: t.Expression, typeAnnotation: t.TSTypeAnnotation, optional: boolean ) => { const obj = t.tsPropertySignature(key, typeAnnotation); obj.optional = optional; return obj }; export const functionDeclaration = ( id: t.Identifier, params: (t.Identifier | t.Pattern | t.RestElement)[], body: t.BlockStatement, generator?: boolean, async?: boolean, returnType?: t.TSTypeAnnotation ): t.FunctionDeclaration => { const func = t.functionDeclaration(id, params, body, generator, async); func.returnType = returnType; return func; }; export const callExpression = ( callee: t.Expression | t.V8IntrinsicIdentifier, _arguments: (t.Expression | t.SpreadElement | t.ArgumentPlaceholder)[], typeParameters: t.TSTypeParameterInstantiation ) => { const callExpr = t.callExpression(callee, _arguments); callExpr.typeParameters = typeParameters; return callExpr; }; export const identifier = (name: string, typeAnnotation: t.TSTypeAnnotation, optional: boolean = false) => { const type = t.identifier(name); type.typeAnnotation = typeAnnotation; type.optional = optional; return type; } export const classDeclaration = ( id: t.Identifier, superClass: t.Expression | null | undefined = null, body: t.ClassBody, decorators: Array<t.Decorator> | null = null, vImplements?: t.TSExpressionWithTypeArguments[], superTypeParameters?: t.TypeParameterInstantiation | t.TSTypeParameterInstantiation ): t.ClassDeclaration => { const obj = t.classDeclaration(id, superClass, body, decorators); if (superTypeParameters) { obj.superTypeParameters = superTypeParameters; } if (vImplements) { obj.implements = vImplements; } return obj; } export function classProperty( key: t.Identifier | t.StringLiteral | t.NumericLiteral | t.Expression, value: t.Expression | null = null, typeAnnotation: t.TypeAnnotation | t.TSTypeAnnotation | t.Noop | null = null, decorators: Array<t.Decorator> | null = null, computed: boolean = false, _static: boolean = false, _readonly: boolean = false, accessibility?: 'private' | 'protected' | 'public', leadingComments: t.CommentLine[] = [] ): t.ClassProperty { const obj = t.classProperty(key, value, typeAnnotation, decorators, computed, _static); if (accessibility) obj.accessibility = accessibility; if (_readonly) obj.readonly = _readonly; if (leadingComments.length) obj.leadingComments = leadingComments; return obj; }; export const arrowFunctionExpression = ( params: (t.Identifier | t.Pattern | t.RestElement)[], body: t.BlockStatement, returnType?: t.TSTypeAnnotation, isAsync: boolean = false, typeParameters?: t.TypeParameterDeclaration | t.TSTypeParameterDeclaration | t.Noop ) => { const func = t.arrowFunctionExpression(params, body, isAsync); func.returnType = returnType; func.typeParameters = typeParameters; return func; }; export const tsTypeParameterDeclaration = (params: Array<t.TSTypeParameter>): t.TSTypeParameterDeclaration => { const obj = t.tsTypeParameterDeclaration(params); delete obj.extra; return obj; }; export const objectPattern = ( properties: (t.RestElement | t.ObjectProperty)[], typeAnnotation: t.TSTypeAnnotation ) => { const obj = t.objectPattern(properties); obj.typeAnnotation = typeAnnotation; return obj; } export const objectMethod = ( kind: "method" | "get" | "set", key: t.Expression, params: (t.Identifier | t.Pattern | t.RestElement)[], body: t.BlockStatement, computed?: boolean, generator?: boolean, async?: boolean, returnType?: t.TSTypeAnnotation | t.TypeAnnotation | t.Noop, typeParameters?: t.TypeParameterDeclaration | t.TSTypeParameterDeclaration | t.Noop ): t.ObjectMethod => { const obj = t.objectMethod(kind, key, params, body, computed, generator, async); obj.returnType = returnType; obj.typeParameters = typeParameters; return obj; }; export const objectProperty = ( key: t.Expression | t.Identifier | t.StringLiteral | t.NumericLiteral | t.BigIntLiteral | t.DecimalLiteral | t.PrivateName, value: t.Expression | t.PatternLike, computed?: boolean, shorthand?: boolean, decorators?: Array<t.Decorator> | null, leadingComments: t.CommentLine[] = [] ): t.ObjectProperty => { const obj = t.objectProperty(key, value, computed, shorthand, decorators); if (leadingComments.length) obj.leadingComments = leadingComments; return obj; }; export const makeCommentLineWithBlocks = (comment: string): t.CommentLine[] => { if (!comment) return []; // NOTE using blocks instead of lines here... // @ts-ignore return [makeCommentBlock(comment)]; } export const newExpression = ( callee: t.Expression | t.V8IntrinsicIdentifier, _arguments: ( | t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder )[], typeParameters?: t.TSTypeParameterInstantiation ): t.NewExpression => { const expr = t.newExpression(callee, _arguments); expr.typeParameters = typeParameters; return expr; };