get rid of recusrion
[fedora-idea.git] / source / com / intellij / psi / impl / ConstantExpressionVisitor.java
bloba033916e1fad6ec6cb51c6c2cf0b7f48f0562c1a
1 package com.intellij.psi.impl;
3 import com.intellij.openapi.util.Key;
4 import com.intellij.psi.*;
5 import com.intellij.psi.tree.IElementType;
6 import com.intellij.psi.util.ConstantEvaluationOverflowException;
7 import com.intellij.psi.util.ConstantExpressionUtil;
8 import com.intellij.util.containers.StringInterner;
9 import gnu.trove.THashSet;
11 import java.util.Set;
13 class ConstantExpressionVisitor extends JavaElementVisitor {
14 private final StringInterner myInterner = new StringInterner();
16 private Set<PsiVariable> myVisitedVars;
17 private final boolean myThrowExceptionOnOverflow;
19 private Object myResult;
21 ConstantExpressionVisitor(Set<PsiVariable> visitedVars, boolean throwExceptionOnOverflow) {
22 myVisitedVars = visitedVars;
23 myThrowExceptionOnOverflow = throwExceptionOnOverflow;
26 Object handle(PsiElement element) {
27 myResult = null;
28 element.accept(this);
29 store(element, myResult);
30 //for (PsiElement child : element.getChildren()) {
31 // store(child, null); //erase garbage
32 //}
33 return myResult;
35 private static final Key<Object> VALUE = Key.create("VALUE");
36 private static Object getStoredValue(PsiElement element) {
37 if (element == null) {
38 return null;
40 try {
41 return element.getUserData(VALUE);
43 finally {
44 element.putUserData(VALUE, null);
47 static void store(PsiElement element, Object value) {
48 element.putUserData(VALUE, value);
51 @Override
52 public void visitLiteralExpression(PsiLiteralExpression expression) {
53 final Object value = expression.getValue();
54 myResult = value instanceof String ? myInterner.intern((String)value) : value;
57 @Override
58 public void visitTypeCastExpression(PsiTypeCastExpression expression) {
59 final PsiTypeElement castTypeElement = expression.getCastType();
61 PsiExpression operand = expression.getOperand();
62 Object opValue = getStoredValue(operand);
63 if(castTypeElement == null || opValue == null) {
64 myResult = null;
65 return;
68 PsiType castType = castTypeElement.getType();
69 myResult = ConstantExpressionUtil.computeCastTo(opValue, castType);
72 @Override public void visitConditionalExpression(PsiConditionalExpression expression) {
73 Object then = getStoredValue(expression.getThenExpression());
74 Object els = getStoredValue(expression.getElseExpression());
75 Object condition = getStoredValue(expression.getCondition());
76 if (then == null || els == null) {
77 myResult = null;
78 return;
81 Object value = null;
83 if (condition instanceof Boolean) {
84 value = ((Boolean)condition).booleanValue() ? then : els;
87 myResult = value;
90 @Override
91 public void visitBinaryExpression(PsiBinaryExpression expression) {
92 Object lOperandValue = getStoredValue(expression.getLOperand());
93 if (lOperandValue == null) {
94 myResult = null;
95 return;
98 Object rOperandValue = getStoredValue(expression.getROperand());
99 if (rOperandValue == null) {
100 myResult = null;
101 return;
104 PsiJavaToken operationSign = expression.getOperationSign();
105 final IElementType tokenType = operationSign.getTokenType();
107 Object value = null;
108 if (tokenType == JavaTokenType.PLUS) {
109 if (lOperandValue instanceof String || rOperandValue instanceof String) {
110 value = myInterner.intern(lOperandValue.toString() + rOperandValue.toString());
112 else {
113 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
114 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
116 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
117 if (lOperandValue instanceof Double || rOperandValue instanceof Double) {
118 value = new Double(((Number)lOperandValue).doubleValue() + ((Number)rOperandValue).doubleValue());
119 checkRealNumberOverflow(value, lOperandValue, rOperandValue,expression);
121 else if (lOperandValue instanceof Float || rOperandValue instanceof Float) {
122 value = new Float(((Number)lOperandValue).floatValue() + ((Number)rOperandValue).floatValue());
123 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
125 else if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
126 final long l = ((Number)lOperandValue).longValue();
127 final long r = ((Number)rOperandValue).longValue();
128 value = Long.valueOf(l + r);
129 checkAdditionOverflow(((Long)value).longValue() >= 0, l >= 0, r >= 0, expression);
131 else {
132 final int l = ((Number)lOperandValue).intValue();
133 final int r = ((Number)rOperandValue).intValue();
134 value = Integer.valueOf(l + r);
135 checkAdditionOverflow(((Integer)value).intValue() >= 0, l >= 0, r >= 0, expression);
140 else if (tokenType == JavaTokenType.MINUS) {
141 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
142 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
143 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
144 if (lOperandValue instanceof Double || rOperandValue instanceof Double) {
145 value = new Double(((Number)lOperandValue).doubleValue() - ((Number)rOperandValue).doubleValue());
146 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
148 else if (lOperandValue instanceof Float || rOperandValue instanceof Float) {
149 value = new Float(((Number)lOperandValue).floatValue() - ((Number)rOperandValue).floatValue());
150 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
152 else if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
153 final long l = ((Number)lOperandValue).longValue();
154 final long r = ((Number)rOperandValue).longValue();
155 value = Long.valueOf(l - r);
156 checkAdditionOverflow(((Long)value).longValue() >= 0, l >= 0, r < 0, expression);
158 else {
159 final int l = ((Number)lOperandValue).intValue();
160 final int r = ((Number)rOperandValue).intValue();
161 value = Integer.valueOf(l - r);
162 checkAdditionOverflow(((Integer)value).intValue() >= 0, l >= 0, r < 0, expression);
166 else if (tokenType == JavaTokenType.ANDAND) {
167 if (lOperandValue instanceof Boolean && !((Boolean)lOperandValue).booleanValue()) {
168 myResult = Boolean.FALSE;
169 return;
171 if (rOperandValue instanceof Boolean && !((Boolean)rOperandValue).booleanValue()) {
172 myResult = Boolean.FALSE;
173 return;
175 if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) {
176 value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() && ((Boolean)rOperandValue).booleanValue());
179 else if (tokenType == JavaTokenType.OROR) {
180 if (lOperandValue instanceof Boolean && ((Boolean)lOperandValue).booleanValue()) {
181 myResult = Boolean.TRUE;
182 return;
184 if (rOperandValue instanceof Boolean && ((Boolean)rOperandValue).booleanValue()) {
185 myResult = Boolean.TRUE;
186 return;
188 if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) {
189 value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() || ((Boolean)rOperandValue).booleanValue());
192 else if (tokenType == JavaTokenType.LT) {
193 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
194 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
195 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
196 value = Boolean.valueOf(((Number)lOperandValue).doubleValue() < ((Number)rOperandValue).doubleValue());
199 else if (tokenType == JavaTokenType.LE) {
200 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
201 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
202 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
203 value = Boolean.valueOf(((Number)lOperandValue).doubleValue() <= ((Number)rOperandValue).doubleValue());
206 else if (tokenType == JavaTokenType.GT) {
207 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
208 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
209 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
210 value = Boolean.valueOf(((Number)lOperandValue).doubleValue() > ((Number)rOperandValue).doubleValue());
213 else if (tokenType == JavaTokenType.GE) {
214 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
215 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
216 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
217 value = Boolean.valueOf(((Number)lOperandValue).doubleValue() >= ((Number)rOperandValue).doubleValue());
220 else if (tokenType == JavaTokenType.EQEQ) {
221 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
222 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
223 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
224 value = Boolean.valueOf(((Number)lOperandValue).doubleValue() == ((Number)rOperandValue).doubleValue());
226 else if (lOperandValue instanceof String && rOperandValue instanceof String) {
227 value = Boolean.valueOf(lOperandValue == rOperandValue);
229 else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) {
230 value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() == ((Boolean)rOperandValue).booleanValue());
233 else if (tokenType == JavaTokenType.NE) {
234 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
235 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
236 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
237 value = Boolean.valueOf(((Number)lOperandValue).doubleValue() != ((Number)rOperandValue).doubleValue());
239 else if (lOperandValue instanceof String && rOperandValue instanceof String) {
240 value = Boolean.valueOf(lOperandValue != rOperandValue);
242 else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) {
243 value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() != ((Boolean)rOperandValue).booleanValue());
246 else if (tokenType == JavaTokenType.ASTERISK) {
247 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
248 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
249 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
250 if (lOperandValue instanceof Double || rOperandValue instanceof Double) {
251 value = new Double(((Number)lOperandValue).doubleValue() * ((Number)rOperandValue).doubleValue());
252 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
254 else if (lOperandValue instanceof Float || rOperandValue instanceof Float) {
255 value = new Float(((Number)lOperandValue).floatValue() * ((Number)rOperandValue).floatValue());
256 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
258 else if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
259 final long l = ((Number)lOperandValue).longValue();
260 final long r = ((Number)rOperandValue).longValue();
261 value = Long.valueOf(l * r);
262 checkMultiplicationOverflow(((Long)value).longValue(), l, r, expression);
264 else {
265 final int l = ((Number)lOperandValue).intValue();
266 final int r = ((Number)rOperandValue).intValue();
267 value = Integer.valueOf(l * r);
268 checkMultiplicationOverflow(((Integer)value).intValue(), l, r, expression);
272 else if (tokenType == JavaTokenType.DIV) {
273 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
274 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
275 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
276 if (lOperandValue instanceof Double || rOperandValue instanceof Double) {
277 value = new Double(((Number)lOperandValue).doubleValue() / ((Number)rOperandValue).doubleValue());
278 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
280 else if (lOperandValue instanceof Float || rOperandValue instanceof Float) {
281 value = new Float(((Number)lOperandValue).floatValue() / ((Number)rOperandValue).floatValue());
282 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
284 else if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
285 final long r = ((Number)rOperandValue).longValue();
286 final long l = ((Number)lOperandValue).longValue();
287 checkDivisionOverflow(l, r, Long.MIN_VALUE, expression);
288 value = r == 0 ? null : Long.valueOf(l / r);
290 else {
291 final int r = ((Number)rOperandValue).intValue();
292 final int l = ((Number)lOperandValue).intValue();
293 checkDivisionOverflow(l, r, Integer.MIN_VALUE, expression);
294 value = r == 0 ? null : Integer.valueOf(l / r);
298 else if (tokenType == JavaTokenType.PERC) {
299 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
300 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
301 if (lOperandValue instanceof Number && rOperandValue instanceof Number) {
302 double rVal = ((Number)rOperandValue).doubleValue();
303 if (myThrowExceptionOnOverflow && rVal == 0) throw new ConstantEvaluationOverflowException(expression);
304 if (lOperandValue instanceof Double || rOperandValue instanceof Double) {
305 value = new Double(((Number)lOperandValue).doubleValue() % ((Number)rOperandValue).doubleValue());
306 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
308 else if (lOperandValue instanceof Float || rOperandValue instanceof Float) {
309 value = new Float(((Number)lOperandValue).floatValue() % ((Number)rOperandValue).floatValue());
310 checkRealNumberOverflow(value, lOperandValue, rOperandValue, expression);
312 else if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
313 final long l = ((Number)lOperandValue).longValue();
314 final long r = ((Number)rOperandValue).longValue();
315 checkDivisionOverflow(l, r, Long.MIN_VALUE, expression);
316 value = r == 0 ? null : Long.valueOf(l % r);
318 else {
319 final int l = ((Number)lOperandValue).intValue();
320 final int r = ((Number)rOperandValue).intValue();
321 checkDivisionOverflow(l, r, Integer.MIN_VALUE, expression);
322 value = r == 0 ? null : Integer.valueOf(l % r);
326 else if (tokenType == JavaTokenType.LTLT) {
327 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
328 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
329 if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) {
330 if (lOperandValue instanceof Long) {
331 value = Long.valueOf(((Number)lOperandValue).longValue() << ((Number)rOperandValue).longValue());
333 else {
334 value = Integer.valueOf(((Number)lOperandValue).intValue() << ((Number)rOperandValue).intValue());
338 else if (tokenType == JavaTokenType.GTGT) {
339 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
340 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
341 if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) {
342 if (lOperandValue instanceof Long) {
343 value = Long.valueOf(((Number)lOperandValue).longValue() >> ((Number)rOperandValue).longValue());
345 else {
346 value = Integer.valueOf(((Number)lOperandValue).intValue() >> ((Number)rOperandValue).intValue());
350 else if (tokenType == JavaTokenType.GTGTGT) {
351 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
352 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
353 if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) {
354 if (lOperandValue instanceof Long) {
355 value = Long.valueOf(((Number)lOperandValue).longValue() >>> ((Number)rOperandValue).longValue());
357 else {
358 value = Integer.valueOf(((Number)lOperandValue).intValue() >>> ((Number)rOperandValue).intValue());
362 else if (tokenType == JavaTokenType.AND) {
363 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
364 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
365 if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) {
366 if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
367 value = Long.valueOf(((Number)lOperandValue).longValue() & ((Number)rOperandValue).longValue());
369 else {
370 value = Integer.valueOf(((Number)lOperandValue).intValue() & ((Number)rOperandValue).intValue());
373 else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) {
374 value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() && ((Boolean)rOperandValue).booleanValue());
377 else if (tokenType == JavaTokenType.OR) {
378 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
379 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
380 if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) {
381 if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
382 value = Long.valueOf(((Number)lOperandValue).longValue() | ((Number)rOperandValue).longValue());
384 else {
385 value = Integer.valueOf(((Number)lOperandValue).intValue() | ((Number)rOperandValue).intValue());
388 else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) {
389 value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() || ((Boolean)rOperandValue).booleanValue());
392 else if (tokenType == JavaTokenType.XOR) {
393 if (lOperandValue instanceof Character) lOperandValue = Integer.valueOf(((Character)lOperandValue).charValue());
394 if (rOperandValue instanceof Character) rOperandValue = Integer.valueOf(((Character)rOperandValue).charValue());
395 if (isIntegral(lOperandValue) && isIntegral(rOperandValue)) {
396 if (lOperandValue instanceof Long || rOperandValue instanceof Long) {
397 value = Long.valueOf(((Number)lOperandValue).longValue() ^ ((Number)rOperandValue).longValue());
399 else {
400 value = Integer.valueOf(((Number)lOperandValue).intValue() ^ ((Number)rOperandValue).intValue());
403 else if (lOperandValue instanceof Boolean && rOperandValue instanceof Boolean) {
404 value = Boolean.valueOf(((Boolean)lOperandValue).booleanValue() ^ ((Boolean)rOperandValue).booleanValue());
408 myResult = value;
411 @Override public void visitPrefixExpression(PsiPrefixExpression expression) {
412 PsiExpression operand = expression.getOperand();
413 Object operandValue = getStoredValue(operand);
414 if (operandValue == null) {
415 myResult = null;
416 return;
418 IElementType tokenType = expression.getOperationSign().getTokenType();
419 Object value = null;
420 if (tokenType == JavaTokenType.MINUS) {
421 if (operandValue instanceof Character) operandValue = Integer.valueOf(((Character)operandValue).charValue());
422 if (operandValue instanceof Number) {
423 if (operandValue instanceof Double) {
424 value = new Double(-((Number)operandValue).doubleValue());
425 checkRealNumberOverflow(value, null, null, expression);
427 else if (operandValue instanceof Float) {
428 value = new Float(-((Number)operandValue).floatValue());
429 checkRealNumberOverflow(value, null, null, expression);
431 else if (operandValue instanceof Long) {
432 value = Long.valueOf(-((Number)operandValue).longValue());
433 if (myThrowExceptionOnOverflow
434 && !(operand instanceof PsiLiteralExpression)
435 && ((Number)operandValue).longValue() == Long.MIN_VALUE) {
436 throw new ConstantEvaluationOverflowException(expression);
439 else {
440 value = Integer.valueOf(-((Number)operandValue).intValue());
441 if (myThrowExceptionOnOverflow
442 && !(operand instanceof PsiLiteralExpression)
443 && ((Number)operandValue).intValue() == Integer.MIN_VALUE) {
444 throw new ConstantEvaluationOverflowException(expression);
449 else if (tokenType == JavaTokenType.PLUS) {
450 if (operandValue instanceof Character) operandValue = Integer.valueOf(((Character)operandValue).charValue());
451 if (operandValue instanceof Number) {
452 value = operandValue;
455 else if (tokenType == JavaTokenType.TILDE) {
456 if (operandValue instanceof Character) operandValue = Integer.valueOf(((Character)operandValue).charValue());
457 if (isIntegral(operandValue)) {
458 value = operandValue instanceof Long
459 ? Long.valueOf(~((Number)operandValue).longValue())
460 : Integer.valueOf(~((Number)operandValue).intValue());
463 else if (tokenType == JavaTokenType.EXCL) {
464 if (operandValue instanceof Boolean) {
465 value = Boolean.valueOf(!((Boolean)operandValue).booleanValue());
469 myResult = value;
472 @Override public void visitParenthesizedExpression(PsiParenthesizedExpression expression) {
473 myResult = getStoredValue(expression.getExpression());
476 @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
477 PsiExpression qualifierExpression = expression.getQualifierExpression();
478 while (qualifierExpression != null) {
479 if (!(qualifierExpression instanceof PsiReferenceExpression)) {
480 myResult = null;
481 return;
484 PsiReferenceExpression qualifier = (PsiReferenceExpression) qualifierExpression;
485 final PsiElement resolved = qualifier.resolve();
486 if (resolved instanceof PsiPackage) break;
487 if (!(resolved instanceof PsiClass)) {
488 myResult = null;
489 return;
491 qualifierExpression = ((PsiReferenceExpression) qualifierExpression).getQualifierExpression();
493 PsiElement resolvedExpression = expression.resolve();
494 if (resolvedExpression instanceof PsiVariable) {
495 PsiVariable variable = (PsiVariable) resolvedExpression;
496 // avoid cycles
497 if (myVisitedVars != null && myVisitedVars.contains(variable)) {
498 myResult = null;
499 return;
502 Set<PsiVariable> oldVisitedVars = myVisitedVars;
503 if (myVisitedVars == null) { myVisitedVars = new THashSet<PsiVariable>(); }
505 myVisitedVars.add(variable);
506 try {
507 if (!(variable instanceof PsiVariableEx)) {
508 myResult = null; //?
509 return;
512 myResult = ((PsiVariableEx) variable).computeConstantValue(myVisitedVars);
513 return;
515 finally {
516 myVisitedVars.remove(variable);
517 myVisitedVars = oldVisitedVars;
521 myResult = null;
524 private static boolean isIntegral(Object o) {
525 return o instanceof Long || o instanceof Integer || o instanceof Short || o instanceof Byte || o instanceof Character;
528 private void checkDivisionOverflow(long l, final long r, long minValue, PsiBinaryExpression expression) {
529 if (!myThrowExceptionOnOverflow) return;
530 if (r == 0) throw new ConstantEvaluationOverflowException(expression);
531 if (r == -1 && l == minValue) throw new ConstantEvaluationOverflowException(expression);
534 private void checkMultiplicationOverflow(long result, long l, long r, PsiExpression expression) {
535 if (!myThrowExceptionOnOverflow) return;
536 if (r == 0 || l == 0) return;
537 if (result / r != l || ((l < 0) ^ (r < 0) != (result < 0))) throw new ConstantEvaluationOverflowException(expression);
540 private void checkAdditionOverflow(boolean resultPositive,
541 boolean lPositive,
542 boolean rPositive, PsiBinaryExpression expression) {
543 if (!myThrowExceptionOnOverflow) return;
544 boolean overflow = lPositive == rPositive && lPositive != resultPositive;
545 if (overflow) throw new ConstantEvaluationOverflowException(expression);
548 private void checkRealNumberOverflow(Object result,
549 Object lOperandValue,
550 Object rOperandValue, PsiExpression expression) {
551 if (!myThrowExceptionOnOverflow) return;
552 if (lOperandValue instanceof Float && ((Float) lOperandValue).isInfinite()) return;
553 if (lOperandValue instanceof Double && ((Double) lOperandValue).isInfinite()) return;
554 if (rOperandValue instanceof Float && ((Float) rOperandValue).isInfinite()) return;
555 if (rOperandValue instanceof Double && ((Double) rOperandValue).isInfinite()) return;
557 if (result instanceof Float && ((Float) result).isInfinite()) throw new ConstantEvaluationOverflowException(expression);
558 if (result instanceof Double && ((Double) result).isInfinite()) throw new ConstantEvaluationOverflowException(expression);