mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IG: check prefix expressions correctly in "Unnecessary explicit numeric cast" inspection (IDEA-286284)
GitOrigin-RevId: 5a51a771dab46183da4345a88298a732701d36bb
This commit is contained in:
committed by
intellij-monorepo-bot
parent
44bf98e41d
commit
83c4c9b7ee
+22
-19
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2011-2017 Bas Leijdekkers
|
||||
*
|
||||
* 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.siyeh.ig.numeric;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
@@ -31,6 +17,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public final class UnnecessaryExplicitNumericCastInspection extends BaseInspection {
|
||||
private static final Set<IElementType> binaryPromotionOperators = Set.of(
|
||||
JavaTokenType.ASTERISK,
|
||||
@@ -129,14 +118,28 @@ public final class UnnecessaryExplicitNumericCastInspection extends BaseInspecti
|
||||
if (!ClassUtils.isPrimitiveNumericType(operandType)) {
|
||||
return false;
|
||||
}
|
||||
if (castType.equals(operandType)) {
|
||||
// cast to the same type is caught by "Redundant type cast" inspection
|
||||
return false;
|
||||
}
|
||||
PsiElement parent = expression.getParent();
|
||||
while (parent instanceof PsiParenthesizedExpression) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
if (parent instanceof PsiPrefixExpression) {
|
||||
// JLS 5.6 Numeric Contexts
|
||||
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)parent;
|
||||
final IElementType tokenType = prefixExpression.getOperationTokenType();
|
||||
if (JavaTokenType.MINUS == tokenType || JavaTokenType.PLUS == tokenType || JavaTokenType.TILDE == tokenType) {
|
||||
if (TypeUtils.isNarrowingConversion(operandType, castType)) {
|
||||
return false;
|
||||
}
|
||||
if (PsiType.INT.equals(castType)) {
|
||||
return !PsiType.LONG.equals(operandType) && !PsiType.FLOAT.equals(operandType) && !PsiType.DOUBLE.equals(operandType);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (castType.equals(operandType)) {
|
||||
// cast to the same type is caught by "Redundant type cast" inspection
|
||||
return false;
|
||||
}
|
||||
if (parent instanceof PsiPolyadicExpression) {
|
||||
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent;
|
||||
final IElementType tokenType = polyadicExpression.getOperationTokenType();
|
||||
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
package com.siyeh.igtest.numeric.unnecessary_explicit_numeric_cast;
|
||||
|
||||
|
||||
|
||||
|
||||
public class UnnecessaryExplicitNumericCast {
|
||||
|
||||
void a(byte b) {
|
||||
double d = <caret>1;
|
||||
d = 1.0f;
|
||||
d = b;
|
||||
char c = 1;
|
||||
b = (int)7;
|
||||
}
|
||||
|
||||
double b(int a, byte b) {
|
||||
return (double)a * b;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int i = 10;
|
||||
|
||||
double d = 123.0 / (456.0 * i);
|
||||
}
|
||||
|
||||
void unary() {
|
||||
byte b = 2;
|
||||
int a[] = new int[b];
|
||||
final int c = a[b];
|
||||
int[] a2 = new int[]{b};
|
||||
int[] a3 = {b};
|
||||
final int result = b << 1;
|
||||
c(b);
|
||||
new UnnecessaryExplicitNumericCast(b);
|
||||
}
|
||||
|
||||
void c(int i) {}
|
||||
UnnecessaryExplicitNumericCast(long i) {}
|
||||
|
||||
void c(int cols, int no) {
|
||||
int rows = (int) Math.ceil((double) no / cols);
|
||||
}
|
||||
|
||||
void source() {
|
||||
target((int)'a');
|
||||
target2('b');
|
||||
}
|
||||
void target(int c) {}
|
||||
void target(char c) {}
|
||||
void target2(int d) {}
|
||||
|
||||
void foo() {
|
||||
float x = 2;
|
||||
target((int) x); // this line complains: 'x' unnecessarily cast to 'int'
|
||||
}
|
||||
|
||||
void a(float angleFromTo) {
|
||||
float f = (float) Math.cos(0.5) * 1.0f; // necessary
|
||||
final long l = i() * 9L;
|
||||
float angle2 = angleFromTo + (float) (Math.PI / 2);
|
||||
}
|
||||
|
||||
int i() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
boolean redundantTypeCast(long l) {
|
||||
return 0L == (long)l;
|
||||
}
|
||||
|
||||
void necessary() {
|
||||
char[] keyChar = {'\t', '\n', '\r', '\f', 'a', '0'};
|
||||
for (char cc : keyChar) {
|
||||
String result;
|
||||
if (cc < 28) {
|
||||
result = "Ascii " + (int)cc;
|
||||
}
|
||||
else {
|
||||
result = "k " + cc + " (" + (int)cc + ')';
|
||||
}
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
|
||||
public static long negate(int x) {
|
||||
return -(long)x;
|
||||
}
|
||||
|
||||
public static int negate2(int x) {
|
||||
return -x;
|
||||
}
|
||||
|
||||
}
|
||||
enum Numeric {
|
||||
A((byte)10);
|
||||
|
||||
Numeric(byte b) {}
|
||||
}
|
||||
class S {
|
||||
|
||||
static void doSomething() {
|
||||
// V --- this cast is reported as unnecessary
|
||||
if ( (int) whatever() < 0 ) {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T whatever() {
|
||||
return (T) (Object) 0;
|
||||
}
|
||||
|
||||
void polyadic() {
|
||||
int a=1;
|
||||
int b=2;
|
||||
System.out.println(((double) a) / b / 10.0);
|
||||
double c = 3.5;
|
||||
System.out.println(a / c / 10.0);
|
||||
System.out.println(19/ (double)a / c / 10.0);
|
||||
}
|
||||
|
||||
private static void foo(int i) {
|
||||
}
|
||||
|
||||
void bar(int i) {
|
||||
foo(0);
|
||||
foo((short)i);
|
||||
int bar = 123;
|
||||
boolean[] booleans = new boolean[6];
|
||||
byte[] bytes = new byte[(int) 2];
|
||||
var v = (short) 666;
|
||||
}
|
||||
|
||||
void noWarnOnRedCode() {
|
||||
foo((long)0);
|
||||
int x = (long)0;
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -6,7 +6,7 @@ package com.siyeh.igtest.numeric.unnecessary_explicit_numeric_cast;
|
||||
public class UnnecessaryExplicitNumericCast {
|
||||
|
||||
void a(byte b) {
|
||||
double d = (<warning descr="'1' unnecessarily cast to 'double'">double</warning>) 1;
|
||||
double d = (<warning descr="'1' unnecessarily cast to 'double'"><caret>double</warning>) 1;
|
||||
d = (<warning descr="'1.0f' unnecessarily cast to 'double'">double</warning>) 1.0f;
|
||||
d = (<warning descr="'b' unnecessarily cast to 'double'">double</warning>) b;
|
||||
char c = (<warning descr="'1' unnecessarily cast to 'char'">char</warning>) 1;
|
||||
@@ -82,6 +82,14 @@ public class UnnecessaryExplicitNumericCast {
|
||||
}
|
||||
}
|
||||
|
||||
public static long negate(int x) {
|
||||
return -(long)x;
|
||||
}
|
||||
|
||||
public static int negate2(int x) {
|
||||
return -(<warning descr="'x' unnecessarily cast to 'int'">int</warning>)x;
|
||||
}
|
||||
|
||||
}
|
||||
enum Numeric {
|
||||
A((byte)10);
|
||||
|
||||
+2
-1
@@ -1,4 +1,4 @@
|
||||
// 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.siyeh.ig.numeric;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
@@ -11,6 +11,7 @@ public class UnnecessaryExplicitNumericCastInspectionTest extends LightJavaInspe
|
||||
|
||||
public void testUnnecessaryExplicitNumericCast() {
|
||||
doTest();
|
||||
checkQuickFixAll();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user