diff --git a/clwb/sdkcompat/v242/BUILD b/clwb/sdkcompat/v242/BUILD index 4543fd52cae..19648e84a59 100644 --- a/clwb/sdkcompat/v242/BUILD +++ b/clwb/sdkcompat/v242/BUILD @@ -14,6 +14,6 @@ filegroup( name = "v242", - srcs = glob(["**/*.java"]), + srcs = glob(["**/*.java", "**/*.kt"]), visibility = ["//clwb/sdkcompat:__pkg__"], ) diff --git a/clwb/sdkcompat/v242/com/google/idea/blaze/clwb/CLionNotificationProvider.java b/clwb/sdkcompat/v242/com/google/idea/blaze/clwb/CLionNotificationProvider.java deleted file mode 100644 index 372a7d8b2a2..00000000000 --- a/clwb/sdkcompat/v242/com/google/idea/blaze/clwb/CLionNotificationProvider.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2023 The Bazel Authors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.idea.blaze.clwb; - -import com.google.idea.blaze.base.lang.buildfile.language.BuildFileType; -import com.google.idea.blaze.base.settings.Blaze; -import com.google.idea.blaze.base.wizard2.BazelImportCurrentProjectAction; -import com.google.idea.blaze.base.wizard2.BazelNotificationProvider; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.EditorNotificationProvider; -import com.jetbrains.cidr.project.ui.ProjectStatusHelperKt; -import com.jetbrains.cidr.project.ui.notifications.EditorNotificationWarningProvider; -import com.jetbrains.cidr.project.ui.notifications.ProjectNotification; -import com.jetbrains.cidr.project.ui.popup.ProjectFixesProvider; -import com.jetbrains.cidr.project.ui.widget.*; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -import static com.jetbrains.cidr.project.ui.ProjectStatusHelperKt.isProjectAwareFile; - -// #api241 -public class CLionNotificationProvider implements ProjectFixesProvider, WidgetStatusProvider, - EditorNotificationWarningProvider { - - private static void unregisterGenericProvider(Project project) { - final var extensionPoint = EditorNotificationProvider.EP_NAME.getPoint(project); - - // Note: We need to remove the default style of showing project status and fixes used in - // Android Studio and IDEA to introduce CLion's PSW style. - for (final var extension : extensionPoint.getExtensions()) { - if (extension instanceof BazelNotificationProvider) { - extensionPoint.unregisterExtension(extension); - } - } - } - - public static void register(Project project) { - unregisterGenericProvider(project); - - final var projectFixes = ProjectFixesProvider.Companion.getEP_NAME().getPoint(); - projectFixes.registerExtension(new CLionNotificationProvider()); - final var projectNotifications = EditorNotificationWarningProvider.Companion.getEP_NAME() - .getPoint(); - projectNotifications.registerExtension(new CLionNotificationProvider()); - final var widgetStatus = WidgetStatusProvider.Companion.getEP_NAME().getPoint(); - widgetStatus.registerExtension(new CLionNotificationProvider()); - } - - @NotNull - @Override - public List collectFixes(@NotNull Project project, @Nullable VirtualFile file, - @NotNull DataContext dataContext) { - if (file == null) { - return List.of(); - } - - if (Blaze.isBlazeProject(project)) { - return List.of(); - } - - if (!isProjectAwareFile(file, project) && file.getFileType() != BuildFileType.INSTANCE) { - return List.of(); - } - if (!BazelImportCurrentProjectAction.projectCouldBeImported(project)) { - return List.of(); - } - - String root = project.getBasePath(); - if (root == null) { - return List.of(); - } - - return List.of(new ImportBazelAction(root)); - } - - private static class ImportBazelAction extends AnAction { - - private final String root; - - public ImportBazelAction(String root) { - super("Import Bazel project"); - this.root = root; - } - - @Override - public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - BazelImportCurrentProjectAction.createAction(root).run(); - } - } - - @Nullable - @Override - public ProjectNotification getProjectNotification(@NotNull Project project, - @NotNull VirtualFile virtualFile) { - return ProjectStatusHelperKt.convertStatus(getWidgetStatus(project, virtualFile)); - } - - @Nullable - @Override - public WidgetStatus getWidgetStatus(@NotNull Project project, @Nullable VirtualFile file) { - - if (Blaze.isBlazeProject(project)) { - return new DefaultWidgetStatus(Status.OK, Scope.Project, "Project is configured"); - } - - if (file == null) { - return null; - } - - if (!isProjectAwareFile(file, project) && file.getFileType() != BuildFileType.INSTANCE) { - return null; - } - if (!BazelImportCurrentProjectAction.projectCouldBeImported(project)) { - return null; - } - - String root = project.getBasePath(); - if (root == null) { - return null; - } - - return new DefaultWidgetStatus(Status.Warning, Scope.Project, "Project is not configured"); - } -} diff --git a/clwb/sdkcompat/v242/com/google/idea/blaze/clwb/CLionNotificationProvider.kt b/clwb/sdkcompat/v242/com/google/idea/blaze/clwb/CLionNotificationProvider.kt new file mode 100644 index 00000000000..01cbc0d57df --- /dev/null +++ b/clwb/sdkcompat/v242/com/google/idea/blaze/clwb/CLionNotificationProvider.kt @@ -0,0 +1,132 @@ +/* + * Copyright 2023 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.idea.blaze.clwb + +import com.google.idea.blaze.base.lang.buildfile.language.BuildFileType +import com.google.idea.blaze.base.settings.Blaze +import com.google.idea.blaze.base.wizard2.BazelImportCurrentProjectAction +import com.google.idea.blaze.base.wizard2.BazelNotificationProvider +import com.intellij.openapi.Disposable +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.service +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.ui.EditorNotificationProvider +import com.jetbrains.cidr.lang.daemon.OCFileScopeProvider.Companion.getProjectSourceLocationKind +import com.jetbrains.cidr.project.ui.convertStatus +import com.jetbrains.cidr.project.ui.isProjectAwareFile +import com.jetbrains.cidr.project.ui.notifications.EditorNotificationWarningProvider +import com.jetbrains.cidr.project.ui.notifications.ProjectNotification +import com.jetbrains.cidr.project.ui.popup.ProjectFixesProvider +import com.jetbrains.cidr.project.ui.widget.* + +private fun isBazelAwareFile(project: Project, file: VirtualFile): Boolean { + if (Blaze.isBlazeProject(project)) { + return false + } + + if (!isProjectAwareFile(file, project) && file.fileType !== BuildFileType.INSTANCE) { + return false + } + + if (getProjectSourceLocationKind(project, file).isInProject()) { + return false + } + + if (!BazelImportCurrentProjectAction.projectCouldBeImported(project)) { + return false + } + + return project.basePath != null +} + +// #api241 +@Service(Service.Level.APP) +class CLionNotificationProvider : ProjectFixesProvider, WidgetStatusProvider, EditorNotificationWarningProvider, + Disposable.Default { + + companion object { + @JvmStatic + fun register(project: Project) { + service().unregisterGenericProvider(project) + } + } + + init { + registerSpecificProvider(); + } + + private fun registerSpecificProvider() { + val projectFixes = ProjectFixesProvider.Companion.EP_NAME.point + projectFixes.registerExtension(this, this) + + val projectNotifications = EditorNotificationWarningProvider.EP_NAME.point + projectNotifications.registerExtension(this, this) + + val widgetStatus = WidgetStatusProvider.EP_NAME.point + widgetStatus.registerExtension(this, this) + } + + private fun unregisterGenericProvider(project: Project) { + val extensionPoint = EditorNotificationProvider.EP_NAME.getPoint(project) + + // Note: We need to remove the default style of showing project status and fixes used in + // Android Studio and IDEA to introduce CLion's PSW style. + for (extension in extensionPoint.extensions) { + if (extension is BazelNotificationProvider) { + extensionPoint.unregisterExtension(extension) + } + } + } + + override fun collectFixes(project: Project, file: VirtualFile?, dataContext: DataContext): List { + if (file == null) { + return emptyList() + } + + val isBazelFile = isBazelAwareFile(project, file) + if (!isBazelFile) { + return emptyList() + } + + return listOf(ImportBazelAction(project.basePath ?: return emptyList())) + } + + private class ImportBazelAction(private val root: String) : AnAction("Import Bazel project") { + override fun actionPerformed(anActionEvent: AnActionEvent) { + BazelImportCurrentProjectAction.createAction(root).run() + } + } + + override fun getProjectNotification(project: Project, virtualFile: VirtualFile): ProjectNotification? { + return convertStatus(getWidgetStatus(project, virtualFile)) + } + + override fun getWidgetStatus(project: Project, file: VirtualFile?): WidgetStatus? { + if (Blaze.isBlazeProject(project)) { + return DefaultWidgetStatus(Status.OK, Scope.Project, "Project is configured") + } + + if (file == null || !isBazelAwareFile(project, file)) { + return null + } + + return DefaultWidgetStatus(Status.Warning, Scope.Project, "Project is not configured") + } +} diff --git a/clwb/sdkcompat/v243/com/google/idea/blaze/clwb/CLionNotificationProvider.kt b/clwb/sdkcompat/v243/com/google/idea/blaze/clwb/CLionNotificationProvider.kt index 1dd1014180d..e9453a4cf33 100644 --- a/clwb/sdkcompat/v243/com/google/idea/blaze/clwb/CLionNotificationProvider.kt +++ b/clwb/sdkcompat/v243/com/google/idea/blaze/clwb/CLionNotificationProvider.kt @@ -19,12 +19,18 @@ import com.google.idea.blaze.base.lang.buildfile.language.BuildFileType import com.google.idea.blaze.base.settings.Blaze import com.google.idea.blaze.base.wizard2.BazelImportCurrentProjectAction import com.google.idea.blaze.base.wizard2.BazelNotificationProvider +import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.application.readAction +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.service +import com.intellij.openapi.extensions.LoadingOrder import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.ui.EditorNotificationProvider +import com.jetbrains.cidr.lang.daemon.OCFileScopeProvider.Companion.getProjectSourceLocationKind import com.jetbrains.cidr.project.ui.convertStatus import com.jetbrains.cidr.project.ui.isProjectAwareFile import com.jetbrains.cidr.project.ui.notifications.EditorNotificationWarningProvider @@ -32,21 +38,72 @@ import com.jetbrains.cidr.project.ui.notifications.ProjectNotification import com.jetbrains.cidr.project.ui.popup.ProjectFixesProvider import com.jetbrains.cidr.project.ui.widget.* +private fun isBazelAwareFile(project: Project, file: VirtualFile): Boolean { + if (Blaze.isBlazeProject(project)) { + return false + } + + if (!isProjectAwareFile(file, project) && file.fileType !== BuildFileType.INSTANCE) { + return false + } + + if (getProjectSourceLocationKind(project, file).isInProject()) { + return false + } + + if (!BazelImportCurrentProjectAction.projectCouldBeImported(project)) { + return false + } + + return project.basePath != null +} + // #api241 -class CLionNotificationProvider : ProjectFixesProvider, WidgetStatusProvider, EditorNotificationWarningProvider { - override suspend fun collectFixes(project: Project, file: VirtualFile?, dataContext: DataContext): List { - if (file == null) { - return emptyList() +@Service(Service.Level.APP) +class CLionNotificationProvider : ProjectFixesProvider, WidgetStatusProvider, EditorNotificationWarningProvider, + Disposable.Default { + + companion object { + @JvmStatic + fun register(project: Project) { + service().unregisterGenericProvider(project) } + } - if (Blaze.isBlazeProject(project)) { - return emptyList() + init { + registerSpecificProvider(); + } + + private fun registerSpecificProvider() { + val projectFixes = ProjectFixesProvider.Companion.EP_NAME.point + projectFixes.registerExtension(this, this) + + val projectNotifications = EditorNotificationWarningProvider.EP_NAME.point + projectNotifications.registerExtension(this, this) + + val widgetStatus = WidgetStatusProvider.EP_NAME.point + widgetStatus.registerExtension(this, this) + } + + private fun unregisterGenericProvider(project: Project) { + val extensionPoint = EditorNotificationProvider.EP_NAME.getPoint(project) + + // Note: We need to remove the default style of showing project status and fixes used in + // Android Studio and IDEA to introduce CLion's PSW style. + for (extension in extensionPoint.extensions) { + if (extension is BazelNotificationProvider) { + extensionPoint.unregisterExtension(extension) + } } + } - if (!isProjectAwareFile(file, project) && file.fileType != BuildFileType.INSTANCE) { + override suspend fun collectFixes(project: Project, file: VirtualFile?, dataContext: DataContext): List { + if (file == null) { return emptyList() } - if (!BazelImportCurrentProjectAction.projectCouldBeImported(project)) { + + val isBazelFile = readAction { isBazelAwareFile(project, file) } + if (!isBazelFile) { return emptyList() } @@ -64,53 +121,14 @@ class CLionNotificationProvider : ProjectFixesProvider, WidgetStatusProvider, Ed } override fun getWidgetStatus(project: Project, file: VirtualFile?): WidgetStatus? { - if (Blaze.isBlazeProject(project)) { - return DefaultWidgetStatus(Status.OK, Scope.Project, "Project is configured") - } - - if (file == null) { - return null - } - - if (!isProjectAwareFile(file, project) && file.getFileType() !== BuildFileType.INSTANCE) { - return null - } - if (!BazelImportCurrentProjectAction.projectCouldBeImported(project)) { - return null - } - - if (project.basePath == null) { - return null - } - - return DefaultWidgetStatus(Status.Warning, Scope.Project, "Project is not configured") - } - - companion object { - private fun unregisterGenericProvider(project: Project) { - val extensionPoint = EditorNotificationProvider.EP_NAME.getPoint(project) - - // Note: We need to remove the default style of showing project status and fixes used in - // Android Studio and IDEA to introduce CLion's PSW style. - for (extension in extensionPoint.extensions) { - if (extension is BazelNotificationProvider) { - extensionPoint.unregisterExtension(extension) - } - } + if (Blaze.isBlazeProject(project)) { + return DefaultWidgetStatus(Status.OK, Scope.Project, "Project is configured") } - @JvmStatic - fun register(project: Project) { - unregisterGenericProvider(project) - - val projectFixes = ProjectFixesProvider.Companion.EP_NAME.point - projectFixes.registerExtension(CLionNotificationProvider()) - - val projectNotifications = EditorNotificationWarningProvider.Companion.EP_NAME.point - projectNotifications.registerExtension(CLionNotificationProvider()) - - val widgetStatus = WidgetStatusProvider.Companion.EP_NAME.point - widgetStatus.registerExtension(CLionNotificationProvider()) + if (file == null || !isBazelAwareFile(project, file)) { + return null } + + return DefaultWidgetStatus(Status.Warning, Scope.Project, "Project is not configured") } }