rename: remember 'Search for text occurrences' checkbox state (IDEA-21328)
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / ExpectedTypeInfoImpl.java
blob2e3bac7cec50110918e2f2be01fad36513e5f8b4
2 /*
3 * Copyright 2000-2009 JetBrains s.r.o.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package com.intellij.codeInsight;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.psi.*;
21 import org.jetbrains.annotations.NotNull;
23 public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
25 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ExpectedTypeInfoImpl");
27 private final PsiType type;
28 private final PsiType defaultType;
29 private boolean myInsertExplicitTypeParams;
31 int getDimCount() {
32 return dimCount;
35 private final int dimCount;
37 public int getKind() {
38 return kind;
41 public int kind;
43 public TailType getTailType() {
44 return myTailType;
47 public TailType myTailType;
49 public String expectedName;
50 private PsiMethod myCalledMethod;
53 public ExpectedTypeInfoImpl(@NotNull PsiType type, int kind, int dimCount, @NotNull PsiType defaultType, @NotNull TailType myTailType) {
54 this.type = type;
55 this.kind = kind;
57 this.myTailType = myTailType;
58 this.dimCount = dimCount;
60 if (type == defaultType && type instanceof PsiClassType) {
61 final PsiClassType psiClassType = (PsiClassType)type;
62 final PsiClass psiClass = psiClassType.resolve();
63 if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) {
64 final PsiType[] parameters = psiClassType.getParameters();
65 if (parameters.length == 1 && parameters[0] instanceof PsiWildcardType) {
66 final PsiType bound = ((PsiWildcardType)parameters[0]).getExtendsBound();
67 if (bound instanceof PsiClassType) {
68 final PsiElementFactory factory = JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory();
69 defaultType = factory.createTypeFromText(CommonClassNames.JAVA_LANG_CLASS + "<" + bound.getCanonicalText() + ">", null);
75 this.defaultType = defaultType;
78 public PsiMethod getCalledMethod() {
79 return myCalledMethod;
82 public void setCalledMethod(final PsiMethod calledMethod) {
83 myCalledMethod = calledMethod;
86 @NotNull
87 public PsiType getType () {
88 PsiType t = type;
89 int dims = dimCount;
91 while (dims-- > 0) t = t.createArrayType();
92 return t;
95 @NotNull
96 public PsiType getDefaultType () {
97 PsiType t = defaultType;
98 int dims = dimCount;
100 while (dims-- > 0) t = t.createArrayType();
101 return t;
104 public boolean isInsertExplicitTypeParams() {
105 return myInsertExplicitTypeParams;
108 public void setInsertExplicitTypeParams(final boolean insertExplicitTypeParams) {
109 this.myInsertExplicitTypeParams = insertExplicitTypeParams;
112 public boolean equals(final Object o) {
113 if (this == o) return true;
114 if (!(o instanceof ExpectedTypeInfoImpl)) return false;
116 final ExpectedTypeInfoImpl that = (ExpectedTypeInfoImpl)o;
118 if (dimCount != that.dimCount) return false;
119 if (kind != that.kind) return false;
120 if (defaultType != null ? !defaultType.equals(that.defaultType) : that.defaultType != null) return false;
121 if (myTailType != null ? !myTailType.equals(that.myTailType) : that.myTailType != null) return false;
122 if (type != null ? !type.equals(that.type) : that.type != null) return false;
124 return true;
127 public int hashCode() {
128 int result;
129 result = (type != null ? type.hashCode() : 0);
130 result = 31 * result + (defaultType != null ? defaultType.hashCode() : 0);
131 result = 31 * result + dimCount;
132 result = 31 * result + kind;
133 result = 31 * result + (myTailType != null ? myTailType.hashCode() : 0);
134 return result;
137 public boolean equals(ExpectedTypeInfo obj) {
138 return equals((Object)obj);
141 @SuppressWarnings({"HardCodedStringLiteral"})
142 public String toString() {
143 return "ExpectedTypeInfo[type='" + type + "' kind='" + kind + "' dims='" + dimCount+ "']";
146 public ExpectedTypeInfo[] intersect(ExpectedTypeInfo info) {
147 ExpectedTypeInfoImpl info1 = (ExpectedTypeInfoImpl)info;
148 LOG.assertTrue(!(type instanceof PsiArrayType) && !(info1.type instanceof PsiArrayType));
150 if (kind == TYPE_STRICTLY) {
151 if (info1.kind == TYPE_STRICTLY) {
152 if (dimCount != info1.dimCount) return ExpectedTypeInfo.EMPTY_ARRAY;
153 if (info1.type.equals(type)) return new ExpectedTypeInfoImpl[] {this};
155 else {
156 return info1.intersect(this);
159 else if (kind == TYPE_OR_SUBTYPE) {
160 if (info1.kind == TYPE_STRICTLY) {
161 if (dimCount != info1.dimCount) return ExpectedTypeInfo.EMPTY_ARRAY;
162 if (type.isAssignableFrom(info1.type)) return new ExpectedTypeInfoImpl[] {info1};
164 else if (info1.kind == TYPE_OR_SUBTYPE) {
165 PsiType type = dimCount == info1.dimCount ? this.type : getType();
166 PsiType otherType = dimCount == info1.dimCount ? info1.type : info1.getType();
167 if (type.isAssignableFrom(otherType)) return new ExpectedTypeInfoImpl[] {info1};
168 else if (otherType.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {this};
170 else {
171 return info1.intersect(this);
174 else if (kind == TYPE_OR_SUPERTYPE) {
175 if (info1.kind == TYPE_STRICTLY) {
176 if (dimCount != info1.dimCount) return ExpectedTypeInfo.EMPTY_ARRAY;
177 if (info1.type.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {info1};
179 else if (info1.kind == TYPE_OR_SUBTYPE) {
180 PsiType type = dimCount == info1.dimCount ? this.type : getType();
181 PsiType otherType = dimCount == info1.dimCount ? info1.type : info1.getType();
182 if (otherType.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {this};
184 else if (info1.kind == TYPE_OR_SUPERTYPE) {
185 PsiType type = dimCount == info1.dimCount ? this.type : getType();
186 PsiType otherType = dimCount == info1.dimCount ? info1.type : info1.getType();
187 if (type.isAssignableFrom(otherType)) return new ExpectedTypeInfoImpl[] {this};
188 else if (otherType.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {info1};
190 else {
191 return info1.intersect(this);
196 //todo: the following cases are not implemented: SUPERxSUB, SUBxSUPER
198 return ExpectedTypeInfo.EMPTY_ARRAY;
201 public boolean isArrayTypeInfo () {
202 return dimCount > 0;