2 * Created by IntelliJ IDEA.
6 * To change template for new class use
7 * Code Style | Class Templates options (Tools | IDE Options).
9 package com
.intellij
.codeInspection
.dataFlow
.value
;
11 import com
.intellij
.openapi
.diagnostic
.Logger
;
12 import com
.intellij
.psi
.*;
13 import com
.intellij
.psi
.impl
.ConstantExpressionEvaluator
;
14 import gnu
.trove
.TIntObjectHashMap
;
15 import org
.jetbrains
.annotations
.NotNull
;
17 public class DfaValueFactory
{
18 private static final Logger LOG
= Logger
.getInstance("#com.intellij.codeInspection.dataFlow.value.DfaValueFactory");
21 private final TIntObjectHashMap
<DfaValue
> myValues
;
23 public DfaValueFactory() {
24 myValues
= new TIntObjectHashMap
<DfaValue
>();
27 myVarFactory
= new DfaVariableValue
.Factory(this);
28 myConstFactory
= new DfaConstValue
.Factory(this);
29 myBoxedFactory
= new DfaBoxedValue
.Factory(this);
30 myNotNullFactory
= new DfaNotNullValue
.Factory(this);
31 myTypeFactory
= new DfaTypeValue
.Factory(this);
32 myRelationFactory
= new DfaRelationValue
.Factory(this);
37 LOG
.assertTrue(myLastID
>= 0, "Overflow");
41 void registerValue(DfaValue value
) {
42 myValues
.put(value
.getID(), value
);
45 public DfaValue
getValue(int id
) {
46 return myValues
.get(id
);
49 public DfaValue
create(PsiExpression psiExpression
) {
50 DfaValue result
= null;
52 if (psiExpression
instanceof PsiReferenceExpression
) {
53 PsiElement psiSource
= ((PsiReferenceExpression
)psiExpression
).resolve();
55 if (psiSource
!= null) {
56 if (psiSource
instanceof PsiVariable
) {
57 final PsiVariable variable
= (PsiVariable
)psiSource
;
58 DfaValue constValue
= getConstFactory().create(variable
);
59 if (constValue
!= null) return constValue
;
61 if (!(psiSource
instanceof PsiField
)) {
62 PsiExpression initializer
= variable
.getInitializer();
63 if (initializer
instanceof PsiBinaryExpression
&& variable
.hasModifierProperty(PsiModifier
.FINAL
)) {
64 PsiType type
= initializer
.getType();
65 if (type
!= null && type
.equalsToText("java.lang.String")) {
66 return getNotNullFactory().create(type
);
72 PsiVariable psiVariable
= resolveVariable((PsiReferenceExpression
)psiExpression
);
73 if (psiVariable
!= null) {
74 result
= getVarFactory().create(psiVariable
, false);
78 else if (psiExpression
instanceof PsiLiteralExpression
) {
79 final PsiLiteralExpression literal
= (PsiLiteralExpression
)psiExpression
;
80 if (literal
.getValue() instanceof String
) {
81 result
= getNotNullFactory().create(psiExpression
.getType()); // Non-null string literal.
84 result
= getConstFactory().create(literal
);
87 else if (psiExpression
instanceof PsiNewExpression
) {
88 result
= getNotNullFactory().create(psiExpression
.getType());
91 final Object value
= ConstantExpressionEvaluator
.computeConstantExpression(psiExpression
, false);
92 PsiType type
= psiExpression
.getType();
93 if (value
!= null && type
!= null) {
94 if (value
instanceof String
) {
95 result
= getNotNullFactory().create(type
); // Non-null string literal.
98 result
= getConstFactory().createFromValue(value
, type
);
106 public static PsiVariable
resolveVariable(PsiReferenceExpression refExpression
) {
107 PsiExpression qualifier
= refExpression
.getQualifierExpression();
108 if (qualifier
== null || qualifier
instanceof PsiThisExpression
) {
109 PsiElement resolved
= refExpression
.resolve();
110 if (resolved
instanceof PsiVariable
) {
111 return (PsiVariable
)resolved
;
118 private final DfaVariableValue
.Factory myVarFactory
;
119 private final DfaConstValue
.Factory myConstFactory
;
120 private final DfaBoxedValue
.Factory myBoxedFactory
;
121 private final DfaNotNullValue
.Factory myNotNullFactory
;
122 private final DfaTypeValue
.Factory myTypeFactory
;
123 private final DfaRelationValue
.Factory myRelationFactory
;
126 public DfaVariableValue
.Factory
getVarFactory() {
131 public DfaConstValue
.Factory
getConstFactory() {
132 return myConstFactory
;
135 public DfaBoxedValue
.Factory
getBoxedFactory() {
136 return myBoxedFactory
;
140 public DfaNotNullValue
.Factory
getNotNullFactory() {
141 return myNotNullFactory
;
145 public DfaTypeValue
.Factory
getTypeFactory() {
146 return myTypeFactory
;
150 public DfaRelationValue
.Factory
getRelationFactory() {
151 return myRelationFactory
;