@@ -6,17 +6,18 @@ export default (proxy: ts.LanguageService, info: ts.server.PluginCreateInfo, c:
6
6
proxy . getDefinitionAndBoundSpan = ( fileName , position ) => {
7
7
const prior = info . languageService . getDefinitionAndBoundSpan ( fileName , position )
8
8
if ( ! prior ) {
9
- if ( c ( 'enableFileDefinitions' ) ) {
10
- const sourceFile = info . languageService . getProgram ( ) ! . getSourceFile ( fileName ) !
11
- const node = findChildContainingExactPosition ( sourceFile , position )
12
- if ( node && ts . isStringLiteral ( node ) && [ './' , '../' ] . some ( str => node . text . startsWith ( str ) ) ) {
9
+ const program = info . languageService . getProgram ( ) !
10
+ const sourceFile = program . getSourceFile ( fileName ) !
11
+ const node = findChildContainingExactPosition ( sourceFile , position )
12
+ if ( node && ts . isStringLiteral ( node ) ) {
13
+ const textSpanStart = node . pos + node . getLeadingTriviaWidth ( ) + 1 // + 1 for quote
14
+ const textSpan = {
15
+ start : textSpanStart ,
16
+ length : node . end - textSpanStart - 1 ,
17
+ }
18
+ if ( c ( 'enableFileDefinitions' ) && [ './' , '../' ] . some ( str => node . text . startsWith ( str ) ) ) {
13
19
const file = join ( fileName , '..' , node . text )
14
20
if ( info . languageServiceHost . fileExists ?.( file ) ) {
15
- const start = node . pos + node . getLeadingTriviaWidth ( ) + 1 // + 1 for quote
16
- const textSpan = {
17
- start,
18
- length : node . end - start - 1 ,
19
- }
20
21
return {
21
22
textSpan,
22
23
definitions : [
@@ -33,9 +34,66 @@ export default (proxy: ts.LanguageService, info: ts.server.PluginCreateInfo, c:
33
34
}
34
35
}
35
36
}
37
+
38
+ // thoughts about type definition: no impl here, will be simpler to do this in core
39
+ if ( ts . isCallExpression ( node . parent ) ) {
40
+ const parameterIndex = node . parent . arguments . indexOf ( node )
41
+ const typeChecker = program . getTypeChecker ( )
42
+ const type = typeChecker . getContextualType ( node . parent . expression ) ?? typeChecker . getTypeAtLocation ( node . parent . expression )
43
+ // todo handle union
44
+ if ( type ) {
45
+ const getDefinitionsFromKeyofType = ( object : ts . Type ) => {
46
+ const origin = object [ 'origin' ] as ts . Type | undefined
47
+ // handle union of type?
48
+ if ( ! origin ?. isIndexType ( ) || ! ( origin . type . flags & ts . TypeFlags . Object ) ) return
49
+ const properties = origin . type . getProperties ( )
50
+ const interestedMember = properties ?. find ( property => property . name === node . text )
51
+ if ( interestedMember ) {
52
+ const definitions = ( interestedMember . getDeclarations ( ) ?? [ ] ) . map ( ( declaration : ts . Node ) => {
53
+ const fileName = declaration . getSourceFile ( ) . fileName
54
+ if ( ts . isPropertySignature ( declaration ) ) declaration = declaration . name
55
+ const start = declaration . pos + declaration . getLeadingTriviaWidth ( )
56
+ return {
57
+ containerKind : undefined as any ,
58
+ containerName : '' ,
59
+ name : '' ,
60
+ fileName,
61
+ textSpan : { start : start , length : declaration . end - start } ,
62
+ kind : ts . ScriptElementKind . memberVariableElement ,
63
+ contextSpan : { start : 0 , length : 0 } ,
64
+ }
65
+ } )
66
+ return {
67
+ textSpan,
68
+ definitions,
69
+ }
70
+ }
71
+ return
72
+ }
73
+ // todo handle unions and string literal
74
+ const sig = type . getCallSignatures ( ) [ 0 ]
75
+ const param = sig ?. getParameters ( ) [ parameterIndex ]
76
+ const argType = param && typeChecker . getTypeOfSymbolAtLocation ( param , node )
77
+ if ( argType ) {
78
+ const definitions = getDefinitionsFromKeyofType ( argType )
79
+ if ( definitions ) {
80
+ return definitions
81
+ }
82
+
83
+ if ( argType . flags & ts . TypeFlags . TypeParameter ) {
84
+ const param = argType as ts . TypeParameter
85
+ const constraint = param . getConstraint ( )
86
+ if ( constraint ) {
87
+ return getDefinitionsFromKeyofType ( constraint )
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
36
93
}
37
94
return
38
95
}
96
+
39
97
if ( __WEB__ ) {
40
98
// let extension handle it
41
99
// TODO failedAliasResolution
0 commit comments