Skip to content

Commit 9143363

Browse files
authored
fix(codewhisperer): closing symbol handling during typeahead #4257
Problem Closing symbol is not handled correctly when there is typeahead because the recommendation passed in as the argument is "original" which doesn't factor in typeahead. Solution Pass in another range marker, effectiveRange which denotes the effective recommendation written by CodeWhisperer.
1 parent 236dcbd commit 9143363

File tree

9 files changed

+30
-6
lines changed

9 files changed

+30
-6
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "CodeWhisperer not handling extra closing symbols (parenthesis, brackets, quotes) when user typeahead exists"
4+
}

src/codewhisperer/commands/onAcceptance.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export async function onAcceptance(acceptanceEntry: OnRecommendationAcceptanceEn
3939
* Mitigation to right context handling mainly for auto closing bracket use case
4040
*/
4141
try {
42-
await handleExtraBrackets(acceptanceEntry.editor, acceptanceEntry.recommendation, end, start)
42+
await handleExtraBrackets(acceptanceEntry.editor, end, start)
4343
} catch (error) {
4444
getLogger().error(`${error} in handleAutoClosingBrackets`)
4545
}

src/codewhisperer/commands/onInlineAcceptance.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const acceptSuggestion = Commands.declare(
3434
(context: ExtContext) =>
3535
async (
3636
range: vscode.Range,
37+
effectiveRange: vscode.Range,
3738
acceptIndex: number,
3839
recommendation: string,
3940
requestId: string,
@@ -49,6 +50,7 @@ export const acceptSuggestion = Commands.declare(
4950
{
5051
editor,
5152
range,
53+
effectiveRange,
5254
acceptIndex,
5355
recommendation,
5456
requestId,
@@ -88,7 +90,7 @@ export async function onInlineAcceptance(
8890
try {
8991
// Do not handle extra bracket if there is a right context merge
9092
if (acceptanceEntry.recommendation === session.recommendations[acceptanceEntry.acceptIndex].content) {
91-
await handleExtraBrackets(acceptanceEntry.editor, acceptanceEntry.recommendation, end, start)
93+
await handleExtraBrackets(acceptanceEntry.editor, end, acceptanceEntry.effectiveRange.start)
9294
}
9395
await ImportAdderProvider.instance.onAcceptRecommendation(
9496
acceptanceEntry.editor,

src/codewhisperer/models/model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export interface AcceptedSuggestionEntry {
122122
export interface OnRecommendationAcceptanceEntry {
123123
readonly editor: vscode.TextEditor | undefined
124124
readonly range: vscode.Range
125+
readonly effectiveRange: vscode.Range
125126
readonly acceptIndex: number
126127
readonly recommendation: string
127128
readonly requestId: string

src/codewhisperer/service/inlineCompletionItemProvider.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export class CWInlineCompletionItemProvider implements vscode.InlineCompletionIt
9696
if (!r.content.startsWith(prefix)) {
9797
return undefined
9898
}
99+
const effectiveStart = document.positionAt(document.offsetAt(start) + prefix.length)
99100
const truncatedSuggestion = this.truncateOverlapWithRightContext(document, r.content, end)
100101
if (truncatedSuggestion.length === 0) {
101102
if (session.getSuggestionState(index) !== 'Showed') {
@@ -111,6 +112,7 @@ export class CWInlineCompletionItemProvider implements vscode.InlineCompletionIt
111112
title: 'On acceptance',
112113
arguments: [
113114
new vscode.Range(start, end),
115+
new vscode.Range(effectiveStart, end),
114116
index,
115117
truncatedSuggestion,
116118
this.requestId,

src/codewhisperer/util/closingBracketUtil.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,26 @@ const openToClose: bracketMapType = {
3030
}
3131

3232
/**
33-
* @param endPosition: end position of the recommendation
34-
* @param startPosition: start position of the recommendation
33+
* LeftContext | Recommendation | RightContext
34+
* This function aims to resolve symbols which are redundant and need to be removed
35+
* The high level logic is as followed
36+
* 1. Pair non-paired closing symbols(parenthesis, brackets, quotes) existing in the "recommendation" with non-paired symbols existing in the "leftContext"
37+
* 2. Remove non-paired closing symbols existing in the "rightContext"
38+
* @param endPosition: end position of the effective recommendation written by CodeWhisperer
39+
* @param startPosition: start position of the effective recommendation by CodeWhisperer
40+
*
41+
* for example given file context ('|' is where we trigger the service):
42+
* anArray.pu|
43+
* recommendation returned: "sh(element);"
44+
* typeahead: "sh("
45+
* the effective recommendation written by CodeWhisperer: "element);"
3546
*/
3647
export async function handleExtraBrackets(
3748
editor: vscode.TextEditor,
38-
recommendation: string,
3949
endPosition: vscode.Position,
4050
startPosition: vscode.Position
4151
) {
52+
const recommendation = editor.document.getText(new vscode.Range(startPosition, endPosition))
4253
const endOffset = editor.document.offsetAt(endPosition)
4354
const startOffset = editor.document.offsetAt(startPosition)
4455
const leftContext = editor.document.getText(

src/test/codewhisperer/commands/onAcceptance.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ describe('onAcceptance', function () {
5151
{
5252
editor: mockEditor,
5353
range: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 26)),
54+
effectiveRange: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 26)),
5455
acceptIndex: 0,
5556
recommendation: "print('Hello World!')",
5657
requestId: '',
@@ -99,6 +100,7 @@ describe('onAcceptance', function () {
99100
{
100101
editor: mockEditor,
101102
range: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 21)),
103+
effectiveRange: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 26)),
102104
acceptIndex: 0,
103105
recommendation: "print('Hello World!')",
104106
requestId: '',

src/test/codewhisperer/commands/onInlineAcceptance.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('onInlineAcceptance', function () {
3838
{
3939
editor: mockEditor,
4040
range: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 21)),
41+
effectiveRange: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 21)),
4142
acceptIndex: 0,
4243
recommendation: "print('Hello World!')",
4344
requestId: '',
@@ -77,6 +78,7 @@ describe('onInlineAcceptance', function () {
7778
{
7879
editor: mockEditor,
7980
range: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 21)),
81+
effectiveRange: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 21)),
8082
acceptIndex: 0,
8183
recommendation: "print('Hello World!')",
8284
requestId: '',

src/test/codewhisperer/util/closingBracketUtil.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('closingBracketUtil', function () {
3636
assert.strictEqual(right, rightContext)
3737
assert.strictEqual(reco, recommendation)
3838

39-
await handleExtraBrackets(editor, recommendation, end, start)
39+
await handleExtraBrackets(editor, end, start)
4040

4141
assert.strictEqual(editor.document.getText(), expected)
4242
}

0 commit comments

Comments
 (0)