2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Created by IntelliJ IDEA.
22 * To change template for new class use
23 * Code Style | Class Templates options (Tools | IDE Options).
25 package com
.intellij
.codeInspection
.dataFlow
.value
;
27 import com
.intellij
.openapi
.util
.Comparing
;
28 import com
.intellij
.util
.containers
.HashMap
;
29 import org
.jetbrains
.annotations
.NonNls
;
30 import org
.jetbrains
.annotations
.Nullable
;
32 import java
.util
.ArrayList
;
34 public class DfaRelationValue
extends DfaValue
{
35 private DfaValue myLeftOperand
;
36 private DfaValue myRightOperand
;
37 private String myRelation
;
38 private boolean myIsNegated
;
40 public static class Factory
{
41 private final DfaRelationValue mySharedInstance
;
42 private final HashMap
<String
,ArrayList
<DfaRelationValue
>> myStringToObject
;
43 private final DfaValueFactory myFactory
;
45 Factory(DfaValueFactory factory
) {
47 mySharedInstance
= new DfaRelationValue(factory
);
48 myStringToObject
= new HashMap
<String
, ArrayList
<DfaRelationValue
>>();
52 public DfaRelationValue
create(DfaValue dfaLeft
, DfaValue dfaRight
, @NonNls String relation
, boolean negated
) {
53 if (dfaRight
instanceof DfaTypeValue
&& !"instanceof".equals(relation
)) return null;
54 if ("+".equals(relation
)) return null;
56 if (dfaLeft
instanceof DfaVariableValue
|| dfaLeft
instanceof DfaBoxedValue
|| dfaLeft
instanceof DfaUnboxedValue
57 || dfaRight
instanceof DfaVariableValue
|| dfaRight
instanceof DfaBoxedValue
|| dfaRight
instanceof DfaUnboxedValue
) {
58 if (!(dfaLeft
instanceof DfaVariableValue
|| dfaLeft
instanceof DfaBoxedValue
|| dfaLeft
instanceof DfaUnboxedValue
)) {
59 return create(dfaRight
, dfaLeft
, getSymmetricOperation(relation
), negated
);
62 return createCanonicalRelation(relation
, negated
, dfaLeft
, dfaRight
);
64 if (dfaLeft
instanceof DfaNotNullValue
&& dfaRight
instanceof DfaConstValue
) {
65 return createCanonicalRelation(relation
, negated
, dfaLeft
, dfaRight
);
67 else if (dfaRight
instanceof DfaNotNullValue
&& dfaLeft
instanceof DfaConstValue
) {
68 return createCanonicalRelation(relation
, negated
, dfaRight
, dfaLeft
);
75 private DfaRelationValue
createCanonicalRelation(String relation
,
77 final DfaValue dfaLeft
,
78 final DfaValue dfaRight
) {
80 if ("!=".equals(relation
)) {
84 else if ("<".equals(relation
)) {
88 else if ("<=".equals(relation
)) {
93 mySharedInstance
.myLeftOperand
= dfaLeft
;
94 mySharedInstance
.myRightOperand
= dfaRight
;
95 mySharedInstance
.myRelation
= relation
;
96 mySharedInstance
.myIsNegated
= negated
;
98 String id
= mySharedInstance
.toString();
99 ArrayList
<DfaRelationValue
> conditions
= myStringToObject
.get(id
);
100 if (conditions
== null) {
101 conditions
= new ArrayList
<DfaRelationValue
>();
102 myStringToObject
.put(id
, conditions
);
105 for (DfaRelationValue rel
: conditions
) {
106 if (rel
.hardEquals(mySharedInstance
)) return rel
;
110 DfaRelationValue result
= new DfaRelationValue(dfaLeft
, dfaRight
, relation
, negated
, myFactory
);
111 conditions
.add(result
);
115 private static String
getSymmetricOperation(String sign
) {
116 if ("<".equals(sign
)) {
119 else if (">=".equals(sign
)) {
122 else if (">".equals(sign
)) {
125 else if ("<=".equals(sign
)) {
133 private DfaRelationValue(DfaValueFactory factory
) {
137 private DfaRelationValue(DfaValue myLeftOperand
, DfaValue myRightOperand
, String myRelation
, boolean myIsNegated
,
138 DfaValueFactory factory
) {
140 this.myLeftOperand
= myLeftOperand
;
141 this.myRightOperand
= myRightOperand
;
142 this.myRelation
= myRelation
;
143 this.myIsNegated
= myIsNegated
;
146 public DfaValue
getLeftOperand() {
147 return myLeftOperand
;
150 public DfaValue
getRightOperand() {
151 return myRightOperand
;
154 public boolean isNegated() {
158 public DfaValue
createNegated() {
159 return myFactory
.getRelationFactory().create(myLeftOperand
, myRightOperand
, myRelation
, !myIsNegated
);
162 private boolean hardEquals(DfaRelationValue rel
) {
163 return Comparing
.equal(rel
.myLeftOperand
,myLeftOperand
)
164 && Comparing
.equal(rel
.myRightOperand
,myRightOperand
) &&
165 rel
.myRelation
.equals(myRelation
) &&
166 rel
.myIsNegated
== myIsNegated
;
169 @NonNls public String
toString() {
170 return (isNegated() ?
"not " : "") + myLeftOperand
+ myRelation
+ myRightOperand
;