Java: render array initializer expressions, switch expressions and instanceof expression correctly

GitOrigin-RevId: aad22125d6c8cbea4c398282a0eabb429c65e735
This commit is contained in:
Bas Leijdekkers
2022-11-16 19:42:12 +00:00
committed by intellij-monorepo-bot
parent 4fe6b200b9
commit b9a6e40f0c
6 changed files with 51 additions and 36 deletions
@@ -1,19 +1,4 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.util;
import com.intellij.openapi.util.NlsSafe;
@@ -41,6 +26,10 @@ public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisito
if (checkType != null) {
myBuf.append(checkType.getText());
}
final PsiPrimaryPattern pattern = expression.getPattern();
if (pattern != null) {
myBuf.append(pattern.getText());
}
}
@Override
@@ -98,6 +87,7 @@ public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisito
PsiExpression operand = operands[i];
if (i != 0) {
PsiJavaToken token = expression.getTokenBeforeOperand(operand);
assert token != null;
myBuf.append(" ").append(token.getText()).append(" ");
}
operand.accept(this);
@@ -182,16 +172,17 @@ public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisito
@Override
public void visitArrayInitializerExpression(final @NotNull PsiArrayInitializerExpression expression) {
myBuf.append("{");
boolean first = true;
for (PsiExpression expr : expression.getInitializers()) {
if (!first) {
myBuf.append(", ");
final PsiExpression[] initializers = expression.getInitializers();
if (initializers.length > 1) {
myBuf.append("{...}");
}
else {
myBuf.append("{");
if (initializers.length > 0) {
initializers[0].accept(this);
}
first = false;
expr.accept(this);
myBuf.append("}");
}
myBuf.append("}");
}
@Override
@@ -205,6 +196,16 @@ public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisito
}
}
@Override
public void visitSwitchExpression(@NotNull PsiSwitchExpression switchExpression) {
myBuf.append("switch (");
final PsiExpression expression = switchExpression.getExpression();
if (expression != null) {
expression.accept(this);
}
myBuf.append(") {...}");
}
@Override
public void visitNewExpression(final @NotNull PsiNewExpression expr) {
final PsiAnonymousClass anonymousClass = expr.getAnonymousClass();
@@ -223,16 +224,17 @@ public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisito
final PsiExpression[] arrayDimensions = expr.getArrayDimensions();
final PsiType type = expr.getType();
final int dimensions = type != null ? type.getArrayDimensions() : arrayDimensions.length;
if (arrayDimensions.length > 0) myBuf.append("[");
for (int i = 0, arrayDimensionsLength = arrayDimensions.length; i < dimensions; i++) {
final PsiExpression dimension = i < arrayDimensionsLength ? arrayDimensions[i] : null;
if (i > 0) myBuf.append("][");
if (dimension != null) {
dimension.accept(this);
for (PsiExpression dimension : arrayDimensions) {
myBuf.append("[");
dimension.accept(this);
myBuf.append("]");
}
if (type != null) {
final int dimensions = type.getArrayDimensions() - arrayDimensions.length;
for (int i = 0; i < dimensions; i++) {
myBuf.append("[]");
}
}
if (arrayDimensions.length > 0) myBuf.append("]");
if (argumentList != null) {
argumentList.accept(this);
@@ -240,6 +242,7 @@ public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisito
final PsiArrayInitializerExpression arrayInitializer = expr.getArrayInitializer();
if (arrayInitializer != null) {
myBuf.append(" ");
arrayInitializer.accept(this);
}
}
@@ -26,7 +26,7 @@ class RedundantCast {
@SuppressWarnings("unchecked")
<T> List<T> getList2(int x) {
return (<warning descr="Casting 'switch(x) { ...' to 'List<T>' is redundant">List<T></warning>) switch(x) {
return (<warning descr="Casting 'switch (x) {...}' to 'List<T>' is redundant">List<T></warning>) switch(x) {
case 0 -> new ArrayList<>();
default -> new ArrayList<>();
};
@@ -4,7 +4,7 @@ public class SwitchExpressionsNullability {
void cons(@NotNull String str) {}
void test(@Nullable String a, @Nullable String b, int i, boolean f) {
cons(((<warning descr="Casting '(switch(i) { ...' to 'String' may produce 'ClassCastException'">String</warning>)(switch(i) {
cons(((<warning descr="Casting '(switch (i) {...})' to 'String' may produce 'ClassCastException'">String</warning>)(switch(i) {
case 1 -> <warning descr="Argument 'a' might be null">a</warning>;
case 2 -> "foo";
case 3 -> <warning descr="Passing 'null' argument to parameter annotated as @NotNull">null</warning>;
@@ -0,0 +1,11 @@
class X {
void x(int i) {
String s = (<warning descr="Casting 'switch (i) {...}' to 'String' is redundant">String</warning>)switch (i) {
case 1 -> "one";
default -> "zero";
};
boolean b = (<warning descr="Casting '(new Object() instanceof String s1 && !s1.isEmpty())' to 'boolean' is redundant">boolean</warning>)(new Object() instanceof String s1 && !s1.isEmpty());
}
}
@@ -6,7 +6,7 @@ class MyTest {
void m() {
assert (<warning descr="Casting '(boolean)(boolean)(new Object() != null)' to 'boolean' is redundant">boolean</warning>)(<warning descr="Casting '(boolean)(new Object() != null)' to 'boolean' is redundant">boolean</warning>)(<warning descr="Casting '(new Object() != null)' to 'boolean' is redundant">boolean</warning>) (new Object() != null) : (<warning descr="Casting '(CharSequence)(String)\"message\"' to 'String' is redundant">String</warning>)(<warning descr="Casting '(String)\"message\"' to 'CharSequence' is redundant">CharSequence</warning>)(<warning descr="Casting '\"message\"' to 'String' is redundant">String</warning>)"message";
if ((<warning descr="Casting '(boolean)(boolean)(1 != 2)' to 'boolean' is redundant">boolean</warning>)(<warning descr="Casting '(boolean)(1 != 2)' to 'boolean' is redundant">boolean</warning>)(<warning descr="Casting '(1 != 2)' to 'boolean' is redundant">boolean</warning>) (1 != 2)) {
for(String string : ((<warning descr="Casting 'new String{\"a\", \"b\", (String)\"c\"}' to 'String[]' is redundant">String[]</warning>)new String[] {"a", "b", (<warning descr="Casting '\"c\"' to 'String' is redundant">String</warning>)"c"})) {
for(String string : ((<warning descr="Casting 'new String[] {...}' to 'String[]' is redundant">String[]</warning>)new String[] {"a", "b", (<warning descr="Casting '\"c\"' to 'String' is redundant">String</warning>)"c"})) {
do {
while ((<warning descr="Casting '(boolean)(boolean)(1 != 2)' to 'boolean' is redundant">boolean</warning>)(<warning descr="Casting '(boolean)(1 != 2)' to 'boolean' is redundant">boolean</warning>)(<warning descr="Casting '(1 != 2)' to 'boolean' is redundant">boolean</warning>) (1 != 2)) {
<error descr="Not a statement">(<warning descr="Casting 'MyTest.class.toString()' to 'String' is redundant">String</warning>)MyTest.class.toString();</error>
@@ -1,4 +1,4 @@
// 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.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
@@ -23,6 +23,7 @@ public class RedundantCast18Test extends LightDaemonAnalyzerTestCase {
public void testLambdaContext() { doTest(); }
public void testMethodRefContext() { doTest(); }
public void testExpectedSupertype() { doTest(); }
public void testExpressionRendering() { doTest(); }
public void testForeachValue() { doTest(); }
public void testConditional() { doTest(); }
public void testInferApplicabilityError() { doTest(); }