cleanup [platform]: dead code; deprecated API; typos; formatting

GitOrigin-RevId: 41d8ae44e3b577b502dec1a75ad8f0a3b0d6b45e
This commit is contained in:
Roman Shevchenko
2026-02-11 20:15:37 +00:00
committed by intellij-monorepo-bot
parent 6b7ecb38dc
commit ad91c3a8ec
12 changed files with 260 additions and 275 deletions
@@ -17,7 +17,6 @@ import org.jetbrains.annotations.Nullable;
* {@link PsiReferenceProvider#getReferencesByElement(PsiElement, com.intellij.util.ProcessingContext)}.
*/
public abstract class PsiReferenceRegistrar implements UserDataHolder {
public static final double DEFAULT_PRIORITY = 0.0;
public static final double HIGHER_PRIORITY = 100.0;
public static final double LOWER_PRIORITY = -100.0;
@@ -27,7 +26,8 @@ public abstract class PsiReferenceRegistrar implements UserDataHolder {
/**
* Register reference provider with default priority ({@link #DEFAULT_PRIORITY}).
*
* @param pattern reference place description. See {@link com.intellij.patterns.StandardPatterns}, {@link com.intellij.patterns.PlatformPatterns} and their extenders.
* @param pattern reference place description. See {@link com.intellij.patterns.StandardPatterns},
* {@link com.intellij.patterns.PlatformPatterns} and their extenders.
* @param provider provider to be registered
*/
public void registerReferenceProvider(@NotNull ElementPattern<? extends PsiElement> pattern, @NotNull PsiReferenceProvider provider) {
@@ -37,13 +37,16 @@ public abstract class PsiReferenceRegistrar implements UserDataHolder {
/**
* Register reference provider with custom priority.
*
* @param pattern reference place description. See {@link com.intellij.patterns.StandardPatterns}, {@link com.intellij.patterns.PlatformPatterns} and their extenders.
* @param pattern reference place description. See {@link com.intellij.patterns.StandardPatterns},
* {@link com.intellij.patterns.PlatformPatterns} and their extenders.
* @param provider provider to be registered
* @param priority see {@link #DEFAULT_PRIORITY), {@link #HIGHER_PRIORITY}, {@link #LOWER_PRIORITY}
*/
public abstract <T extends PsiElement> void registerReferenceProvider(@NotNull ElementPattern<T> pattern,
@NotNull PsiReferenceProvider provider,
double priority);
public abstract <T extends PsiElement> void registerReferenceProvider(
@NotNull ElementPattern<T> pattern,
@NotNull PsiReferenceProvider provider,
double priority
);
@Override
public <T> @Nullable T getUserData(@NotNull Key<T> key) {
@@ -1,5 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.impl.source.resolve.reference;
import com.intellij.psi.PsiElement;
@@ -16,7 +15,8 @@ import java.util.List;
public interface ProviderBinding {
class ProviderInfo<T> {
static final ProviderInfo<?>[] EMPTY_ARRAY = new ProviderInfo[0];
static final ArrayFactory<ProviderInfo<?>> ARRAY_FACTORY = n -> n == 0 ? ProviderInfo.EMPTY_ARRAY : new ProviderInfo[n];
static final ArrayFactory<ProviderInfo<?>> ARRAY_FACTORY = n -> n == 0 ? EMPTY_ARRAY : new ProviderInfo[n];
final @NotNull PsiReferenceProvider provider;
final @NotNull T processingContext;
final double priority;
@@ -32,9 +32,12 @@ public interface ProviderBinding {
return "ProviderInfo{provider=" + provider + ", priority=" + priority + '}';
}
}
void addAcceptableReferenceProviders(@NotNull PsiElement position,
@NotNull List<? super ProviderInfo<ProcessingContext>> list,
@NotNull PsiReferenceService.Hints hints);
void addAcceptableReferenceProviders(
@NotNull PsiElement position,
@NotNull List<? super ProviderInfo<ProcessingContext>> list,
@NotNull PsiReferenceService.Hints hints
);
void unregisterProvider(@NotNull PsiReferenceProvider provider);
}
@@ -46,20 +46,19 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
PsiReferenceRegistrarImpl() {
myBindingCache = ConcurrentFactoryMap.createMap(key -> {
List<ProviderBinding> result = new SmartList<>();
for (Class<?> bindingClass : myBindingsMap.keySet()) {
if (bindingClass.isAssignableFrom(key)) {
result.add(myBindingsMap.get(bindingClass));
}
}
for (Class<?> bindingClass : myNamedBindingsMap.keySet()) {
if (bindingClass.isAssignableFrom(key)) {
result.add(myNamedBindingsMap.get(bindingClass));
}
}
return result.toArray(new ProviderBinding[0]);
}
);
List<ProviderBinding> result = new SmartList<>();
for (Class<?> bindingClass : myBindingsMap.keySet()) {
if (bindingClass.isAssignableFrom(key)) {
result.add(myBindingsMap.get(bindingClass));
}
}
for (Class<?> bindingClass : myNamedBindingsMap.keySet()) {
if (bindingClass.isAssignableFrom(key)) {
result.add(myNamedBindingsMap.get(bindingClass));
}
}
return result.toArray(new ProviderBinding[0]);
});
}
void markInitialized() {
@@ -74,16 +73,20 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
}
@Override
public <T extends PsiElement> void registerReferenceProvider(@NotNull ElementPattern<T> pattern,
@NotNull PsiReferenceProvider provider,
double priority) {
public <T extends PsiElement> void registerReferenceProvider(
@NotNull ElementPattern<T> pattern,
@NotNull PsiReferenceProvider provider,
double priority
) {
registerReferenceProvider(pattern, provider, priority, null);
}
public <T extends PsiElement> void registerReferenceProvider(@NotNull ElementPattern<T> pattern,
@NotNull PsiReferenceProvider provider,
double priority,
@Nullable Disposable parentDisposable) {
public <T extends PsiElement> void registerReferenceProvider(
@NotNull ElementPattern<T> pattern,
@NotNull PsiReferenceProvider provider,
double priority,
@Nullable Disposable parentDisposable
) {
if (myInitialized && !ApplicationManager.getApplication().isUnitTestMode() && parentDisposable == null) {
LOG.error("Reference provider registration is only allowed from PsiReferenceContributor");
}
@@ -98,9 +101,8 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
List<PatternCondition<? super String>> conditions1 = nameCondition.getNamePattern().getCondition().getConditions();
for (PatternCondition<? super String> condition1 : conditions1) {
if (condition1 instanceof ValuePatternCondition) {
Collection<String> strings = ((ValuePatternCondition)condition1).getValues();
registerNamedReferenceProvider(ArrayUtilRt.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern,
parentDisposable);
@SuppressWarnings({"unchecked", "rawtypes"}) Collection<String> strings = ((ValuePatternCondition)condition1).getValues();
registerNamedReferenceProvider(ArrayUtilRt.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern, parentDisposable);
return;
}
if (condition1 instanceof CaseInsensitiveValuePatternCondition) {
@@ -127,7 +129,7 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
@Override
public String toString() {
return "PsiReferenceRegistrarImpl cleanuper for " + provider +" ("+provider.getClass()+")";
return "PsiReferenceRegistrarImpl cleaner for " + provider + " (" + provider.getClass() + ")";
}
};
Disposer.register(parentDisposable, disposable);
@@ -152,14 +154,16 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
clearBindingsCache();
}
private void registerNamedReferenceProvider(String @NotNull [] names,
PsiNamePatternCondition<?> nameCondition,
@NotNull Class<?> scopeClass,
boolean caseSensitive,
@NotNull PsiReferenceProvider provider,
double priority,
@NotNull ElementPattern<?> pattern,
@Nullable Disposable parentDisposable) {
private void registerNamedReferenceProvider(
String @NotNull [] names,
PsiNamePatternCondition<?> nameCondition,
@NotNull Class<?> scopeClass,
boolean caseSensitive,
@NotNull PsiReferenceProvider provider,
double priority,
@NotNull ElementPattern<?> pattern,
@Nullable Disposable parentDisposable
) {
NamedObjectProviderBinding providerBinding = myNamedBindingsMap.get(scopeClass);
if (providerBinding == null) {
@@ -189,9 +193,10 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
}
@ApiStatus.Internal
@Unmodifiable
@NotNull List<ProviderBinding.ProviderInfo<ProcessingContext>> getPairsByElement(@NotNull PsiElement element,
@NotNull PsiReferenceService.Hints hints) {
@Unmodifiable @NotNull List<ProviderBinding.ProviderInfo<ProcessingContext>> getPairsByElement(
@NotNull PsiElement element,
@NotNull PsiReferenceService.Hints hints
) {
ProviderBinding[] bindings = myBindingCache.get(element.getClass());
if (bindings.length == 0) return Collections.emptyList();
@@ -201,9 +206,12 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
}
return ret;
}
@ApiStatus.Internal
public @Unmodifiable @NotNull List<PsiReferenceProvider> getPsiReferenceProvidersByElement(@NotNull PsiElement element,
@NotNull PsiReferenceService.Hints hints) {
public @Unmodifiable @NotNull List<PsiReferenceProvider> getPsiReferenceProvidersByElement(
@NotNull PsiElement element,
@NotNull PsiReferenceService.Hints hints
) {
return ContainerUtil.map(getPairsByElement(element, hints), info -> info.provider);
}
}
@@ -45,18 +45,17 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
private final Map<Language, PsiReferenceRegistrarImpl> myRegistrars = new ConcurrentHashMap<>();
@SuppressWarnings("deprecation")
public ReferenceProvidersRegistryImpl() {
if (ApplicationManager.getApplication().getExtensionArea().hasExtensionPoint(PsiReferenceContributor.EP_NAME)) {
PsiReferenceContributor.EP_NAME.addExtensionPointListener(new ExtensionPointListener<KeyedLazyInstance<PsiReferenceContributor>>() {
@Override
public void extensionAdded(@NotNull KeyedLazyInstance<PsiReferenceContributor> extension,
@NotNull PluginDescriptor pluginDescriptor) {
public void extensionAdded(@NotNull KeyedLazyInstance<PsiReferenceContributor> extension, @NotNull PluginDescriptor pluginDescriptor) {
reset();
}
@Override
public void extensionRemoved(@NotNull KeyedLazyInstance<PsiReferenceContributor> extension,
@NotNull PluginDescriptor pluginDescriptor) {
public void extensionRemoved(@NotNull KeyedLazyInstance<PsiReferenceContributor> extension, @NotNull PluginDescriptor pluginDescriptor) {
reset();
}
@@ -75,7 +74,7 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
private static @NotNull PsiReferenceRegistrarImpl createRegistrar(@NotNull Language language) {
PsiReferenceRegistrarImpl registrar = new PsiReferenceRegistrarImpl();
for (PsiReferenceContributor contributor : CONTRIBUTOR_EXTENSION.allForLanguageOrAny(language)) {
registerContributedReferenceProviders(registrar, contributor);
contributor.registerReferenceProviders(registrar);
}
List<PsiReferenceProviderBean> referenceProviderBeans = REFERENCE_PROVIDER_EXTENSION.allForLanguageOrAny(language);
@@ -83,7 +82,7 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
ElementPattern<PsiElement> pattern = providerBean.createElementPattern();
if (pattern != null) {
registrar.registerReferenceProvider(pattern, new PsiReferenceProvider() {
PsiReferenceProvider myProvider;
private PsiReferenceProvider myProvider;
@Override
public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
@@ -104,11 +103,6 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
return registrar;
}
private static void registerContributedReferenceProviders(@NotNull PsiReferenceRegistrarImpl registrar,
@NotNull PsiReferenceContributor contributor) {
contributor.registerReferenceProviders(registrar);
}
@ApiStatus.Internal
@Override
public @NotNull PsiReferenceRegistrarImpl getRegistrar(@NotNull Language language) {
@@ -130,9 +124,12 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
// 1. we create priorities map: "priority" -> non-empty references from providers
// if provider returns EMPTY_ARRAY or array with "null" references then this provider isn't added in priorities map.
// 2. references with the highest priority are added "as is"
// 3. all other references are added only they could be correctly merged with any reference with higher priority (ReferenceRange.containsRangeInElement(higherPriorityRef, lowerPriorityRef)
protected PsiReference @NotNull [] doGetReferencesFromProviders(@NotNull PsiElement context,
@NotNull PsiReferenceService.Hints hints) {
// 3. all other references are added only they could be correctly merged with any reference with higher priority
// (ReferenceRange.containsRangeInElement(higherPriorityRef, lowerPriorityRef)
protected PsiReference @NotNull [] doGetReferencesFromProviders(
@NotNull PsiElement context,
@NotNull PsiReferenceService.Hints hints
) {
List<ProviderBinding.ProviderInfo<ProcessingContext>> providers = getRegistrar(context.getLanguage()).getPairsByElement(context, hints);
Double2ObjectMap<List<PsiReference[]>> allReferencesMap = mapNotEmptyReferencesFromProviders(context, providers);
@@ -152,8 +149,10 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
// we create priorities map: "priority" -> non-empty references from providers
// if provider returns EMPTY_ARRAY or array with "null" references then this provider isn't added in priorities map.
private static @NotNull Double2ObjectMap<List<PsiReference[]>> mapNotEmptyReferencesFromProviders(@NotNull PsiElement context,
@NotNull List<? extends ProviderBinding.ProviderInfo<ProcessingContext>> providers) {
private static @NotNull Double2ObjectMap<List<PsiReference[]>> mapNotEmptyReferencesFromProviders(
@NotNull PsiElement context,
@NotNull List<? extends ProviderBinding.ProviderInfo<ProcessingContext>> providers
) {
Double2ObjectOpenHashMap<List<PsiReference[]>> map = new Double2ObjectOpenHashMap<>();
for (ProviderBinding.ProviderInfo<ProcessingContext> info : providers) {
PsiReference[] refs = getReferences(context, info);
@@ -172,19 +171,22 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
return map;
}
private static PsiReference @NotNull [] getReferences(@NotNull PsiElement context,
@NotNull ProviderBinding.ProviderInfo<ProcessingContext> providerInfo) {
private static PsiReference @NotNull [] getReferences(
@NotNull PsiElement context,
@NotNull ProviderBinding.ProviderInfo<ProcessingContext> providerInfo
) {
try {
return providerInfo.provider.getReferencesByElement(context, providerInfo.processingContext);
}
catch (IndexNotReadyException ignored) {
}
catch (IndexNotReadyException ignored) { }
return PsiReference.EMPTY_ARRAY;
}
private static @NotNull List<PsiReference> getLowerPriorityReferences(@NotNull Double2ObjectMap<List<PsiReference[]>> allReferencesMap,
double maxPriority,
@NotNull List<? extends PsiReference> maxPriorityRefs) {
private static @NotNull List<PsiReference> getLowerPriorityReferences(
@NotNull Double2ObjectMap<List<PsiReference[]>> allReferencesMap,
double maxPriority,
@NotNull List<? extends PsiReference> maxPriorityRefs
) {
List<PsiReference> result = new SmartList<>();
for (Double2ObjectMap.Entry<List<PsiReference[]>> entry : Double2ObjectMaps.fastIterable(allReferencesMap)) {
if (maxPriority != entry.getDoubleKey()) {
@@ -198,8 +200,10 @@ public final class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegi
return result;
}
private static boolean haveNotIntersectedTextRanges(@NotNull List<? extends PsiReference> higherPriorityRefs,
PsiReference @NotNull [] lowerPriorityRefs) {
private static boolean haveNotIntersectedTextRanges(
@NotNull List<? extends PsiReference> higherPriorityRefs,
PsiReference @NotNull [] lowerPriorityRefs
) {
for (PsiReference ref : lowerPriorityRefs) {
if (ref != null) {
for (PsiReference reference : higherPriorityRefs) {
@@ -2,6 +2,7 @@
package com.intellij.internal.statistic.devkit
import com.intellij.internal.statistic.StatisticsBundle
import com.intellij.internal.statistic.eventLog.FUS_RECORDER
import com.intellij.internal.statistic.eventLog.StatisticsEventLogProviderUtil
import com.intellij.internal.statistic.eventLog.StatisticsEventLoggerProvider
import com.intellij.internal.statistic.utils.StatisticsRecorderUtil
@@ -10,7 +11,7 @@ import com.intellij.notification.NotificationType
import com.intellij.openapi.project.Project
internal object StatisticsDevKitUtil {
const val DEFAULT_RECORDER = "FUS"
const val DEFAULT_RECORDER = FUS_RECORDER
const val STATISTICS_NOTIFICATION_GROUP_ID = "FeatureUsageStatistics"
fun getLogProvidersInTestMode(): List<StatisticsEventLoggerProvider> {
@@ -2,8 +2,8 @@ java.code.block=Java Code Block
java.expression=Java Expression
java.method=Java Method
inspections.group.path=Plugin DevKit
inspections.group.code=Code
inspections.group.path=Plugin Dev
inspections.highlight.visitor.internal.display.name=Good code is red
#PSI Viewer Debugger
@@ -19,4 +19,4 @@ psi.viewer.show.whitespace.action = Show Whitespace
psi.viewer.show.whitespace.description = Show whitespace nodes in the PSI tree
psi.viewer.show.tree.nodes.action = Show Tree Nodes
psi.viewer.show.tree.nodes.description = Show tree nodes in the PSI tree
psi.viewer.debug.evaluation.failed=Failed to find PSI structure
psi.viewer.debug.evaluation.failed=Failed to find PSI structure
@@ -4,72 +4,61 @@ package org.jetbrains.idea.devkit.inspections;
import com.intellij.codeInspection.LocalInspectionEP;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
public class DevkitInspectionsRegistrationCheckTest extends BasePlatformTestCase {
private static final int EXPECTED_INSPECTIONS_NUMBER = 94;
/**
* Inspections that are finished and intentionally disabled.
*/
private static final List<String> DISABLED_INSPECTIONS =
Stream.of(
"SerializableCtor",
"StatisticsCollectorNotRegistered"
).sorted().toList();
private static final List<String> DISABLED_INSPECTIONS = List.of(
"SerializableCtor",
"StatisticsCollectorNotRegistered"
);
/**
* Inspections which implementation is in progress
* or are finished but not battle-tested yet and may require improvements/polishing.
* Inspections which implementation is in progress or are finished but not battle-tested yet and may require improvements/polishing.
*/
private static final List<String> WIP_INSPECTIONS =
Stream.of("ExtensionClassShouldBeFinalAndNonPublic",
"CanBeDumbAware",
"CancellationCheckInLoops",
"ThreadingConcurrency",
"CallingMethodShouldBeRequiresBlockingContext",
"PotentialDeadlockInServiceInitialization",
"ObsoleteDispatchersEdt",
"PathAnnotationInspection"
).sorted().toList();
private static final List<String> WIP_INSPECTIONS = List.of(
"ExtensionClassShouldBeFinalAndNonPublic",
"CanBeDumbAware",
"CancellationCheckInLoops",
"ThreadingConcurrency",
"CallingMethodShouldBeRequiresBlockingContext",
"PotentialDeadlockInServiceInitialization",
"ObsoleteDispatchersEdt",
"PathAnnotationInspection"
);
public void testNumberOfKnownDevKitInspections() {
List<LocalInspectionEP> devkitInspections = getDevKitInspections();
assertEquals(
"""
Mismatch in total number of DevKit inspections.
* If you've just added a DevKit inspection, then just increment DevkitInspectionsRegistrationCheckTest#EXPECTED_INSPECTIONS_NUMBER.
* Otherwise, check classpath in test run configuration (intellij.devkit.plugin.main)""",
EXPECTED_INSPECTIONS_NUMBER, devkitInspections.size()
EXPECTED_INSPECTIONS_NUMBER, getDevKitInspections().count()
);
}
/**
* Validates all DevKit inspections that are disabled by default match the expected known set.
*/
/**
* Validates all DevKit inspections that are disabled by default match the expected known set.
*/
public void testKnownDisabledByDefaultInspections() {
List<LocalInspectionEP> devkitInspections = getDevKitInspections();
List<LocalInspectionEP> disabledInspections = ContainerUtil.filter(devkitInspections, ep -> !ep.enabledByDefault);
List<String> disabledInspectionShortNames = new ArrayList<>(ContainerUtil.map(disabledInspections, ep -> ep.getShortName()));
Collections.sort(disabledInspectionShortNames);
assertContainsElements("Mismatch in known disabled inspections", disabledInspectionShortNames, DISABLED_INSPECTIONS);
List<String> allKnownDisabledInspections = new ArrayList<>(ContainerUtil.concat(DISABLED_INSPECTIONS, WIP_INSPECTIONS));
Collections.sort(allKnownDisabledInspections);
assertSameElements("Mismatch in known WIP inspections", disabledInspectionShortNames, allKnownDisabledInspections);
var disabledInspectionShortNames = getDevKitInspections()
.filter(ep -> !ep.enabledByDefault)
.map(ep -> ep.getShortName())
.toList();
var allKnownDisabledInspections = ContainerUtil.concat(DISABLED_INSPECTIONS, WIP_INSPECTIONS);
assertThat(disabledInspectionShortNames).containsExactlyInAnyOrderElementsOf(allKnownDisabledInspections);
}
private static @NotNull List<LocalInspectionEP> getDevKitInspections() {
List<LocalInspectionEP> devkitInspections = ContainerUtil.filter(LocalInspectionEP.LOCAL_INSPECTION.getExtensionList(), ep -> {
return "DevKit".equals(ep.getPluginDescriptor().getPluginId().getIdString());
});
return devkitInspections;
private static Stream<LocalInspectionEP> getDevKitInspections() {
return LocalInspectionEP.LOCAL_INSPECTION.getExtensionList().stream()
.filter(ep -> "DevKit".equals(ep.getPluginDescriptor().getPluginId().getIdString()));
}
}
@@ -15,22 +15,19 @@ import java.util.List;
public class PropertyReference extends PropertyReferenceBase implements LocalQuickFixProvider {
private final @Nullable String myBundleName;
public PropertyReference(final @NotNull String key, final @NotNull PsiElement element, final @Nullable String bundleName, final boolean soft, final TextRange range) {
super(key, soft, element, range);
public PropertyReference(@NotNull String key, @NotNull PsiElement element, @Nullable String bundleName, boolean soft) {
super(key, soft, element);
myBundleName = bundleName;
}
public PropertyReference(@NotNull String key, @NotNull PsiElement element, final @Nullable String bundleName, final boolean soft) {
super(key, soft, element);
public PropertyReference(@NotNull String key, @NotNull PsiElement element, @Nullable String bundleName, boolean soft, TextRange range) {
super(key, soft, element, range);
myBundleName = bundleName;
}
@Override
protected @Nullable List<PropertiesFile> getPropertiesFiles() {
if (myBundleName == null) {
return null;
}
return retrievePropertyFilesByBundleName(myBundleName, myElement);
return myBundleName == null ? null : retrievePropertyFilesByBundleName(myBundleName, myElement);
}
protected List<PropertiesFile> retrievePropertyFilesByBundleName(String bundleName, PsiElement element) {
@@ -39,8 +36,8 @@ public class PropertyReference extends PropertyReferenceBase implements LocalQui
@Override
public @NotNull LocalQuickFix @Nullable [] getQuickFixes() {
List<PropertiesFile> propertiesFiles = retrievePropertyFilesByBundleName(myBundleName, getElement());
LocalQuickFix fix = PropertiesQuickFixFactory.getInstance().createCreatePropertyFix(myElement, myKey, propertiesFiles);
var propertiesFiles = retrievePropertyFilesByBundleName(myBundleName, getElement());
var fix = PropertiesQuickFixFactory.getInstance().createCreatePropertyFix(myElement, myKey, propertiesFiles);
return new LocalQuickFix[] {fix};
}
}
@@ -30,17 +30,16 @@ import java.util.List;
import java.util.Set;
public abstract class PropertyReferenceBase implements PsiPolyVariantReference, EmptyResolveMessageProvider {
protected final String myKey;
protected final PsiElement myElement;
protected boolean mySoft;
private final boolean mySoft;
private final TextRange myTextRange;
public PropertyReferenceBase(@NotNull String key, final boolean soft, @NotNull PsiElement element) {
public PropertyReferenceBase(@NotNull String key, boolean soft, @NotNull PsiElement element) {
this(key, soft, element, ElementManipulators.getValueTextRange(element));
}
public PropertyReferenceBase(@NotNull String key, final boolean soft, @NotNull PsiElement element, TextRange range) {
public PropertyReferenceBase(@NotNull String key, boolean soft, @NotNull PsiElement element, TextRange range) {
myKey = key;
mySoft = soft;
myElement = element;
@@ -49,7 +48,7 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference,
@Override
public PsiElement resolve() {
ResolveResult[] resolveResults = multiResolve(false);
var resolveResults = multiResolve(false);
return resolveResults.length == 1 ? resolveResults[0].getElement() : null;
}
@@ -58,11 +57,10 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference,
}
@Override
public boolean equals(final Object o) {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PropertyReferenceBase other = (PropertyReferenceBase)o;
var other = (PropertyReferenceBase)o;
return getElement() == other.getElement() && getKeyText().equals(other.getKeyText());
}
@@ -99,8 +97,8 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference,
@Override
public boolean isReferenceTo(@NotNull PsiElement element) {
if (!isProperty(element)) return false;
for (ResolveResult result : multiResolve(false)) {
final PsiElement el = result.getElement();
for (var result : multiResolve(false)) {
var el = result.getElement();
if (el != null && el.isEquivalentTo(element)) return true;
}
return false;
@@ -110,10 +108,6 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference,
variants.add(property);
}
protected void setSoft(final boolean soft) {
mySoft = soft;
}
@Override
public boolean isSoft() {
return mySoft;
@@ -125,37 +119,33 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference,
}
@Override
public ResolveResult @NotNull [] multiResolve(final boolean incompleteCode) {
final String key = getKeyText();
public ResolveResult @NotNull [] multiResolve(boolean incompleteCode) {
var key = getKeyText();
List<IProperty> properties;
final List<PropertiesFile> propertiesFiles = getPropertiesFiles();
var propertiesFiles = getPropertiesFiles();
if (propertiesFiles == null) {
properties = PropertiesImplUtil.findPropertiesByKey(getElement().getProject(), key);
}
else {
properties = new ArrayList<>();
for (PropertiesFile propertiesFile : propertiesFiles) {
for (var propertiesFile : propertiesFiles) {
properties.addAll(propertiesFile.findPropertiesByKey(key));
}
}
// put default properties file first
ContainerUtil.quickSort(properties, (o1, o2) -> {
String name1 = o1.getPropertiesFile().getName();
String name2 = o2.getPropertiesFile().getName();
return Comparing.compare(name1, name2);
});
return getResolveResults(properties);
}
private static ResolveResult @NotNull [] getResolveResults(List<? extends IProperty> properties) {
if (properties.isEmpty()) return ResolveResult.EMPTY_ARRAY;
final ResolveResult[] results = new ResolveResult[properties.size()];
for (int i = 0; i < properties.size(); i++) {
IProperty property = properties.get(i);
results[i] = new PsiElementResolveResult(property instanceof PsiElement ? (PsiElement)property : PomService.convertToPsi(
(PsiTarget)property));
// put default properties file first
ContainerUtil.quickSort(properties, (o1, o2) -> {
var name1 = o1.getPropertiesFile().getName();
var name2 = o2.getPropertiesFile().getName();
return Comparing.compare(name1, name2);
});
var results = new ResolveResult[properties.size()];
for (var i = 0; i < properties.size(); i++) {
var property = properties.get(i);
results[i] = new PsiElementResolveResult(property instanceof PsiElement psi ? psi : PomService.convertToPsi((PsiTarget)property));
}
return results;
}
@@ -50,9 +50,11 @@ fun injectionHostUExpression(strict: Boolean = true): UExpressionPattern<UExpres
val requestedPsi = processingContext.get(REQUESTED_PSI_ELEMENT)
if (requestedPsi == null) {
if (strict && ApplicationManager.getApplication().isUnitTestMode) {
throw AssertionError("no ProcessingContext with `REQUESTED_PSI_ELEMENT` passed for `injectionHostUExpression`," +
" please consider creating one using `UastPatterns.withRequestedPsi`, providing a source psi for which " +
" this pattern was originally created, or make this `injectionHostUExpression` non-strict.")
throw AssertionError(
"no ProcessingContext with `REQUESTED_PSI_ELEMENT` passed for `injectionHostUExpression`," +
" please consider creating one using `UastPatterns.withRequestedPsi`, providing a source psi for which " +
" this pattern was originally created, or make this `injectionHostUExpression` non-strict."
)
}
else return@filterWithContext !strict
}
@@ -109,6 +111,7 @@ open class UElementPattern<T : UElement, Self : UElementPattern<T, Self>>(clazz:
it.uastParent?.let { parentPattern.accepts(it, context) } ?: false
}
@Suppress("unused")
fun withUastParentOrSelf(parentPattern: ElementPattern<out UElement>): Self = filterWithContext { it, context ->
parentPattern.accepts(it, context) || it.uastParent?.let { parentPattern.accepts(it, context) } ?: false
}
@@ -126,14 +129,15 @@ open class UElementPattern<T : UElement, Self : UElementPattern<T, Self>>(clazz:
private val constructorOrMethodCall = setOf(UastCallKind.CONSTRUCTOR_CALL, UastCallKind.METHOD_CALL)
private fun isCallExpressionParameter(argumentExpression: UExpression,
parameterIndex: Int,
callPattern: ElementPattern<UCallExpression>, context: ProcessingContext): Boolean {
private fun isCallExpressionParameter(
argumentExpression: UExpression,
parameterIndex: Int,
callPattern: ElementPattern<UCallExpression>, context: ProcessingContext,
): Boolean {
val call = argumentExpression.uastParent.getUCallExpression(searchLimit = 2) ?: return false
return callPattern.accepts(call, context)
&& call.kind in constructorOrMethodCall
&& call.getArgumentForParameter(parameterIndex) == argumentExpression
return callPattern.accepts(call, context) &&
call.kind in constructorOrMethodCall &&
call.getArgumentForParameter(parameterIndex) == argumentExpression
}
private fun isPropertyAssignCall(argument: UElement, methodPattern: ElementPattern<out PsiMethod>, context: ProcessingContext): Boolean {
@@ -158,8 +162,7 @@ class UCallExpressionPattern : UElementPattern<UCallExpression, UCallExpressionP
fun withAnyResolvedMethod(method: ElementPattern<out PsiMethod>): UCallExpressionPattern = withResolvedMethod(method, true)
fun withResolvedMethod(method: ElementPattern<out PsiMethod>,
multiResolve: Boolean): UCallExpressionPattern {
fun withResolvedMethod(method: ElementPattern<out PsiMethod>, multiResolve: Boolean): UCallExpressionPattern {
val methodNames = method.condition.conditions
.filterIsInstance<PsiNamePatternCondition<*>>()
.flatMap { it.namePattern.condition.conditions }
@@ -212,14 +215,13 @@ class UCallExpressionPattern : UElementPattern<UCallExpression, UCallExpressionP
fun constructor(className: String): UCallExpressionPattern = constructor(psiClass().withQualifiedName(className))
fun constructor(className: String, parameterCount: Int): UCallExpressionPattern = constructor(psiClass().withQualifiedName(className),
parameterCount)
fun constructor(className: String, parameterCount: Int): UCallExpressionPattern =
constructor(psiClass().withQualifiedName(className), parameterCount)
}
private val IS_UAST_ANNOTATION_PARAMETER: Key<Boolean> = Key.create("UAST_ANNOTATION_PARAMETER")
open class UExpressionPattern<T : UExpression, Self : UExpressionPattern<T, Self>>(clazz: Class<T>) : UElementPattern<T, Self>(clazz) {
fun annotationParam(@NonNls parameterName: String, annotationPattern: ElementPattern<UAnnotation>): Self =
annotationParams(annotationPattern, string().equalTo(parameterName))
@@ -228,13 +230,13 @@ open class UExpressionPattern<T : UExpression, Self : UExpressionPattern<T, Self
override fun accepts(uElement: T, context: ProcessingContext?): Boolean {
val sharedContext = context?.sharedContext
val isAnnotationParameter = sharedContext?.get(IS_UAST_ANNOTATION_PARAMETER, uElement)
if (isAnnotationParameter == java.lang.Boolean.FALSE) {
if (isAnnotationParameter == false) {
return false
}
val containingUAnnotationEntry = getContainingUAnnotationEntry(uElement)
if (containingUAnnotationEntry == null) {
sharedContext?.put(IS_UAST_ANNOTATION_PARAMETER, uElement, java.lang.Boolean.FALSE)
sharedContext?.put(IS_UAST_ANNOTATION_PARAMETER, uElement, false)
return false
}
@@ -268,7 +270,6 @@ open class UExpressionPattern<T : UExpression, Self : UExpressionPattern<T, Self
fun setterParameter(methodPattern: ElementPattern<out PsiMethod>): Self {
val callPattern = callExpression().withAnyResolvedMethod(methodPattern)
return filterWithContext("setterParameter") { it, context ->
isPropertyAssignCall(it, methodPattern, context) ||
isCallExpressionParameter(it, 0, callPattern, context)
@@ -278,7 +279,6 @@ open class UExpressionPattern<T : UExpression, Self : UExpressionPattern<T, Self
@JvmOverloads
fun methodCallParameter(parameterIndex: Int, methodPattern: ElementPattern<out PsiMethod>, multiResolve: Boolean = true): Self {
val callPattern = callExpression().withResolvedMethod(methodPattern, multiResolve)
return callParameter(parameterIndex, callPattern)
}
@@ -321,7 +321,6 @@ fun uAnnotationQualifiedNamePattern(annotationQualifiedName: ElementPattern<Stri
}
open class UDeclarationPattern<T : UDeclaration>(clazz: Class<T>) : UElementPattern<T, UDeclarationPattern<T>>(clazz) {
fun annotatedWith(@NotNull annotationQualifiedNames: List<String>): UDeclarationPattern<T> {
return this.with(object : PatternCondition<UDeclaration>("annotatedWith") {
override fun accepts(uDeclaration: UDeclaration, context: ProcessingContext?): Boolean {
@@ -333,4 +332,4 @@ open class UDeclarationPattern<T : UDeclaration>(clazz: Class<T>) : UElementPatt
}
})
}
}
}
@@ -1,6 +1,5 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:JvmName("UastReferenceRegistrar")
package com.intellij.psi
import com.intellij.openapi.util.Key
@@ -17,55 +16,58 @@ import org.jetbrains.uast.expressions.UInjectionHost
* Groups all UAST-based reference providers by chunks with the same priority and supported UElement types.
*/
@JvmOverloads
fun PsiReferenceRegistrar.registerUastReferenceProvider(pattern: (UElement, ProcessingContext) -> Boolean,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY) {
fun PsiReferenceRegistrar.registerUastReferenceProvider(
pattern: (UElement, ProcessingContext) -> Boolean,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY,
) {
val adapter = UastReferenceProviderAdapter(provider.supportedUElementTypes, provider)
this.registerReferenceProvider(adaptPattern(pattern, provider.supportedUElementTypes), adapter, priority)
registerReferenceProvider(adaptPattern(pattern, provider.supportedUElementTypes), adapter, priority)
}
@JvmOverloads
fun PsiReferenceRegistrar.registerUastReferenceProvider(pattern: ElementPattern<out UElement>,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY) {
this.registerUastReferenceProvider(pattern::accepts, provider, priority)
fun PsiReferenceRegistrar.registerUastReferenceProvider(
pattern: ElementPattern<out UElement>,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY,
) {
registerUastReferenceProvider(pattern::accepts, provider, priority)
}
fun uastInjectionHostReferenceProvider(provider: (UExpression, PsiLanguageInjectionHost) -> Array<PsiReference>): UastInjectionHostReferenceProvider =
uastInjectionHostReferenceProvider(null, provider)
fun uastInjectionHostReferenceProvider(
provider: (UExpression, PsiLanguageInjectionHost) -> Array<PsiReference>
): UastInjectionHostReferenceProvider = uastInjectionHostReferenceProvider(null, provider)
fun uastInjectionHostReferenceProvider(targetClass: Class<out PsiElement>?,
provider: (UExpression, PsiLanguageInjectionHost) -> Array<PsiReference>): UastInjectionHostReferenceProvider =
object : UastInjectionHostReferenceProvider() {
override fun getReferencesForInjectionHost(uExpression: UExpression,
host: PsiLanguageInjectionHost,
context: ProcessingContext): Array<PsiReference> = provider(uExpression, host)
fun uastInjectionHostReferenceProvider(
targetClass: Class<out PsiElement>?,
provider: (UExpression, PsiLanguageInjectionHost) -> Array<PsiReference>,
): UastInjectionHostReferenceProvider = object : UastInjectionHostReferenceProvider() {
override fun getReferencesForInjectionHost(
uExpression: UExpression,
host: PsiLanguageInjectionHost,
context: ProcessingContext,
): Array<PsiReference> = provider(uExpression, host)
override fun acceptsTarget(target: PsiElement): Boolean {
return targetClass?.isInstance(target) ?: true
}
override fun acceptsTarget(target: PsiElement): Boolean = targetClass?.isInstance(target) ?: true
override fun toString(): String = "uastInjectionHostReferenceProvider($provider)"
}
fun <T : UElement> uastReferenceProvider(cls: Class<T>, targetClass: Class<out PsiElement>?,
provider: (T, PsiElement) -> Array<PsiReference>): UastReferenceProvider =
object : UastReferenceProvider(cls) {
override fun getReferencesByElement(element: UElement, context: ProcessingContext): Array<PsiReference> {
return provider(cls.cast(element), getRequestedPsiElement(context))
}
override fun acceptsTarget(target: PsiElement): Boolean {
return targetClass?.isInstance(target) ?: true
}
override fun toString(): String = "uastReferenceProvider($provider)"
}
fun getRequestedPsiElement(context: ProcessingContext): PsiElement {
return context[REQUESTED_PSI_ELEMENT]
override fun toString(): String = "uastInjectionHostReferenceProvider($provider)"
}
fun <T : UElement> uastReferenceProvider(
cls: Class<T>, targetClass: Class<out PsiElement>?,
provider: (T, PsiElement) -> Array<PsiReference>,
): UastReferenceProvider = object : UastReferenceProvider(cls) {
override fun getReferencesByElement(element: UElement, context: ProcessingContext): Array<PsiReference> {
return provider(cls.cast(element), getRequestedPsiElement(context))
}
override fun acceptsTarget(target: PsiElement): Boolean = targetClass?.isInstance(target) ?: true
override fun toString(): String = "uastReferenceProvider($provider)"
}
fun getRequestedPsiElement(context: ProcessingContext): PsiElement = context[REQUESTED_PSI_ELEMENT]
fun <T : UElement> uastReferenceProvider(cls: Class<T>, provider: (T, PsiElement) -> Array<PsiReference>): UastReferenceProvider =
uastReferenceProvider(cls, null, provider)
@@ -75,11 +77,13 @@ inline fun <reified T : UElement> uastReferenceProvider(noinline provider: (T, P
internal val REQUESTED_PSI_ELEMENT: Key<PsiElement> = Key.create("REQUESTED_PSI_ELEMENT")
internal val USAGE_PSI_ELEMENT: Key<PsiElement> = Key.create("USAGE_PSI_ELEMENT")
internal fun adaptPattern(pattern: (UElement, ProcessingContext) -> Boolean,
supportedUElementTypes: List<Class<out UElement>>): ElementPattern<out PsiElement> {
internal fun adaptPattern(
pattern: (UElement, ProcessingContext) -> Boolean,
supportedUElementTypes: List<Class<out UElement>>
): ElementPattern<out PsiElement> {
val uastPatternAdapter = UastPatternAdapter(pattern, supportedUElementTypes)
// optimisation until IDEA-211738 is implemented
// optimization until IDEA-211738 is implemented
if (supportedUElementTypes.size == 1 && supportedUElementTypes[0] == UInjectionHost::class.java) {
return StandardPatterns.instanceOf(PsiLanguageInjectionHost::class.java).and(uastPatternAdapter)
}
@@ -88,8 +92,9 @@ internal fun adaptPattern(pattern: (UElement, ProcessingContext) -> Boolean,
}
@ApiStatus.Experimental
fun uastReferenceProviderByUsage(provider: (UExpression, referencePsi: PsiLanguageInjectionHost, usagePsi: PsiElement) -> Array<PsiReference>): UastReferenceProvider =
uastReferenceProviderByUsage(null, provider)
fun uastReferenceProviderByUsage(
provider: (UExpression, referencePsi: PsiLanguageInjectionHost, usagePsi: PsiElement) -> Array<PsiReference>
): UastReferenceProvider = uastReferenceProviderByUsage(null, provider)
/**
* Creates UAST reference provider that accepts additional PSI element that could be either the same as reference PSI element or reference
@@ -98,24 +103,22 @@ fun uastReferenceProviderByUsage(provider: (UExpression, referencePsi: PsiLangua
* @see registerReferenceProviderByUsage
*/
@ApiStatus.Experimental
fun uastReferenceProviderByUsage(targetClass: Class<out PsiElement>?,
provider: (UExpression, referencePsi: PsiLanguageInjectionHost, usagePsi: PsiElement) -> Array<PsiReference>): UastReferenceProvider =
object : UastReferenceProvider(UInjectionHost::class.java) {
override fun getReferencesByElement(element: UElement, context: ProcessingContext): Array<PsiReference> {
val uLiteral = element as? UExpression ?: return PsiReference.EMPTY_ARRAY
val host = getRequestedPsiElement(context) as? PsiLanguageInjectionHost ?: return PsiReference.EMPTY_ARRAY
val usagePsi = context[USAGE_PSI_ELEMENT] ?: getRequestedPsiElement(context)
return provider(uLiteral, host, usagePsi)
}
override fun acceptsTarget(target: PsiElement): Boolean {
return targetClass?.isInstance(target) ?: true
}
override fun toString(): String = "uastByUsageReferenceProvider($provider)"
fun uastReferenceProviderByUsage(
targetClass: Class<out PsiElement>?,
provider: (UExpression, referencePsi: PsiLanguageInjectionHost, usagePsi: PsiElement) -> Array<PsiReference>,
): UastReferenceProvider = object : UastReferenceProvider(UInjectionHost::class.java) {
override fun getReferencesByElement(element: UElement, context: ProcessingContext): Array<PsiReference> {
val uLiteral = element as? UExpression ?: return PsiReference.EMPTY_ARRAY
val host = getRequestedPsiElement(context) as? PsiLanguageInjectionHost ?: return PsiReference.EMPTY_ARRAY
val usagePsi = context[USAGE_PSI_ELEMENT] ?: getRequestedPsiElement(context)
return provider(uLiteral, host, usagePsi)
}
override fun acceptsTarget(target: PsiElement): Boolean = targetClass?.isInstance(target) ?: true
override fun toString(): String = "uastByUsageReferenceProvider($provider)"
}
/**
* Registers a provider that will be called on the expressions that directly satisfy the [usagePattern] or at least one of the expression
* usages satisfies the pattern if it was assigned to a variable. The provider will search for usages of variables only for expressions that
@@ -125,21 +128,25 @@ fun uastReferenceProviderByUsage(targetClass: Class<out PsiElement>?,
*/
@ApiStatus.Experimental
@JvmOverloads
fun PsiReferenceRegistrar.registerReferenceProviderByUsage(expressionPattern: ElementPattern<out UElement>,
usagePattern: ElementPattern<out UElement>,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY) {
this.registerUastReferenceProvider(usagePattern, provider, priority)
fun PsiReferenceRegistrar.registerReferenceProviderByUsage(
expressionPattern: ElementPattern<out UElement>,
usagePattern: ElementPattern<out UElement>,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY,
) {
registerUastReferenceProvider(usagePattern, provider, priority)
if (Registry.`is`("uast.references.by.usage", true)) {
val adapter = UastReferenceByUsageAdapter(expressionPattern, usagePattern, provider)
this.registerReferenceProvider(adaptPattern(expressionPattern::accepts, adapter.supportedUElementTypes), adapter, priority)
registerReferenceProvider(adaptPattern(expressionPattern::accepts, adapter.supportedUElementTypes), adapter, priority)
}
}
@ApiStatus.Experimental
fun PsiReferenceRegistrar.registerReferenceProviderByUsage(usagePattern: ElementPattern<out UElement>,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY) {
fun PsiReferenceRegistrar.registerReferenceProviderByUsage(
usagePattern: ElementPattern<out UElement>,
provider: UastReferenceProvider,
priority: Double = PsiReferenceRegistrar.DEFAULT_PRIORITY,
) {
registerReferenceProviderByUsage(uExpressionInVariable(), usagePattern, provider, priority)
}
@@ -1,7 +1,6 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:JvmMultifileClass
@file:JvmName("UastUtils")
package org.jetbrains.uast
import com.intellij.openapi.util.TextRange
@@ -18,7 +17,6 @@ import com.intellij.util.SmartList
import one.util.streamex.StreamEx
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.visitor.AbstractUastVisitor
import java.io.File
import java.util.stream.Stream
inline fun <reified T : UElement> UElement.getParentOfType(strict: Boolean = true): T? = getParentOfType(T::class.java, strict)
@@ -87,7 +85,7 @@ fun <T : UElement> UElement.getParentOfType(
fun UElement?.getUCallExpression(searchLimit: Int = Int.MAX_VALUE): UCallExpression? {
if (this == null) return null
var u: UElement? = this
for (i in 1..searchLimit) {
for (@Suppress("unused") i in 1..searchLimit) {
if (u == null) break
if (u is UCallExpression) return u
@@ -115,7 +113,7 @@ fun <T : UElement> PsiElement?.findContaining(clazz: Class<T>): T? {
return null
}
fun <T : UElement> PsiElement?.findAnyContaining(vararg types: Class<out T>): T? = findAnyContaining(Int.Companion.MAX_VALUE, *types)
fun <T : UElement> PsiElement?.findAnyContaining(vararg types: Class<out T>): T? = findAnyContaining(Int.MAX_VALUE, *types)
fun <T : UElement> PsiElement?.findAnyContaining(depthLimit: Int, vararg types: Class<out T>): T? {
var element = this
@@ -180,11 +178,10 @@ fun skipParenthesizedExprUp(elem: UElement?): UElement? {
return parent
}
/**
* Get a physical [File] for this file, or null if there is no such file on disk.
*/
fun UFile.getIoFile(): File? = sourcePsi.virtualFile?.let { VfsUtilCore.virtualToIoFile(it) }
@Deprecated("avoid j.i.File use")
@ApiStatus.ScheduledForRemoval
@Suppress("IO_FILE_USAGE")
fun UFile.getIoFile(): java.io.File? = sourcePsi.virtualFile?.let { VfsUtilCore.virtualToIoFile(it) }
@Deprecated("use UastFacade", ReplaceWith("UastFacade"))
@ApiStatus.ScheduledForRemoval
@@ -198,22 +195,9 @@ tailrec fun UElement.getUastContext(): UastContext {
return (uastParent ?: error("PsiElement should exist at least for UFile")).getUastContext()
}
@Deprecated("could unexpectedly throw exception", ReplaceWith("UastFacade.findPlugin"))
@ApiStatus.ScheduledForRemoval
tailrec fun UElement.getLanguagePlugin(): UastLanguagePlugin {
val psi = this.sourcePsi
if (psi != null) {
return UastFacade.findPlugin(psi) ?: error("Language plugin was not found for $this (${this.javaClass.name})")
}
return (uastParent ?: error("PsiElement should exist at least for UFile")).getLanguagePlugin()
}
fun Collection<UElement?>.toPsiElements(): List<PsiElement> = mapNotNull { it?.sourcePsi }
/**
* A helper function for getting parents for given [PsiElement] that could be considered as identifier.
* Useful for working with gutter according to recommendations in [com.intellij.codeInsight.daemon.LineMarkerProvider].
* Useful for working with gutter according to recommendations in `LineMarkerProvider`.
*
* @see [getUParentForAnnotationIdentifier] for working with annotations
*/
@@ -307,4 +291,4 @@ fun nonStructuralChildren(expression: UExpression): Stream<UExpression> {
}.remove { e ->
e is UBlockExpression || e is UIfExpression || e is UParenthesizedExpression || e is USwitchExpression
}
}
}