Skip to content

Commit 44d81f0

Browse files
authored
feat: merge updates for inline completions (#1299)
1 parent 50a5bd1 commit 44d81f0

File tree

8 files changed

+382
-150
lines changed

8 files changed

+382
-150
lines changed

client/vscode/src/inlineCompletionActivation.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ export const CodewhispererInlineCompletionLanguages = [
4141
{ scheme: 'file', language: 'scala' },
4242
{ scheme: 'file', language: 'vue' },
4343
{ scheme: 'file', language: 'csharp' },
44+
{ scheme: 'file', language: 'c' },
45+
{ scheme: 'file', language: 'cpp' },
46+
{ scheme: 'file', language: 'python' },
47+
{ scheme: 'file', language: 'sql' },
48+
{ scheme: 'file', language: 'jsx' },
49+
{ scheme: 'file', language: 'tsx' },
4450
]
4551

4652
export function registerInlineCompletion(languageClient: LanguageClient) {

server/aws-lsp-codewhisperer/src/language-server/inline-completion/codeWhispererServer.test.ts

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,22 @@ import {
2121
import { CodeWhispererSession, SessionData, SessionManager } from './session/sessionManager'
2222
import {
2323
EMPTY_RESULT,
24+
EXPECTED_NEXT_TOKEN,
2425
EXPECTED_REFERENCE,
2526
EXPECTED_RESPONSE_CONTEXT,
2627
EXPECTED_RESULT,
28+
EXPECTED_RESULT_WITHOUT_IMPORTS,
2729
EXPECTED_RESULT_WITHOUT_REFERENCES,
30+
EXPECTED_RESULT_WITH_IMPORTS,
2831
EXPECTED_RESULT_WITH_REFERENCES,
2932
EXPECTED_SESSION_ID,
3033
EXPECTED_SUGGESTION,
3134
EXPECTED_SUGGESTION_LIST,
35+
EXPECTED_SUGGESTION_LIST_WITH_IMPORTS,
3236
HELLO_WORLD_IN_CSHARP,
3337
HELLO_WORLD_LINE,
3438
HELLO_WORLD_WITH_WINDOWS_ENDING,
39+
SAMPLE_SESSION_DATA,
3540
SINGLE_LINE_FILE_CUTOFF_INDEX,
3641
SOME_CLOSED_FILE,
3742
SOME_FILE,
@@ -413,8 +418,10 @@ describe('CodeWhisperer Server', () => {
413418
insertText: deletedLine.concat('\n '),
414419
range: undefined,
415420
references: undefined,
421+
mostRelevantMissingImports: undefined,
416422
},
417423
],
424+
partialResultToken: undefined,
418425
}
419426

420427
const result = await features.doInlineCompletionWithReferences(
@@ -497,8 +504,10 @@ describe('CodeWhisperer Server', () => {
497504
insertText: HELLO_WORLD_LINE.substring(0, SINGLE_LINE_FILE_CUTOFF_INDEX),
498505
range: undefined,
499506
references: undefined,
507+
mostRelevantMissingImports: undefined,
500508
},
501509
],
510+
partialResultToken: undefined,
502511
}
503512

504513
const result = await features.doInlineCompletionWithReferences(
@@ -529,8 +538,10 @@ describe('CodeWhisperer Server', () => {
529538
insertText: EXPECTED_SUGGESTION[0].content,
530539
range: undefined,
531540
references: undefined,
541+
mostRelevantMissingImports: undefined,
532542
},
533543
],
544+
partialResultToken: undefined,
534545
}
535546

536547
const result = await features.doInlineCompletionWithReferences(
@@ -561,6 +572,54 @@ describe('CodeWhisperer Server', () => {
561572
assert.deepEqual(result, EMPTY_RESULT)
562573
})
563574

575+
// pagination
576+
it('returns next token from service', async () => {
577+
service.generateSuggestions.returns(
578+
Promise.resolve({
579+
suggestions: EXPECTED_SUGGESTION,
580+
responseContext: { ...EXPECTED_RESPONSE_CONTEXT, nextToken: EXPECTED_NEXT_TOKEN },
581+
})
582+
)
583+
584+
const result = await features.doInlineCompletionWithReferences(
585+
{
586+
textDocument: { uri: SOME_FILE.uri },
587+
position: { line: 0, character: 0 },
588+
context: { triggerKind: InlineCompletionTriggerKind.Invoked },
589+
},
590+
CancellationToken.None
591+
)
592+
593+
assert.deepEqual(result, { ...EXPECTED_RESULT, partialResultToken: EXPECTED_NEXT_TOKEN })
594+
})
595+
596+
it('handles partialResultToken in request', async () => {
597+
const manager = SessionManager.getInstance()
598+
manager.createSession(SAMPLE_SESSION_DATA)
599+
await features.doInlineCompletionWithReferences(
600+
{
601+
textDocument: { uri: SOME_FILE.uri },
602+
position: { line: 0, character: 0 },
603+
context: { triggerKind: InlineCompletionTriggerKind.Invoked },
604+
partialResultToken: EXPECTED_NEXT_TOKEN,
605+
},
606+
CancellationToken.None
607+
)
608+
609+
const expectedGenerateSuggestionsRequest = {
610+
fileContext: {
611+
filename: SOME_FILE.uri,
612+
programmingLanguage: { languageName: 'csharp' },
613+
leftFileContent: '',
614+
rightFileContent: HELLO_WORLD_IN_CSHARP,
615+
},
616+
maxResults: 5,
617+
nextToken: EXPECTED_NEXT_TOKEN,
618+
}
619+
620+
sinon.assert.calledOnceWithExactly(service.generateSuggestions, expectedGenerateSuggestionsRequest)
621+
})
622+
564623
describe('Supplemental Context', () => {
565624
it('should send supplemental context when using token authentication', async () => {
566625
const test_service = sinon.createStubInstance(
@@ -700,6 +759,53 @@ describe('CodeWhisperer Server', () => {
700759
assert.deepEqual(result, EXPECTED_RESULT_WITHOUT_REFERENCES)
701760
})
702761

762+
it('should not include import statements if no settings are specified', async () => {
763+
features.lsp.workspace.getConfiguration.returns(Promise.resolve({}))
764+
await startServer(features, server)
765+
766+
service.generateSuggestions.returns(
767+
Promise.resolve({
768+
suggestions: EXPECTED_SUGGESTION_LIST_WITH_IMPORTS,
769+
responseContext: EXPECTED_RESPONSE_CONTEXT,
770+
})
771+
)
772+
773+
const result = await features.openDocument(SOME_FILE).doInlineCompletionWithReferences(
774+
{
775+
textDocument: { uri: SOME_FILE.uri },
776+
position: { line: 0, character: 0 },
777+
context: { triggerKind: InlineCompletionTriggerKind.Invoked },
778+
},
779+
CancellationToken.None
780+
)
781+
782+
// Check the completion result
783+
assert.deepEqual(result, EXPECTED_RESULT_WITHOUT_IMPORTS)
784+
})
785+
786+
it('should include import statements if enabled', async () => {
787+
features.lsp.workspace.getConfiguration.returns(Promise.resolve({ includeImportsWithSuggestions: true }))
788+
await startServer(features, server)
789+
790+
service.generateSuggestions.returns(
791+
Promise.resolve({
792+
suggestions: EXPECTED_SUGGESTION_LIST_WITH_IMPORTS,
793+
responseContext: EXPECTED_RESPONSE_CONTEXT,
794+
})
795+
)
796+
797+
const result = await features.openDocument(SOME_FILE).doInlineCompletionWithReferences(
798+
{
799+
textDocument: { uri: SOME_FILE.uri },
800+
position: { line: 0, character: 0 },
801+
context: { triggerKind: InlineCompletionTriggerKind.Invoked },
802+
},
803+
CancellationToken.None
804+
)
805+
806+
assert.deepEqual(result, EXPECTED_RESULT_WITH_IMPORTS)
807+
})
808+
703809
it('should filter recommendations with references if GetConfiguration is not handled by the client', async () => {
704810
features.lsp.workspace.getConfiguration.returns(Promise.reject(new Error('GetConfiguration failed')))
705811
await startServer(features, server)
@@ -870,8 +976,10 @@ describe('CodeWhisperer Server', () => {
870976
},
871977
},
872978
],
979+
mostRelevantMissingImports: undefined,
873980
},
874981
],
982+
partialResultToken: undefined,
875983
}
876984
service.generateSuggestions.returns(
877985
Promise.resolve({
@@ -929,8 +1037,10 @@ describe('CodeWhisperer Server', () => {
9291037
insertText: insertText,
9301038
range: undefined,
9311039
references: undefined,
1040+
mostRelevantMissingImports: undefined,
9321041
},
9331042
],
1043+
partialResultToken: undefined,
9341044
}
9351045
service.generateSuggestions.returns(
9361046
Promise.resolve({
@@ -1792,7 +1902,7 @@ describe('CodeWhisperer Server', () => {
17921902
const EXPECTED_COMPLETION_RESPONSES = [
17931903
{ sessionId: '', items: [] },
17941904
{ sessionId: '', items: [] },
1795-
{ sessionId: SESSION_IDS_LOG[2], items: EXPECTED_RESULT.items }, // Last session wins
1905+
{ sessionId: SESSION_IDS_LOG[2], items: EXPECTED_RESULT.items, partialResultToken: undefined }, // Last session wins
17961906
]
17971907
// Only last request must return completion items
17981908
assert.deepEqual(getCompletionsResponses, EXPECTED_COMPLETION_RESPONSES)

0 commit comments

Comments
 (0)