@@ -20,28 +20,42 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
2020 } )
2121 }
2222
23+ const program = languageService . getProgram ( ) !
24+ const sourceFile = program . getSourceFile ( fileName ) !
25+ const getNode = ( ) => {
26+ return findChildContainingExactPosition ( sourceFile , position )
27+ }
28+
29+ const noDefs = ! prior || ! prior . definitions || prior . definitions . length === 0
30+ const tryFileResolve = noDefs || [ '?' , '#' ] . some ( x => prior . definitions ?. [ 0 ] ?. fileName ?. includes ( x ) )
31+
2332 // Definition fallbacks
24- if ( ! prior || prior . definitions ?. length === 0 ) {
25- const program = languageService . getProgram ( ) !
26- const sourceFile = program . getSourceFile ( fileName ) !
27- const node = findChildContainingExactPosition ( sourceFile , position )
33+ if ( noDefs || tryFileResolve ) {
34+ const node = getNode ( )
2835 if ( node && ts . isStringLiteral ( node ) ) {
2936 const textSpanStart = node . pos + node . getLeadingTriviaWidth ( ) + 1 // + 1 for quote
3037 const textSpan = {
3138 start : textSpanStart ,
3239 length : node . end - textSpanStart - 1 ,
3340 }
34- if ( c ( 'enableFileDefinitions' ) && [ './' , '../' ] . some ( str => node . text . startsWith ( str ) ) ) {
35- const file = join ( fileName , '..' , node . text )
36- if ( languageServiceHost . fileExists ?.( file ) ) {
41+
42+ if ( tryFileResolve && c ( 'enableFileDefinitions' ) && [ './' , '../' ] . some ( str => node . text . startsWith ( str ) ) ) {
43+ const pathText = node . text . split ( '?' ) [ 0 ] ! . split ( '#' ) [ 0 ] !
44+ const fileCandidates = [
45+ join ( fileName , '..' , pathText ) ,
46+ // also try to resolve from root. Why? It might common in Node.js script paths that go from working directory (project root)
47+ pathText . startsWith ( './' ) ? join ( languageServiceHost . getCurrentDirectory ( ) , pathText ) : ( undefined as never ) ,
48+ ] . filter ( Boolean )
49+ const resolvedFile = fileCandidates . find ( file => languageServiceHost . fileExists ?.( file ) )
50+ if ( resolvedFile ) {
3751 return {
3852 textSpan,
3953 definitions : [
4054 {
4155 containerKind : undefined as any ,
4256 containerName : '' ,
4357 name : '' ,
44- fileName : file ,
58+ fileName : resolvedFile ,
4559 textSpan : { start : 0 , length : 0 } ,
4660 kind : ts . ScriptElementKind . moduleElement ,
4761 contextSpan : { start : 0 , length : 0 } ,
@@ -50,10 +64,9 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
5064 }
5165 }
5266 }
53-
5467 // partial fix for https://github.com/microsoft/TypeScript/issues/49033 (string literal in function call definition)
5568 // thoughts about type definition: no impl here, will be simpler to do this in core instead
56- if ( ts . isCallExpression ( node . parent ) ) {
69+ if ( noDefs && ts . isCallExpression ( node . parent ) ) {
5770 const parameterIndex = node . parent . arguments . indexOf ( node )
5871 const typeChecker = program . getTypeChecker ( )
5972 const type = typeChecker . getContextualType ( node . parent . expression ) ?? typeChecker . getTypeAtLocation ( node . parent . expression )
@@ -108,7 +121,8 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
108121 }
109122 }
110123 }
111- return prior
124+
125+ if ( noDefs ) return prior
112126 }
113127
114128 if ( __WEB__ ) {
0 commit comments