Skip to content

Commit a205b61

Browse files
committed
fix(amazonq): apply fix removes other issues
1 parent ce5e05b commit a205b61

File tree

4 files changed

+59
-39
lines changed

4 files changed

+59
-39
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": "/review: Apply fix removes other issues in the same file."
4+
}

packages/core/src/codewhisperer/activation.ts

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -670,27 +670,28 @@ export async function activate(context: ExtContext): Promise<void> {
670670
function setSubscriptionsForCodeIssues() {
671671
context.extensionContext.subscriptions.push(
672672
vscode.workspace.onDidChangeTextDocument(async (e) => {
673-
// verify the document is something with a finding
674-
for (const issue of SecurityIssueProvider.instance.issues) {
675-
if (issue.filePath === e.document.uri.fsPath) {
676-
disposeSecurityDiagnostic(e)
677-
678-
SecurityIssueProvider.instance.handleDocumentChange(e)
679-
SecurityIssueTreeViewProvider.instance.refresh()
680-
await syncSecurityIssueWebview(context)
681-
682-
toggleIssuesVisibility((issue, filePath) =>
683-
filePath !== e.document.uri.fsPath
684-
? issue.visible
685-
: !detectCommentAboveLine(
686-
e.document,
687-
issue.startLine,
688-
CodeWhispererConstants.amazonqIgnoreNextLine
689-
)
690-
)
691-
break
692-
}
673+
if (e.document.uri.scheme !== 'file') {
674+
return
693675
}
676+
const diagnostics = securityScanRender.securityDiagnosticCollection?.get(e.document.uri)
677+
if (!diagnostics || diagnostics.length === 0) {
678+
return
679+
}
680+
disposeSecurityDiagnostic(e)
681+
682+
SecurityIssueProvider.instance.handleDocumentChange(e)
683+
SecurityIssueTreeViewProvider.instance.refresh()
684+
await syncSecurityIssueWebview(context)
685+
686+
toggleIssuesVisibility((issue, filePath) =>
687+
filePath !== e.document.uri.fsPath
688+
? issue.visible
689+
: !detectCommentAboveLine(
690+
e.document,
691+
issue.startLine,
692+
CodeWhispererConstants.amazonqIgnoreNextLine
693+
)
694+
)
694695
})
695696
)
696697
}

packages/core/src/codewhisperer/commands/basicCommands.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import { cancel, confirm } from '../../shared'
6666
import { startCodeFixGeneration } from './startCodeFixGeneration'
6767
import { DefaultAmazonQAppInitContext } from '../../amazonq/apps/initContext'
6868
import path from 'path'
69+
import { parsePatch } from 'diff'
6970

7071
const MessageTimeOut = 5_000
7172

@@ -459,11 +460,21 @@ export const applySecurityFix = Commands.declare(
459460
}
460461

461462
const edit = new vscode.WorkspaceEdit()
462-
edit.replace(
463-
document.uri,
464-
new vscode.Range(document.lineAt(0).range.start, document.lineAt(document.lineCount - 1).range.end),
465-
updatedContent
466-
)
463+
const diffs = parsePatch(suggestedFix.code)
464+
for (const diff of diffs) {
465+
for (const hunk of [...diff.hunks].reverse()) {
466+
const startLine = document.lineAt(hunk.oldStart - 1)
467+
const endLine = document.lineAt(hunk.oldStart - 1 + hunk.oldLines - 1)
468+
const range = new vscode.Range(startLine.range.start, endLine.range.end)
469+
470+
const newText = updatedContent
471+
.split('\n')
472+
.slice(hunk.newStart - 1, hunk.newStart - 1 + hunk.newLines)
473+
.join('\n')
474+
475+
edit.replace(document.uri, range, newText)
476+
}
477+
}
467478
const isApplied = await vscode.workspace.applyEdit(edit)
468479
if (isApplied) {
469480
void document.save().then((didSave) => {

packages/core/src/codewhisperer/service/securityIssueProvider.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import * as vscode from 'vscode'
7-
import { AggregatedCodeScanIssue, CodeScanIssue, SuggestedFix } from '../models/model'
7+
import { AggregatedCodeScanIssue, CodeScanIssue, CodeScansState, SuggestedFix } from '../models/model'
88
export class SecurityIssueProvider {
99
static #instance: SecurityIssueProvider
1010
public static get instance() {
@@ -25,13 +25,15 @@ export class SecurityIssueProvider {
2525
if (!event.contentChanges || event.contentChanges.length === 0) {
2626
return
2727
}
28-
const { changedRange, lineOffset } = event.contentChanges.reduce(
28+
const { changedRange, changedText, lineOffset } = event.contentChanges.reduce(
2929
(acc, change) => ({
3030
changedRange: acc.changedRange.union(change.range),
31+
changedText: acc.changedText + change.text,
3132
lineOffset: acc.lineOffset + this._getLineOffset(change.range, change.text),
3233
}),
3334
{
3435
changedRange: event.contentChanges[0].range,
36+
changedText: '',
3537
lineOffset: 0,
3638
}
3739
)
@@ -43,18 +45,20 @@ export class SecurityIssueProvider {
4345
return {
4446
...group,
4547
issues: group.issues
46-
.filter(
47-
(issue) =>
48-
// Filter out any modified issues
49-
!changedRange.intersection(
50-
new vscode.Range(
51-
issue.startLine,
52-
event.document.lineAt(issue.startLine)?.range.start.character ?? 0,
53-
issue.endLine,
54-
event.document.lineAt(issue.endLine)?.range.end.character ?? 0
55-
)
56-
)
57-
)
48+
.filter((issue) => {
49+
const range = new vscode.Range(
50+
issue.startLine,
51+
event.document.lineAt(issue.startLine)?.range.start.character ?? 0,
52+
issue.endLine,
53+
event.document.lineAt(issue.endLine - 1)?.range.end.character ?? 0
54+
)
55+
const intersection = changedRange.intersection(range)
56+
return !(
57+
intersection &&
58+
(/\S/.test(changedText) || changedText === '') &&
59+
!CodeScansState.instance.isScansEnabled()
60+
)
61+
})
5862
.map((issue) => {
5963
if (issue.startLine < changedRange.end.line) {
6064
return issue

0 commit comments

Comments
 (0)