mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-125805 (language level increase quickfix for switch on enum/string)
This commit is contained in:
+46
-32
@@ -1314,48 +1314,62 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkSwitchSelectorType(@NotNull PsiSwitchStatement statement) {
|
||||
final PsiExpression expression = statement.getExpression();
|
||||
PsiType type = expression == null ? null : expression.getType();
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
HighlightInfo errorResult = null;
|
||||
final boolean atLeastJava7 = PsiUtil.isLanguageLevel7OrHigher(expression);
|
||||
if (!isValidTypeForSwitchSelector(type, atLeastJava7)) {
|
||||
final String switchSelectorMessage = atLeastJava7 ? JavaErrorMessages.message("valid.switch.17.selector.types")
|
||||
: JavaErrorMessages.message("valid.switch.selector.types");
|
||||
String message =
|
||||
JavaErrorMessages.message("incompatible.types", switchSelectorMessage, JavaHighlightUtil.formatType(type));
|
||||
errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
|
||||
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createConvertSwitchToIfIntention(statement));
|
||||
public static HighlightInfo checkSwitchSelectorType(@NotNull PsiSwitchStatement statement, @NotNull LanguageLevel level) {
|
||||
PsiExpression expression = statement.getExpression();
|
||||
if (expression == null) return null;
|
||||
PsiType type = expression.getType();
|
||||
if (type == null) return null;
|
||||
|
||||
SelectorKind kind = getSwitchSelectorKind(type);
|
||||
if (kind == SelectorKind.INT) return null;
|
||||
|
||||
LanguageLevel requiredLevel = null;
|
||||
if (kind == SelectorKind.ENUM) requiredLevel = LanguageLevel.JDK_1_5;
|
||||
if (kind == SelectorKind.STRING) requiredLevel = LanguageLevel.JDK_1_7;
|
||||
|
||||
if (kind == null || requiredLevel != null && !level.isAtLeast(requiredLevel)) {
|
||||
boolean is7 = level.isAtLeast(LanguageLevel.JDK_1_7);
|
||||
String expected = JavaErrorMessages.message(is7 ? "valid.switch.17.selector.types" : "valid.switch.selector.types");
|
||||
String message = JavaErrorMessages.message("incompatible.types", expected, JavaHighlightUtil.formatType(type));
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createConvertSwitchToIfIntention(statement));
|
||||
if (PsiType.LONG.equals(type) || PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)) {
|
||||
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createAddTypeCastFix(PsiType.INT, expression));
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createAddTypeCastFix(PsiType.INT, expression));
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiClass member = PsiUtil.resolveClassInClassTypeOnly(type);
|
||||
if (member != null && !PsiUtil.isAccessible(member.getProject(), member, expression, null)) {
|
||||
String message = PsiFormatUtil.formatClass(member, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_FQ_NAME) + " is inaccessible here";
|
||||
errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
|
||||
if (requiredLevel != null) {
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createIncreaseLanguageLevelFix(requiredLevel));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
return errorResult;
|
||||
|
||||
PsiClass member = PsiUtil.resolveClassInClassTypeOnly(type);
|
||||
if (member != null && !PsiUtil.isAccessible(member.getProject(), member, expression, null)) {
|
||||
String className = PsiFormatUtil.formatClass(member, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_FQ_NAME);
|
||||
String message = JavaErrorMessages.message("inaccessible.type", className);
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValidTypeForSwitchSelector(@NotNull PsiType type, final boolean languageLevel7OrHigher) {
|
||||
if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.INT_RANK) return true;
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass == null) return false;
|
||||
private enum SelectorKind { INT, ENUM, STRING }
|
||||
|
||||
private static SelectorKind getSwitchSelectorKind(@NotNull PsiType type) {
|
||||
if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.INT_RANK) {
|
||||
return SelectorKind.INT;
|
||||
}
|
||||
|
||||
PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(type);
|
||||
if (psiClass != null) {
|
||||
if (psiClass.isEnum()) {
|
||||
return true;
|
||||
return SelectorKind.ENUM;
|
||||
}
|
||||
if (languageLevel7OrHigher) {
|
||||
return Comparing.strEqual(psiClass.getQualifiedName(), CommonClassNames.JAVA_LANG_STRING);
|
||||
if (Comparing.strEqual(psiClass.getQualifiedName(), CommonClassNames.JAVA_LANG_STRING)) {
|
||||
return SelectorKind.STRING;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-1
@@ -1391,7 +1391,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
@Override
|
||||
public void visitSwitchStatement(PsiSwitchStatement statement) {
|
||||
super.visitSwitchStatement(statement);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSwitchSelectorType(statement));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSwitchSelectorType(statement, myLanguageLevel));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -219,6 +219,7 @@ exception.already.caught.warn=Unreachable section: {1, choice, 0#exception|2#exc
|
||||
not.a.statement=Not a statement
|
||||
invalid.statement=Invalid statement
|
||||
incompatible.types=Incompatible types. Found: ''{1}'', required: ''{0}''
|
||||
inaccessible.type=''{0}'' is inaccessible here
|
||||
incompatible.call.types=Wrong {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} argument type. Found: ''{2}'', required: ''{1}''
|
||||
valid.switch.selector.types=byte, char, short or int
|
||||
valid.switch.17.selector.types=char, byte, short, int, Character, Byte, Short, Integer, String, or an enum
|
||||
|
||||
+2
-27
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
@@ -34,16 +18,7 @@ class UnsupportedFeatures {
|
||||
<error descr="Incompatible types. Found: 'boolean', required: 'java.lang.Boolean'">Boolean b = true;</error>
|
||||
<error descr="Incompatible types. Found: 'java.lang.Boolean', required: 'boolean'">boolean b1 = Boolean.TRUE;</error>
|
||||
|
||||
try { Reader r = new FileReader("/dev/null"); }
|
||||
catch (<error descr="Multi-catches are not supported at this language level">FileNotFoundException | IOException e</error>) { e.printStackTrace(); }
|
||||
|
||||
try <error descr="Try-with-resources are not supported at this language level">(Reader r = new FileReader("/dev/null"))</error> { }
|
||||
|
||||
I i1 = <error descr="Method references are not supported at this language level">UnsupportedFeatures::m</error>;
|
||||
I i2 = <error descr="Lambda expressions are not supported at this language level">() -> { }</error>;
|
||||
}
|
||||
|
||||
interface I {
|
||||
<error descr="Extension methods are not supported at this language level">default void m() { }</error>
|
||||
java.lang.annotation.ElementType t = null;
|
||||
switch (<error descr="Incompatible types. Found: 'java.lang.annotation.ElementType', required: 'byte, char, short or int'">t</error>) { }
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -41,6 +41,10 @@ class UnsupportedFeatures {
|
||||
|
||||
I i1 = <error descr="Method references are not supported at this language level">UnsupportedFeatures::m</error>;
|
||||
I i2 = <error descr="Lambda expressions are not supported at this language level">() -> { }</error>;
|
||||
|
||||
switch (<error descr="Incompatible types. Found: 'java.lang.String', required: 'byte, char, short or int'">list.get(0)</error>) {
|
||||
case "foo": break;
|
||||
}
|
||||
}
|
||||
|
||||
interface I {
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ interface A {
|
||||
class D {
|
||||
public static void f(A a) {
|
||||
A.B b = a.getB();
|
||||
switch (<error descr="A.B.C is inaccessible here">b.c</error>) {
|
||||
switch (<error descr="'A.B.C' is inaccessible here">b.c</error>) {
|
||||
case SOME:
|
||||
break;
|
||||
}
|
||||
|
||||
+18
-6
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.convertToJava;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -39,10 +41,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvalua
|
||||
*/
|
||||
public class SwitchStatementGenerator {
|
||||
|
||||
private static final boolean LANGUAGE_LEVEL_7_OR_HIGHER = false;
|
||||
|
||||
private SwitchStatementGenerator() {
|
||||
}
|
||||
private SwitchStatementGenerator() { }
|
||||
|
||||
public static void generate(@NotNull StringBuilder builder,
|
||||
@NotNull ExpressionContext context,
|
||||
@@ -51,7 +50,7 @@ public class SwitchStatementGenerator {
|
||||
final GrCaseSection[] caseSections = switchStatement.getCaseSections();
|
||||
|
||||
final PsiType type = condition == null ? null : TypesUtil.unboxPrimitiveTypeWrapper(condition.getType());
|
||||
if (type == null || HighlightUtil.isValidTypeForSwitchSelector(type, LANGUAGE_LEVEL_7_OR_HIGHER)) {
|
||||
if (type == null || isValidTypeForSwitchSelector(type)) {
|
||||
generateSwitch(builder, context, condition, caseSections);
|
||||
}
|
||||
else {
|
||||
@@ -59,6 +58,19 @@ public class SwitchStatementGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidTypeForSwitchSelector(@NotNull PsiType type) {
|
||||
if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.INT_RANK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type);
|
||||
if (aClass != null && aClass.isEnum()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void generateIfs(@NotNull StringBuilder builder,
|
||||
@NotNull ExpressionContext context,
|
||||
@NotNull GrExpression condition,
|
||||
|
||||
Reference in New Issue
Block a user