Skip to content

Commit 82cca2b

Browse files
committed
fix: use last args to avoid improper suggestions
1 parent 142566b commit 82cca2b

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

packages/amazonq/src/app/inline/recommendationService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class RecommendationService {
2222
private readonly inlineGeneratingMessage: InlineGeneratingMessage
2323
) {}
2424

25-
getAllRecommendations = debounce(this._getAllRecommendations.bind(this), inlineCompletionsDebounceDelay)
25+
getAllRecommendations = debounce(this._getAllRecommendations.bind(this), inlineCompletionsDebounceDelay, true)
2626

2727
private async _getAllRecommendations(
2828
languageClient: LanguageClient,

packages/amazonq/test/unit/amazonq/apps/inline/recommendationService.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,47 @@ describe('RecommendationService', () => {
214214

215215
await promise2
216216
})
217+
218+
it('makes request with the last call', async () => {
219+
const mockResult = {
220+
sessionId: 'test-session',
221+
items: [mockInlineCompletionItemOne],
222+
partialResultToken: undefined,
223+
}
224+
225+
sendRequestStub.resolves(mockResult)
226+
227+
const promise1 = service.getAllRecommendations(
228+
languageClient,
229+
mockDocument,
230+
mockPosition,
231+
mockContext,
232+
mockToken
233+
)
234+
235+
const promise2 = service.getAllRecommendations(
236+
languageClient,
237+
mockDocument,
238+
{ line: 2, character: 2 } as Position,
239+
mockContext,
240+
mockToken
241+
)
242+
243+
await clock.tickAsync(inlineCompletionsDebounceDelay + 1000)
244+
245+
await promise1
246+
await promise2
247+
248+
const expectedRequestArgs = {
249+
textDocument: {
250+
uri: 'file:///test.py',
251+
},
252+
position: { line: 2, character: 2 } as Position,
253+
context: mockContext,
254+
}
255+
const firstCallArgs = sendRequestStub.firstCall.args[1]
256+
assert.deepStrictEqual(firstCallArgs, expectedRequestArgs)
257+
})
217258
})
218259
})
219260
})

packages/core/src/shared/utilities/functionUtils.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,10 @@ export function memoize<T, U extends any[]>(fn: (...args: U) => T): (...args: U)
9393
*/
9494
export function debounce<Input extends any[], Output>(
9595
cb: (...args: Input) => Output | Promise<Output>,
96-
delay: number = 0
96+
delay: number = 0,
97+
useLastCall: boolean = false
9798
): (...args: Input) => Promise<Output> {
98-
return cancellableDebounce(cb, delay).promise
99+
return cancellableDebounce(cb, delay, useLastCall).promise
99100
}
100101

101102
/**
@@ -104,10 +105,12 @@ export function debounce<Input extends any[], Output>(
104105
*/
105106
export function cancellableDebounce<Input extends any[], Output>(
106107
cb: (...args: Input) => Output | Promise<Output>,
107-
delay: number = 0
108+
delay: number = 0,
109+
useLastCall: boolean = false
108110
): { promise: (...args: Input) => Promise<Output>; cancel: () => void } {
109111
let timeout: Timeout | undefined
110112
let promise: Promise<Output> | undefined
113+
let lastestArgs: Input | undefined
111114

112115
const cancel = (): void => {
113116
if (timeout) {
@@ -119,14 +122,16 @@ export function cancellableDebounce<Input extends any[], Output>(
119122

120123
return {
121124
promise: (...args: Input) => {
125+
lastestArgs = args
122126
timeout?.refresh()
123127

124128
return (promise ??= new Promise<Output>((resolve, reject) => {
125129
timeout = new Timeout(delay)
126130
timeout.onCompletion(async () => {
127131
timeout = promise = undefined
128132
try {
129-
resolve(await cb(...args))
133+
const argsToUse = useLastCall ? lastestArgs! : args
134+
resolve(await cb(...argsToUse))
130135
} catch (err) {
131136
reject(err)
132137
}

packages/core/src/test/shared/utilities/functionUtils.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,32 @@ describe('debounce', function () {
152152
assert.strictEqual(counter, 2)
153153
})
154154

155+
describe('useLastCall option', function () {
156+
let args: number[]
157+
let clock: ReturnType<typeof installFakeClock>
158+
let addToArgs: (i: number) => void
159+
160+
before(function () {
161+
args = []
162+
clock = installFakeClock()
163+
addToArgs = args.push
164+
})
165+
166+
afterEach(function () {
167+
clock.uninstall()
168+
args.length = 0
169+
})
170+
171+
it('only calls with the last args', async function () {
172+
const debounced = debounce((i: number) => args.push(i), 10, true)
173+
debounced(1)
174+
debounced(2)
175+
debounced(3)
176+
await clock.tickAsync(100)
177+
assert.deepStrictEqual(args, [3])
178+
})
179+
})
180+
155181
describe('window rolling', function () {
156182
let clock: ReturnType<typeof installFakeClock>
157183
const calls: ReturnType<typeof fn>[] = []

0 commit comments

Comments
 (0)