IDEA-283352 Devkit: code insight for EP 'id' in com.intellij.openapi.options.advanced.AdvancedSettings

GitOrigin-RevId: 9959c85d8595b83c120622bcd79fd674aa2bdb09
This commit is contained in:
Yann Cébron
2021-12-08 17:38:22 +01:00
committed by intellij-monorepo-bot
parent 816f5eb6e6
commit 0d8c1bf2c3
7 changed files with 148 additions and 36 deletions

View File

@@ -284,6 +284,7 @@
<implicitUsageProvider implementation="org.jetbrains.idea.devkit.inspections.DevKitImplicitUsageProvider"/>
<psi.referenceContributor language="XML" implementation="org.jetbrains.idea.devkit.dom.impl.I18nReferenceContributor"/>
<psi.referenceContributor language="UAST" implementation="org.jetbrains.idea.devkit.references.ExperimentalFeatureIdContributor"/>
<psi.referenceContributor language="UAST" implementation="org.jetbrains.idea.devkit.references.AdvancedSettingsIdContributor"/>
<psi.referenceContributor implementation="org.jetbrains.idea.devkit.references.IconsReferencesContributor"/>
<psi.referenceContributor language="UAST" implementation="org.jetbrains.idea.devkit.references.TestDataFilesReferencesContributor"/>
<psi.referenceContributor language="XML" implementation="org.jetbrains.idea.devkit.references.ThemeEPPathReferenceContributor"/>

View File

@@ -0,0 +1,79 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.idea.devkit.references;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.options.advanced.AdvancedSettings;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.util.SmartList;
import com.intellij.util.xml.GenericAttributeValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.devkit.DevKitBundle;
import java.util.Collections;
import java.util.List;
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
import static com.intellij.patterns.StandardPatterns.string;
import static com.intellij.patterns.uast.UastPatterns.injectionHostUExpression;
class AdvancedSettingsIdContributor extends PsiReferenceContributor {
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
UastReferenceRegistrar
.registerUastReferenceProvider(registrar,
injectionHostUExpression().methodCallParameter(0, psiMethod()
.withName(string().oneOf(
"getBoolean", "getInt", "getString", "getEnum",
"getDefaultBoolean", "getDefaultInt", "getDefaultString", "getDefaultEnum",
"setBoolean", "setInt", "setString", "setEnum")
)
.definedInClass(AdvancedSettings.class.getName())),
UastReferenceRegistrar.uastInjectionHostReferenceProvider(
(expression, host) -> new PsiReference[]{new AdvancedSettingReference(host)}),
PsiReferenceRegistrar.DEFAULT_PRIORITY);
}
static class AdvancedSettingReference extends ExtensionPointReferenceBase {
AdvancedSettingReference(PsiElement element) {
super(element);
}
AdvancedSettingReference(PsiElement element, TextRange range) {
super(element, range);
}
@Override
protected String getExtensionPointFqn() {
return "com.intellij.advancedSetting";
}
@Override
public @NotNull String getUnresolvedMessagePattern() {
return DevKitBundle.message("message.bundle.convert.advanced.setting.id.cannot.resolve", getValue());
}
@Override
public Object @NotNull [] getVariants() {
final List<LookupElement> variants = Collections.synchronizedList(new SmartList<>());
processCandidates(extension -> {
final GenericAttributeValue<String> id = extension.getId();
if (id == null || extension.getXmlElement() == null) return true;
final String value = id.getStringValue();
if (value == null) return true;
variants.add(LookupElementBuilder.create(extension.getXmlElement(), value)
.withIcon(AllIcons.General.Settings)
.withTypeText(StringUtil.notNullize(getAttributeValue(extension, "default"))));
return true;
});
return variants.toArray(LookupElement.EMPTY_ARRAY);
}
}
}

View File

