fileoverview import { debug as d } from '@hint/utils-debug' ; import { Parser } from 'hint/dist/src/lib/types' ; import { Engine } from 'hint/dist/src/lib/engine' ; import { Node , ScriptEvents } from '@hint/parser-javascript' ; import { base , combineWalk } from '@hint/parser-javascript/dist/src/walk' ; const debug = d ( __filename ) ; let TypeScriptESTree = null ; try { TypeScriptESTree = require ( '@typescript-eslint/typescript-estree' ) ; } catch ( e ) { debug ( `Unable to load TypeScript parser: ${ e }` ) ; } if ( TypeScriptESTree ) { for ( const type of Object . keys ( TypeScriptESTree . AST_NODE_TYPES ) ) { if ( type === 'ClassProperty' ) { base [ type ] = ( node , st , c ) => { if ( node . value ) { c ( node . value , st ) ; } } ; } if ( ! base [ type ] ) { base [ type ] = base . Identifier ; } } } export default class TypeScriptParser extends Parser < ScriptEvents > { public constructor ( engine ) { super ( engine , 'typescript' ) ; engine . on ( 'fetch::end::unknown' , async ( { resource , response } ) => { if ( ! resource . endsWith ( '.ts' ) && ! resource . endsWith ( '.tsx' ) ) { return ; } if ( ! TypeScriptESTree ) { return ; } debug ( `Parsing TypeScript file: ${ resource }` ) ; const sourceCode = response . body . content ; const jsx = resource . endsWith ( '.tsx' ) ; try { await engine . emitAsync ( 'parse::start::javascript' , { resource } ) ; const result = TypeScriptESTree . parse ( sourceCode , { jsx , loc : true , useJSXTextNode : jsx } ) ; await combineWalk ( async ( walk ) => { await engine . emitAsync ( 'parse::end::javascript' , { ast : result as Node , element : null , resource , sourceCode , tokens : result . tokens as any , walk } ) ; } ) ; } catch ( err ) { debug ( `Error parsing TypeScript code (${ err }): ${ sourceCode }` ) ; } } ) ; } }