mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-205011 DFA: limited support for shift-left
This commit is contained in:
+1
-1
@@ -32,7 +32,7 @@ import static com.intellij.psi.JavaTokenType.*;
|
||||
|
||||
public class BinopInstruction extends BranchingInstruction implements ExpressionPushingInstruction {
|
||||
private static final TokenSet ourSignificantOperations =
|
||||
TokenSet.create(EQEQ, NE, LT, GT, LE, GE, INSTANCEOF_KEYWORD, PLUS, MINUS, AND, PERC, DIV, ASTERISK, GTGT, GTGTGT);
|
||||
TokenSet.create(EQEQ, NE, LT, GT, LE, GE, INSTANCEOF_KEYWORD, PLUS, MINUS, AND, PERC, DIV, ASTERISK, GTGT, GTGTGT, LTLT);
|
||||
private final IElementType myOperationSign;
|
||||
private final @Nullable PsiType myResultType;
|
||||
private final int myLastOperand;
|
||||
|
||||
+22
@@ -184,6 +184,9 @@ public abstract class LongRangeSet {
|
||||
if (token.equals(JavaTokenType.DIV)) {
|
||||
return div(right, isLong);
|
||||
}
|
||||
if (token.equals(JavaTokenType.LTLT)) {
|
||||
return shiftLeft(right, isLong);
|
||||
}
|
||||
if (token.equals(JavaTokenType.GTGT)) {
|
||||
return shiftRight(right, isLong);
|
||||
}
|
||||
@@ -371,6 +374,25 @@ public abstract class LongRangeSet {
|
||||
.unite(point(-1).minus(point(-1).minus(negative, isLong).shrPositive(min, max, isLong), isLong));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a range which represents all the possible values after applying {@code x << y} operation for
|
||||
* all {@code x} from this set and for all {@code y} from the shiftSize set. The resulting set may contain
|
||||
* some more values.
|
||||
*
|
||||
* @param shiftSize set of possible shift sizes (number of bits to shift to the left)
|
||||
* @param isLong whether the operation is performed on long type (if false, the int type is assumed).
|
||||
* @return a new range
|
||||
*/
|
||||
@NotNull
|
||||
public LongRangeSet shiftLeft(LongRangeSet shiftSize, boolean isLong) {
|
||||
if (isEmpty() || shiftSize.isEmpty()) return empty();
|
||||
if (shiftSize instanceof Point) {
|
||||
long shift = ((Point)shiftSize).myValue & ((isLong ? Long.SIZE : Integer.SIZE)-1);
|
||||
return point(1 << shift).mul(this, isLong);
|
||||
}
|
||||
return isLong ? Range.LONG_RANGE : Range.INT_RANGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a range which represents all the possible values after applying {@code x >>> y} operation for
|
||||
* all {@code x} from this set and for all {@code y} from the shiftSize set. The resulting set may contain
|
||||
|
||||
+16
@@ -432,6 +432,17 @@ public class LongRangeSetTest {
|
||||
checkShr(range(1000000, 1000020), range(3, 5), true, "{31250..125002}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShl() {
|
||||
assertEquals(empty(), empty().shiftLeft(all(), true));
|
||||
assertEquals(empty(), all().shiftLeft(empty(), true));
|
||||
assertEquals(all(), all().shiftLeft(all(), true));
|
||||
checkShl(point(1), point(3), false, "{8}");
|
||||
checkShl(range(0, 10), point(3), false, "{0..80}");
|
||||
checkShl(range(0, 15), point(28), false, "{Integer.MIN_VALUE..Integer.MAX_VALUE}");
|
||||
checkShl(range(0, 15), point(28), true, "{0..4026531840}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUShr() {
|
||||
assertEquals(empty(), empty().unsignedShiftRight(all(), true));
|
||||
@@ -549,6 +560,11 @@ public class LongRangeSetTest {
|
||||
checkBinOp(arg, shiftSize, result, x -> true, (a, b) -> isLong ? a >> b : ((int)a >> (int)b), expected, ">>");
|
||||
}
|
||||
|
||||
void checkShl(LongRangeSet arg, LongRangeSet shiftSize, boolean isLong, String expected) {
|
||||
LongRangeSet result = arg.shiftLeft(shiftSize, isLong);
|
||||
checkBinOp(arg, shiftSize, result, x -> true, (a, b) -> isLong ? a << b : ((int)a << (int)b), expected, "<<");
|
||||
}
|
||||
|
||||
void checkUShr(LongRangeSet arg, LongRangeSet shiftSize, boolean isLong, String expected) {
|
||||
LongRangeSet result = arg.unsignedShiftRight(shiftSize, isLong);
|
||||
checkBinOp(arg, shiftSize, result, x -> true, (a, b) -> isLong ? a >>> b : ((int)a >>> (int)b), expected, ">>>");
|
||||
|
||||
Reference in New Issue
Block a user