diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt index 9e393f6fe17..0ea4c15fc43 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt @@ -48,7 +48,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsFileScope import org.jetbrains.kotlin.resolve.source.toSourceElement -import org.jetbrains.kotlin.types.ErrorUtils +import org.jetbrains.kotlin.types.FunctionPlaceholders import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils @@ -268,7 +268,8 @@ public fun getResolvedCallableReferenceShapeType( context: ResolutionContext<*>, expectedTypeUnknown: Boolean, reflectionTypes: ReflectionTypes, - builtIns: KotlinBuiltIns + builtIns: KotlinBuiltIns, + functionPlaceholders: FunctionPlaceholders ): JetType? = when { overloadResolutionResults == null -> @@ -278,7 +279,7 @@ public fun getResolvedCallableReferenceShapeType( createReflectionTypeForCallableDescriptor(call.getResultingDescriptor(), context, reflectionTypes, reference) } expectedTypeUnknown /* && overload resolution was ambiguous */ -> - ErrorUtils.createFunctionPlaceholderType(emptyList(), false) + functionPlaceholders.createFunctionPlaceholderType(emptyList(), false) else -> builtIns.getFunctionType(Annotations.EMPTY, null, emptyList(), TypeUtils.DONT_CARE) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java index 5d39c649b6a..d1f3fcfb78a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java @@ -44,7 +44,8 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; -import org.jetbrains.kotlin.types.ErrorUtils; +import org.jetbrains.kotlin.types.FunctionPlaceholders; +import org.jetbrains.kotlin.types.FunctionPlaceholdersKt; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.TypeUtils; import org.jetbrains.kotlin.types.checker.JetTypeChecker; @@ -72,6 +73,7 @@ public class ArgumentTypeResolver { @NotNull private final KotlinBuiltIns builtIns; @NotNull private final ReflectionTypes reflectionTypes; @NotNull private final ConstantExpressionEvaluator constantExpressionEvaluator; + @NotNull private final FunctionPlaceholders functionPlaceholders; public ArgumentTypeResolver( @NotNull TypeResolver typeResolver, @@ -79,7 +81,8 @@ public class ArgumentTypeResolver { @NotNull ExpressionTypingServices expressionTypingServices, @NotNull KotlinBuiltIns builtIns, @NotNull ReflectionTypes reflectionTypes, - @NotNull ConstantExpressionEvaluator constantExpressionEvaluator + @NotNull ConstantExpressionEvaluator constantExpressionEvaluator, + @NotNull FunctionPlaceholders functionPlaceholders ) { this.typeResolver = typeResolver; this.callResolver = callResolver; @@ -87,13 +90,14 @@ public class ArgumentTypeResolver { this.builtIns = builtIns; this.reflectionTypes = reflectionTypes; this.constantExpressionEvaluator = constantExpressionEvaluator; + this.functionPlaceholders = functionPlaceholders; } public static boolean isSubtypeOfForArgumentType( @NotNull JetType actualType, @NotNull JetType expectedType ) { - if (ErrorUtils.isFunctionPlaceholder(actualType)) { + if (FunctionPlaceholdersKt.isFunctionPlaceholder(actualType)) { JetType functionType = createTypeForFunctionPlaceholder(actualType, expectedType); return JetTypeChecker.DEFAULT.isSubtypeOf(functionType, expectedType); } @@ -247,7 +251,7 @@ public class ArgumentTypeResolver { callResolver); return CallableReferencesPackage.getResolvedCallableReferenceShapeType( callableReferenceExpression, overloadResolutionResults, context, expectedTypeIsUnknown, - reflectionTypes, builtIns); + reflectionTypes, builtIns, functionPlaceholders); } @NotNull @@ -274,7 +278,8 @@ public class ArgumentTypeResolver { boolean isFunctionLiteral = function instanceof JetFunctionLiteral; if (function.getValueParameterList() == null && isFunctionLiteral) { return expectedTypeIsUnknown - ? ErrorUtils.createFunctionPlaceholderType(Collections.emptyList(), /* hasDeclaredArguments = */ false) + ? functionPlaceholders + .createFunctionPlaceholderType(Collections.emptyList(), /* hasDeclaredArguments = */ false) : builtIns.getFunctionType(Annotations.EMPTY, null, Collections.emptyList(), DONT_CARE); } List valueParameters = function.getValueParameters(); @@ -289,7 +294,7 @@ public class ArgumentTypeResolver { JetType receiverType = resolveTypeRefWithDefault(function.getReceiverTypeReference(), scope, temporaryTrace, null); return expectedTypeIsUnknown && isFunctionLiteral - ? ErrorUtils.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true) + ? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true) : builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameterTypes, returnType); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt index 557cf6a2a17..153fd8e5203 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt @@ -49,10 +49,7 @@ import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue -import org.jetbrains.kotlin.types.ErrorUtils -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.noExpectedType import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils @@ -62,7 +59,6 @@ public class CandidateResolver( private val argumentTypeResolver: ArgumentTypeResolver, private val genericCandidateResolver: GenericCandidateResolver, private val reflectionTypes: ReflectionTypes, - private val modifiersChecker: ModifiersChecker, private val additionalTypeCheckers: Iterable, private val smartCastManager: SmartCastManager ){ @@ -339,7 +335,7 @@ public class CandidateResolver( var matchStatus = ArgumentMatchStatus.SUCCESS var resultingType: JetType? = type - if (type == null || (type.isError() && !ErrorUtils.isFunctionPlaceholder(type))) { + if (type == null || (type.isError() && !type.isFunctionPlaceholder)) { matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE } else if (!noExpectedType(expectedType)) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index bdb4cca00e3..75d095d25f6 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.ErrorUtils.FunctionPlaceholderTypeConstructor import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure @@ -269,7 +268,7 @@ public class ConstraintSystemImpl : ConstraintSystem { return true } - if (type == null || (type.isError() && !ErrorUtils.isFunctionPlaceholder(type))) { + if (type == null || (type.isError() && !type.isFunctionPlaceholder)) { errors.add(ErrorInConstrainingType(constraintPosition)) return true } @@ -287,13 +286,13 @@ public class ConstraintSystemImpl : ConstraintSystem { if (isErrorOrSpecialType(subType, constraintPosition) || isErrorOrSpecialType(superType, constraintPosition)) return if (subType == null || superType == null) return - assert(!ErrorUtils.isFunctionPlaceholder(superType)) { + assert(!superType.isFunctionPlaceholder) { "The type for " + constraintPosition + " shouldn't be a placeholder for function type" } // function literal { x -> ... } goes without declaring receiver type // and can be considered as extension function if one is expected - val newSubType = if (constraintKind == SUB_TYPE && ErrorUtils.isFunctionPlaceholder(subType)) { + val newSubType = if (constraintKind == SUB_TYPE && subType.isFunctionPlaceholder) { if (isMyTypeVariable(superType)) { // the constraint binds type parameter and a function type, // we don't add it without knowing whether it's a function type or an extension function type @@ -503,12 +502,12 @@ fun createTypeForFunctionPlaceholder( functionPlaceholder: JetType, expectedType: JetType ): JetType { - if (!ErrorUtils.isFunctionPlaceholder(functionPlaceholder)) return functionPlaceholder + if (!functionPlaceholder.isFunctionPlaceholder) return functionPlaceholder val functionPlaceholderTypeConstructor = functionPlaceholder.getConstructor() as FunctionPlaceholderTypeConstructor val isExtension = KotlinBuiltIns.isExtensionFunctionType(expectedType) - val newArgumentTypes = if (!functionPlaceholderTypeConstructor.hasDeclaredArguments()) { + val newArgumentTypes = if (!functionPlaceholderTypeConstructor.hasDeclaredArguments) { val typeParamSize = expectedType.getConstructor().getParameters().size() // the first parameter is receiver (if present), the last one is return type, // the remaining are function arguments @@ -518,7 +517,7 @@ fun createTypeForFunctionPlaceholder( result } else { - functionPlaceholderTypeConstructor.getArgumentTypes() + functionPlaceholderTypeConstructor.argumentTypes } val receiverType = if (isExtension) DONT_CARE else null return functionPlaceholder.builtIns.getFunctionType(Annotations.EMPTY, receiverType, newArgumentTypes, DONT_CARE) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index 13d4b31f3db..16aeea58621 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -513,7 +513,12 @@ public class ErrorUtils { @NotNull public static JetType createErrorTypeWithCustomDebugName(@NotNull String debugName) { - return new ErrorTypeImpl(createErrorTypeConstructorWithCustomDebugName(debugName), createErrorScope(debugName)); + return createErrorTypeWithCustomConstructor(debugName, createErrorTypeConstructorWithCustomDebugName(debugName)); + } + + @NotNull + public static JetType createErrorTypeWithCustomConstructor(@NotNull String debugName, @NotNull TypeConstructor typeConstructor) { + return new ErrorTypeImpl(typeConstructor, createErrorScope(debugName)); } @NotNull @@ -527,7 +532,7 @@ public class ErrorUtils { } @NotNull - private static TypeConstructor createErrorTypeConstructorWithCustomDebugName(@NotNull String debugName) { + public static TypeConstructor createErrorTypeConstructorWithCustomDebugName(@NotNull String debugName) { return createErrorTypeConstructorWithCustomDebugName(debugName, ERROR_CLASS); } @@ -709,9 +714,8 @@ public class ErrorUtils { @NotNull public static JetType createUninferredParameterType(@NotNull TypeParameterDescriptor typeParameterDescriptor) { - return new ErrorTypeImpl( - new UninferredParameterTypeConstructor(typeParameterDescriptor), - createErrorScope("Scope for error type for not inferred parameter: " + typeParameterDescriptor.getName())); + return createErrorTypeWithCustomConstructor("Scope for error type for not inferred parameter: " + typeParameterDescriptor.getName(), + new UninferredParameterTypeConstructor(typeParameterDescriptor)); } public static class UninferredParameterTypeConstructor implements TypeConstructor { @@ -769,82 +773,5 @@ public class ErrorUtils { } } - public static boolean isFunctionPlaceholder(@Nullable JetType type) { - return type != null && type.getConstructor() instanceof FunctionPlaceholderTypeConstructor; - } - - @NotNull - public static JetType createFunctionPlaceholderType(@NotNull List argumentTypes, boolean hasDeclaredArguments) { - return new ErrorTypeImpl( - new FunctionPlaceholderTypeConstructor(argumentTypes, hasDeclaredArguments), - createErrorScope("Scope for function placeholder type")); - } - - public static class FunctionPlaceholderTypeConstructor implements TypeConstructor { - private final TypeConstructor errorTypeConstructor; - private final List argumentTypes; - private final boolean hasDeclaredArguments; - - private FunctionPlaceholderTypeConstructor(@NotNull List argumentTypes, boolean hasDeclaredArguments) { - errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE" + argumentTypes); - this.argumentTypes = argumentTypes; - this.hasDeclaredArguments = hasDeclaredArguments; - } - - @NotNull - public List getArgumentTypes() { - return argumentTypes; - } - - public boolean hasDeclaredArguments() { - return hasDeclaredArguments; - } - - @NotNull - @Override - public List getParameters() { - return errorTypeConstructor.getParameters(); - } - - @NotNull - @Override - public Collection getSupertypes() { - return errorTypeConstructor.getSupertypes(); - } - - @Override - public boolean isFinal() { - return errorTypeConstructor.isFinal(); - } - - @Override - public boolean isDenotable() { - return errorTypeConstructor.isDenotable(); - } - - @Nullable - @Override - public ClassifierDescriptor getDeclarationDescriptor() { - return errorTypeConstructor.getDeclarationDescriptor(); - } - - @NotNull - @Override - public Annotations getAnnotations() { - return errorTypeConstructor.getAnnotations(); - } - - @Override - public String toString() { - return errorTypeConstructor.toString(); - } - - @NotNull - @Override - public KotlinBuiltIns getBuiltIns() { - return errorTypeConstructor.getBuiltIns(); - } - } - private ErrorUtils() {} } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/FunctionPlaceholders.kt b/core/descriptors/src/org/jetbrains/kotlin/types/FunctionPlaceholders.kt new file mode 100644 index 00000000000..864bf1c5345 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/types/FunctionPlaceholders.kt @@ -0,0 +1,79 @@ +/* + * 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 org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.annotations.Annotations + +class FunctionPlaceholders(private val builtIns: KotlinBuiltIns) { + fun createFunctionPlaceholderType( + argumentTypes: List, + hasDeclaredArguments: Boolean + ): JetType { + return ErrorUtils.createErrorTypeWithCustomConstructor( + "function placeholder type", + FunctionPlaceholderTypeConstructor(argumentTypes, hasDeclaredArguments, builtIns) + ) + } +} + +val JetType?.isFunctionPlaceholder: Boolean + get() { + return this != null && constructor is FunctionPlaceholderTypeConstructor + } + +class FunctionPlaceholderTypeConstructor( + val argumentTypes: List, + val hasDeclaredArguments: Boolean, + private val kotlinBuiltIns: KotlinBuiltIns +) : TypeConstructor { + private val errorTypeConstructor: TypeConstructor = ErrorUtils.createErrorTypeConstructorWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE" + argumentTypes) + + override fun getParameters(): List { + return errorTypeConstructor.parameters + } + + override fun getSupertypes(): Collection { + return errorTypeConstructor.supertypes + } + + override fun isFinal(): Boolean { + return errorTypeConstructor.isFinal + } + + override fun isDenotable(): Boolean { + return errorTypeConstructor.isDenotable + } + + override fun getDeclarationDescriptor(): ClassifierDescriptor? { + return errorTypeConstructor.declarationDescriptor + } + + override fun getAnnotations(): Annotations { + return errorTypeConstructor.annotations + } + + override fun toString(): String { + return errorTypeConstructor.toString() + } + + override fun getBuiltIns(): KotlinBuiltIns { + return kotlinBuiltIns + } +}