933df88216f9eb7db13d23f1d3f33b6d01c3259a
[idea/community.git] / python / src / com / jetbrains / python / psi / types / PyCollectionTypeImpl.java
1 /*
2  * Copyright 2000-2014 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.jetbrains.python.psi.types;
17
18 import com.intellij.psi.PsiElement;
19 import com.jetbrains.python.psi.PyClass;
20 import com.jetbrains.python.psi.PyPsiFacade;
21 import org.jetbrains.annotations.NotNull;
22 import org.jetbrains.annotations.Nullable;
23
24 import java.util.List;
25
26 /**
27  * @author yole
28  */
29 public class PyCollectionTypeImpl extends PyClassTypeImpl implements PyCollectionType {
30   @NotNull private final List<PyType> myElementTypes;
31
32   public PyCollectionTypeImpl(@NotNull PyClass source, boolean isDefinition, @NotNull List<PyType> elementTypes) {
33     super(source, isDefinition);
34     myElementTypes = elementTypes;
35   }
36
37   @NotNull
38   @Override
39   public List<PyType> getElementTypes(@NotNull TypeEvalContext context) {
40     return myElementTypes;
41   }
42
43   @Nullable
44   public static PyCollectionTypeImpl createTypeByQName(@NotNull final PsiElement anchor,
45                                                        @NotNull final String classQualifiedName,
46                                                        final boolean isDefinition,
47                                                        @NotNull final List<PyType> elementTypes) {
48     final PyClass pyClass = PyPsiFacade.getInstance(anchor.getProject()).createClassByQName(classQualifiedName, anchor);
49     if (pyClass == null) {
50       return null;
51     }
52     return new PyCollectionTypeImpl(pyClass, isDefinition, elementTypes);
53   }
54
55   @Override
56   public boolean equals(Object o) {
57     if (this == o) return true;
58     if (!(o instanceof PyCollectionType)) return false;
59     if (!super.equals(o)) return false;
60
61     PyCollectionType type = (PyCollectionType)o;
62
63     final TypeEvalContext context = TypeEvalContext.codeInsightFallback(myClass.getProject());
64     final List<PyType> otherElementTypes = type.getElementTypes(context);
65     if (myElementTypes.size() != otherElementTypes.size()) return false;
66     for (int i = 0; i < myElementTypes.size(); i++) {
67       final PyType elementType = myElementTypes.get(i);
68       final PyType otherElementType = otherElementTypes.get(i);
69       if (elementType == null && otherElementType != null) return false;
70       if (elementType != null && !elementType.equals(otherElementType)) return false;
71     }
72     return true;
73   }
74
75   @Override
76   public int hashCode() {
77     int result = super.hashCode();
78     result = 31 * result;
79     for (PyType type : myElementTypes) {
80       result += type != null ? type.hashCode() : 0;
81     }
82     return result;
83   }
84 }