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 &lt;R&gt; foo(r: R, t: java.util.List&lt;R&gt;) {}</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&lt;R&gt; is a supertype of List&lt;String&gt;"</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 &lt;E&gt; 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 &lt;R&gt; foo(t: List&lt;R&gt;) {}</pre> in invocation <tt>foo(hashSet("s"))</tt>
091         * there is type constructor mismatch: <tt>"HashSet&lt;String&gt; cannot be a subtype of List&lt;R&gt;"</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 &lt;R&gt; foo(t: List&lt;R&gt;) {}</pre> in invocation <tt>foo(hashSet("s"))</tt>
099         * there is type constructor mismatch: <tt>"HashSet&lt;String&gt; cannot be a subtype of List&lt;R&gt;"</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    }