@@ -6,23 +6,48 @@ namespace ts.codefix {
66 * @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
77 * @returns Empty string iff there are no member insertions.
88 */
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 {
1010 const classMembers = classDeclaration . symbol . members ! ;
1111 for ( const symbol of possiblyMissingSymbols ) {
1212 if ( ! classMembers . has ( symbol . escapedName ) ) {
13- addNewNodeForMemberSymbol ( symbol , classDeclaration , checker , preferences , out ) ;
13+ addNewNodeForMemberSymbol ( symbol , classDeclaration , context , preferences , out ) ;
1414 }
1515 }
1616 }
1717
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+
1842 /**
1943 * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
2044 */
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 {
2246 const declarations = symbol . getDeclarations ( ) ;
2347 if ( ! ( declarations && declarations . length ) ) {
2448 return undefined ;
2549 }
50+ const checker = context . program . getTypeChecker ( ) ;
2651
2752 const declaration = declarations [ 0 ] ;
2853 const name = getSynthesizedDeepClone ( getNameOfDeclaration ( declaration ) , /*includeTrivia*/ false ) as PropertyName ;
@@ -36,7 +61,7 @@ namespace ts.codefix {
3661 case SyntaxKind . SetAccessor :
3762 case SyntaxKind . PropertySignature :
3863 case SyntaxKind . PropertyDeclaration :
39- const typeNode = checker . typeToTypeNode ( type , enclosingDeclaration ) ;
64+ const typeNode = checker . typeToTypeNode ( type , enclosingDeclaration , /*flags*/ undefined , getNoopSymbolTrackerWithResolver ( context ) ) ;
4065 out ( createProperty (
4166 /*decorators*/ undefined ,
4267 modifiers ,
@@ -83,21 +108,22 @@ namespace ts.codefix {
83108 }
84109
85110 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 ) ;
87112 if ( method ) out ( method ) ;
88113 }
89114 }
90115
91116 function signatureToMethodDeclaration (
92- checker : TypeChecker ,
117+ context : TypeConstructionContext ,
93118 signature : Signature ,
94119 enclosingDeclaration : ClassLikeDeclaration ,
95120 modifiers : NodeArray < Modifier > | undefined ,
96121 name : PropertyName ,
97122 optional : boolean ,
98123 body : Block | undefined ,
99124 ) : 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 ) ) ;
101127 if ( ! signatureDeclaration ) {
102128 return undefined ;
103129 }
@@ -117,18 +143,20 @@ namespace ts.codefix {
117143 inJs : boolean ,
118144 makeStatic : boolean ,
119145 preferences : UserPreferences ,
120- body : boolean ,
146+ contextNode : Node ,
121147 ) : MethodDeclaration {
148+ const body = ! isInterfaceDeclaration ( contextNode ) ;
122149 const { typeArguments, arguments : args , parent } = call ;
123150 const checker = context . program . getTypeChecker ( ) ;
151+ const tracker = getNoopSymbolTrackerWithResolver ( context ) ;
124152 const types = map ( args , arg =>
125153 // 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 ) ) ;
127155 const names = map ( args , arg =>
128156 isIdentifier ( arg ) ? arg . text :
129157 isPropertyAccessExpression ( arg ) ? arg . name . text : undefined ) ;
130158 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 ) ;
132160 return createMethod (
133161 /*decorators*/ undefined ,
134162 /*modifiers*/ makeStatic ? [ createToken ( SyntaxKind . StaticKeyword ) ] : undefined ,
0 commit comments