Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "bugfix",
"description" : "Amazon Q /review: Unable to navigate to code location when selecting issues"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.ActionGroup
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.ActionToolbar
import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.AnimatedIcon
import com.intellij.ui.ClickListener
import com.intellij.ui.OnePixelSplitter
import com.intellij.ui.ScrollPaneFactory
import com.intellij.ui.border.CustomLineBorder
Expand All @@ -19,7 +21,8 @@ import com.intellij.ui.treeStructure.Tree
import com.intellij.util.ui.JBUI
import icons.AwsIcons
import kotlinx.coroutines.CoroutineScope
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.listeners.CodeWhispererCodeScanTreeMouseListener
import software.aws.toolkits.core.utils.error
import software.aws.toolkits.core.utils.getLogger
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.utils.IssueGroupingStrategy
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.utils.IssueSeverity
import software.aws.toolkits.jetbrains.services.codewhisperer.layout.CodeWhispererLayoutConfig
Expand All @@ -31,7 +34,6 @@ import java.awt.BorderLayout
import java.awt.Component
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
import java.awt.event.MouseEvent
import java.time.Instant
import java.time.format.DateTimeFormatter
import javax.swing.BorderFactory
Expand All @@ -52,15 +54,18 @@ internal class CodeWhispererCodeScanResultsView(private val project: Project, pr

private val codeScanTree: Tree = Tree().apply {
isRootVisible = false
CodeWhispererCodeScanTreeMouseListener(project).installOn(this)
object : ClickListener() {
override fun onClick(event: MouseEvent, clickCount: Int): Boolean {
val issueNode = (event.source as Tree).selectionPath?.lastPathComponent as? DefaultMutableTreeNode
val issue = issueNode?.userObject as? CodeWhispererCodeScanIssue ?: return false
showIssueDetails(issue, defaultScope)
return true

addTreeSelectionListener { e ->
val issueNode = e.path.lastPathComponent as? DefaultMutableTreeNode
val issue = issueNode?.userObject as? CodeWhispererCodeScanIssue ?: return@addTreeSelectionListener

showIssueDetails(issue, defaultScope)

synchronized(issueNode) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what exactly does the synchronized block solve?

Copy link
Contributor Author

@zuoyaofu zuoyaofu Feb 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a logic transfer from the OnDoubleClick function.

My guess is that it prevents the issue from being modified (by auto scan completion which modifies the code issues or other selection?) during the execution of navigating to the line in the Editor, but I have not been able to reproduce such scenario. I left the synchronized block there just in case.

if (issueNode.userObject !is CodeWhispererCodeScanIssue) return@addTreeSelectionListener
navigateToIssue(issueNode.userObject as CodeWhispererCodeScanIssue)
}
}.installOn(this)
}
cellRenderer = ColoredTreeCellRenderer()
}

Expand Down Expand Up @@ -390,8 +395,31 @@ internal class CodeWhispererCodeScanResultsView(private val project: Project, pr
}
}

// Move navigateToIssue as a private class function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh before, the navigateToIssue was in the On double click function. This comment does not make sense anymore now. Let me delete it.

private fun navigateToIssue(codeScanIssue: CodeWhispererCodeScanIssue) {
val textRange = codeScanIssue.textRange ?: return
val startOffset = textRange.startOffset

if (codeScanIssue.isInvalid) return

runInEdt {
val editor = FileEditorManager.getInstance(project).openTextEditor(
OpenFileDescriptor(project, codeScanIssue.file, startOffset),
false
)
if (editor == null) {
LOG.error { "Cannot fetch editor for the file ${codeScanIssue.file.path}" }
return@runInEdt
}
if (codeScanIssue.rangeHighlighter == null) {
codeScanIssue.rangeHighlighter = codeScanIssue.addRangeHighlighter(editor.markupModel)
}
}
}

private companion object {
const val ACTION_PLACE = "CodeScanResultsPanel"
const val CODE_SCAN_SPLITTER_PROPORTION_KEY = "CODE_SCAN_SPLITTER_PROPORTION"
private val LOG = getLogger<CodeWhispererCodeScanResultsView>()
}
}

This file was deleted.

Loading