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 org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
022 import org.jetbrains.jet.lang.types.JetType;
023 import org.jetbrains.jet.lang.types.TypeSubstitutor;
024 import org.jetbrains.jet.lang.types.Variance;
025
026 import java.util.Set;
027
028 public interface ConstraintSystem {
029
030 /**
031 * Registers a variable in a constraint system.
032 */
033 void registerTypeVariable(@NotNull TypeParameterDescriptor typeVariable, @NotNull Variance positionVariance);
034
035 /**
036 * Returns a set of all registered type variables.
037 */
038 @NotNull
039 Set<TypeParameterDescriptor> getTypeVariables();
040
041 /**
042 * Adds a constraint that the constraining type is a subtype of the subject type.<p/>
043 * Asserts that only subject type may contain registered type variables. <p/>
044 *
045 * For example, for {@code "fun <T> id(t: T) {}"} to infer <tt>T</tt> in invocation <tt>"id(1)"</tt>
046 * should be generated a constraint <tt>"Int is a subtype of T"</tt> where T is a subject type, and Int is a constraining type.
047 */
048 void addSubtypeConstraint(@Nullable JetType constrainingType, @NotNull JetType subjectType, @NotNull ConstraintPosition constraintPosition);
049
050 /**
051 * Adds a constraint that the constraining type is a supertype of the subject type. <p/>
052 * Asserts that only subject type may contain registered type variables. <p/>
053 *
054 * For example, for {@code "fun <T> create() : T"} to infer <tt>T</tt> in invocation <tt>"val i: Int = create()"</tt>
055 * should be generated a constraint <tt>"Int is a supertype of T"</tt> where T is a subject type, and Int is a constraining type.
056 */
057 void addSupertypeConstraint(@Nullable JetType constrainingType, @NotNull JetType subjectType, @NotNull ConstraintPosition constraintPosition);
058
059 /**
060 * Returns <tt>true</tt> if constraint system has a solution (has no contradiction and has enough information to infer each registered type variable).
061 */
062 boolean isSuccessful();
063
064 /**
065 * Return <tt>true</tt> if constraint system has no contradiction (it can be not successful because of the lack of information for a type variable).
066 */
067 boolean hasContradiction();
068
069 /**
070 * Returns <tt>true</tt> if type constraints for some type variable are contradicting. <p/>
071 *
072 * For example, for <pre>fun <R> foo(r: R, t: java.util.List<R>) {}</pre> in invocation <tt>foo(1, arrayList("s"))</tt>
073 * type variable <tt>R</tt> has two conflicting constraints: <p/>
074 * - <tt>"R is a supertype of Int"</tt> <p/>
075 * - <tt>"List<R> is a supertype of List<String>"</tt> which leads to <tt>"R is equal to String"</tt>
076 */
077 boolean hasConflictingConstraints();
078
079 /**
080 * Returns <tt>true</tt> if there is no information for some registered type variable.
081 *
082 * For example, for <pre>fun <E> newList()</pre> in invocation <tt>"val nl = newList()"</tt>
083 * there is no information to infer type variable <tt>E</tt>.
084 */
085 boolean hasUnknownParameters();
086
087 /**
088 * Returns <tt>true</tt> if some constraint cannot be processed because of type constructor mismatch.
089 *
090 * For example, for <pre>fun <R> foo(t: List<R>) {}</pre> in invocation <tt>foo(hashSet("s"))</tt>
091 * there is type constructor mismatch: <tt>"HashSet<String> cannot be a subtype of List<R>"</tt>.
092 */
093 boolean hasTypeConstructorMismatch();
094
095 /**
096 * Returns <tt>true</tt> if there is type constructor mismatch error at a specific {@code constraintPosition}.
097 *
098 * For example, for <pre>fun <R> foo(t: List<R>) {}</pre> in invocation <tt>foo(hashSet("s"))</tt>
099 * there is type constructor mismatch: <tt>"HashSet<String> cannot be a subtype of List<R>"</tt>
100 * at a constraint position {@code ConstraintPosition.getValueParameterPosition(0)}.
101 */
102 boolean hasTypeConstructorMismatchAt(@NotNull ConstraintPosition constraintPosition);
103
104 /**
105 * Returns <tt>true</tt> if there is type constructor mismatch only in {@link ConstraintPosition.EXPECTED_TYPE_POSITION}.
106 */
107 boolean hasOnlyExpectedTypeMismatch();
108
109 /**
110 * Returns <tt>true</tt> if there is an error in constraining types. <p/>
111 * Is used not to generate type inference error if there was one in argument types.
112 */
113 boolean hasErrorInConstrainingTypes();
114
115 /**
116 * Returns the resulting type constraints of solving the constraint system for specific type variable. <p/>
117 * Returns null if the type variable was not registered.
118 */
119 @Nullable
120 TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeVariable);
121
122 /**
123 * Returns a result of solving the constraint system (mapping from the type variable to the resulting type projection). <p/>
124 * In the resulting substitution should be concerned: <p/>
125 * - type constraints <p/>
126 * - variance of the type variable // not implemented yet <p/>
127 * - type parameter bounds (that can bind type variables with each other). // not implemented yet
128 * If the addition of the 'expected type' constraint made the system fail,
129 * this constraint is not included in the resulting substitution.
130 */
131 @NotNull
132 TypeSubstitutor getResultingSubstitutor();
133
134 /**
135 * Returns a current result of solving the constraint system (mapping from the type variable to the resulting type projection).
136 * If there is no information for type parameter, returns type projection for DONT_CARE type.
137 */
138 @NotNull
139 TypeSubstitutor getCurrentSubstitutor();
140
141 ConstraintSystem copy();
142 }