import { Program , Node , CallExpression , forEachChild , isCallExpression , Identifier } from '@tsd/typescript' ; import { Assertion } from './assertions' ; import { Location , Diagnostic } from './interfaces' ; const assertionFnNames = new Set < string > ( Object . values ( Assertion ) ) ; param program export const extractAssertions = ( program ) : Map < Assertion , Set < CallExpression > > => { const assertions = new Map < Assertion , Set < CallExpression > > ( ) ; /**
     * Recursively loop over all the nodes and extract all the assertions out of the source files.
     */ function walkNodes ( node ) { if ( isCallExpression ( node ) ) { const identifier = ( node . expression as Identifier ) . getText ( ) ; if ( assertionFnNames . has ( identifier ) ) { const assertion = identifier as Assertion ; const nodes = assertions . get ( assertion ) ?? new Set < CallExpression > ( ) ; nodes . add ( node ) ; assertions . set ( assertion , nodes ) ; } } forEachChild ( node , walkNodes ) ; } for ( const sourceFile of program . getSourceFiles ( ) ) { walkNodes ( sourceFile ) ; } return assertions ; } ; export type ExpectedError = Pick < Diagnostic , 'fileName' | 'line' | 'column' > ; param assertions export const parseErrorAssertionToLocation = ( assertions ) : Map < Location , ExpectedError > => { const nodes = assertions . get ( Assertion . EXPECT_ERROR ) ; const expectedErrors = new Map < Location , ExpectedError > ( ) ; if ( ! nodes ) { return expectedErrors ; } for ( const node of nodes ) { const location = { fileName : node . getSourceFile ( ) . fileName , start : node . getStart ( ) , end : node . getEnd ( ) } ; const pos = node . getSourceFile ( ) . getLineAndCharacterOfPosition ( node . getStart ( ) ) ; expectedErrors . set ( location , { fileName : location . fileName , line : pos . line + 1 , column : pos . character } ) ; } return expectedErrors ; } ;