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
;
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
) {
29 store(element
, myResult
);
30 //for (PsiElement child : element.getChildren()) {
31 // store(child, null); //erase garbage
35 private static final Key
<Object
> VALUE
= Key
.create("VALUE");
36 private static Object
getStoredValue(PsiElement element
) {
37 if (element
== null) {
41 return element
.getUserData(VALUE
);
44 element
.putUserData(VALUE
, null);
47 static void store(PsiElement element
, Object value
) {
48 element
.putUserData(VALUE
, value
);
52 public void visitLiteralExpression(PsiLiteralExpression expression
) {
53 final Object value
= expression
.getValue();
54 myResult
= value
instanceof String ? myInterner
.intern((String
)value
) : value
;
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) {
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) {
83 if (condition
instanceof Boolean
) {
84 value
= ((Boolean
)condition
).booleanValue() ? then
: els
;
91 public void visitBinaryExpression(PsiBinaryExpression expression
) {
92 Object lOperandValue
= getStoredValue(expression
.getLOperand());
93 if (lOperandValue
== null) {
98 Object rOperandValue
= getStoredValue(expression
.getROperand());
99 if (rOperandValue
== null) {
104 PsiJavaToken operationSign
= expression
.getOperationSign();
105 final IElementType tokenType
= operationSign
.getTokenType();
108 if (tokenType
== JavaTokenType
.PLUS
) {
109 if (lOperandValue
instanceof String
|| rOperandValue
instanceof String
) {
110 value
= myInterner
.intern(lOperandValue
.toString() + rOperandValue
.toString());
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
);
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
);
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
;
171 if (rOperandValue
instanceof Boolean
&& !((Boolean
)rOperandValue
).booleanValue()) {
172 myResult
= Boolean
.FALSE
;
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
;
184 if (rOperandValue
instanceof Boolean
&& ((Boolean
)rOperandValue
).booleanValue()) {
185 myResult
= Boolean
.TRUE
;
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
);
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
);
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
);
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());
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());
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());
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());
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());
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());
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());
411 @Override public void visitPrefixExpression(PsiPrefixExpression expression
) {
412 PsiExpression operand
= expression
.getOperand();
413 Object operandValue
= getStoredValue(operand
);
414 if (operandValue
== null) {
418 IElementType tokenType
= expression
.getOperationSign().getTokenType();
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
);
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());
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
)) {
484 PsiReferenceExpression qualifier
= (PsiReferenceExpression
) qualifierExpression
;
485 final PsiElement resolved
= qualifier
.resolve();
486 if (resolved
instanceof PsiPackage
) break;
487 if (!(resolved
instanceof PsiClass
)) {
491 qualifierExpression
= ((PsiReferenceExpression
) qualifierExpression
).getQualifierExpression();
493 PsiElement resolvedExpression
= expression
.resolve();
494 if (resolvedExpression
instanceof PsiVariable
) {
495 PsiVariable variable
= (PsiVariable
) resolvedExpression
;
497 if (myVisitedVars
!= null && myVisitedVars
.contains(variable
)) {
502 Set
<PsiVariable
> oldVisitedVars
= myVisitedVars
;
503 if (myVisitedVars
== null) { myVisitedVars
= new THashSet
<PsiVariable
>(); }
505 myVisitedVars
.add(variable
);
507 if (!(variable
instanceof PsiVariableEx
)) {
512 myResult
= ((PsiVariableEx
) variable
).computeConstantValue(myVisitedVars
);
516 myVisitedVars
.remove(variable
);
517 myVisitedVars
= oldVisitedVars
;
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
,
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
);