@@ -67,7 +67,8 @@ export async function fetchSupplementalContextForSrc(
6767 position : Position ,
6868 workspace : Workspace ,
6969 cancellationToken : CancellationToken ,
70- amazonQServiceManager ?: AmazonQBaseServiceManager
70+ amazonQServiceManager ?: AmazonQBaseServiceManager ,
71+ openTabFiles ?: string [ ]
7172) : Promise < Pick < CodeWhispererSupplementalContext , 'supplementalContextItems' | 'strategy' > | undefined > {
7273 const supplementalContextConfig = getSupplementalContextConfig ( document . languageId )
7374
@@ -76,7 +77,14 @@ export async function fetchSupplementalContextForSrc(
7677 }
7778 //TODO: add logic for other strategies once available
7879 if ( supplementalContextConfig === 'codemap' ) {
79- return await codemapContext ( document , position , workspace , cancellationToken , amazonQServiceManager )
80+ return await codemapContext (
81+ document ,
82+ position ,
83+ workspace ,
84+ cancellationToken ,
85+ amazonQServiceManager ,
86+ openTabFiles
87+ )
8088 }
8189 return { supplementalContextItems : [ ] , strategy : 'Empty' }
8290}
@@ -86,13 +94,14 @@ export async function codemapContext(
8694 position : Position ,
8795 workspace : Workspace ,
8896 cancellationToken : CancellationToken ,
89- amazonQServiceManager ?: AmazonQBaseServiceManager
97+ amazonQServiceManager ?: AmazonQBaseServiceManager ,
98+ openTabFiles ?: string [ ]
9099) : Promise < Pick < CodeWhispererSupplementalContext , 'supplementalContextItems' | 'strategy' > | undefined > {
91100 let strategy : SupplementalContextStrategy = 'Empty'
92101
93102 const openTabsContextPromise = waitUntil (
94103 async function ( ) {
95- return await fetchOpenTabsContext ( document , position , workspace , cancellationToken )
104+ return await fetchOpenTabsContext ( document , position , workspace , cancellationToken , openTabFiles )
96105 } ,
97106 { timeout : supplementalContextTimeoutInMs , interval : 5 , truthy : false }
98107 )
@@ -160,12 +169,13 @@ export async function fetchOpenTabsContext(
160169 document : TextDocument ,
161170 position : Position ,
162171 workspace : Workspace ,
163- cancellationToken : CancellationToken
172+ cancellationToken : CancellationToken ,
173+ openTabFiles ?: string [ ]
164174) : Promise < CodeWhispererSupplementalContextItem [ ] > {
165175 const codeChunksCalculated = crossFileContextConfig . numberOfChunkToFetch
166176
167177 // Step 1: Get relevant cross files to refer
168- const relevantCrossFileCandidates = await getCrossFileCandidates ( document , workspace )
178+ const relevantCrossFileCandidates = await getCrossFileCandidates ( document , workspace , openTabFiles )
169179
170180 throwIfCancelled ( cancellationToken )
171181
@@ -318,11 +328,102 @@ function createFileUrl(uri: string): URL {
318328 return nodeUrl . pathToFileURL ( resolvedPath )
319329}
320330
331+ /**
332+ * Returns the language id for construction a TextDocument
333+ * @param filepath
334+ * @returns
335+ */
336+
337+ function guessLanguageId ( filepath : string ) : string {
338+ const ext = path . extname ( filepath ) . toLowerCase ( )
339+ switch ( ext ) {
340+ case '.abap' :
341+ return 'abap'
342+ case '.c' :
343+ return 'c'
344+ case '.cpp' :
345+ case '.cc' :
346+ case '.cxx' :
347+ case '.hpp' :
348+ case '.h' :
349+ return 'cpp'
350+ case '.cs' :
351+ return 'csharp'
352+ case '.dart' :
353+ return 'dart'
354+ case '.go' :
355+ return 'go'
356+ case '.java' :
357+ return 'java'
358+ case '.js' :
359+ return 'javascript'
360+ case '.json' :
361+ return 'json'
362+ case '.jsx' :
363+ return 'jsx'
364+ case '.kt' :
365+ case '.kts' :
366+ return 'kotlin'
367+ case '.lua' :
368+ return 'lua'
369+ case '.php' :
370+ return 'php'
371+ case '.txt' :
372+ return 'plaintext'
373+ case '.ps1' :
374+ case '.psm1' :
375+ case '.psd1' :
376+ return 'powershell'
377+ case '.py' :
378+ return 'python'
379+ case '.r' :
380+ case '.R' :
381+ return 'r'
382+ case '.rb' :
383+ case '.rbw' :
384+ return 'ruby'
385+ case '.rs' :
386+ return 'rust'
387+ case '.scala' :
388+ case '.sc' :
389+ return 'scala'
390+ case '.sh' :
391+ case '.bash' :
392+ return 'shell'
393+ case '.sql' :
394+ return 'sql'
395+ case '.swift' :
396+ return 'swift'
397+ case '.sv' :
398+ case '.svh' :
399+ case '.v' :
400+ return 'systemverilog'
401+ case '.tf' :
402+ case '.tfvars' :
403+ return 'tf'
404+ case '.tsx' :
405+ return 'tsx'
406+ case '.ts' :
407+ return 'typescript'
408+ case '.vue' :
409+ return 'vue'
410+ case '.yml' :
411+ case '.yaml' :
412+ return 'yaml'
413+ default :
414+ return ''
415+ }
416+ }
417+
321418/**
322419 * This function will return relevant cross files sorted by file distance for the given editor file
323420 * by referencing open files, imported files and same package files.
324421 */
325- export async function getCrossFileCandidates ( document : TextDocument , workspace : Workspace ) : Promise < TextDocument [ ] > {
422+ export async function getCrossFileCandidates (
423+ document : TextDocument ,
424+ workspace : Workspace ,
425+ openTabFiles ?: string [ ]
426+ ) : Promise < TextDocument [ ] > {
326427 const targetFile = document . uri
327428 const language = document . languageId as CrossFileSupportedLanguage
328429 const dialects = supportedLanguageToDialects [ language ]
@@ -335,8 +436,34 @@ export async function getCrossFileCandidates(document: TextDocument, workspace:
335436 *
336437 * Porting note: this function relies of Workspace feature to get all documents,
337438 * managed by this language server, instead of VSCode `vscode.window` API as VSCode toolkit does.
439+ * this function only gets the user opened tab in this IDE session
440+ * for a resumed IDE session, opened tabs are restored but this getAllTextDocuments function returns empty
441+ * in that case we manually create TextDocuments from it
338442 */
339- const unsortedCandidates = await workspace . getAllTextDocuments ( )
443+ let unsortedCandidates : TextDocument [ ] = await workspace . getAllTextDocuments ( )
444+ if ( openTabFiles && openTabFiles . length > 0 ) {
445+ for ( const openTabFile of openTabFiles ) {
446+ try {
447+ const openTabFilesUri = URI . file ( openTabFile )
448+ if ( ! unsortedCandidates . some ( x => x . uri === openTabFilesUri . toString ( ) ) ) {
449+ const content = await workspace . fs . readFile ( openTabFilesUri . fsPath )
450+ if ( content ) {
451+ unsortedCandidates . push (
452+ TextDocument . create (
453+ URI . file ( openTabFile ) . toString ( ) ,
454+ guessLanguageId ( openTabFilesUri . fsPath ) ,
455+ 1 ,
456+ content
457+ )
458+ )
459+ }
460+ }
461+ } catch ( e ) {
462+ // do not throw here.
463+ }
464+ }
465+ }
466+
340467 return unsortedCandidates
341468 . filter ( ( candidateFile : TextDocument ) => {
342469 let candidateFileURL
0 commit comments