import type * as ts from 'typescript' ; import { MockDefiner } from '../../mockDefiner/mockDefiner' ; import { Identifiers } from '../../mockIdentifier/mockIdentifier' ; import { Scope } from '../../scope/scope' ; import { core } from '../../core/core' ; import { GetDescriptor } from '../descriptor' ; import { TypescriptHelper } from '../helper/helper' ; import { GetNullDescriptor } from '../null/null' ; import { createArrowFunction , createBinaryExpression , createBlock , createCall , createIdentifier , createIfStatement , createIIFE , createNumericLiteral , createParameter , createPropertyAccess , createPunctuationToken , createReturnStatement , createStringLiteral , createVariableDeclaration , createVariableDeclarationList , createVariableStatement , } from '../../../typescriptFactory/typescriptFactory' ; import GetDeclarationFromSymbol = TypescriptHelper . GetDeclarationFromSymbol ; export function GetTypeParameterDescriptor ( node , scope ) { const type = core . typeChecker . getTypeAtLocation ( node ) ; const descriptor = node . default ? GetDescriptor ( node . default , scope ) : GetNullDescriptor ( ) ; const declaration = GetDeclarationFromSymbol ( type . symbol ) ; const typeDeclaration = TypescriptHelper . GetTypeParameterOwnerMock ( declaration ) ; if ( ! typeDeclaration ) { throw new Error ( `Failed to determine the owner (parent) of the type parameter: \`${ declaration . getText ( ) }'.` ) ; } const genericKey = MockDefiner . instance . getDeclarationKeyMapBasedOnScope ( typeDeclaration , scope ) ; return createFunctionToAccessToGenericValue ( genericKey + node . name . escapedText . toString ( ) , descriptor ) ; } function createFunctionToAccessToGenericValue ( key , descriptor ) { const returnWhenGenericDoesNotExist = createReturnStatement ( descriptor ) ; const expressionWhenGenericExist = getValueFromGenericIfExist ( ) ; const findGenericCall = createFindGeneric ( key ) ; const generic = assignGenericConstToCall ( findGenericCall ) ; return createIIFE ( createBlock ( [ generic , expressionWhenGenericExist , returnWhenGenericDoesNotExist ] , true ) ) ; } function createFindGeneric ( genericKey ) { return createCall ( createPropertyAccess ( Identifiers . MockIdentifierGenericParameter , createIdentifier ( 'find' ) ) , [ createArrowFunction ( createBlock ( [ createReturnStatement ( createBinaryExpression ( createCall ( createPropertyAccess ( createPropertyAccess ( createIdentifier ( 'generic' ) , Identifiers . MockIdentifierGenericParameterIds ) , createIdentifier ( 'indexOf' ) ) , [ createStringLiteral ( genericKey ) ] ) , createPunctuationToken ( core . ts . SyntaxKind . GreaterThanEqualsToken ) , createNumericLiteral ( '0' ) ) ) , ] , true ) , [ createParameter ( 'generic' ) ] ) , ] ) ; } function assignGenericConstToCall ( call ) { return createVariableStatement ( createVariableDeclarationList ( [ createVariableDeclaration ( createIdentifier ( 'generic' ) , call ) ] , core . ts . NodeFlags . Const ) ) ; } function getValueFromGenericIfExist ( ) { return createIfStatement ( createIdentifier ( 'generic' ) , createBlock ( [ createReturnStatement ( createCall ( createPropertyAccess ( createIdentifier ( 'generic' ) , Identifiers . MockIdentifierGenericParameterValue ) , [ ] ) ) , ] , true ) ) ; }