@@ -6,23 +6,48 @@ namespace ts.codefix {
6
6
* @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
7
7
* @returns Empty string iff there are no member insertions.
8
8
*/
9
- export function createMissingMemberNodes ( classDeclaration : ClassLikeDeclaration , possiblyMissingSymbols : ReadonlyArray < Symbol > , checker : TypeChecker , preferences : UserPreferences , out : ( node : ClassElement ) => void ) : void {
9
+ export function createMissingMemberNodes ( classDeclaration : ClassLikeDeclaration , possiblyMissingSymbols : ReadonlyArray < Symbol > , context : TypeConstructionContext , preferences : UserPreferences , out : ( node : ClassElement ) => void ) : void {
10
10
const classMembers = classDeclaration . symbol . members ! ;
11
11
for ( const symbol of possiblyMissingSymbols ) {
12
12
if ( ! classMembers . has ( symbol . escapedName ) ) {
13
- addNewNodeForMemberSymbol ( symbol , classDeclaration , checker , preferences , out ) ;
13
+ addNewNodeForMemberSymbol ( symbol , classDeclaration , context , preferences , out ) ;
14
14
}
15
15
}
16
16
}
17
17
18
+ function getModuleSpecifierResolverHost ( context : TypeConstructionContext ) : SymbolTracker [ "moduleResolverHost" ] {
19
+ return {
20
+ directoryExists : context . host . directoryExists ? d => context . host . directoryExists ! ( d ) : undefined ,
21
+ fileExists : context . host . fileExists ? f => context . host . fileExists ! ( f ) : undefined ,
22
+ getCurrentDirectory : context . host . getCurrentDirectory ? ( ) => context . host . getCurrentDirectory ! ( ) : undefined ,
23
+ readFile : context . host . readFile ? f => context . host . readFile ! ( f ) : undefined ,
24
+ useCaseSensitiveFileNames : context . host . useCaseSensitiveFileNames ? ( ) => context . host . useCaseSensitiveFileNames ! ( ) : undefined ,
25
+ getSourceFiles : ( ) => context . program . getSourceFiles ( ) ,
26
+ getCommonSourceDirectory : ( ) => context . program . getCommonSourceDirectory ( ) ,
27
+ } ;
28
+ }
29
+
30
+ export function getNoopSymbolTrackerWithResolver ( context : TypeConstructionContext ) : SymbolTracker {
31
+ return {
32
+ trackSymbol : noop ,
33
+ moduleResolverHost : getModuleSpecifierResolverHost ( context ) ,
34
+ } ;
35
+ }
36
+
37
+ export interface TypeConstructionContext {
38
+ program : Program ;
39
+ host : ModuleSpecifierResolutionHost ;
40
+ }
41
+
18
42
/**
19
43
* @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
20
44
*/
21
- function addNewNodeForMemberSymbol ( symbol : Symbol , enclosingDeclaration : ClassLikeDeclaration , checker : TypeChecker , preferences : UserPreferences , out : ( node : Node ) => void ) : void {
45
+ function addNewNodeForMemberSymbol ( symbol : Symbol , enclosingDeclaration : ClassLikeDeclaration , context : TypeConstructionContext , preferences : UserPreferences , out : ( node : Node ) => void ) : void {
22
46
const declarations = symbol . getDeclarations ( ) ;
23
47
if ( ! ( declarations && declarations . length ) ) {
24
48
return undefined ;
25
49
}
50
+ const checker = context . program . getTypeChecker ( ) ;
26
51
27
52
const declaration = declarations [ 0 ] ;
28
53
const name = getSynthesizedDeepClone ( getNameOfDeclaration ( declaration ) , /*includeTrivia*/ false ) as PropertyName ;
@@ -36,7 +61,7 @@ namespace ts.codefix {
36
61
case SyntaxKind . SetAccessor :
37
62
case SyntaxKind . PropertySignature :
38
63
case SyntaxKind . PropertyDeclaration :
39
- const typeNode = checker . typeToTypeNode ( type , enclosingDeclaration ) ;
64
+ const typeNode = checker . typeToTypeNode ( type , enclosingDeclaration , /*flags*/ undefined , getNoopSymbolTrackerWithResolver ( context ) ) ;
40
65
out ( createProperty (
41
66
/*decorators*/ undefined ,
42
67
modifiers ,
@@ -83,21 +108,22 @@ namespace ts.codefix {
83
108
}
84
109
85
110
function outputMethod ( signature : Signature , modifiers : NodeArray < Modifier > | undefined , name : PropertyName , body ?: Block ) : void {
86
- const method = signatureToMethodDeclaration ( checker , signature , enclosingDeclaration , modifiers , name , optional , body ) ;
111
+ const method = signatureToMethodDeclaration ( context , signature , enclosingDeclaration , modifiers , name , optional , body ) ;
87
112
if ( method ) out ( method ) ;
88
113
}
89
114
}
90
115
91
116
function signatureToMethodDeclaration (
92
- checker : TypeChecker ,
117
+ context : TypeConstructionContext ,
93
118
signature : Signature ,
94
119
enclosingDeclaration : ClassLikeDeclaration ,
95
120
modifiers : NodeArray < Modifier > | undefined ,
96
121
name : PropertyName ,
97
122
optional : boolean ,
98
123
body : Block | undefined ,
99
124
) : MethodDeclaration | undefined {
100
- const signatureDeclaration = < MethodDeclaration > checker . signatureToSignatureDeclaration ( signature , SyntaxKind . MethodDeclaration , enclosingDeclaration , NodeBuilderFlags . NoTruncation | NodeBuilderFlags . SuppressAnyReturnType ) ;
125
+ const program = context . program ;
126
+ const signatureDeclaration = < MethodDeclaration > program . getTypeChecker ( ) . signatureToSignatureDeclaration ( signature , SyntaxKind . MethodDeclaration , enclosingDeclaration , NodeBuilderFlags . NoTruncation | NodeBuilderFlags . SuppressAnyReturnType , getNoopSymbolTrackerWithResolver ( context ) ) ;
101
127
if ( ! signatureDeclaration ) {
102
128
return undefined ;
103
129
}
@@ -117,18 +143,20 @@ namespace ts.codefix {
117
143
inJs : boolean ,
118
144
makeStatic : boolean ,
119
145
preferences : UserPreferences ,
120
- body : boolean ,
146
+ contextNode : Node ,
121
147
) : MethodDeclaration {
148
+ const body = ! isInterfaceDeclaration ( contextNode ) ;
122
149
const { typeArguments, arguments : args , parent } = call ;
123
150
const checker = context . program . getTypeChecker ( ) ;
151
+ const tracker = getNoopSymbolTrackerWithResolver ( context ) ;
124
152
const types = map ( args , arg =>
125
153
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
126
- checker . typeToTypeNode ( checker . getBaseTypeOfLiteralType ( checker . getTypeAtLocation ( arg ) ) ) ) ;
154
+ checker . typeToTypeNode ( checker . getBaseTypeOfLiteralType ( checker . getTypeAtLocation ( arg ) ) , contextNode , /*flags*/ undefined , tracker ) ) ;
127
155
const names = map ( args , arg =>
128
156
isIdentifier ( arg ) ? arg . text :
129
157
isPropertyAccessExpression ( arg ) ? arg . name . text : undefined ) ;
130
158
const contextualType = checker . getContextualType ( call ) ;
131
- const returnType = inJs ? undefined : contextualType && checker . typeToTypeNode ( contextualType , call ) || createKeywordTypeNode ( SyntaxKind . AnyKeyword ) ;
159
+ const returnType = inJs ? undefined : contextualType && checker . typeToTypeNode ( contextualType , contextNode , /*flags*/ undefined , tracker ) || createKeywordTypeNode ( SyntaxKind . AnyKeyword ) ;
132
160
return createMethod (
133
161
/*decorators*/ undefined ,
134
162
/*modifiers*/ makeStatic ? [ createToken ( SyntaxKind . StaticKeyword ) ] : undefined ,
0 commit comments