mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
Java: add cast when necessary in more places (IJ-CR-107436, IDEA-248610)
GitOrigin-RevId: 97431697ea4a59bb68a0d2309ad70d6bfe6e674f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8804e740be
commit
e91500e822
@@ -1083,7 +1083,7 @@ public class TypeMigrationLabeler {
|
|||||||
return myRootsTree;
|
return myRootsTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeMigrationUsageInfo getCurrentRoot() {
|
public TypeMigrationUsageInfo getCurrentRoot() {
|
||||||
return myCurrentRoot;
|
return myCurrentRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,15 +22,14 @@ import java.util.List;
|
|||||||
public class ThreadLocalConversionRule extends TypeConversionRule {
|
public class ThreadLocalConversionRule extends TypeConversionRule {
|
||||||
private static final Logger LOG = Logger.getInstance(ThreadLocalConversionRule.class);
|
private static final Logger LOG = Logger.getInstance(ThreadLocalConversionRule.class);
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeConversionDescriptorBase findConversion(PsiType from,
|
public TypeConversionDescriptorBase findConversion(PsiType from,
|
||||||
PsiType to,
|
PsiType to,
|
||||||
PsiMember member,
|
PsiMember member,
|
||||||
PsiExpression context,
|
PsiExpression context,
|
||||||
TypeMigrationLabeler labeler) {
|
TypeMigrationLabeler labeler) {
|
||||||
if (to instanceof PsiClassType && isThreadLocalTypeMigration(from, (PsiClassType)to, context)) {
|
if (to instanceof PsiClassType toClassType && isThreadLocalTypeMigration(from, toClassType, context)) {
|
||||||
return findDirectConversion(context, to, from, labeler);
|
return findDirectConversion(context, toClassType, from, labeler);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -64,13 +63,17 @@ public class ThreadLocalConversionRule extends TypeConversionRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static TypeConversionDescriptor findDirectConversion(PsiElement context, PsiType to, PsiType from, TypeMigrationLabeler labeler) {
|
private static TypeConversionDescriptor findDirectConversion(PsiElement context,
|
||||||
final PsiClass toTypeClass = PsiUtil.resolveClassInType(to);
|
PsiClassType to,
|
||||||
|
PsiType from,
|
||||||
|
TypeMigrationLabeler labeler) {
|
||||||
|
final PsiClass toTypeClass = to.resolve();
|
||||||
LOG.assertTrue(toTypeClass != null);
|
LOG.assertTrue(toTypeClass != null);
|
||||||
|
|
||||||
final PsiElement parent = context.getParent();
|
final PsiElement parent = context.getParent();
|
||||||
if (parent instanceof PsiVariable && ((PsiVariable)parent).getInitializer() == context) {
|
if (parent.equals(labeler.getCurrentRoot().getElement()) && ((PsiVariable)parent).getInitializer() == context) {
|
||||||
return wrapWithNewExpression(to, from, (PsiExpression)context);
|
|
||||||
|
return wrapWithNewExpression(from, to, (PsiExpression)context);
|
||||||
}
|
}
|
||||||
if (context instanceof PsiArrayAccessExpression) {
|
if (context instanceof PsiArrayAccessExpression) {
|
||||||
return new TypeConversionDescriptor("$qualifier$[$val$]", "$qualifier$.get()[$val$]");
|
return new TypeConversionDescriptor("$qualifier$[$val$]", "$qualifier$.get()[$val$]");
|
||||||
@@ -78,8 +81,10 @@ public class ThreadLocalConversionRule extends TypeConversionRule {
|
|||||||
if (parent instanceof PsiAssignmentExpression) {
|
if (parent instanceof PsiAssignmentExpression) {
|
||||||
final IElementType operationSign = ((PsiAssignmentExpression)parent).getOperationTokenType();
|
final IElementType operationSign = ((PsiAssignmentExpression)parent).getOperationTokenType();
|
||||||
if (operationSign == JavaTokenType.EQ) {
|
if (operationSign == JavaTokenType.EQ) {
|
||||||
boolean rightInfected = ((PsiAssignmentExpression)parent).getLExpression() == context;
|
final boolean rightInfected = ((PsiAssignmentExpression)parent).getLExpression() == context;
|
||||||
String replacement = rightInfected ? "$qualifier$ = $val$.get()" : "$qualifier$.set(" + toBoxed("$val$", from, context) + ")";
|
final String replacement = rightInfected
|
||||||
|
? "$qualifier$ = $val$.get()"
|
||||||
|
: "$qualifier$.set(" + coerceType("$val$", from, to, context) + ")";
|
||||||
return new TypeConversionDescriptor("$qualifier$ = $val$", replacement, (PsiAssignmentExpression)parent);
|
return new TypeConversionDescriptor("$qualifier$ = $val$", replacement, (PsiAssignmentExpression)parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,11 +140,11 @@ public class ThreadLocalConversionRule extends TypeConversionRule {
|
|||||||
if (lExpression instanceof PsiReferenceExpression) {
|
if (lExpression instanceof PsiReferenceExpression) {
|
||||||
final PsiElement element = ((PsiReferenceExpression)lExpression).resolve();
|
final PsiElement element = ((PsiReferenceExpression)lExpression).resolve();
|
||||||
if (element instanceof PsiVariable && ((PsiVariable)element).hasModifierProperty(PsiModifier.FINAL)) {
|
if (element instanceof PsiVariable && ((PsiVariable)element).hasModifierProperty(PsiModifier.FINAL)) {
|
||||||
return wrapWithNewExpression(to, from, ((PsiAssignmentExpression)context).getRExpression());
|
return wrapWithNewExpression(from, to, ((PsiAssignmentExpression)context).getRExpression());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new TypeConversionDescriptor("$qualifier$ = $val$",
|
return new TypeConversionDescriptor("$qualifier$ = $val$",
|
||||||
"$qualifier$.set(" + toBoxed("$val$", from, context) + ")");
|
"$qualifier$.set(" + coerceType("$val$", from, to, context) + ")");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final PsiExpression rExpression = assignmentExpression.getRExpression();
|
final PsiExpression rExpression = assignmentExpression.getRExpression();
|
||||||
@@ -155,39 +160,32 @@ public class ThreadLocalConversionRule extends TypeConversionRule {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TypeConversionDescriptor wrapWithNewExpression(PsiType to, PsiType from, PsiExpression initializer) {
|
private static TypeConversionDescriptor wrapWithNewExpression(PsiType from, PsiClassType to, PsiExpression initializer) {
|
||||||
List<PsiVariable> toMakeFinal = TypeConversionRuleUtil.getVariablesToMakeFinal(initializer);
|
List<PsiVariable> toMakeFinal = TypeConversionRuleUtil.getVariablesToMakeFinal(initializer);
|
||||||
if (toMakeFinal == null) return null;
|
if (toMakeFinal == null) return null;
|
||||||
return new WrappingWithInnerClassOrLambdaDescriptor("$qualifier$",
|
return new WrappingWithInnerClassOrLambdaDescriptor("$qualifier$",
|
||||||
createThreadLocalInitializerReplacement(to, from, initializer),
|
createThreadLocalInitializerReplacement(from, to, initializer),
|
||||||
initializer,
|
initializer,
|
||||||
toMakeFinal);
|
toMakeFinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NonNls String createThreadLocalInitializerReplacement(PsiType to, PsiType from, PsiElement context) {
|
private static @NonNls String createThreadLocalInitializerReplacement(PsiType from, PsiClassType to, PsiElement context) {
|
||||||
if (PsiUtil.isLanguageLevel8OrHigher(context)) {
|
if (PsiUtil.isLanguageLevel8OrHigher(context)) {
|
||||||
if (from instanceof PsiPrimitiveType) {
|
return "java.lang.ThreadLocal.withInitial(() -> " + coerceType("$qualifier$", from, to, context) + ")";
|
||||||
PsiType parameterType = ((PsiClassType)to).getParameters()[0];
|
|
||||||
PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(parameterType);
|
|
||||||
if (unboxed != null && !from.equals(unboxed)) {
|
|
||||||
return "java.lang.ThreadLocal.withInitial(() -> (" + unboxed.getCanonicalText() + ")$qualifier$)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "java.lang.ThreadLocal.withInitial(() -> $qualifier$)";
|
|
||||||
}
|
}
|
||||||
final String boxedTypeName =
|
final StringBuilder result = new StringBuilder("new ");
|
||||||
from instanceof PsiPrimitiveType ? ((PsiPrimitiveType)from).getBoxedTypeName() : from.getCanonicalText();
|
result.append(to.getCanonicalText()).append("() {\n");
|
||||||
return ("""
|
if (PsiUtil.isLanguageLevel5OrHigher(context)) {
|
||||||
new %s() {
|
result.append(" @java.lang.Override\n");
|
||||||
@Override
|
}
|
||||||
protected %s initialValue() {
|
result.append(" protected ")
|
||||||
return %s;
|
.append(PsiUtil.isLanguageLevel5OrHigher(context) ? to.getParameters()[0].getCanonicalText() : "java.lang.Object")
|
||||||
}
|
.append(" initialValue() {\n")
|
||||||
}""").formatted(to.getCanonicalText(),
|
.append(" return ")
|
||||||
boxedTypeName,
|
.append(coerceType("$qualifier$", from, to, context)).append(";\n")
|
||||||
from instanceof PsiPrimitiveType && !PsiUtil.isLanguageLevel5OrHigher(context)
|
.append(" }\n")
|
||||||
? "new " + ((PsiPrimitiveType)from).getBoxedTypeName() + "($qualifier$)"
|
.append("}");
|
||||||
: "$qualifier$");
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NonNls String toPrimitive(@NonNls String replaceByArg, PsiType from, PsiElement context) {
|
private static @NonNls String toPrimitive(@NonNls String replaceByArg, PsiType from, PsiElement context) {
|
||||||
@@ -199,8 +197,16 @@ public class ThreadLocalConversionRule extends TypeConversionRule {
|
|||||||
: "((" + from.getCanonicalText() + ")" + replaceByArg + ")";
|
: "((" + from.getCanonicalText() + ")" + replaceByArg + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NonNls String toBoxed(@NonNls String replaceByArg, PsiType from, PsiElement context) {
|
private static @NonNls String coerceType(@NonNls String replaceByArg, PsiType from, PsiClassType to, PsiElement context) {
|
||||||
if (PsiUtil.isLanguageLevel5OrHigher(context)) {
|
if (PsiUtil.isLanguageLevel5OrHigher(context)) {
|
||||||
|
if (from instanceof PsiPrimitiveType) {
|
||||||
|
final PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(to.getParameters()[0]);
|
||||||
|
if (unboxed != null && !from.equals(unboxed)) {
|
||||||
|
return context instanceof PsiLiteralExpression && PsiTypes.longType().equals(unboxed)
|
||||||
|
? replaceByArg + "L"
|
||||||
|
: "(" + unboxed.getCanonicalText() + ")" + replaceByArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
return replaceByArg;
|
return replaceByArg;
|
||||||
}
|
}
|
||||||
return from instanceof PsiPrimitiveType
|
return from instanceof PsiPrimitiveType
|
||||||
@@ -209,7 +215,7 @@ public class ThreadLocalConversionRule extends TypeConversionRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static @NonNls String getBoxedWrapper(PsiType from,
|
private static @NonNls String getBoxedWrapper(PsiType from,
|
||||||
PsiType to,
|
PsiClassType to,
|
||||||
@NotNull @NonNls String arg,
|
@NotNull @NonNls String arg,
|
||||||
TypeMigrationLabeler labeler,
|
TypeMigrationLabeler labeler,
|
||||||
PsiElement context,
|
PsiElement context,
|
||||||
@@ -227,14 +233,14 @@ public class ThreadLocalConversionRule extends TypeConversionRule {
|
|||||||
final PsiType exprType = labeler.getTypeEvaluator().evaluateType(
|
final PsiType exprType = labeler.getTypeEvaluator().evaluateType(
|
||||||
JavaPsiFacade.getElementFactory(threadLocalClass.getProject()).createExpressionFromText(tryType, context));
|
JavaPsiFacade.getElementFactory(threadLocalClass.getProject()).createExpressionFromText(tryType, context));
|
||||||
if (exprType != null && unboxedInitialType.isAssignableFrom(exprType)) {
|
if (exprType != null && unboxedInitialType.isAssignableFrom(exprType)) {
|
||||||
return toBoxed(arg, from, context);
|
return coerceType(arg, from, to, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "new " + initial.getCanonicalText() + "((" + unboxedInitialType.getCanonicalText() + ")(" + arg + "))";
|
return "new " + initial.getCanonicalText() + "((" + unboxedInitialType.getCanonicalText() + ")(" + arg + "))";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return toBoxed(arg, from, context);
|
return coerceType(arg, from, to, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class WrappingWithInnerClassOrLambdaDescriptor extends ArrayInitializerAwareConversionDescriptor {
|
private static final class WrappingWithInnerClassOrLambdaDescriptor extends ArrayInitializerAwareConversionDescriptor {
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
// "Convert to 'ThreadLocal'" "true"
|
// "Convert to 'ThreadLocal'" "true"
|
||||||
class T {
|
class T {
|
||||||
private static final ThreadLocal<Long> l = ThreadLocal.withInitial(() -> (long) 1); // choose "Convert to ThreadLocal" intention
|
private static final ThreadLocal<Long> l = ThreadLocal.withInitial(() -> 1L); // choose "Convert to ThreadLocal" intention
|
||||||
|
|
||||||
|
static {
|
||||||
|
int i = 1;
|
||||||
|
l.set((long) i);
|
||||||
|
long z = l.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
// "Convert to 'ThreadLocal'" "true"
|
// "Convert to 'ThreadLocal'" "true"
|
||||||
class T {
|
class T {
|
||||||
private static final long <caret>l = 1; // choose "Convert to ThreadLocal" intention
|
private static final long <caret>l = 1; // choose "Convert to ThreadLocal" intention
|
||||||
|
|
||||||
|
static {
|
||||||
|
int i = 1;
|
||||||
|
l = i;
|
||||||
|
long z = l;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// "Convert to 'ThreadLocal'" "true"
|
||||||
|
class T {
|
||||||
|
private static final ThreadLocal<Long> l = new ThreadLocal<Long>() {
|
||||||
|
@Override
|
||||||
|
protected Long initialValue() {
|
||||||
|
return 1L;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static {
|
||||||
|
int i = 1;
|
||||||
|
l.set((long) i);
|
||||||
|
long z = l.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Convert to 'ThreadLocal'" "true"
|
||||||
|
class T {
|
||||||
|
private static final long <caret>l = 1;
|
||||||
|
|
||||||
|
static {
|
||||||
|
int i = 1;
|
||||||
|
l = i;
|
||||||
|
long z = l;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ PsiReferenceExpression:myS : java.lang.ThreadLocal<java.lang.String>
|
|||||||
|
|
||||||
Conversions:
|
Conversions:
|
||||||
"" -> new java.lang.ThreadLocal<java.lang.String>() {
|
"" -> new java.lang.ThreadLocal<java.lang.String>() {
|
||||||
@Override
|
@java.lang.Override
|
||||||
protected java.lang.String initialValue() {
|
protected java.lang.String initialValue() {
|
||||||
return $qualifier$;
|
return $qualifier$;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user