[inspections] Experimentally inject field names

GitOrigin-RevId: 8de92f5de8409806e67cb0e834cd01b24c06d044
This commit is contained in:
Tagir Valeev
2022-12-11 16:31:01 +01:00
committed by intellij-monorepo-bot
parent 6d23486911
commit 4fb7bcbadb
11 changed files with 117 additions and 19 deletions

View File

@@ -2357,6 +2357,7 @@
<compiler.task execute="AFTER" implementation="com.intellij.execution.scratch.JavaScratchCompilationSupport"/>
<registryKey key="load.maven.dependencies.timeout" defaultValue="120" description="How long (in minutes) idea will wait for results of synchronized maven dependencies resolution"/>
<referenceInjector implementation="com.intellij.java.JvmMethodNameReferenceInjector"/>
<referenceInjector implementation="com.intellij.java.JvmFieldNameReferenceInjector"/>
<applicationService serviceInterface="com.intellij.ide.starters.local.generator.AssetsProcessor"
serviceImplementation="com.intellij.ide.starters.local.generator.AssetsProcessorImpl"

View File

@@ -0,0 +1,80 @@
// 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.
package com.intellij.java;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.injection.ReferenceInjector;
import com.intellij.util.ProcessingContext;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UElementKt;
import org.jetbrains.uast.UField;
import org.jetbrains.uast.UastContextKt;
import org.jetbrains.uast.expressions.UInjectionHost;
import javax.swing.*;
public class JvmFieldNameReferenceInjector extends ReferenceInjector {
@Override
public @NotNull String getId() {
return "jvm-field-name";
}
@Override
public @NotNull @NlsContexts.Label String getDisplayName() {
return JavaBundle.message("label.jvm.field.name");
}
@Override
public PsiReference @NotNull [] getReferences(@NotNull PsiElement element,
@NotNull ProcessingContext context,
@NotNull TextRange range) {
UInjectionHost host = UastContextKt.toUElement(element, UInjectionHost.class);
if (host == null) return PsiReference.EMPTY_ARRAY;
String text = range.substring(element.getText());
if (text.isEmpty()) return PsiReference.EMPTY_ARRAY;
UClass uClass = UastContextKt.getUastParentOfType(element, UClass.class);
if (uClass == null) return PsiReference.EMPTY_ARRAY;
PsiClass containingClass = UElementKt.getAsJavaPsiElement(uClass, PsiClass.class);
if (containingClass == null) return PsiReference.EMPTY_ARRAY;
PsiField field = containingClass.findFieldByName(text, true);
if (field != null && !field.hasModifierProperty(PsiModifier.STATIC)) {
return new JavaFieldReference[]{new JavaFieldReference(element, range, field, uClass)};
}
return new JavaFieldReference[]{new JavaFieldReference(element, range, null, uClass)};
}
@Override
public @NotNull Icon getIcon() {
return AllIcons.Nodes.Field;
}
private static final class JavaFieldReference extends PsiReferenceBase<PsiElement> {
private final @Nullable PsiField myField;
private final @NotNull UClass myContainingClass;
JavaFieldReference(@NotNull PsiElement literal, @NotNull TextRange range,
@Nullable PsiField field, @NotNull UClass containingClass) {
super(literal, range, field == null);
myField = field;
myContainingClass = containingClass;
}
@Override
public Object @NotNull [] getVariants() {
return StreamEx.of(myContainingClass.getJavaPsi().getAllFields())
.remove(field -> field.hasModifierProperty(PsiModifier.STATIC))
.distinct(PsiField::getName).toArray(PsiField.EMPTY_ARRAY);
}
@Override
public @Nullable PsiElement resolve() {
UField uField = UastContextKt.toUElement(myField, UField.class);
return uField == null ? null : uField.getSourcePsi();
}
}
}

View File