@@ -132,7 +132,8 @@ public final class MessageBundleReferenceContributor extends PsiReferenceContrib
String s = StringUtil.notNullize(StringUtil.substringAfter(text, ADVANCED_SETTING));
String id = s.endsWith(DESCRIPTION) ? StringUtil.trimEnd(s, DESCRIPTION) :
(s.endsWith(TRAILING_LABEL) ? StringUtil.trimEnd(s, TRAILING_LABEL) : s);
return new AdvancedSettingReference(element, id);
TextRange range = TextRange.allOf(id).shiftRight(ADVANCED_SETTING.length());
return new AdvancedSettingsIdContributor.AdvancedSettingReference(element, range);
}
});
}
@@ -308,40 +309,6 @@ public final class MessageBundleReferenceContributor extends PsiReferenceContrib
}
private static class AdvancedSettingReference extends ExtensionPointReferenceBase {
private AdvancedSettingReference(PsiElement element, String id) {
super(element, TextRange.allOf(id).shiftRight(ADVANCED_SETTING.length()));
}
@Override
protected String getExtensionPointFqn() {
return "com.intellij.advancedSetting";
}
@Override
public @NotNull String getUnresolvedMessagePattern() {
return DevKitBundle.message("message.bundle.convert.advanced.setting.id.cannot.resolve", getValue());
}
@Override
public Object @NotNull [] getVariants() {
final List<LookupElement> variants = Collections.synchronizedList(new SmartList<>());
processCandidates(extension -> {
final GenericAttributeValue<String> id = extension.getId();
if (id == null || extension.getXmlElement() == null) return true;
final String value = id.getStringValue();
if (value == null) return true;
variants.add(LookupElementBuilder.create(extension.getXmlElement(), value));
return true;
});
return variants.toArray(LookupElement.EMPTY_ARRAY);
}
}
private static class ExportableIdReference extends PsiReferenceBase.Poly<PsiElement> {
private ExportableIdReference(PsiElement element, String id) {

View File

@@ -0,0 +1,33 @@
import java.util.concurrent.TimeUnit;
import com.intellij.openapi.options.advanced.AdvancedSettings;
public class AdvancedSettingsId {
public static void main(String[] args) {
AdvancedSettings.getBoolean("advancedSettingId");
AdvancedSettings.getInt("advancedSettingId");
AdvancedSettings.getString("advancedSettingId");
AdvancedSettings.getEnum("advancedSettingId", TimeUnit.class);
AdvancedSettings.getBoolean("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>");
AdvancedSettings.getInt("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>");
AdvancedSettings.getString("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>");
AdvancedSettings.getEnum("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>", TimeUnit.class);
AdvancedSettings.getDefaultBoolean("advancedSettingId");
AdvancedSettings.getDefaultInt("advancedSettingId");
AdvancedSettings.getDefaultString("advancedSettingId");
AdvancedSettings.getDefaultEnum("advancedSettingId", TimeUnit.class);
AdvancedSettings.getDefaultBoolean("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>");
AdvancedSettings.getDefaultInt("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>");
AdvancedSettings.getDefaultString("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>");
AdvancedSettings.getDefaultEnum("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>", TimeUnit.class);
AdvancedSettings.setBoolean("advancedSettingId", false);
AdvancedSettings.setInt("advancedSettingId", 42);
AdvancedSettings.setString("advancedSettingId", "dummy");
AdvancedSettings.setEnum("advancedSettingId", TimeUnit.SECONDS);
AdvancedSettings.setBoolean("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>", false);
AdvancedSettings.setInt("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>", 42);
AdvancedSettings.setString("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>", "dummy");
AdvancedSettings.setEnum("<error descr="Cannot resolve advanced setting ID 'INVALID_VALUE'">INVALID_VALUE</error>", TimeUnit.SECONDS);
}
}

View File

@@ -0,0 +1,7 @@
import com.intellij.openapi.options.advanced.AdvancedSettings;
public class AdvancedSettingsIdCompletion {
public static void main(String[] args) {
AdvancedSettings.getBoolean("<caret>");
}
}

View File

@@ -0,0 +1,6 @@
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<advancedSetting id="advancedSettingId" default="defaultValue"/>
<advancedSetting id="advancedSettingId2" default="defaultValue2"/>
</extensions>
</idea-plugin>

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.idea.devkit.inspections;
import com.intellij.codeInsight.lookup.LookupElement;
@@ -7,6 +7,7 @@ import com.intellij.codeInspection.LocalInspectionEP;
import com.intellij.diagnostic.ITNReporter;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.advanced.AdvancedSettings;
import com.intellij.openapi.util.Iconable;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.TestDataPath;
@@ -40,6 +41,7 @@ public class PluginConfigReferenceTest extends JavaCodeInsightFixtureTestCase {
moduleBuilder.addLibrary("platform-resources", Paths.get(PathUtil.getJarPathForClass(LocalInspectionEP.class))
.resolveSibling("intellij.platform.resources").toString());
moduleBuilder.addLibrary("ide-core", PathUtil.getJarPathForClass(Configurable.class));
moduleBuilder.addLibrary("editor-ui-api", PathUtil.getJarPathForClass(AdvancedSettings.class));
}
public void testRegistryKeyIdHighlighting() {
@@ -90,6 +92,23 @@ public class PluginConfigReferenceTest extends JavaCodeInsightFixtureTestCase {
assertEquals(AllIcons.Nodes.Plugin, internal.getIcon());
}
public void testAdvancedSettingsIdHighlighting() {
doHighlightingTest("AdvancedSettingsId.java",
"advancedSettingsId.xml");
}
public void testAdvancedSettingsIdCompletion() {
final List<String> variants = myFixture.getCompletionVariants("AdvancedSettingsIdCompletion.java",
"advancedSettingsId.xml");
assertContainsElements(variants,
"advancedSettingId",
"advancedSettingId2");
final LookupElementPresentation setting = getLookupElementPresentation("advancedSettingId");
assertEquals("defaultValue", setting.getTypeText());
assertEquals(AllIcons.General.Settings, setting.getIcon());
}
public void testNotificationGroupIdHighlighting() {
doHighlightingTest("NotificationGroupId.java",
"notificationGroupId.xml");