Extract TypeIntersector from TypeUtils

This commit is contained in:
Pavel V. Talanov
2015-07-27 19:48:25 +03:00
parent 52bc84cb5f
commit f393ce598d
14 changed files with 242 additions and 217 deletions
@@ -41,12 +41,9 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TY
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
import org.jetbrains.kotlin.types.TypeUtils.makeConstantSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
@@ -191,7 +188,7 @@ class GenericCandidateResolver(
val possibleTypes = context.dataFlowInfo.getPossibleTypes(dataFlowValue)
if (possibleTypes.isEmpty()) return type
return TypeUtils.intersect(JetTypeChecker.DEFAULT, possibleTypes)
return TypeIntersector.intersect(JetTypeChecker.DEFAULT, possibleTypes)
}
public fun <D : CallableDescriptor> completeTypeInferenceDependentOnFunctionArgumentsForCall(
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeIntersector;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
@@ -151,7 +152,7 @@ public class SmartCastUtils {
}
if (subTypes.isEmpty()) return null;
JetType intersection = TypeUtils.intersect(JetTypeChecker.DEFAULT, subTypes);
JetType intersection = TypeIntersector.intersect(JetTypeChecker.DEFAULT, subTypes);
if (intersection == null || !intersection.getConstructor().isDenotable()) {
return receiverParameterType;
}
@@ -1251,7 +1251,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetType rightType = facade.getTypeInfo(right, context).getType();
if (rightType != null) {
if (TypeUtils.isIntersectionEmpty(leftType, rightType)) {
if (TypeIntersector.isIntersectionEmpty(leftType, rightType)) {
context.trace.report(EQUALITY_NOT_APPLICABLE.on(expression, expression.getOperationReference(), leftType, rightType));
}
SenselessComparisonChecker.checkSenselessComparisonWithNull(
@@ -44,8 +44,8 @@ import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
import static org.jetbrains.kotlin.types.TypeIntersector.isIntersectionEmpty;
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.kotlin.types.TypeUtils.isIntersectionEmpty;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.newWritableScopeImpl;
public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
@@ -523,7 +523,7 @@ public class JetTypeCheckerTest extends JetLiteFixture {
for (String type : types) {
typesToIntersect.add(makeType(type));
}
JetType result = TypeUtils.intersect(JetTypeChecker.DEFAULT, typesToIntersect);
JetType result = TypeIntersector.intersect(JetTypeChecker.DEFAULT, typesToIntersect);
// assertNotNull("Intersection is null for " + typesToIntersect, result);
assertEquals(makeType(expected), result);
}
@@ -178,7 +178,7 @@ class LazyJavaTypeResolver(
for (supertype in (classifier() as JavaTypeParameter).getUpperBounds()) {
supertypesJet.add(transformJavaType(supertype, UPPER_BOUND.toAttributes()))
}
return TypeUtils.intersect(JetTypeChecker.DEFAULT, supertypesJet)
return TypeIntersector.intersect(JetTypeChecker.DEFAULT, supertypesJet)
?: ErrorUtils.createErrorType("Can't intersect upper bounds of " + javaType.getPresentableText())
}
@@ -135,7 +135,7 @@ public abstract class AbstractTypeParameterDescriptor extends DeclarationDescrip
private JetType computeUpperBoundsAsType() {
Set<JetType> upperBounds = getUpperBounds();
assert !upperBounds.isEmpty() : "Upper bound list is empty in " + getName();
JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.DEFAULT, upperBounds);
JetType upperBoundsAsType = TypeIntersector.intersect(JetTypeChecker.DEFAULT, upperBounds);
return upperBoundsAsType != null ? upperBoundsAsType : getBuiltIns(this).getNothingType();
}
@@ -134,7 +134,7 @@ public class TypeBoundsImpl(
}
val upperBounds = filterBounds(bounds, TypeBounds.BoundKind.UPPER_BOUND, values)
val intersectionOfUpperBounds = TypeUtils.intersect(JetTypeChecker.DEFAULT, upperBounds)
val intersectionOfUpperBounds = TypeIntersector.intersect(JetTypeChecker.DEFAULT, upperBounds)
if (!upperBounds.isEmpty() && intersectionOfUpperBounds != null) {
if (tryPossibleAnswer(bounds, intersectionOfUpperBounds)) {
return setOf(intersectionOfUpperBounds)
@@ -299,7 +299,7 @@ public class CommonSupertypes {
return new TypeProjectionImpl(projectionKind, findCommonSupertype(outs, recursionDepth + 1, maxDepth));
}
if (ins != null) {
JetType intersection = TypeUtils.intersect(JetTypeChecker.DEFAULT, ins);
JetType intersection = TypeIntersector.intersect(JetTypeChecker.DEFAULT, ins);
if (intersection == null) {
return new TypeProjectionImpl(OUT_VARIANCE, findCommonSupertype(parameterDescriptor.getUpperBounds(), recursionDepth + 1, maxDepth));
}
@@ -0,0 +1,205 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.types;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl;
import org.jetbrains.kotlin.resolve.scopes.ChainedScope;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
import java.util.*;
import static org.jetbrains.kotlin.resolve.calls.inference.InferencePackage.registerTypeVariables;
import static org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.SPECIAL;
public class TypeIntersector {
public static boolean isIntersectionEmpty(@NotNull JetType typeA, @NotNull JetType typeB) {
return intersect(JetTypeChecker.DEFAULT, new LinkedHashSet<JetType>(Arrays.asList(typeA, typeB))) == null;
}
@Nullable
public static JetType intersect(@NotNull JetTypeChecker typeChecker, @NotNull Set<JetType> types) {
if (types.isEmpty()) {
return KotlinBuiltIns.getInstance().getNullableAnyType();
}
if (types.size() == 1) {
return types.iterator().next();
}
// Intersection of T1..Tn is an intersection of their non-null versions,
// made nullable is they all were nullable
boolean allNullable = true;
boolean nothingTypePresent = false;
List<JetType> nullabilityStripped = new ArrayList<JetType>(types.size());
for (JetType type : types) {
if (type.isError()) continue;
nothingTypePresent |= KotlinBuiltIns.isNothingOrNullableNothing(type);
allNullable &= type.isMarkedNullable();
nullabilityStripped.add(TypeUtils.makeNotNullable(type));
}
if (nothingTypePresent) {
return allNullable ? KotlinBuiltIns.getInstance().getNullableNothingType() : KotlinBuiltIns.getInstance().getNothingType();
}
if (nullabilityStripped.isEmpty()) {
// All types were errors
return ErrorUtils.createErrorType("Intersection of errors types: " + types);
}
// Now we remove types that have subtypes in the list
List<JetType> resultingTypes = new ArrayList<JetType>();
outer:
for (JetType type : nullabilityStripped) {
if (!TypeUtils.canHaveSubtypes(typeChecker, type)) {
for (JetType other : nullabilityStripped) {
// It makes sense to check for subtyping (other <: type), despite that
// type is not supposed to be open, for there're enums
if (!TypeUnifier.mayBeEqual(type, other) && !typeChecker.isSubtypeOf(type, other) && !typeChecker.isSubtypeOf(other, type)) {
return null;
}
}
return TypeUtils.makeNullableAsSpecified(type, allNullable);
}
else {
for (JetType other : nullabilityStripped) {
if (!type.equals(other) && typeChecker.isSubtypeOf(other, type)) {
continue outer;
}
}
}
// Don't add type if it is already present, to avoid trivial type intersections in result
for (JetType other : resultingTypes) {
if (typeChecker.equalTypes(other, type)) {
continue outer;
}
}
resultingTypes.add(type);
}
if (resultingTypes.isEmpty()) {
// If we ended up here, it means that all types from `nullabilityStripped` were excluded by the code above
// most likely, this is because they are all semantically interchangeable (e.g. List<Foo>! and List<Foo>),
// in that case, we can safely select the best representative out of that set and return it
// TODO: maybe return the most specific among the types that are subtypes to all others in the `nullabilityStripped`?
// TODO: e.g. among {Int, Int?, Int!}, return `Int` (now it returns `Int!`).
JetType bestRepresentative = TypesPackage.singleBestRepresentative(nullabilityStripped);
if (bestRepresentative == null) {
throw new AssertionError("Empty intersection for types " + types);
}
return TypeUtils.makeNullableAsSpecified(bestRepresentative, allNullable);
}
if (resultingTypes.size() == 1) {
return TypeUtils.makeNullableAsSpecified(resultingTypes.get(0), allNullable);
}
TypeConstructor constructor = new IntersectionTypeConstructor(Annotations.EMPTY, resultingTypes);
JetScope[] scopes = new JetScope[resultingTypes.size()];
int i = 0;
for (JetType type : resultingTypes) {
scopes[i] = type.getMemberScope();
i++;
}
return JetTypeImpl.create(
Annotations.EMPTY,
constructor,
allNullable,
Collections.<TypeProjection>emptyList(),
new IntersectionScope(constructor, scopes)
);
}
// TODO : check intersectibility, don't use a chanied scope
private static class IntersectionScope extends ChainedScope {
public IntersectionScope(@NotNull TypeConstructor constructor, @NotNull JetScope[] scopes) {
super(null, "member scope for intersection type " + constructor, scopes);
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
throw new UnsupportedOperationException("Should not call getContainingDeclaration on intersection scope " + this);
}
}
private static class TypeUnifier {
private static class TypeParameterUsage {
private final TypeParameterDescriptor typeParameterDescriptor;
private final Variance howTheTypeParameterIsUsed;
public TypeParameterUsage(TypeParameterDescriptor typeParameterDescriptor, Variance howTheTypeParameterIsUsed) {
this.typeParameterDescriptor = typeParameterDescriptor;
this.howTheTypeParameterIsUsed = howTheTypeParameterIsUsed;
}
}
public static boolean mayBeEqual(@NotNull JetType type, @NotNull JetType other) {
return unify(type, other);
}
private static boolean unify(JetType withParameters, JetType expected) {
// T -> how T is used
final Map<TypeParameterDescriptor, Variance> parameters = new HashMap<TypeParameterDescriptor, Variance>();
Function1<TypeParameterUsage, Unit> processor = new Function1<TypeParameterUsage, Unit>() {
@Override
public Unit invoke(TypeParameterUsage parameterUsage) {
Variance howTheTypeIsUsedBefore = parameters.get(parameterUsage.typeParameterDescriptor);
if (howTheTypeIsUsedBefore == null) {
howTheTypeIsUsedBefore = Variance.INVARIANT;
}
parameters.put(parameterUsage.typeParameterDescriptor,
parameterUsage.howTheTypeParameterIsUsed.superpose(howTheTypeIsUsedBefore));
return Unit.INSTANCE$;
}
};
processAllTypeParameters(withParameters, Variance.INVARIANT, processor);
processAllTypeParameters(expected, Variance.INVARIANT, processor);
ConstraintSystemImpl constraintSystem = new ConstraintSystemImpl();
registerTypeVariables(constraintSystem, parameters);
constraintSystem.addSubtypeConstraint(withParameters, expected, SPECIAL.position());
return constraintSystem.getStatus().isSuccessful();
}
private static void processAllTypeParameters(JetType type, Variance howThisTypeIsUsed, Function1<TypeParameterUsage, Unit> result) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) {
result.invoke(new TypeParameterUsage((TypeParameterDescriptor) descriptor, howThisTypeIsUsed));
}
for (TypeProjection projection : type.getArguments()) {
if (projection.isStarProjection()) continue;
processAllTypeParameters(projection.getType(), projection.getProjectionKind(), result);
}
}
}
}
@@ -17,19 +17,15 @@
package org.jetbrains.kotlin.types;
import kotlin.KotlinPackage;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor;
import org.jetbrains.kotlin.resolve.scopes.ChainedScope;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
import org.jetbrains.kotlin.utils.DFS;
@@ -37,9 +33,6 @@ import org.jetbrains.kotlin.utils.UtilsPackage;
import java.util.*;
import static org.jetbrains.kotlin.resolve.calls.inference.InferencePackage.registerTypeVariables;
import static org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.SPECIAL;
public class TypeUtils {
public static final JetType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE");
public static final JetType PLACEHOLDER_FUNCTION_TYPE = ErrorUtils.createErrorTypeWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE");
@@ -165,173 +158,6 @@ public class TypeUtils {
return type;
}
public static boolean isIntersectionEmpty(@NotNull JetType typeA, @NotNull JetType typeB) {
return intersect(JetTypeChecker.DEFAULT, new LinkedHashSet<JetType>(Arrays.asList(typeA, typeB))) == null;
}
@Nullable
public static JetType intersect(@NotNull JetTypeChecker typeChecker, @NotNull Set<JetType> types) {
if (types.isEmpty()) {
return KotlinBuiltIns.getInstance().getNullableAnyType();
}
if (types.size() == 1) {
return types.iterator().next();
}
// Intersection of T1..Tn is an intersection of their non-null versions,
// made nullable is they all were nullable
boolean allNullable = true;
boolean nothingTypePresent = false;
List<JetType> nullabilityStripped = new ArrayList<JetType>(types.size());
for (JetType type : types) {
if (type.isError()) continue;
nothingTypePresent |= KotlinBuiltIns.isNothingOrNullableNothing(type);
allNullable &= type.isMarkedNullable();
nullabilityStripped.add(makeNotNullable(type));
}
if (nothingTypePresent) {
return allNullable ? KotlinBuiltIns.getInstance().getNullableNothingType() : KotlinBuiltIns.getInstance().getNothingType();
}
if (nullabilityStripped.isEmpty()) {
// All types were errors
return ErrorUtils.createErrorType("Intersection of errors types: " + types);
}
// Now we remove types that have subtypes in the list
List<JetType> resultingTypes = new ArrayList<JetType>();
outer:
for (JetType type : nullabilityStripped) {
if (!canHaveSubtypes(typeChecker, type)) {
for (JetType other : nullabilityStripped) {
// It makes sense to check for subtyping (other <: type), despite that
// type is not supposed to be open, for there're enums
if (!TypeUnifier.mayBeEqual(type, other) && !typeChecker.isSubtypeOf(type, other) && !typeChecker.isSubtypeOf(other, type)) {
return null;
}
}
return makeNullableAsSpecified(type, allNullable);
}
else {
for (JetType other : nullabilityStripped) {
if (!type.equals(other) && typeChecker.isSubtypeOf(other, type)) {
continue outer;
}
}
}
// Don't add type if it is already present, to avoid trivial type intersections in result
for (JetType other : resultingTypes) {
if (typeChecker.equalTypes(other, type)) {
continue outer;
}
}
resultingTypes.add(type);
}
if (resultingTypes.isEmpty()) {
// If we ended up here, it means that all types from `nullabilityStripped` were excluded by the code above
// most likely, this is because they are all semantically interchangeable (e.g. List<Foo>! and List<Foo>),
// in that case, we can safely select the best representative out of that set and return it
// TODO: maybe return the most specific among the types that are subtypes to all others in the `nullabilityStripped`?
// TODO: e.g. among {Int, Int?, Int!}, return `Int` (now it returns `Int!`).
JetType bestRepresentative = TypesPackage.singleBestRepresentative(nullabilityStripped);
if (bestRepresentative == null) {
throw new AssertionError("Empty intersection for types " + types);
}
return makeNullableAsSpecified(bestRepresentative, allNullable);
}
if (resultingTypes.size() == 1) {
return makeNullableAsSpecified(resultingTypes.get(0), allNullable);
}
TypeConstructor constructor = new IntersectionTypeConstructor(Annotations.EMPTY, resultingTypes);
JetScope[] scopes = new JetScope[resultingTypes.size()];
int i = 0;
for (JetType type : resultingTypes) {
scopes[i] = type.getMemberScope();
i++;
}
return JetTypeImpl.create(
Annotations.EMPTY,
constructor,
allNullable,
Collections.<TypeProjection>emptyList(),
new IntersectionScope(constructor, scopes)
);
}
// TODO : check intersectibility, don't use a chanied scope
public static class IntersectionScope extends ChainedScope {
public IntersectionScope(@NotNull TypeConstructor constructor, @NotNull JetScope[] scopes) {
super(null, "member scope for intersection type " + constructor, scopes);
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
throw new UnsupportedOperationException("Should not call getContainingDeclaration on intersection scope " + this);
}
}
private static class TypeUnifier {
private static class TypeParameterUsage {
private final TypeParameterDescriptor typeParameterDescriptor;
private final Variance howTheTypeParameterIsUsed;
public TypeParameterUsage(TypeParameterDescriptor typeParameterDescriptor, Variance howTheTypeParameterIsUsed) {
this.typeParameterDescriptor = typeParameterDescriptor;
this.howTheTypeParameterIsUsed = howTheTypeParameterIsUsed;
}
}
public static boolean mayBeEqual(@NotNull JetType type, @NotNull JetType other) {
return unify(type, other);
}
private static boolean unify(JetType withParameters, JetType expected) {
// T -> how T is used
final Map<TypeParameterDescriptor, Variance> parameters = new HashMap<TypeParameterDescriptor, Variance>();
Function1<TypeParameterUsage, Unit> processor = new Function1<TypeParameterUsage, Unit>() {
@Override
public Unit invoke(TypeParameterUsage parameterUsage) {
Variance howTheTypeIsUsedBefore = parameters.get(parameterUsage.typeParameterDescriptor);
if (howTheTypeIsUsedBefore == null) {
howTheTypeIsUsedBefore = Variance.INVARIANT;
}
parameters.put(parameterUsage.typeParameterDescriptor,
parameterUsage.howTheTypeParameterIsUsed.superpose(howTheTypeIsUsedBefore));
return Unit.INSTANCE$;
}
};
processAllTypeParameters(withParameters, Variance.INVARIANT, processor);
processAllTypeParameters(expected, Variance.INVARIANT, processor);
ConstraintSystemImpl constraintSystem = new ConstraintSystemImpl();
registerTypeVariables(constraintSystem, parameters);
constraintSystem.addSubtypeConstraint(withParameters, expected, SPECIAL.position());
return constraintSystem.getStatus().isSuccessful();
}
private static void processAllTypeParameters(JetType type, Variance howThisTypeIsUsed, Function1<TypeParameterUsage, Unit> result) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) {
result.invoke(new TypeParameterUsage((TypeParameterDescriptor) descriptor, howThisTypeIsUsed));
}
for (TypeProjection projection : type.getArguments()) {
if (projection.isStarProjection()) continue;
processAllTypeParameters(projection.getType(), projection.getProjectionKind(), result);
}
}
}
public static boolean canHaveSubtypes(JetTypeChecker typeChecker, @NotNull JetType type) {
if (type.isMarkedNullable()) {
return true;
@@ -196,7 +196,7 @@ private fun JetNamedDeclaration.guessType(context: BindingContext): Array<JetTyp
if (expectedTypes.isEmpty() || expectedTypes.any { expectedType -> ErrorUtils.containsErrorType(expectedType) }) {
return arrayOf()
}
val theType = TypeUtils.intersect(JetTypeChecker.DEFAULT, expectedTypes)
val theType = TypeIntersector.intersect(JetTypeChecker.DEFAULT, expectedTypes)
if (theType != null) {
return arrayOf(theType)
}
@@ -16,36 +16,32 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import com.intellij.psi.JavaPsiFacade
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.guessTypes
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.noSubstitutions
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix
import org.jetbrains.kotlin.idea.quickfix.DelegatingIntentionAction
import org.jetbrains.kotlin.idea.JetBundle
import com.intellij.psi.PsiPackage
import org.jetbrains.kotlin.idea.core.refactoring.canRefactor
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPackage
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.refactoring.canRefactor
import org.jetbrains.kotlin.idea.quickfix.DelegatingIntentionAction
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.guessTypes
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.noSubstitutions
import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.descriptors.ClassKind as ClassDescriptorKind
private fun String.checkClassName(): Boolean = isNotEmpty() && Character.isUpperCase(first())
@@ -519,7 +519,7 @@ private class MutableParameter(
private val defaultType: JetType by lazy {
writable = false
TypeUtils.intersect(JetTypeChecker.DEFAULT, defaultTypes)!!
TypeIntersector.intersect(JetTypeChecker.DEFAULT, defaultTypes)!!
}
private val parameterTypeCandidates: List<JetType> by lazy {