001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.types;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
021    import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
022    import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
023    
024    import java.util.*;
025    
026    public class IntersectionTypeConstructor implements TypeConstructor {
027        private final Set<KotlinType> intersectedTypes;
028        private final int hashCode;
029    
030        public IntersectionTypeConstructor(Collection<KotlinType> typesToIntersect) {
031            assert !typesToIntersect.isEmpty() : "Attempt to create an empty intersection";
032    
033            this.intersectedTypes = new LinkedHashSet<KotlinType>(typesToIntersect);
034            this.hashCode = intersectedTypes.hashCode();
035        }
036    
037        @NotNull
038        @Override
039        public List<TypeParameterDescriptor> getParameters() {
040            return Collections.emptyList();
041        }
042    
043        @NotNull
044        @Override
045        public Collection<KotlinType> getSupertypes() {
046            return intersectedTypes;
047        }
048    
049        @Override
050        public boolean isFinal() {
051            return false;
052        }
053    
054        @Override
055        public boolean isDenotable() {
056            return false;
057        }
058    
059        @Override
060        public ClassifierDescriptor getDeclarationDescriptor() {
061            return null;
062        }
063    
064        @NotNull
065        @Override
066        public KotlinBuiltIns getBuiltIns() {
067            return intersectedTypes.iterator().next().getConstructor().getBuiltIns();
068        }
069    
070        @Override
071        public String toString() {
072            return makeDebugNameForIntersectionType(intersectedTypes);
073        }
074    
075        private static String makeDebugNameForIntersectionType(Iterable<KotlinType> resultingTypes) {
076            StringBuilder debugName = new StringBuilder("{");
077            for (Iterator<KotlinType> iterator = resultingTypes.iterator(); iterator.hasNext(); ) {
078                KotlinType type = iterator.next();
079    
080                debugName.append(type.toString());
081                if (iterator.hasNext()) {
082                    debugName.append(" & ");
083                }
084            }
085            debugName.append("}");
086            return debugName.toString();
087        }
088    
089        @Override
090        public boolean equals(Object o) {
091            if (this == o) return true;
092            if (o == null || getClass() != o.getClass()) return false;
093    
094            IntersectionTypeConstructor that = (IntersectionTypeConstructor) o;
095    
096            if (intersectedTypes != null ? !intersectedTypes.equals(that.intersectedTypes) : that.intersectedTypes != null) return false;
097    
098            return true;
099        }
100    
101        @Override
102        public int hashCode() {
103            return hashCode;
104        }
105    }