fix: [NO BACKPORT] replace internal API usage with safe reflection

This commit is contained in:
FalsePattern 2024-09-20 13:31:18 +02:00
parent 52a3714175
commit a76138ddea
Signed by: falsepattern
GPG key ID: E930CDEC50C50E23
2 changed files with 63 additions and 12 deletions

View file

@ -19,9 +19,9 @@ package com.falsepattern.zigbrains.zig.lsp;
import com.falsepattern.zigbrains.ZigBundle; import com.falsepattern.zigbrains.ZigBundle;
import com.falsepattern.zigbrains.common.util.ApplicationUtil; import com.falsepattern.zigbrains.common.util.ApplicationUtil;
import com.falsepattern.zigbrains.zig.settings.ZLSProjectSettingsService; import com.falsepattern.zigbrains.zig.settings.ZLSProjectSettingsService;
import com.falsepattern.zigbrains.zig.util.JBInternalPluginManagerConfigurable;
import com.intellij.ide.BrowserUtil; import com.intellij.ide.BrowserUtil;
import com.intellij.ide.plugins.PluginManager; import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.PluginManagerConfigurable;
import com.intellij.notification.Notification; import com.intellij.notification.Notification;
import com.intellij.notification.NotificationAction; import com.intellij.notification.NotificationAction;
import com.intellij.notification.NotificationType; import com.intellij.notification.NotificationType;
@ -69,17 +69,17 @@ public class ZLSStartupActivity implements ProjectActivity {
ZigBundle.message("notification.nativedebug.text"), ZigBundle.message("notification.nativedebug.text"),
NotificationType.INFORMATION NotificationType.INFORMATION
); );
notif.addAction(new NotificationAction(ZigBundle.message("notification.nativedebug.market")) { if (JBInternalPluginManagerConfigurable.successful) {
@Override notif.addAction(new NotificationAction(ZigBundle.message("notification.nativedebug.market")) {
public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { @Override
val configurable = new PluginManagerConfigurable(); public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) {
ShowSettingsUtil.getInstance().editConfigurable((Project)null, val configurable = new JBInternalPluginManagerConfigurable();
configurable, ShowSettingsUtil.getInstance().editConfigurable((Project) null, configurable.instance, () -> {
() -> { configurable.openMarketplaceTab("/vendor:\"JetBrains s.r.o.\" /tag:Debugging \"Native Debugging Support\"");
configurable.openMarketplaceTab("/vendor:\"JetBrains s.r.o.\" /tag:Debugging \"Native Debugging Support\""); });
}); }
} });
}); }
notif.addAction(new NotificationAction(ZigBundle.message("notification.nativedebug.browser")) { notif.addAction(new NotificationAction(ZigBundle.message("notification.nativedebug.browser")) {
@Override @Override
public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) {

View file

@ -0,0 +1,51 @@
package com.falsepattern.zigbrains.zig.util;
import com.intellij.openapi.options.Configurable;
import lombok.val;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//JetBrains Internal API, but we need to access it, so access it reflectively (hopefully safe enough to pass verifier)
public class JBInternalPluginManagerConfigurable {
private static final Constructor<?> constructor;
private static final Method openMarketplaceTab;
public static final boolean successful;
public final Configurable instance;
static {
boolean success = false;
Constructor<?> constructor1 = null;
Method openMarketplaceTab1 = null;
try {
val theClass = Class.forName("com_intellij_ide_plugins_PluginManagerConfigurable".replace('_', '.'));
constructor1 = theClass.getDeclaredConstructor();
constructor1.setAccessible(true);
openMarketplaceTab1 = theClass.getDeclaredMethod("openMarketplaceTab", String.class);
openMarketplaceTab1.setAccessible(true);
success = true;
} catch (Throwable ignored) {
}
successful = success;
constructor = constructor1;
openMarketplaceTab = openMarketplaceTab1;
}
public JBInternalPluginManagerConfigurable() {
try {
instance = (Configurable) constructor.newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public void openMarketplaceTab(String option) {
try {
openMarketplaceTab.invoke(instance, option);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}