missing files
[idea/community.git] / java / java-impl / src / com / intellij / codeInspection / NumericOverflowInspection.java
1 /*
2  * Copyright 2000-2010 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.codeInspection;
17
18 import com.intellij.codeInsight.daemon.GroupNames;
19 import com.intellij.codeInsight.daemon.JavaErrorMessages;
20 import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
21 import com.intellij.openapi.util.Key;
22 import com.intellij.psi.*;
23 import com.intellij.psi.util.ConstantEvaluationOverflowException;
24 import com.intellij.psi.util.TypeConversionUtil;
25 import org.jetbrains.annotations.Nls;
26 import org.jetbrains.annotations.NotNull;
27
28 /**
29  * User: cdr
30  */
31 public class NumericOverflowInspection extends BaseLocalInspectionTool {
32   private static final Key<String> HAS_OVERFLOW_IN_CHILD = Key.create("HAS_OVERFLOW_IN_CHILD");
33
34   @Nls
35   @NotNull
36   @Override
37   public String getGroupDisplayName() {
38     return GroupNames.NUMERIC_GROUP_NAME;
39   }
40
41   @Nls
42   @NotNull
43   @Override
44   public String getDisplayName() {
45     return "Numeric overflow";
46   }
47
48   @NotNull
49   @Override
50   public String getShortName() {
51     return "NumericOverflow";
52   }
53
54   @NotNull
55   @Override
56   public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
57     return new JavaElementVisitor() {
58       @Override
59       public void visitReferenceExpression(PsiReferenceExpression expression) {
60         visitExpression(expression);
61       }
62
63       @Override
64       public void visitExpression(PsiExpression expression) {
65         boolean info = hasOverflow(expression);
66         if (info) {
67           holder.registerProblem(expression, JavaErrorMessages.message("numeric.overflow.in.expression"), ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
68         }
69       }
70     };
71   }
72
73   private static boolean hasOverflow(PsiExpression expr) {
74     if (!TypeConversionUtil.isNumericType(expr.getType())) return false;
75     boolean overflow = false;
76     try {
77       if (expr.getUserData(HAS_OVERFLOW_IN_CHILD) == null) {
78         JavaPsiFacade.getInstance(expr.getProject()).getConstantEvaluationHelper().computeConstantExpression(expr, true);
79       }
80       else {
81         overflow = true;
82       }
83     }
84     catch (ConstantEvaluationOverflowException e) {
85       overflow = true;
86     }
87     finally {
88       PsiElement parent = expr.getParent();
89       if (overflow && parent instanceof PsiExpression) {
90         parent.putUserData(HAS_OVERFLOW_IN_CHILD, "");
91       }
92     }
93
94     return overflow;
95   }
96
97 }