Skip to content

Commit

Permalink
use project scope for navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
LeFrosch committed Oct 18, 2024
1 parent 590a382 commit 2611aef
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,48 @@ package com.google.idea.blaze.base.buildview.events

import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager
import com.google.idea.blaze.base.lang.buildfile.references.LabelUtils
import com.google.idea.blaze.base.util.pluginProjectScope
import com.intellij.build.issue.BuildIssue
import com.intellij.build.issue.BuildIssueQuickFix
import com.intellij.openapi.application.invokeLater
import com.intellij.openapi.application.readAction
import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.project.Project
import com.intellij.pom.Navigatable
import com.intellij.pom.NavigatableAdapter
import kotlinx.coroutines.launch

data class BazelBuildIssue(
override val title: String,
override val description: String,
override val quickFixes: List<BuildIssueQuickFix> = emptyList(),
val label: String? = null,
) : BuildIssue {
override fun getNavigatable(project: Project): Navigatable? {
if (label == null) return null
return LabelNavigatable(project, label)
}
}

inner class LabelNavigatable(private val project: Project) : NavigatableAdapter() {
override fun navigate(requestFocus: Boolean) {
// TODO: better use `bazel query "label" --output=location` - would be way more accurate ??

val label = LabelUtils.createLabelFromString(null, label) ?: return
val element = BuildReferenceManager.getInstance(project).resolveLabel(label) ?: return

val file = element.containingFile.virtualFile ?: return
OpenFileDescriptor(project, file, element.textRange.startOffset).navigate(requestFocus)
private class LabelNavigatable(private val project: Project, private val label: String) : NavigatableAdapter() {
override fun navigate(requestFocus: Boolean) {
pluginProjectScope(project).launch {
val descriptor = readAction { findFileAsync() }
if (descriptor != null && descriptor.canNavigate()) {
invokeLater {
descriptor.navigate(requestFocus)
}
}
}
}

override fun getNavigatable(project: Project): Navigatable? {
if (label == null) return null
return LabelNavigatable(project)
private fun findFileAsync(): OpenFileDescriptor? {
// TODO: better use `bazel query "label" --output=location` - would be way more accurate ??

val label = LabelUtils.createLabelFromString(null, label) ?: return null
val element = BuildReferenceManager.getInstance(project).resolveLabel(label) ?: return null

val file = element.containingFile.virtualFile ?: return null
return OpenFileDescriptor(project, file, element.textRange.startOffset)
}
}
25 changes: 25 additions & 0 deletions base/src/com/google/idea/blaze/base/util/ScopeService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.google.idea.blaze.base.util

import com.intellij.openapi.Disposable
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel

@Service(Service.Level.PROJECT)
private class ProjectScopeService : Disposable {
// #api223 use the injected scope
val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)

override fun dispose() {
scope.cancel()
}
}

/**
* Gets a coroutine scope that is canceled when either the project is closed or the plugin is unloaded.
*/
fun pluginProjectScope(project: Project): CoroutineScope = project.service<ProjectScopeService>().scope

0 comments on commit 2611aef

Please sign in to comment.