Skip to content

Commit 80b389e

Browse files
author
Jiatong Li
committed
feat(amazonq): send relative file path for inline completion
1 parent 116ea07 commit 80b389e

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ import {
4141
SINGLE_LINE_FILE_CUTOFF_INDEX,
4242
SOME_CLOSED_FILE,
4343
SOME_FILE,
44+
SOME_FILE_UNDER_WORKSPACE_FOLDER,
4445
SOME_FILE_WITH_ALT_CASED_LANGUAGE_ID,
4546
SOME_FILE_WITH_EXTENSION,
4647
SOME_SINGLE_LINE_FILE,
4748
SOME_UNSUPPORTED_FILE,
49+
SOME_WORKSPACE_FOLDER,
4850
SPECIAL_CHARACTER_HELLO_WORLD,
4951
stubCodeWhispererService,
5052
} from '../../shared/testUtils'
@@ -55,6 +57,7 @@ import { LocalProjectContextController } from '../../shared/localProjectContextC
5557
import { URI } from 'vscode-uri'
5658
import { INVALID_TOKEN } from '../../shared/constants'
5759
import { AmazonQError, AmazonQServiceConnectionExpiredError } from '../../shared/amazonQServiceManager/errors'
60+
import * as path from 'path'
5861

5962
const updateConfiguration = async (
6063
features: TestFeatures,
@@ -148,6 +151,7 @@ describe('CodeWhisperer Server', () => {
148151
.openDocument(SOME_UNSUPPORTED_FILE)
149152
.openDocument(SOME_FILE_WITH_EXTENSION)
150153
.openDocument(SOME_SINGLE_LINE_FILE)
154+
.openDocument(SOME_FILE_UNDER_WORKSPACE_FOLDER)
151155
})
152156

153157
afterEach(() => {
@@ -245,6 +249,35 @@ describe('CodeWhisperer Server', () => {
245249
)
246250
})
247251

252+
it('should correctly get filename', async () => {
253+
features.workspace.getWorkspaceFolder
254+
.withArgs(SOME_FILE_UNDER_WORKSPACE_FOLDER.uri)
255+
.returns(SOME_WORKSPACE_FOLDER)
256+
const result = await features.doInlineCompletionWithReferences(
257+
{
258+
textDocument: { uri: SOME_FILE_UNDER_WORKSPACE_FOLDER.uri },
259+
position: { line: 0, character: 0 },
260+
context: { triggerKind: InlineCompletionTriggerKind.Invoked },
261+
},
262+
CancellationToken.None
263+
)
264+
265+
// Check the completion result
266+
assert.deepEqual(result, EXPECTED_RESULT)
267+
268+
const expectedGenerateSuggestionsRequest = {
269+
fileContext: {
270+
fileUri: SOME_FILE_UNDER_WORKSPACE_FOLDER.uri,
271+
filename: path.relative(SOME_WORKSPACE_FOLDER.uri, SOME_FILE_UNDER_WORKSPACE_FOLDER.uri),
272+
programmingLanguage: { languageName: 'csharp' },
273+
leftFileContent: '',
274+
rightFileContent: HELLO_WORLD_IN_CSHARP,
275+
},
276+
maxResults: 5,
277+
}
278+
sinon.assert.calledOnceWithExactly(service.generateSuggestions, expectedGenerateSuggestionsRequest)
279+
})
280+
248281
it('should return recommendations when using a different languageId casing', async () => {
249282
const result = await features.doInlineCompletionWithReferences(
250283
{

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

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
TextDocument,
1414
ResponseError,
1515
LSPErrorCodes,
16+
WorkspaceFolder,
1617
} from '@aws/language-server-runtimes/server-interface'
1718
import { AWSError } from 'aws-sdk'
1819
import { autoTrigger, triggerType } from './auto-trigger/autoTrigger'
@@ -56,13 +57,15 @@ import { UserWrittenCodeTracker } from '../../shared/userWrittenCodeTracker'
5657

5758
const EMPTY_RESULT = { sessionId: '', items: [] }
5859
export const FILE_URI_CHARS_LIMIT = 1024
60+
export const FILENAME_CHARS_LIMIT = 1024
5961
export const CONTEXT_CHARACTERS_LIMIT = 10240
6062

6163
// Both clients (token, sigv4) define their own types, this return value needs to match both of them.
6264
const getFileContext = (params: {
6365
textDocument: TextDocument
6466
position: Position
6567
inferredLanguageId: CodewhispererLanguage
68+
workspaceFolder: WorkspaceFolder | null | undefined
6669
}): {
6770
fileUri: string
6871
filename: string
@@ -81,18 +84,13 @@ const getFileContext = (params: {
8184
end: params.textDocument.positionAt(params.textDocument.getText().length),
8285
})
8386

84-
let relativeFileName = params.textDocument.uri
85-
relativeFileName = path.basename(params.textDocument.uri)
86-
// const workspaceFolder = WorkspaceFolderManager.getInstance()?.getWorkspaceFolder(params.textDocument.uri)
87-
// if (workspaceFolder) {
88-
// relativeFileName = getRelativePath(workspaceFolder, params.textDocument.uri)
89-
// } else {
90-
// relativeFileName = path.basename(params.textDocument.uri)
91-
// }
87+
const relativeFilePath = params.workspaceFolder
88+
? getRelativePath(params.workspaceFolder, params.textDocument.uri)
89+
: path.basename(params.textDocument.uri)
9290

9391
return {
9492
fileUri: params.textDocument.uri.substring(0, FILE_URI_CHARS_LIMIT),
95-
filename: relativeFileName,
93+
filename: relativeFilePath.substring(0, FILENAME_CHARS_LIMIT),
9694
programmingLanguage: {
9795
languageName: getRuntimeLanguage(params.inferredLanguageId),
9896
},
@@ -346,7 +344,12 @@ export const CodewhispererServerFactory =
346344
params.context.triggerKind == InlineCompletionTriggerKind.Automatic
347345
const maxResults = isAutomaticLspTriggerKind ? 1 : 5
348346
const selectionRange = params.context.selectedCompletionInfo?.range
349-
const fileContext = getFileContext({ textDocument, inferredLanguageId, position: params.position })
347+
const fileContext = getFileContext({
348+
textDocument,
349+
inferredLanguageId,
350+
position: params.position,
351+
workspaceFolder: workspace.getWorkspaceFolder(textDocument.uri),
352+
})
350353
const workspaceState = WorkspaceFolderManager.getInstance()?.getWorkspaceState()
351354
const workspaceId = workspaceState?.webSocketClient?.isConnected()
352355
? workspaceState.workspaceId

server/aws-lsp-codewhisperer/src/shared/testUtils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { SsoConnectionType } from './utils'
55
import { stubInterface } from 'ts-sinon'
66
import { StreamingClientServiceBase } from './streamingClientService'
77
import { SessionData } from '../language-server/inline-completion/session/sessionManager'
8+
import { WorkspaceFolder } from '@aws/language-server-runtimes/protocol'
89

910
export const HELLO_WORLD_IN_CSHARP = `class HelloWorld
1011
{
@@ -34,6 +35,16 @@ export const SOME_UNSUPPORTED_FILE = TextDocument.create(
3435
'INPUT HELLO ; OUTPUT WORLD'
3536
)
3637
export const SOME_FILE_WITH_EXTENSION = TextDocument.create('file:///missing.hpp', '', 1, HELLO_WORLD_IN_CSHARP)
38+
export const SOME_WORKSPACE_FOLDER: WorkspaceFolder = {
39+
uri: 'file:///tmp/workspaceFolderTest',
40+
name: 'workspaceFolderTest',
41+
}
42+
export const SOME_FILE_UNDER_WORKSPACE_FOLDER = TextDocument.create(
43+
`${SOME_WORKSPACE_FOLDER.uri}/relativePath/test.cs`,
44+
'csharp',
45+
1,
46+
HELLO_WORLD_IN_CSHARP
47+
)
3748

3849
export const SAMPLE_FILE_OF_60_LINES_IN_JAVA = `import java.util.List;
3950
// we need this comment on purpose because chunk will be trimed right, adding this to avoid trimRight and make assertion easier

0 commit comments

Comments
 (0)