001    /*
002     * Copyright 2010-2013 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.jet.lang.resolve.calls.inference;
018    
019    import com.google.common.collect.Lists;
020    import com.google.common.collect.Sets;
021    import com.intellij.openapi.util.Pair;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.jet.lang.types.JetType;
024    import org.jetbrains.jet.lang.types.Variance;
025    
026    import java.util.Collection;
027    import java.util.Set;
028    
029    public class TypeConstraintsImpl implements TypeConstraints {
030        private final Variance varianceOfPosition;
031        private final Set<JetType> upperBounds = Sets.newLinkedHashSet();
032        private final Set<JetType> lowerBounds = Sets.newLinkedHashSet();
033        private final Set<JetType> exactBounds = Sets.newLinkedHashSet();
034    
035        public TypeConstraintsImpl(Variance varianceOfPosition) {
036            this.varianceOfPosition = varianceOfPosition;
037        }
038    
039        @NotNull
040        @Override
041        public Variance getVarianceOfPosition() {
042            return varianceOfPosition;
043        }
044    
045        public void addBound(@NotNull BoundKind boundKind, @NotNull JetType type) {
046            switch (boundKind) {
047                case LOWER_BOUND:
048                    lowerBounds.add(type);
049                    break;
050                case UPPER_BOUND:
051                    upperBounds.add(type);
052                    break;
053                case EXACT_BOUND:
054                    exactBounds.add(type);
055            }
056        }
057    
058        @Override
059        public boolean isEmpty() {
060            return upperBounds.isEmpty() && lowerBounds.isEmpty() && exactBounds.isEmpty();
061        }
062    
063        @NotNull
064        @Override
065        public Set<JetType> getLowerBounds() {
066            return lowerBounds;
067        }
068    
069        @NotNull
070        @Override
071        public Set<JetType> getUpperBounds() {
072            return upperBounds;
073        }
074    
075        @NotNull
076        @Override
077        public Set<JetType> getExactBounds() {
078            return exactBounds;
079        }
080    
081        /*package*/ TypeConstraintsImpl copy() {
082            TypeConstraintsImpl typeConstraints = new TypeConstraintsImpl(varianceOfPosition);
083            typeConstraints.upperBounds.addAll(upperBounds);
084            typeConstraints.lowerBounds.addAll(lowerBounds);
085            typeConstraints.exactBounds.addAll(exactBounds);
086            return typeConstraints;
087        }
088    
089        public static enum BoundKind {
090            LOWER_BOUND, UPPER_BOUND, EXACT_BOUND
091        }
092    
093        public Collection<Pair<BoundKind, JetType>> getAllBounds() {
094            Collection<Pair<BoundKind, JetType>> result = Lists.newArrayList();
095            for (JetType exactBound : exactBounds) {
096                result.add(Pair.create(BoundKind.EXACT_BOUND, exactBound));
097            }
098            for (JetType exactBound : upperBounds) {
099                result.add(Pair.create(BoundKind.UPPER_BOUND, exactBound));
100            }
101            for (JetType exactBound : lowerBounds) {
102                result.add(Pair.create(BoundKind.LOWER_BOUND, exactBound));
103            }
104            return result;
105        }
106    }