mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 22:11:40 +07:00
Java: fix "Replace multiply with shift" intention for expressions with long type (IDEA-369236)
GitOrigin-RevId: 6122adad1f437c410371a9291b45ac4d187d2165
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a0d3056dfb
commit
9d7ba0dc56
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2022 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2025 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -100,23 +100,10 @@ public final class ReplaceMultiplyWithShiftIntention extends MCIntention {
|
||||
final PsiExpression lhs = expression.getLOperand();
|
||||
final PsiExpression rhs = PsiUtil.skipParenthesizedExprDown(expression.getROperand());
|
||||
final IElementType tokenType = expression.getOperationTokenType();
|
||||
final String operatorString;
|
||||
if (tokenType.equals(JavaTokenType.ASTERISK)) {
|
||||
operatorString = "<<";
|
||||
}
|
||||
else {
|
||||
operatorString = ">>";
|
||||
}
|
||||
final String lhsText;
|
||||
if (ParenthesesUtils.getPrecedence(lhs) >
|
||||
ParenthesesUtils.SHIFT_PRECEDENCE) {
|
||||
lhsText = '(' + lhs.getText() + ')';
|
||||
}
|
||||
else {
|
||||
lhsText = lhs.getText();
|
||||
}
|
||||
String expString =
|
||||
lhsText + operatorString + ShiftUtils.getLogBase2(rhs);
|
||||
final String operatorString = tokenType.equals(JavaTokenType.ASTERISK) ? "<<" : ">>";
|
||||
final String lhsText = PsiTypes.intType().equals(lhs.getType()) && PsiTypes.longType().equals(expression.getType())
|
||||
? "((long)" + lhs.getText() + ')' : lhs.getText();
|
||||
String expString = lhsText + operatorString + ShiftUtils.getLogBase2(rhs);
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiExpression) {
|
||||
if (!(parent instanceof PsiParenthesizedExpression) &&
|
||||
|
||||
@@ -37,26 +37,16 @@ final class ShiftUtils {
|
||||
if (value instanceof Double || value instanceof Float) {
|
||||
return false;
|
||||
}
|
||||
int intValue = ((Number)value).intValue();
|
||||
if (intValue <= 0) {
|
||||
return false;
|
||||
}
|
||||
while (intValue % 2 == 0) {
|
||||
intValue >>= 1;
|
||||
}
|
||||
return intValue == 1;
|
||||
long v = ((Number)value).longValue();
|
||||
return v > 0 && (v & (v - 1)) == 0; // https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
|
||||
}
|
||||
|
||||
public static int getLogBase2(PsiExpression rhs) {
|
||||
public static long getLogBase2(PsiExpression rhs) {
|
||||
final PsiLiteralExpression literal = (PsiLiteralExpression)rhs;
|
||||
final Object value = literal.getValue();
|
||||
int intValue = ((Number)value).intValue();
|
||||
int log = 0;
|
||||
while (intValue % 2 == 0) {
|
||||
intValue >>= 1;
|
||||
log++;
|
||||
}
|
||||
return log;
|
||||
assert value != null;
|
||||
long v = ((Number)value).longValue();
|
||||
return 63 - Long.numberOfLeadingZeros(v);
|
||||
}
|
||||
|
||||
public static boolean isIntegral(PsiType lhsType) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class Test {
|
||||
void test(int foo) {
|
||||
int x = 1; long y = x * <caret>4294967296L;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Test {
|
||||
void test(int foo) {
|
||||
int x = 1; long y = ((lo<caret>ng) x) << 32;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Test {
|
||||
void test(int foo) {
|
||||
long x = 1; long y = x * <caret>4294967296L;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Test {
|
||||
void test(int foo) {
|
||||
long x = 1; long y = x <<<caret> 32;
|
||||
}
|
||||
}
|
||||
@@ -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-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.siyeh.ipp.shift;
|
||||
|
||||
import com.siyeh.ipp.IPPTestCase;
|
||||
@@ -6,6 +6,8 @@ import com.siyeh.ipp.IPPTestCase;
|
||||
public class ReplaceMultiplyWithShiftIntentionTest extends IPPTestCase {
|
||||
|
||||
public void testLeftShift() { doTest("Replace '*' with '<<'"); }
|
||||
public void testLongShift() { doTest("Replace '*' with '<<'"); }
|
||||
public void testCastedLongShift() { doTest("Replace '*' with '<<'"); }
|
||||
public void testLeftShiftAssign() { doTest("Replace '*=' with '<<='"); }
|
||||
public void testParentheses() { doTest("Replace '*' with '<<'"); }
|
||||
public void testRightShift() { doTest("Replace '/' with '>>'"); }
|
||||
|
||||
Reference in New Issue
Block a user