@@ -68,7 +68,9 @@ public class JvmMethodNameReferenceInjector extends ReferenceInjector {
@Override
public Object @NotNull [] getVariants() {
return StreamEx.of(myContainingClass.getMethods()).distinct(PsiMethod::getName).toArray(PsiMethod.EMPTY_ARRAY);
return StreamEx.of(myContainingClass.getJavaPsi().getAllMethods())
.remove(method -> method.hasModifierProperty(PsiModifier.STATIC))
.distinct(PsiMethod::getName).toArray(PsiMethod.EMPTY_ARRAY);
}
@Override

View File

@@ -1691,6 +1691,7 @@ accessible.name.change.modifier=Change Modifier
usages.telescope={0,choice, 0#no usages|1#1 usage|2#{0,number} usages}
label.jvm.method.name=JVM method name
label.jvm.field.name=JVM field name
link.configure.classes.excluded.from.completion=Configure classes excluded from completion
inspection.preview.feature.0.is.preview.api.message={0} is a preview API and may be removed in a future release
progress.title.detect.overridden.methods=Check overriding methods

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.options;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -12,5 +13,7 @@ import java.util.List;
* @param label label to display next to a checkbox
* @param children optional list of children controls to display next to checkbox. They are disabled if checkbox is unchecked
*/
public record OptCheckbox(@NotNull String bindId, @NotNull LocMessage label, @NotNull List<@NotNull OptComponent> children) implements OptControl {
public record OptCheckbox(@Language("jvm-field-name") @NotNull String bindId,
@NotNull LocMessage label,
@NotNull List<@NotNull OptComponent> children) implements OptControl {
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.options;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -10,7 +11,9 @@ import java.util.List;
* @param splitLabel label to display around the control
* @param options drop-down options
*/
public record OptDropdown(@NotNull String bindId, @NotNull LocMessage splitLabel, @NotNull List<@NotNull Option> options) implements OptControl {
public record OptDropdown(@Language("jvm-field-name") @NotNull String bindId,
@NotNull LocMessage splitLabel,
@NotNull List<@NotNull Option> options) implements OptControl {
/**
* Drop down option
*

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.options;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -12,6 +13,6 @@ import org.jetbrains.annotations.Nullable;
* @param keyValidator optional validator for keys column
* @param valueValidator optional validator for values column
*/
public record OptMap(@NotNull String bindId, @NotNull LocMessage label,
public record OptMap(@Language("jvm-field-name") @NotNull String bindId, @NotNull LocMessage label,
@Nullable StringValidator keyValidator, @Nullable StringValidator valueValidator) implements OptControl {
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.options;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
/**
@@ -11,5 +12,6 @@ import org.jetbrains.annotations.NotNull;
* @param minValue minimal allowed value of the variable
* @param maxValue maximal allowed value of the variable
*/
public record OptNumber(@NotNull String bindId, @NotNull LocMessage splitLabel, int minValue, int maxValue) implements OptControl {
public record OptNumber(@Language("jvm-field-name") @NotNull String bindId,
@NotNull LocMessage splitLabel, int minValue, int maxValue) implements OptControl {
}

View File

@@ -3,6 +3,7 @@ package com.intellij.codeInspection.options;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.openapi.util.NlsContexts;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -81,7 +82,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @param children optional list of children controls to display next to checkbox. They are disabled if checkbox is unchecked
* @return a checkbox
*/
public static @NotNull OptCheckbox checkbox(@NotNull String bindId,
public static @NotNull OptCheckbox checkbox(@Language("jvm-field-name") @NotNull String bindId,
@NotNull @NlsContexts.Label String label,
@NotNull OptComponent @NotNull ... children) {
return new OptCheckbox(bindId, new PlainMessage(label), List.of(children));
@@ -102,7 +103,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @param maxValue maximal allowed value of the variable
* @return an edit box to enter a number
*/
public static @NotNull OptNumber number(@NotNull String bindId,
public static @NotNull OptNumber number(@Language("jvm-field-name") @NotNull String bindId,
@NotNull @NlsContexts.Label String splitLabel,
int minValue,
int maxValue) {
@@ -114,7 +115,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @param splitLabel label to display around the control
* @return an edit box to enter a string
*/
public static @NotNull OptString string(@NotNull String bindId,
public static @NotNull OptString string(@Language("jvm-field-name") @NotNull String bindId,
@NotNull @NlsContexts.Label String splitLabel) {
return new OptString(bindId, new PlainMessage(splitLabel), null, -1);
}
@@ -125,7 +126,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @param width width of the control in approximate number of characters; if -1 then it will be determined automatically
* @return an edit box to enter a string
*/
public static @NotNull OptString string(@NotNull String bindId,
public static @NotNull OptString string(@Language("jvm-field-name") @NotNull String bindId,
@NotNull @NlsContexts.Label String splitLabel,
int width) {
return new OptString(bindId, new PlainMessage(splitLabel), null, width);
@@ -138,7 +139,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* (e.g., validate that a string is a class-name which is a subclass of specific class)
* @return an edit box to enter a string
*/
public static @NotNull OptString string(@NotNull String bindId,
public static @NotNull OptString string(@Language("jvm-field-name") @NotNull String bindId,
@NotNull @NlsContexts.Label String splitLabel,
@NotNull StringValidator validator) {
return new OptString(bindId, new PlainMessage(splitLabel), validator, -1);
@@ -152,7 +153,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* (e.g., validate that a string is a class-name which is a subclass of specific class)
* @return an edit box to enter a string
*/
public static @NotNull OptString string(@NotNull String bindId,
public static @NotNull OptString string(@Language("jvm-field-name") @NotNull String bindId,
@NotNull @NlsContexts.Label String splitLabel,
int width,
@NotNull StringValidator validator) {
@@ -166,7 +167,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @return a drop-down control to select a single option from
* @see #option(String, String)
*/
public static @NotNull OptDropdown dropdown(@NotNull String bindId,
public static @NotNull OptDropdown dropdown(@Language("jvm-field-name") @NotNull String bindId,
@NotNull @NlsContexts.Label String splitLabel,
@NotNull OptDropdown.Option @NotNull ... options) {
return new OptDropdown(bindId, new PlainMessage(splitLabel), List.of(options));
@@ -198,7 +199,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @param label label above the control
* @return editable sorted list of unique strings
*/
public static @NotNull OptSet stringSet(@NotNull String bindId, @NotNull @NlsContexts.Label String label) {
public static @NotNull OptSet stringSet(@Language("jvm-field-name") @NotNull String bindId, @NotNull @NlsContexts.Label String label) {
return new OptSet(bindId, new PlainMessage(label), null);
}
@@ -210,7 +211,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* (e.g., validate that a string is a class-name which is a subclass of specific class)
* @return editable sorted list of unique strings
*/
public static @NotNull OptSet stringSet(@NotNull String bindId, @NotNull @NlsContexts.Label String label,
public static @NotNull OptSet stringSet(@Language("jvm-field-name") @NotNull String bindId, @NotNull @NlsContexts.Label String label,
@NotNull StringValidator validator) {
return new OptSet(bindId, new PlainMessage(label), validator);
}
@@ -221,7 +222,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @param label label above the control
* @return editable two-column table of strings; strings in the left column are unique and sorted
*/
public static @NotNull OptMap stringMap(@NotNull String bindId, @NotNull @NlsContexts.Label String label) {
public static @NotNull OptMap stringMap(@Language("jvm-field-name") @NotNull String bindId, @NotNull @NlsContexts.Label String label) {
return new OptMap(bindId, new PlainMessage(label), null, null);
}
@@ -233,7 +234,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
* @param valueValidator optional validator for values column
* @return editable two-column table of strings; strings in the left column are unique and sorted
*/
public static @NotNull OptMap stringMap(@NotNull String bindId, @NotNull @NlsContexts.Label String label,
public static @NotNull OptMap stringMap(@Language("jvm-field-name") @NotNull String bindId, @NotNull @NlsContexts.Label String label,
@NotNull StringValidator keyValidator, @NotNull StringValidator valueValidator) {
return new OptMap(bindId, new PlainMessage(label), keyValidator, valueValidator);
}
@@ -283,7 +284,7 @@ public record OptPane(@NotNull List<@NotNull OptComponent> components) {
/**
* @param label tab label
* @param content tab content
* @param children tab content
* @return tab description
* @see #tabs(OptTabSet.TabInfo...)
*/

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.options;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,5 +14,6 @@ import org.jetbrains.annotations.Nullable;
* @param validator optional validator for content; can validate max-length or be something more complicated
* (e.g., validate that a string is a class-name which is a subclass of specific class)
*/
public record OptSet(@NotNull String bindId, @NotNull LocMessage label, @Nullable StringValidator validator) implements OptControl {
public record OptSet(@Language("jvm-field-name") @NotNull String bindId,
@NotNull LocMessage label, @Nullable StringValidator validator) implements OptControl {
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.options;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,5 +14,6 @@ import org.jetbrains.annotations.Nullable;
* @param validator optional validator for content; can validate max-length or be something more complicated
* (e.g., validate that a string is a class-name which is a subclass of specific class)
*/
public record OptString(@NotNull String bindId, @NotNull LocMessage splitLabel, @Nullable StringValidator validator, int width) implements OptControl {
public record OptString(@Language("jvm-field-name") @NotNull String bindId, @NotNull LocMessage splitLabel,
@Nullable StringValidator validator, int width) implements OptControl {
}