Skip to content

Commit f94910f

Browse files
authored
bug fix(amazonq): fix an issue where user action is accept but telemetry is reject (#5319)
* bug fix(amazonq): fix an issue where user action is accept but telemetry is reject * detekt * fix increment logic when IntelliSense is showing up * Change to use a semaphore
1 parent 76f7518 commit f94910f

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/popup/CodeWhispererPopupManager.kt

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ import com.intellij.ui.popup.AbstractPopup
4141
import com.intellij.ui.popup.PopupFactoryImpl
4242
import com.intellij.util.messages.Topic
4343
import com.intellij.util.ui.UIUtil
44+
import kotlinx.coroutines.sync.Semaphore
4445
import software.amazon.awssdk.services.codewhispererruntime.model.Import
4546
import software.amazon.awssdk.services.codewhispererruntime.model.Reference
4647
import software.aws.toolkits.core.utils.debug
48+
import software.aws.toolkits.core.utils.error
4749
import software.aws.toolkits.core.utils.getLogger
4850
import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorManager
4951
import software.aws.toolkits.jetbrains.services.codewhisperer.layout.CodeWhispererLayoutConfig.addHorizontalGlue
@@ -85,7 +87,8 @@ import javax.swing.JLabel
8587
class CodeWhispererPopupManager {
8688
val popupComponents = CodeWhispererPopupComponents()
8789

88-
var shouldListenerCancelPopup: Boolean = true
90+
// Act like a semaphore: one increment only corresponds to one decrement
91+
var allowEditsDuringSuggestionPreview = Semaphore(MAX_EDIT_SOURCE_DURING_SUGGESTION_PREVIEW)
8992
var sessionContext = SessionContext()
9093
private set
9194

@@ -245,12 +248,20 @@ class CodeWhispererPopupManager {
245248
}
246249
}
247250

251+
// Don't want to block or throw any kinds of exceptions here if it can continue to provide suggestions
248252
fun dontClosePopupAndRun(runnable: () -> Unit) {
249-
try {
250-
shouldListenerCancelPopup = false
251-
runnable()
252-
} finally {
253-
shouldListenerCancelPopup = true
253+
if (allowEditsDuringSuggestionPreview.tryAcquire()) {
254+
try {
255+
runnable()
256+
} finally {
257+
try {
258+
allowEditsDuringSuggestionPreview.release()
259+
} catch (e: Exception) {
260+
LOG.error(e) { "Failed to release allowEditsDuringSuggestionPreview semaphore" }
261+
}
262+
}
263+
} else {
264+
LOG.error { "Failed to acquire allowEditsDuringSuggestionPreview semaphore" }
254265
}
255266
}
256267

@@ -496,7 +507,7 @@ class CodeWhispererPopupManager {
496507
val editor = states.requestContext.editor
497508
val codewhispererSelectionListener: SelectionListener = object : SelectionListener {
498509
override fun selectionChanged(event: SelectionEvent) {
499-
if (shouldListenerCancelPopup) {
510+
if (allowEditsDuringSuggestionPreview.availablePermits == MAX_EDIT_SOURCE_DURING_SUGGESTION_PREVIEW) {
500511
cancelPopup(states.popup)
501512
}
502513
super.selectionChanged(event)
@@ -512,7 +523,7 @@ class CodeWhispererPopupManager {
512523
if (!delete) return
513524
if (editor.caretModel.offset == event.offset) {
514525
changeStates(states, 0)
515-
} else if (shouldListenerCancelPopup) {
526+
} else if (allowEditsDuringSuggestionPreview.availablePermits == MAX_EDIT_SOURCE_DURING_SUGGESTION_PREVIEW) {
516527
cancelPopup(states.popup)
517528
}
518529
}
@@ -521,7 +532,7 @@ class CodeWhispererPopupManager {
521532

522533
val codewhispererCaretListener: CaretListener = object : CaretListener {
523534
override fun caretPositionChanged(event: CaretEvent) {
524-
if (shouldListenerCancelPopup) {
535+
if (allowEditsDuringSuggestionPreview.availablePermits == MAX_EDIT_SOURCE_DURING_SUGGESTION_PREVIEW) {
525536
cancelPopup(states.popup)
526537
}
527538
super.caretPositionChanged(event)
@@ -702,6 +713,7 @@ class CodeWhispererPopupManager {
702713
"CodeWhisperer user action performed",
703714
CodeWhispererUserActionListener::class.java
704715
)
716+
const val MAX_EDIT_SOURCE_DURING_SUGGESTION_PREVIEW = 2
705717
}
706718
}
707719

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/popup/listeners/CodeWhispererPopupIntelliSenseAcceptListener.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ import com.intellij.codeInsight.lookup.LookupEvent
88
import com.intellij.codeInsight.lookup.LookupListener
99
import com.intellij.codeInsight.lookup.LookupManagerListener
1010
import com.intellij.codeInsight.lookup.impl.LookupImpl
11+
import software.aws.toolkits.core.utils.error
12+
import software.aws.toolkits.core.utils.getLogger
1113
import software.aws.toolkits.jetbrains.services.codewhisperer.model.InvocationContext
1214
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager
15+
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.listeners.CodeWhispererPopupIntelliSenseAcceptListener.Companion.LOG
1316
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatus
1417

1518
class CodeWhispererPopupIntelliSenseAcceptListener(private val states: InvocationContext) : LookupManagerListener {
@@ -18,14 +21,17 @@ class CodeWhispererPopupIntelliSenseAcceptListener(private val states: Invocatio
1821

1922
addIntelliSenseAcceptListener(newLookup, states)
2023
}
24+
25+
companion object {
26+
val LOG = getLogger<CodeWhispererPopupIntelliSenseAcceptListener>()
27+
}
2128
}
2229

2330
fun addIntelliSenseAcceptListener(lookup: Lookup, states: InvocationContext) {
31+
if (!CodeWhispererPopupManager.getInstance().allowEditsDuringSuggestionPreview.tryAcquire()) {
32+
LOG.error { "Failed to acquire allowEditsDuringSuggestionPreview semaphore" }
33+
}
2434
lookup.addLookupListener(object : LookupListener {
25-
override fun beforeItemSelected(event: LookupEvent): Boolean {
26-
CodeWhispererPopupManager.getInstance().shouldListenerCancelPopup = false
27-
return super.beforeItemSelected(event)
28-
}
2935
override fun itemSelected(event: LookupEvent) {
3036
if (!CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive() ||
3137
!(event.lookup as LookupImpl).isShown
@@ -46,7 +52,11 @@ fun addIntelliSenseAcceptListener(lookup: Lookup, states: InvocationContext) {
4652

4753
private fun cleanup() {
4854
lookup.removeLookupListener(this)
49-
CodeWhispererPopupManager.getInstance().shouldListenerCancelPopup = true
55+
try {
56+
CodeWhispererPopupManager.getInstance().allowEditsDuringSuggestionPreview.release()
57+
} catch (e: Exception) {
58+
LOG.error(e) { "Failed to release allowEditsDuringSuggestionPreview semaphore" }
59+
}
5060
}
5161
})
5262
}

0 commit comments

Comments
 (0)