update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInspection / dataFlow / value / DfaRelationValue.java
blob63246a6f20f81633e67711f12b6b7f97e068008e
1 /*
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.
19 * User: max
20 * Date: Feb 6, 2002
21 * Time: 10:01:02 PM
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) {
46 myFactory = factory;
47 mySharedInstance = new DfaRelationValue(factory);
48 myStringToObject = new HashMap<String, ArrayList<DfaRelationValue>>();
51 @Nullable
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);
70 else {
71 return null;
75 private DfaRelationValue createCanonicalRelation(String relation,
76 boolean negated,
77 final DfaValue dfaLeft,
78 final DfaValue dfaRight) {
79 // To canonical form.
80 if ("!=".equals(relation)) {
81 relation = "==";
82 negated = !negated;
84 else if ("<".equals(relation)) {
85 relation = ">=";
86 negated = !negated;
88 else if ("<=".equals(relation)) {
89 relation = ">";
90 negated = !negated;
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);
104 else {
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);
112 return result;
115 private static String getSymmetricOperation(String sign) {
116 if ("<".equals(sign)) {
117 return ">";
119 else if (">=".equals(sign)) {
120 return "<=";
122 else if (">".equals(sign)) {
123 return "<";
125 else if ("<=".equals(sign)) {
126 return ">=";
129 return sign;
133 private DfaRelationValue(DfaValueFactory factory) {
134 super(factory);
137 private DfaRelationValue(DfaValue myLeftOperand, DfaValue myRightOperand, String myRelation, boolean myIsNegated,
138 DfaValueFactory factory) {
139 super(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() {
155 return myIsNegated;
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;