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 kotlin.Function1;
020 import kotlin.KotlinPackage;
021 import org.jetbrains.annotations.NotNull;
022
023 import java.util.Arrays;
024 import java.util.Collection;
025 import java.util.HashMap;
026 import java.util.Map;
027
028 public class ConstraintPosition {
029 public static final ConstraintPosition RECEIVER_POSITION = new ConstraintPosition("RECEIVER_POSITION", true);
030 public static final ConstraintPosition EXPECTED_TYPE_POSITION = new ConstraintPosition("EXPECTED_TYPE_POSITION", true);
031 public static final ConstraintPosition FROM_COMPLETER = new ConstraintPosition("FROM_COMPLETER", true);
032 public static final ConstraintPosition SPECIAL = new ConstraintPosition("SPECIAL", true);
033
034 private static final Map<Integer, ConstraintPosition> valueParameterPositions = new HashMap<Integer, ConstraintPosition>();
035 private static final Map<Integer, ConstraintPosition> typeBoundPositions = new HashMap<Integer, ConstraintPosition>();
036
037 public static ConstraintPosition getValueParameterPosition(int index) {
038 ConstraintPosition position = valueParameterPositions.get(index);
039 if (position == null) {
040 position = new ConstraintPosition("VALUE_PARAMETER_POSITION(" + index + ")", true);
041 valueParameterPositions.put(index, position);
042 }
043 return position;
044 }
045
046 public static ConstraintPosition getTypeBoundPosition(int index) {
047 ConstraintPosition position = typeBoundPositions.get(index);
048 if (position == null) {
049 position = new ConstraintPosition("TYPE_BOUND_POSITION(" + index + ")", false);
050 typeBoundPositions.put(index, position);
051 }
052 return position;
053 }
054
055 public static class CompoundConstraintPosition extends ConstraintPosition {
056 private final Collection<ConstraintPosition> positions;
057
058 public CompoundConstraintPosition(Collection<ConstraintPosition> positions) {
059 super("COMPOUND_CONSTRAINT_POSITION", hasConstraint(positions, /*strong=*/true));
060 this.positions = positions;
061 }
062
063 public boolean consistsOfOnlyStrongConstraints() {
064 return !hasConstraint(positions, /*strong=*/false);
065 }
066
067 private static boolean hasConstraint(@NotNull Collection<ConstraintPosition> positions, final boolean strong) {
068 return KotlinPackage.any(positions, new Function1<ConstraintPosition, Boolean>() {
069 @Override
070 public Boolean invoke(ConstraintPosition constraintPosition) {
071 return constraintPosition.isStrong() == strong;
072 }
073 });
074 }
075 }
076
077 public static ConstraintPosition getCompoundConstraintPosition(ConstraintPosition... positions) {
078 return new CompoundConstraintPosition(Arrays.asList(positions));
079 }
080
081 private final String debugName;
082 private final boolean isStrong;
083
084 private ConstraintPosition(String name, boolean isStrong) {
085 debugName = name;
086 this.isStrong = isStrong;
087 }
088
089 public boolean isStrong() {
090 return isStrong;
091 }
092
093 @Override
094 public String toString() {
095 return debugName;
096 }
097 }