Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(codewhisperer): make CWSPR connection application wide #3658

Closed
wants to merge 9 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ class CodeWhispererWhatIsAction :
),
DumbAware {
override fun update(e: AnActionEvent) {
e.project?.let {
e.presentation.isEnabledAndVisible = isCodeWhispererEnabled(it)
}
e.presentation.isEnabledAndVisible = isCodeWhispererEnabled()
}

override fun actionPerformed(e: AnActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ class CodeWhispererCodeScanManager(val project: Project) {
* Triggers a code scan and displays results in the new tab in problems view panel.
*/
fun runCodeScan() {
if (!isCodeWhispererEnabled(project)) return
if (!isCodeWhispererEnabled()) return

// Return if a scan is already in progress.
if (isCodeScanInProgress.getAndSet(true)) return
if (promptReAuth(project)) {
if (promptReAuth()) {
isCodeScanInProgress.set(false)
return
}
Expand Down Expand Up @@ -165,7 +165,7 @@ class CodeWhispererCodeScanManager(val project: Project) {
val startTime = Instant.now().toEpochMilli()
var codeScanResponseContext = defaultCodeScanResponseContext()
var getProjectSize: Deferred<Long?> = async { null }
val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())
val connection = ToolkitConnectionManager.getInstance(null).activeConnectionForFeature(CodeWhispererConnection.getInstance())
zixlin7 marked this conversation as resolved.
Show resolved Hide resolved
try {
val file = FileEditorManager.getInstance(project).selectedEditor?.file
?: noFileOpenError()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CodeWhispererCodeScanRunAction : DumbAwareAction(
) {
override fun update(event: AnActionEvent) {
val project = event.project ?: return
event.presentation.isEnabledAndVisible = isCodeWhispererEnabled(project)
event.presentation.isEnabledAndVisible = isCodeWhispererEnabled()
val scanManager = CodeWhispererCodeScanManager.getInstance(project)
event.presentation.icon = scanManager.getRunActionButtonIcon()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ interface CodeWhispererClientAdaptor : Disposable {
fun getInstance(project: Project): CodeWhispererClientAdaptor = project.service()

private fun shouldUseSigv4Client(project: Project) =
CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType(project) == CodeWhispererLoginType.Accountless
CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType() == CodeWhispererLoginType.Accountless
}
}

Expand Down Expand Up @@ -158,7 +158,7 @@ open class CodeWhispererClientAdaptorImpl(override val project: Project) : CodeW
ApplicationManager.getApplication().messageBus.syncPublisher(CREDENTIALS_CHANGED)
.providerRemoved(oldProviderIdToRemove)

val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())
val connection = ToolkitConnectionManager.getInstance(null).activeConnectionForFeature(CodeWhispererConnection.getInstance())
connection as? AwsBearerTokenConnection ?: error("$connection is not a bearer token connection")
return AwsClientManager.getInstance().getClient<CodeWhispererRuntimeClient>(connection.getConnectionSettings())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CodeWhispererEditorListener : EditorFactoryListener {
editor.document.addDocumentListener(
object : BulkAwareDocumentListener {
override fun documentChanged(event: DocumentEvent) {
if (!isCodeWhispererEnabled(project)) return
if (!isCodeWhispererEnabled()) return
CodeWhispererInvocationStatus.getInstance().documentChanged()
CodeWhispererCodeCoverageTracker.getInstance(language).apply {
activateTrackerIfNotActive()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class CodeWhispererExplorerActionManager : PersistentStateComponent<CodeWhispere
}

private fun getCodeWhispererConnectionStartUrl(project: Project): String {
val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())
val connection = ToolkitConnectionManager.getInstance(null).activeConnectionForFeature(CodeWhispererConnection.getInstance())
return getConnectionStartUrl(connection) ?: CodeWhispererConstants.ACCOUNTLESS_START_URL
}

Expand Down Expand Up @@ -118,11 +118,11 @@ class CodeWhispererExplorerActionManager : PersistentStateComponent<CodeWhispere
return actionState.token
}

fun checkActiveCodeWhispererConnectionType(project: Project) = when {
fun checkActiveCodeWhispererConnectionType() = when {
actionState.token != null -> CodeWhispererLoginType.Accountless
isAccessTokenExpired(project) || isRefreshTokenExpired(project) -> CodeWhispererLoginType.Expired
isAccessTokenExpired() || isRefreshTokenExpired() -> CodeWhispererLoginType.Expired
else -> {
val conn = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())
val conn = ToolkitConnectionManager.getInstance(null).activeConnectionForFeature(CodeWhispererConnection.getInstance())
if (conn != null) {
if (conn.isSono()) {
CodeWhispererLoginType.Sono
Expand Down Expand Up @@ -196,10 +196,10 @@ interface CodeWhispererActivationChangedListener {
fun activationChanged(value: Boolean) {}
}

fun isCodeWhispererEnabled(project: Project) = with(CodeWhispererExplorerActionManager.getInstance()) {
checkActiveCodeWhispererConnectionType(project) != CodeWhispererLoginType.Logout
fun isCodeWhispererEnabled() = with(CodeWhispererExplorerActionManager.getInstance()) {
checkActiveCodeWhispererConnectionType() != CodeWhispererLoginType.Logout
}

fun isCodeWhispererExpired(project: Project) = with(CodeWhispererExplorerActionManager.getInstance()) {
checkActiveCodeWhispererConnectionType(project) == CodeWhispererLoginType.Expired
fun isCodeWhispererExpired() = with(CodeWhispererExplorerActionManager.getInstance()) {
checkActiveCodeWhispererConnectionType() == CodeWhispererLoginType.Expired
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class CodeWhispererServiceNode(
}

val manager = CodeWhispererExplorerActionManager.getInstance()
val activeConnectionType = manager.checkActiveCodeWhispererConnectionType(project)
val activeConnectionType = manager.checkActiveCodeWhispererConnectionType()

return when (activeConnectionType) {
CodeWhispererLoginType.Logout -> listOf(whatIsCodeWhispererNode, getStartedCodeWhispererNode)
Expand All @@ -106,7 +106,7 @@ class CodeWhispererServiceNode(
return
}

val connectionType = CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType(project)
val connectionType = CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType()
when (connectionType) {
CodeWhispererLoginType.Expired -> {
presentation.addText(message("codewhisperer.explorer.root_node.login_type.expired"), SimpleTextAttributes.GRAY_ATTRIBUTES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ class CodeWhispererReconnectNode(nodeProject: Project) : CodeWhispererActionNode
AllIcons.Actions.Execute
) {
override fun onDoubleClick(event: MouseEvent) {
reconnectCodeWhisperer(project)
reconnectCodeWhisperer()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class GetStartedNode(nodeProject: Project) : CodeWhispererActionNode(
*/
private fun enableCodeWhisperer(project: Project) {
val explorerActionManager = CodeWhispererExplorerActionManager.getInstance()
val connectionManager = ToolkitConnectionManager.getInstance(project)
val connectionManager = ToolkitConnectionManager.getInstance(null)
connectionManager.activeConnectionForFeature(CodeWhispererConnection.getInstance())?.let {
project.refreshDevToolTree()
} ?: run {
Expand All @@ -58,7 +58,7 @@ class GetStartedNode(nodeProject: Project) : CodeWhispererActionNode(
}
}

if (isCodeWhispererEnabled(project)) {
if (isCodeWhispererEnabled()) {
StartupActivity.POST_STARTUP_ACTIVITY.findExtension(CodeWhispererProjectStartupActivity::class.java)?.let {
it.runActivity(project)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ class CodeWhispererService {
latencyContext: LatencyContext
) {
val project = editor.project ?: return
if (!isCodeWhispererEnabled(project)) return
if (!isCodeWhispererEnabled()) return

latencyContext.credentialFetchingStart = System.nanoTime()

if (promptReAuth(project)) return
if (promptReAuth()) return

latencyContext.credentialFetchingEnd = System.nanoTime()
val psiFile = runReadAction { PsiDocumentManager.getInstance(project).getPsiFile(editor.document) }
Expand Down Expand Up @@ -490,7 +490,7 @@ class CodeWhispererService {
): RequestContext {
val fileContextInfo = getFileContextInfo(editor, psiFile)
val caretPosition = getCaretPosition(editor)
val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())
val connection = ToolkitConnectionManager.getInstance(null).activeConnectionForFeature(CodeWhispererConnection.getInstance())
return RequestContext(project, editor, triggerTypeInfo, caretPosition, fileContextInfo, connection, latencyContext)
}

Expand Down Expand Up @@ -573,10 +573,8 @@ class CodeWhispererService {
}

fun canDoInvocation(editor: Editor, type: CodewhispererTriggerType): Boolean {
editor.project?.let {
if (!isCodeWhispererEnabled(it)) {
return false
}
if (!isCodeWhispererEnabled()) {
return false
}

if (type == CodewhispererTriggerType.AutoTrigger && !CodeWhispererExplorerActionManager.getInstance().isAutoEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ class CodeWhispererConfigurable(private val project: Project) :
get() = CodeWhispererSettings.getInstance()

private val isSso: Boolean
get() = CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType(project) == CodeWhispererLoginType.SSO
get() = CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType() == CodeWhispererLoginType.SSO

override fun getId() = "aws.codewhisperer"

override fun createPanel() = panel {
val connect = project.messageBus.connect(disposable ?: error("disposable wasn't initialized by framework"))
val invoke = isCodeWhispererEnabled(project)
val invoke = isCodeWhispererEnabled()

// TODO: can we remove message bus subscribe and solely use visible(boolean) / enabled(boolean), consider multi project cases
row {
Expand All @@ -42,7 +42,7 @@ class CodeWhispererConfigurable(private val project: Project) :
ToolkitConnectionManagerListener.TOPIC,
object : ToolkitConnectionManagerListener {
override fun activeConnectionChanged(newConnection: ToolkitConnection?) {
visible(!isCodeWhispererEnabled(project))
visible(!isCodeWhispererEnabled())
}
}
)
Expand All @@ -55,7 +55,7 @@ class CodeWhispererConfigurable(private val project: Project) :
ToolkitConnectionManagerListener.TOPIC,
object : ToolkitConnectionManagerListener {
override fun activeConnectionChanged(newConnection: ToolkitConnection?) {
enabled(isCodeWhispererEnabled(project) && !isSso)
enabled(isCodeWhispererEnabled() && !isSso)
}
}
)
Expand All @@ -70,7 +70,7 @@ class CodeWhispererConfigurable(private val project: Project) :
ToolkitConnectionManagerListener.TOPIC,
object : ToolkitConnectionManagerListener {
override fun activeConnectionChanged(newConnection: ToolkitConnection?) {
enabled(isCodeWhispererEnabled(project))
enabled(isCodeWhispererEnabled())
}
}
)
Expand All @@ -85,7 +85,7 @@ class CodeWhispererConfigurable(private val project: Project) :
ToolkitConnectionManagerListener.TOPIC,
object : ToolkitConnectionManagerListener {
override fun activeConnectionChanged(newConnection: ToolkitConnection?) {
enabled(isCodeWhispererEnabled(project) && !isSso)
enabled(isCodeWhispererEnabled() && !isSso)
}
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ class CodeWhispererProjectStartupActivity : StartupActivity.DumbAware {
if (!ApplicationManager.getApplication().isUnitTestMode) {
CodeWhispererStatusBarManager.getInstance(project).updateWidget()
}
if (!isCodeWhispererEnabled(project)) return
if (!isCodeWhispererEnabled()) return
if (runOnce) return

// Reconnect CodeWhisperer on startup
promptReAuth(project)
promptReAuth()

CodeWhispererAutoTriggerService.getInstance().determineUserGroupIfNeeded()

Expand All @@ -56,7 +56,7 @@ class CodeWhispererProjectStartupActivity : StartupActivity.DumbAware {
}

private fun showAccountlessNotificationIfNeeded(project: Project) {
if (CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType(project) == CodeWhispererLoginType.Accountless) {
if (CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType() == CodeWhispererLoginType.Accountless) {
// simply show a notification when user login with Accountless, and it's still supported by CodeWhisperer
if (!isExpired()) {
// don't show warn notification if user selected Don't show again or if notification was shown less than a week ago
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class CodeWhispererProjectStartupSettingsListener(private val project: Project)
override fun toolWindowShown(toolWindow: ToolWindow) {
super.toolWindowShown(toolWindow)
if (toolWindow.id != ProblemsView.ID) return
if (!isCodeWhispererEnabled(project)) return
if (!isCodeWhispererEnabled()) return
CodeWhispererCodeScanManager.getInstance(project).addCodeScanUI()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class CodeWhispererStatusBarManager(private val project: Project) : Disposable {
ExtensionPointName<StatusBarWidgetFactory>("com.intellij.statusBarWidgetFactory").extensionList.find {
it.id == CodeWhispererStatusBarWidgetFactory.ID
}?.let {
settings.setEnabled(it, isCodeWhispererEnabled(project))
settings.setEnabled(it, isCodeWhispererEnabled())
widgetsManager.updateWidget(it)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ class CodeWhispererStatusBarWidget(project: Project) :
override fun getClickConsumer(): Consumer<MouseEvent>? = null

override fun getPopupStep(): ListPopup? =
if (isCodeWhispererExpired(project)) {
JBPopupFactory.getInstance().createConfirmation(message("codewhisperer.statusbar.popup.title"), { reconnectCodeWhisperer(project) }, 0)
if (isCodeWhispererExpired()) {
JBPopupFactory.getInstance().createConfirmation(message("codewhisperer.statusbar.popup.title"), { reconnectCodeWhisperer() }, 0)
} else {
null
}

override fun getSelectedValue(): String = message("codewhisperer.statusbar.display_name")

override fun getIcon(): Icon =
if (isCodeWhispererExpired(project)) {
if (isCodeWhispererExpired()) {
AllIcons.General.BalloonWarning
} else if (CodeWhispererInvocationStatus.getInstance().hasExistingInvocation()) {
AnimatedIcon.Default()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ class CodeWhispererStatusBarWidgetFactory : StatusBarEditorBasedWidgetFactory()

override fun getDisplayName(): String = message("codewhisperer.statusbar.display_name")

override fun isAvailable(project: Project): Boolean =
isCodeWhispererEnabled(project)
override fun isAvailable(project: Project): Boolean = isCodeWhispererEnabled()

override fun createWidget(project: Project): StatusBarWidget = CodeWhispererStatusBarWidget(project)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,22 @@ class CodeWhispererCodeReferenceComponents(private val project: Project) {
}.asCodeReferencePanelFont()

init {
repaint(project)
repaint()

// set the reference panel text different for SSO users vs AWS Builder ID / Accless users
project.messageBus.connect().subscribe(
ToolkitConnectionManagerListener.TOPIC,
object : ToolkitConnectionManagerListener {
override fun activeConnectionChanged(newConnection: ToolkitConnection?) {
repaint(project)
repaint()
}
}
)
}

// TODO: figure out how to have a different view for SSO user in a cleaner way, maybe have 2 sets of components stored in [ReferenceManager]?
private fun repaint(project: Project) {
val loginType = CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType(project)
private fun repaint() {
val loginType = CodeWhispererExplorerActionManager.getInstance().checkActiveCodeWhispererConnectionType()
settingsLabelPrefixText as JLabel
settingsLabelLink as ActionLink
if (loginType == CodeWhispererLoginType.SSO) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class CodeWhispererCodeReferenceToolWindowFactory : ToolWindowFactory, DumbAware
toolWindow.contentManager.addContent(toolWindowContent)
}

override fun shouldBeAvailable(project: Project): Boolean = isCodeWhispererEnabled(project)
override fun shouldBeAvailable(project: Project): Boolean = isCodeWhispererEnabled()

companion object {
const val id = "aws.codewhisperer.codereference"
Expand Down
Loading
Loading