mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java] Move 'forbiddenApi' API to LanguageLevelUtil
Decouples Java15APIUsageInspection from other inspections and completion GitOrigin-RevId: ae37f8f01514e2e557acac9757b11cba11bcdbb5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
89025c2c75
commit
e48a6f2573
@@ -1,15 +1,27 @@
|
||||
// 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.
|
||||
// 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 com.intellij.openapi.module;
|
||||
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.roots.LanguageLevelModuleExtension;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.ref.Reference;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class LanguageLevelUtil {
|
||||
/**
|
||||
* Returns explicitly specified custom language level for {@code module}, or {@code null} if the module uses 'Project default' language level
|
||||
@@ -26,4 +38,142 @@ public class LanguageLevelUtil {
|
||||
if (level != null) return level;
|
||||
return LanguageLevelProjectExtension.getInstance(module.getProject()).getLanguageLevel();
|
||||
}
|
||||
|
||||
private static final Map<LanguageLevel, Reference<Set<String>>> ourForbiddenAPI = new EnumMap<>(LanguageLevel.class);
|
||||
|
||||
public static String getJdkName(LanguageLevel languageLevel) {
|
||||
final String presentableText = languageLevel.getPresentableText();
|
||||
return presentableText.substring(0, presentableText.indexOf(' '));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param api The language level to get the next from.
|
||||
* @return Next {@link LanguageLevel} that is not in preview.
|
||||
*/
|
||||
public static @Nullable LanguageLevel getNextLanguageLevel(@NotNull LanguageLevel api) {
|
||||
final LanguageLevel[] levels = LanguageLevel.values();
|
||||
final int currentLevelId = api.ordinal();
|
||||
for (int i = currentLevelId + 1; i < levels.length; i++) {
|
||||
final LanguageLevel level = levels[i];
|
||||
if (!level.isPreview()) return level;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Map<LanguageLevel, String> ourPresentableShortMessage = new EnumMap<>(LanguageLevel.class);
|
||||
|
||||
static {
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_3, "1.4");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_4, "1.5");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_5, "1.6");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_6, "1.7");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_7, "1.8");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_8, "9");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_9, "10");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_10, "11");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_11, "12");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_12, "13");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_13, "14");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_14, "15");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_15, "16");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_16, "17");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_16_PREVIEW, "17");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getShortMessage(@NotNull LanguageLevel languageLevel) {
|
||||
return ourPresentableShortMessage.get(languageLevel);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Set<String> getForbiddenApi(@NotNull LanguageLevel languageLevel) {
|
||||
if (!ourPresentableShortMessage.containsKey(languageLevel)) return null;
|
||||
Reference<Set<String>> ref = ourForbiddenAPI.get(languageLevel);
|
||||
Set<String> result = SoftReference.dereference(ref);
|
||||
if (result == null) {
|
||||
result = loadSignatureList(LanguageLevelUtil.class.getResource("api" + getShortMessage(languageLevel) + ".txt"));
|
||||
ourForbiddenAPI.put(languageLevel, new SoftReference<>(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param member The {@link PsiMember} to get the language level from
|
||||
* @param languageLevel The effective language level
|
||||
* @return The last compatible language level for a {@link PsiMember} as annotated by the @since javadoc
|
||||
*/
|
||||
public static LanguageLevel getLastIncompatibleLanguageLevel(@NotNull PsiMember member, @NotNull LanguageLevel languageLevel) {
|
||||
if (member instanceof PsiAnonymousClass) return null;
|
||||
PsiClass containingClass = member.getContainingClass();
|
||||
if (containingClass instanceof PsiAnonymousClass) return null;
|
||||
if (member instanceof PsiClass && !(member.getParent() instanceof PsiClass || member.getParent() instanceof PsiFile)) return null;
|
||||
|
||||
Set<String> forbiddenApi = getForbiddenApi(languageLevel);
|
||||
if (forbiddenApi == null) return null;
|
||||
String signature = getSignature(member);
|
||||
if (signature == null) return null;
|
||||
LanguageLevel lastIncompatibleLanguageLevel = getLastIncompatibleLanguageLevelForSignature(signature, languageLevel, forbiddenApi);
|
||||
if (lastIncompatibleLanguageLevel != null) return lastIncompatibleLanguageLevel;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static LanguageLevel getLastIncompatibleLanguageLevelForSignature(@NotNull String signature, @NotNull LanguageLevel languageLevel, @NotNull Set<String> forbiddenApi) {
|
||||
if (forbiddenApi.contains(signature)) {
|
||||
return languageLevel;
|
||||
}
|
||||
if (languageLevel.compareTo(LanguageLevel.HIGHEST) == 0) {
|
||||
return null;
|
||||
}
|
||||
LanguageLevel nextLanguageLevel = LanguageLevel.values()[languageLevel.ordinal() + 1];
|
||||
Set<String> nextForbiddenApi = getForbiddenApi(nextLanguageLevel);
|
||||
return nextForbiddenApi != null ? getLastIncompatibleLanguageLevelForSignature(signature, nextLanguageLevel, nextForbiddenApi) : null;
|
||||
}
|
||||
|
||||
public static Set<String> loadSignatureList(URL resource) {
|
||||
if (resource == null) {
|
||||
Logger.getInstance(LanguageLevelUtil.class).warn("not found: " + resource.getFile());
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.openStream(), StandardCharsets.UTF_8))) {
|
||||
return new HashSet<>(FileUtil.loadLines(reader));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getInstance(LanguageLevelUtil.class).warn("cannot load: " + resource.getFile(), ex);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For serialization of forbidden api.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getSignature(@Nullable PsiMember member) {
|
||||
if (member instanceof PsiClass) {
|
||||
return ((PsiClass)member).getQualifiedName();
|
||||
}
|
||||
if (member instanceof PsiField) {
|
||||
String containingClass = getSignature(member.getContainingClass());
|
||||
return containingClass == null ? null : containingClass + "#" + member.getName();
|
||||
}
|
||||
if (member instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)member;
|
||||
String containingClass = getSignature(member.getContainingClass());
|
||||
if (containingClass == null) return null;
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(containingClass);
|
||||
buf.append('#');
|
||||
buf.append(method.getName());
|
||||
buf.append('(');
|
||||
for (PsiType type : method.getSignature(PsiSubstitutor.EMPTY).getParameterTypes()) {
|
||||
buf.append(type.getCanonicalText());
|
||||
buf.append(";");
|
||||
}
|
||||
buf.append(')');
|
||||
return buf.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
// Copyright 2000-2018 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. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.DeleteCatchFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.DeleteMultiCatchFix;
|
||||
import com.intellij.codeInspection.java15api.Java15APIUsageInspection;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -187,7 +187,7 @@ public class CharsetObjectCanBeUsedInspection extends AbstractBaseJavaLocalInspe
|
||||
PsiMethod[] candidates = method.isConstructor() ? aClass.getConstructors() : aClass.findMethodsByName(method.getName(), false);
|
||||
PsiMethod charsetMethod = Arrays.stream(candidates)
|
||||
.filter(psiMethod -> checkMethod(psiMethod, "java.nio.charset.Charset"))
|
||||
.filter(psiMethod -> Java15APIUsageInspection.getLastIncompatibleLanguageLevel(psiMethod, languageLevel) == null)
|
||||
.filter(psiMethod -> LanguageLevelUtil.getLastIncompatibleLanguageLevel(psiMethod, languageLevel) == null)
|
||||
.findFirst().orElse(null);
|
||||
if (charsetMethod == null) return null;
|
||||
return new CharsetMatch(argument, method, charsetMethod);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// 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. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.codeInspection.java15api.Java15APIUsageInspection;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.ReadActionProcessor;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
@@ -151,7 +151,7 @@ public final class FunctionalInterfaceSuggester {
|
||||
@Override
|
||||
public boolean processInReadAction(PsiMember member) {
|
||||
if (member instanceof PsiClass &&
|
||||
Java15APIUsageInspection.getLastIncompatibleLanguageLevel(member, PsiUtil.getLanguageLevel(element)) == null) {
|
||||
LanguageLevelUtil.getLastIncompatibleLanguageLevel(member, PsiUtil.getLanguageLevel(element)) == null) {
|
||||
if (!JavaPsiFacade.getInstance(project).getResolveHelper().isAccessible(member, element, null)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import com.intellij.codeInsight.daemon.impl.analysis.LambdaHighlightingUtil;
|
||||
import com.intellij.codeInsight.editorActions.TabOutScopesTracker;
|
||||
import com.intellij.codeInsight.guess.GuessManager;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.codeInspection.java15api.Java15APIUsageInspection;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -503,7 +503,7 @@ public final class JavaCompletionUtil {
|
||||
|
||||
private boolean shouldMarkRed(@NotNull Object object) {
|
||||
if (!(object instanceof PsiMember)) return false;
|
||||
if (Java15APIUsageInspection.getLastIncompatibleLanguageLevel((PsiMember)object, myLanguageLevel) != null) {
|
||||
if (LanguageLevelUtil.getLastIncompatibleLanguageLevel((PsiMember)object, myLanguageLevel) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+12
-142
@@ -19,49 +19,25 @@ import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.VerticalFlowLayout;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.ui.SimpleListCellRenderer;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.ref.Reference;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* In order to add the support for new API in the most recent JDK execute:
|
||||
* <ol>
|
||||
* <li>Generate apiXXX.txt by uncommenting the body of {@link com.intellij.java.codeInspection.JavaAPIUsagesInspectionTest#testCollectSinceApiUsages} and run it;</li>
|
||||
* <li>Add two new entries to the {@link Java15APIUsageInspection#ourHighestKnownLanguage}:
|
||||
* <ul>
|
||||
* <li>The First entry: The key is the most recent language level, the value is the second to the most recent language level.</li>
|
||||
* <li>The Second entry: The key is the most recent preview language level, the value is the second to the most recent language level.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Reassign the value of {@link Java15APIUsageInspection#ourHighestKnownLanguage} to the most recent language level</li>
|
||||
* </ol>
|
||||
* To
|
||||
* @author max
|
||||
*/
|
||||
public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionTool {
|
||||
private static final Logger LOGGER = Logger.getInstance(Java15APIUsageInspection.class.getName());
|
||||
|
||||
@@ -69,12 +45,11 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
|
||||
private static final String EFFECTIVE_LL = "effectiveLL";
|
||||
|
||||
private static final Map<LanguageLevel, Reference<Set<String>>> ourForbiddenAPI = new EnumMap<>(LanguageLevel.class);
|
||||
private static final Set<String> ourIgnored16ClassesAPI = loadForbiddenApi("ignore16List.txt");
|
||||
private static final Set<String> ourIgnored16ClassesAPI = LanguageLevelUtil.loadSignatureList(
|
||||
Java15APIUsageInspection.class.getResource("ignore6List.txt")
|
||||
);
|
||||
private static final Map<LanguageLevel, String> ourPresentableShortMessage = new EnumMap<>(LanguageLevel.class);
|
||||
|
||||
private static final LanguageLevel ourHighestKnownLanguage = LanguageLevel.JDK_17;
|
||||
|
||||
static {
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_3, "1.4");
|
||||
ourPresentableShortMessage.put(LanguageLevel.JDK_1_4, "1.5");
|
||||
@@ -154,34 +129,6 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Set<String> getForbiddenApi(@NotNull LanguageLevel languageLevel) {
|
||||
if (!ourPresentableShortMessage.containsKey(languageLevel)) return null;
|
||||
Reference<Set<String>> ref = ourForbiddenAPI.get(languageLevel);
|
||||
Set<String> result = SoftReference.dereference(ref);
|
||||
if (result == null) {
|
||||
result = loadForbiddenApi("api" + getShortName(languageLevel) + ".txt");
|
||||
ourForbiddenAPI.put(languageLevel, new SoftReference<>(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Set<String> loadForbiddenApi(String fileName) {
|
||||
URL resource = Java15APIUsageInspection.class.getResource(fileName);
|
||||
if (resource == null) {
|
||||
Logger.getInstance(Java15APIUsageInspection.class).warn("not found: " + fileName);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.openStream(), StandardCharsets.UTF_8))) {
|
||||
return new HashSet<>(FileUtil.loadLines(reader));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getInstance(Java15APIUsageInspection.class).warn("cannot load: " + fileName, ex);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
@@ -256,7 +203,7 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
final List<PsiMethod> methods = new ArrayList<>();
|
||||
for (HierarchicalMethodSignature methodSignature : aClass.getVisibleSignatures()) {
|
||||
final PsiMethod method = methodSignature.getMethod();
|
||||
if (ourDefaultMethods.contains(getSignature(method))) {
|
||||
if (ourDefaultMethods.contains(LanguageLevelUtil.getSignature(method))) {
|
||||
methods.add(method);
|
||||
}
|
||||
}
|
||||
@@ -267,8 +214,8 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
element2Highlight = aClass instanceof PsiAnonymousClass ? ((PsiAnonymousClass)aClass).getBaseClassReference() : aClass;
|
||||
}
|
||||
myHolder.registerProblem(element2Highlight,
|
||||
methods.size() == 1 ? JavaBundle.message("inspection.1.8.problem.single.descriptor", methods.get(0).getName(), getJdkName(effectiveLanguageLevel))
|
||||
: JavaBundle.message("inspection.1.8.problem.descriptor", methods.size(), getJdkName(effectiveLanguageLevel)),
|
||||
methods.size() == 1 ? JavaBundle.message("inspection.1.8.problem.single.descriptor", methods.get(0).getName(), LanguageLevelUtil.getJdkName(effectiveLanguageLevel))
|
||||
: JavaBundle.message("inspection.1.8.problem.descriptor", methods.size(), LanguageLevelUtil.getJdkName(effectiveLanguageLevel)),
|
||||
QuickFixFactory.getInstance().createImplementMethodsFix(aClass));
|
||||
}
|
||||
}
|
||||
@@ -290,7 +237,7 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(pair);
|
||||
if (module != null) {
|
||||
final LanguageLevel languageLevel = getEffectiveLanguageLevel(module);
|
||||
LanguageLevel sinceLanguageLevel = getLastIncompatibleLanguageLevel((PsiMember)resolve, languageLevel);
|
||||
LanguageLevel sinceLanguageLevel = LanguageLevelUtil.getLastIncompatibleLanguageLevel((PsiMember)resolve, languageLevel);
|
||||
if (sinceLanguageLevel != null) {
|
||||
registerError(ObjectUtils.notNull(pair.getNameIdentifier(), pair), sinceLanguageLevel);
|
||||
}
|
||||
@@ -307,7 +254,7 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(reference.getElement());
|
||||
if (module != null) {
|
||||
final LanguageLevel languageLevel = getEffectiveLanguageLevel(module);
|
||||
LanguageLevel sinceLanguageLevel = getLastIncompatibleLanguageLevel((PsiMember)resolved, languageLevel);
|
||||
LanguageLevel sinceLanguageLevel = LanguageLevelUtil.getLastIncompatibleLanguageLevel((PsiMember)resolved, languageLevel);
|
||||
if (sinceLanguageLevel != null) {
|
||||
PsiClass psiClass = null;
|
||||
final PsiElement qualifier = reference.getQualifier();
|
||||
@@ -332,7 +279,7 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
for (String generifiedClass : ourGenerifiedClasses) {
|
||||
if (InheritanceUtil.isInheritor((PsiClass)resolved, generifiedClass) &&
|
||||
!isRawInheritance(generifiedClass, (PsiClass)resolved, new HashSet<>())) {
|
||||
String message = JavaBundle.message("inspection.1.7.problem.descriptor", getJdkName(languageLevel));
|
||||
String message = JavaBundle.message("inspection.1.7.problem.descriptor", LanguageLevelUtil.getJdkName(languageLevel));
|
||||
myHolder.registerProblem(reference, message);
|
||||
break;
|
||||
}
|
||||
@@ -371,7 +318,7 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
if (module != null) {
|
||||
final LanguageLevel languageLevel = getEffectiveLanguageLevel(module);
|
||||
if (constructor instanceof PsiCompiledElement) {
|
||||
LanguageLevel sinceLanguageLevel = getLastIncompatibleLanguageLevel(constructor, languageLevel);
|
||||
LanguageLevel sinceLanguageLevel = LanguageLevelUtil.getLastIncompatibleLanguageLevel(constructor, languageLevel);
|
||||
if (sinceLanguageLevel != null) {
|
||||
registerError(expression.getClassReference(), sinceLanguageLevel);
|
||||
}
|
||||
@@ -391,7 +338,7 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
final PsiMethod[] methods = method.findSuperMethods();
|
||||
for (PsiMethod superMethod : methods) {
|
||||
if (superMethod instanceof PsiCompiledElement) {
|
||||
sinceLanguageLevel = getLastIncompatibleLanguageLevel(superMethod, languageLevel);
|
||||
sinceLanguageLevel = LanguageLevelUtil.getLastIncompatibleLanguageLevel(superMethod, languageLevel);
|
||||
if (sinceLanguageLevel == null) {
|
||||
return;
|
||||
}
|
||||
@@ -415,7 +362,7 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
private void registerError(PsiElement reference, LanguageLevel api) {
|
||||
if (reference == null || !isInProject(reference)) return;
|
||||
|
||||
final LanguageLevel targetLanguageLevel = getNextLanguageLevel(api);
|
||||
final LanguageLevel targetLanguageLevel = LanguageLevelUtil.getNextLanguageLevel(api);
|
||||
|
||||
if (targetLanguageLevel == null) {
|
||||
LOGGER.error("Unable to get the next language level for " + api);
|
||||
@@ -436,81 +383,4 @@ public class Java15APIUsageInspection extends AbstractBaseJavaLocalInspectionToo
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static @Nullable LanguageLevel getNextLanguageLevel(@NotNull LanguageLevel api) {
|
||||
final LanguageLevel[] levels = LanguageLevel.values();
|
||||
final int currentLevelId = api.ordinal();
|
||||
for (int i = currentLevelId + 1; i < levels.length; i++) {
|
||||
final LanguageLevel level = levels[i];
|
||||
if (!level.isPreview()) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getJdkName(LanguageLevel languageLevel) {
|
||||
final String presentableText = languageLevel.getPresentableText();
|
||||
return presentableText.substring(0, presentableText.indexOf(' '));
|
||||
}
|
||||
|
||||
public static LanguageLevel getLastIncompatibleLanguageLevel(@NotNull PsiMember member, @NotNull LanguageLevel languageLevel) {
|
||||
if (member instanceof PsiAnonymousClass) return null;
|
||||
PsiClass containingClass = member.getContainingClass();
|
||||
if (containingClass instanceof PsiAnonymousClass) return null;
|
||||
if (member instanceof PsiClass && !(member.getParent() instanceof PsiClass || member.getParent() instanceof PsiFile)) return null;
|
||||
|
||||
Set<String> forbiddenApi = getForbiddenApi(languageLevel);
|
||||
String signature = getSignature(member);
|
||||
if (forbiddenApi != null && signature != null) {
|
||||
LanguageLevel lastIncompatibleLanguageLevel = getLastIncompatibleLanguageLevelForSignature(signature, languageLevel, forbiddenApi);
|
||||
if (lastIncompatibleLanguageLevel != null) return lastIncompatibleLanguageLevel;
|
||||
}
|
||||
return containingClass != null ? getLastIncompatibleLanguageLevel(containingClass, languageLevel) : null;
|
||||
|
||||
}
|
||||
|
||||
private static LanguageLevel getLastIncompatibleLanguageLevelForSignature(@NotNull String signature, @NotNull LanguageLevel languageLevel, @NotNull Set<String> forbiddenApi) {
|
||||
if (forbiddenApi.contains(signature)) {
|
||||
return languageLevel;
|
||||
}
|
||||
if (languageLevel.compareTo(ourHighestKnownLanguage) == 0) {
|
||||
return null;
|
||||
}
|
||||
LanguageLevel nextLanguageLevel = LanguageLevel.values()[languageLevel.ordinal() + 1];
|
||||
Set<String> nextForbiddenApi = getForbiddenApi(nextLanguageLevel);
|
||||
return nextForbiddenApi != null ? getLastIncompatibleLanguageLevelForSignature(signature, nextLanguageLevel, nextForbiddenApi) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* please leave public for JavaAPIUsagesInspectionTest#testCollectSinceApiUsages
|
||||
*/
|
||||
@Nullable
|
||||
public static String getSignature(@Nullable PsiMember member) {
|
||||
if (member instanceof PsiClass) {
|
||||
return ((PsiClass)member).getQualifiedName();
|
||||
}
|
||||
if (member instanceof PsiField) {
|
||||
String containingClass = getSignature(member.getContainingClass());
|
||||
return containingClass == null ? null : containingClass + "#" + member.getName();
|
||||
}
|
||||
if (member instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)member;
|
||||
String containingClass = getSignature(member.getContainingClass());
|
||||
if (containingClass == null) return null;
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(containingClass);
|
||||
buf.append('#');
|
||||
buf.append(method.getName());
|
||||
buf.append('(');
|
||||
for (PsiType type : method.getSignature(PsiSubstitutor.EMPTY).getParameterTypes()) {
|
||||
buf.append(type.getCanonicalText());
|
||||
buf.append(";");
|
||||
}
|
||||
buf.append(')');
|
||||
return buf.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
// Copyright 2000-2018 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. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.siyeh.ig.inheritance;
|
||||
|
||||
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.java15api.Java15APIUsageInspection;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -235,7 +234,7 @@ public class MissingOverrideAnnotationInspection extends AbstractBaseJavaLocalIn
|
||||
@Contract("_, _, _,null -> true")
|
||||
private boolean ignoreSuperMethod(PsiMethod method, PsiClass methodClass, PsiMethod superMethod, PsiClass superClass) {
|
||||
return !InheritanceUtil.isInheritorOrSelf(methodClass, superClass, true) ||
|
||||
Java15APIUsageInspection.getLastIncompatibleLanguageLevel(superMethod, PsiUtil.getLanguageLevel(method)) != null;
|
||||
LanguageLevelUtil.getLastIncompatibleLanguageLevel(superMethod, PsiUtil.getLanguageLevel(method)) != null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
// 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. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.siyeh.ig.internationalization;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.java15api.Java15APIUsageInspection;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -59,7 +59,7 @@ public class ImplicitDefaultCharsetUsageInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
InspectionGadgetsFix createFix(LanguageLevel level) {
|
||||
return myMethod == null || Java15APIUsageInspection.getLastIncompatibleLanguageLevel(myMethod, level) != null
|
||||
return myMethod == null || LanguageLevelUtil.getLastIncompatibleLanguageLevel(myMethod, level) != null
|
||||
? null
|
||||
: new AddUtf8CharsetFix(this);
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,7 +1,6 @@
|
||||
// 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.
|
||||
// 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 com.intellij.uiDesigner.inspections;
|
||||
|
||||
import com.intellij.codeInspection.java15api.Java15APIUsageInspection;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.openapi.module.LanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -45,8 +44,8 @@ public class Java15FormInspection extends BaseFormInspection {
|
||||
final PsiMethod getter = PropertyUtilBase.findPropertyGetter(aClass, prop.getName(), false, true);
|
||||
if (getter == null) continue;
|
||||
final LanguageLevel languageLevel = LanguageLevelUtil.getEffectiveLanguageLevel(module);
|
||||
if (Java15APIUsageInspection.getLastIncompatibleLanguageLevel(getter, languageLevel) != null) {
|
||||
registerError(component, collector, prop, "@since " + Java15APIUsageInspection.getShortName(languageLevel));
|
||||
if (LanguageLevelUtil.getLastIncompatibleLanguageLevel(getter, languageLevel) != null) {
|
||||
registerError(component, collector, prop, "@since " + LanguageLevelUtil.getJdkName(languageLevel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user