Move static function type utilities from KotlinBuiltIns to functionTypes.kt

This commit is contained in:
Alexander Udalov
2016-03-14 13:12:04 +03:00
parent 569a5888ff
commit fd344561fc
39 changed files with 248 additions and 224 deletions
@@ -24,6 +24,7 @@ import kotlin.Unit;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor; import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
@@ -443,7 +444,7 @@ public class BodyResolver {
if (classDescriptor != null) { if (classDescriptor != null) {
if (ErrorUtils.isError(classDescriptor)) continue; if (ErrorUtils.isError(classDescriptor)) continue;
if (KotlinBuiltIns.isExactExtensionFunctionType(supertype)) { if (FunctionTypesKt.isExactExtensionFunctionType(supertype)) {
trace.report(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE.on(typeReference)); trace.report(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE.on(typeReference));
} }
@@ -27,6 +27,7 @@ import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter; import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter;
@@ -611,7 +612,7 @@ public class DescriptorResolver {
if (DynamicTypesKt.isDynamic(upperBoundType)) { if (DynamicTypesKt.isDynamic(upperBoundType)) {
trace.report(DYNAMIC_UPPER_BOUND.on(upperBound)); trace.report(DYNAMIC_UPPER_BOUND.on(upperBound));
} }
if (KotlinBuiltIns.isExactExtensionFunctionType(upperBoundType)) { if (FunctionTypesKt.isExactExtensionFunctionType(upperBoundType)) {
trace.report(UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE.on(upperBound)); trace.report(UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE.on(upperBound));
} }
} }
@@ -17,6 +17,9 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getValueParametersFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl
@@ -217,12 +220,12 @@ class FunctionDescriptorResolver(
) )
} }
private fun KotlinType.functionTypeExpected() = !TypeUtils.noExpectedType(this) && KotlinBuiltIns.isFunctionOrExtensionFunctionType(this) private fun KotlinType.functionTypeExpected() = !TypeUtils.noExpectedType(this) && isFunctionOrExtensionFunctionType
private fun KotlinType.getReceiverType(): KotlinType? = private fun KotlinType.getReceiverType(): KotlinType? =
if (functionTypeExpected()) KotlinBuiltIns.getReceiverType(this) else null if (functionTypeExpected()) getReceiverTypeFromFunctionType(this) else null
private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? = private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? =
if (functionTypeExpected()) KotlinBuiltIns.getValueParameters(owner, this) else null if (functionTypeExpected()) getValueParametersFromFunctionType(owner, this) else null
fun resolvePrimaryConstructorDescriptor( fun resolvePrimaryConstructorDescriptor(
scope: LexicalScope, scope: LexicalScope,
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
@@ -27,16 +27,14 @@ import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.KtParameter
object InlineParameterChecker : DeclarationChecker { object InlineParameterChecker : DeclarationChecker {
override fun check(declaration: KtDeclaration, override fun check(
descriptor: DeclarationDescriptor, declaration: KtDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink, bindingContext: BindingContext
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) { ) {
if (declaration is KtFunction) { if (declaration is KtFunction) {
val inline = declaration.hasModifier(KtTokens.INLINE_KEYWORD) val inline = declaration.hasModifier(KtTokens.INLINE_KEYWORD)
for (parameter in declaration.valueParameters) { for (parameter in declaration.valueParameters) {
val parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, parameter) val parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, parameter)
if (!inline || (parameterDescriptor != null && !KotlinBuiltIns.isFunctionOrExtensionFunctionType(parameterDescriptor.type))) { if (!inline || (parameterDescriptor != null && !parameterDescriptor.type.isFunctionOrExtensionFunctionType)) {
parameter.reportIncorrectInline(KtTokens.NOINLINE_KEYWORD, diagnosticHolder) parameter.reportIncorrectInline(KtTokens.NOINLINE_KEYWORD, diagnosticHolder)
parameter.reportIncorrectInline(KtTokens.CROSSINLINE_KEYWORD, diagnosticHolder) parameter.reportIncorrectInline(KtTokens.CROSSINLINE_KEYWORD, diagnosticHolder)
} }
@@ -50,4 +48,4 @@ object InlineParameterChecker : DeclarationChecker {
diagnosticHolder.report(Errors.ILLEGAL_INLINE_PARAMETER_MODIFIER.on(modifier, modifierToken)) diagnosticHolder.report(Errors.ILLEGAL_INLINE_PARAMETER_MODIFIER.on(modifier, modifierToken))
} }
} }
} }
@@ -16,8 +16,7 @@
package org.jetbrains.kotlin.resolve.callableReferences package org.jetbrains.kotlin.resolve.callableReferences
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
@@ -211,11 +210,11 @@ private fun bindFunctionReference(expression: KtCallableReferenceExpression, typ
) )
functionDescriptor.initialize( functionDescriptor.initialize(
KotlinBuiltIns.getReceiverType(type), getReceiverTypeFromFunctionType(type),
null, null,
emptyList(), emptyList(),
KotlinBuiltIns.getValueParameters(functionDescriptor, type), getValueParametersFromFunctionType(functionDescriptor, type),
KotlinBuiltIns.getReturnTypeFromFunctionType(type), getReturnTypeFromFunctionType(type),
Modality.FINAL, Modality.FINAL,
Visibilities.PUBLIC Visibilities.PUBLIC
) )
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.resolve.calls
import com.google.common.collect.Lists import com.google.common.collect.Lists
import com.google.common.collect.Sets import com.google.common.collect.Sets
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.isExactExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER import org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER
@@ -276,12 +276,11 @@ class CandidateResolver(
private fun CallCandidateResolutionContext<*>.checkNonExtensionCalledWithReceiver() = checkAndReport { private fun CallCandidateResolutionContext<*>.checkNonExtensionCalledWithReceiver() = checkAndReport {
val call = candidateCall.call val call = candidateCall.call
if (call is CallTransformer.CallForImplicitInvoke && candidateCall.extensionReceiver != null if (call is CallTransformer.CallForImplicitInvoke &&
&& candidateCall.dispatchReceiver != null candidateCall.extensionReceiver != null &&
candidateCall.dispatchReceiver != null
) { ) {
if (call.dispatchReceiver == candidateCall.dispatchReceiver if (call.dispatchReceiver == candidateCall.dispatchReceiver && !call.dispatchReceiver.type.isExactExtensionFunctionType) {
&& !KotlinBuiltIns.isExactExtensionFunctionType(call.dispatchReceiver.type)
) {
tracing.nonExtensionFunctionCalledAsExtension(trace) tracing.nonExtensionFunctionCalledAsExtension(trace)
return@checkAndReport OTHER_ERROR return@checkAndReport OTHER_ERROR
} }
@@ -16,8 +16,8 @@
package org.jetbrains.kotlin.resolve.calls package org.jetbrains.kotlin.resolve.calls
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
@@ -238,11 +238,10 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
) = if (!TypeUtils.noExpectedType(context.expectedType) && ) = if (!TypeUtils.noExpectedType(context.expectedType) &&
ownerReturnType != null && ownerReturnType != null &&
TypeUtils.isTypeParameter(ownerReturnType) && TypeUtils.isTypeParameter(ownerReturnType) &&
KotlinBuiltIns.isFunctionOrExtensionFunctionType(literalExpectedType) && literalExpectedType.isFunctionOrExtensionFunctionType &&
getReturnTypeForCallable(literalExpectedType) == ownerReturnType) getReturnTypeForCallable(literalExpectedType) == ownerReturnType)
context.expectedType
context.expectedType else DONT_CARE
else DONT_CARE
private fun <D : CallableDescriptor> addConstraintForFunctionLiteralArgument( private fun <D : CallableDescriptor> addConstraintForFunctionLiteralArgument(
functionLiteral: KtFunction, functionLiteral: KtFunction,
@@ -259,8 +258,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) { if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) {
expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, false) expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, false)
} }
if (expectedType == null || !KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType) || if (expectedType == null || !expectedType.isFunctionOrExtensionFunctionType || hasUnknownFunctionParameter(expectedType)) {
hasUnknownFunctionParameter(expectedType)) {
return return
} }
val dataFlowInfoForArguments = context.candidateCall.dataFlowInfoForArguments val dataFlowInfoForArguments = context.candidateCall.dataFlowInfoForArguments
@@ -330,7 +328,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
return substitutedType return substitutedType
val shapeType = argumentTypeResolver.getShapeTypeOfCallableReference(callableReference, context, false) val shapeType = argumentTypeResolver.getShapeTypeOfCallableReference(callableReference, context, false)
if (shapeType != null && KotlinBuiltIns.isFunctionOrExtensionFunctionType(shapeType) && !hasUnknownFunctionParameter(shapeType)) if (shapeType != null && shapeType.isFunctionOrExtensionFunctionType && !hasUnknownFunctionParameter(shapeType))
return shapeType return shapeType
return null return null
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.KtToken; import org.jetbrains.kotlin.lexer.KtToken;
@@ -232,9 +232,10 @@ class InlineChecker implements CallChecker {
} }
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
boolean isInvoke = descriptor.getName().equals(OperatorNameConventions.INVOKE) && boolean isInvoke =
containingDeclaration instanceof ClassDescriptor && descriptor.getName().equals(OperatorNameConventions.INVOKE) &&
KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(((ClassDescriptor) containingDeclaration).getDefaultType()); containingDeclaration instanceof ClassDescriptor &&
FunctionTypesKt.isExactFunctionOrExtensionFunctionType(((ClassDescriptor) containingDeclaration).getDefaultType());
return isInvoke || InlineUtil.isInline(descriptor); return isInvoke || InlineUtil.isInline(descriptor);
} }
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.checkers package org.jetbrains.kotlin.resolve.calls.checkers
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExactExtensionFunctionType
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
@@ -29,7 +29,8 @@ class InvokeConventionChecker : CallChecker {
if (resolvedCall is VariableAsFunctionResolvedCallImpl) { if (resolvedCall is VariableAsFunctionResolvedCallImpl) {
val functionCall = resolvedCall.functionCall val functionCall = resolvedCall.functionCall
val variableCall = resolvedCall.variableCall val variableCall = resolvedCall.variableCall
if (functionCall.dispatchReceiver != null && functionCall.extensionReceiver != null && KotlinBuiltIns.isExactExtensionFunctionType(variableCall.resultingDescriptor.type)) { if (functionCall.dispatchReceiver != null && functionCall.extensionReceiver != null &&
variableCall.resultingDescriptor.type.isExactExtensionFunctionType) {
if (variableCall.dispatchReceiver is ExpressionReceiver || variableCall.extensionReceiver is ExpressionReceiver) { if (variableCall.dispatchReceiver is ExpressionReceiver || variableCall.extensionReceiver is ExpressionReceiver) {
val callElement = variableCall.call.callElement val callElement = variableCall.call.callElement
context.trace.report(Errors.INVOKE_ON_EXTENSION_FUNCTION_WITH_EXPLICIT_DISPATCH_RECEIVER.on(callElement)) context.trace.report(Errors.INVOKE_ON_EXTENSION_FUNCTION_WITH_EXPLICIT_DISPATCH_RECEIVER.on(callElement))
@@ -37,5 +38,4 @@ class InvokeConventionChecker : CallChecker {
} }
} }
} }
}
}
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.inference package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL
@@ -419,7 +419,7 @@ internal fun createTypeForFunctionPlaceholder(
val functionPlaceholderTypeConstructor = functionPlaceholder.constructor as FunctionPlaceholderTypeConstructor val functionPlaceholderTypeConstructor = functionPlaceholder.constructor as FunctionPlaceholderTypeConstructor
val isExtension = KotlinBuiltIns.isExtensionFunctionType(expectedType) val isExtension = expectedType.isExtensionFunctionType
val newArgumentTypes = if (!functionPlaceholderTypeConstructor.hasDeclaredArguments) { val newArgumentTypes = if (!functionPlaceholderTypeConstructor.hasDeclaredArguments) {
val typeParamSize = expectedType.constructor.parameters.size val typeParamSize = expectedType.constructor.parameters.size
// the first parameter is receiver (if present), the last one is return type, // the first parameter is receiver (if present), the last one is return type,
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.resolve.calls.tasks;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.psi.Call; import org.jetbrains.kotlin.psi.Call;
import org.jetbrains.kotlin.psi.KtExpression; import org.jetbrains.kotlin.psi.KtExpression;
@@ -87,7 +87,7 @@ public class TracingStrategyForInvoke extends AbstractTracingStrategy {
} }
private void functionExpectedOrNoReceiverAllowed(BindingTrace trace) { private void functionExpectedOrNoReceiverAllowed(BindingTrace trace) {
if (KotlinBuiltIns.isFunctionType(calleeType)) { if (FunctionTypesKt.isFunctionType(calleeType)) {
trace.report(NO_RECEIVER_ALLOWED.on(reference)); trace.report(NO_RECEIVER_ALLOWED.on(reference));
} }
else { else {
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
@@ -35,7 +36,7 @@ public class InlineUtil {
public static boolean isInlineLambdaParameter(@NotNull ParameterDescriptor valueParameterOrReceiver) { public static boolean isInlineLambdaParameter(@NotNull ParameterDescriptor valueParameterOrReceiver) {
return !(valueParameterOrReceiver instanceof ValueParameterDescriptor return !(valueParameterOrReceiver instanceof ValueParameterDescriptor
&& ((ValueParameterDescriptor) valueParameterOrReceiver).isNoinline()) && && ((ValueParameterDescriptor) valueParameterOrReceiver).isNoinline()) &&
KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(valueParameterOrReceiver.getOriginal().getType()); FunctionTypesKt.isExactFunctionOrExtensionFunctionType(valueParameterOrReceiver.getOriginal().getType());
} }
public static boolean isInline(@Nullable DeclarationDescriptor descriptor) { public static boolean isInline(@Nullable DeclarationDescriptor descriptor) {
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.types.expressions
import com.google.common.collect.Lists import com.google.common.collect.Lists
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -142,7 +144,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
if (!expression.functionLiteral.hasBody()) return null if (!expression.functionLiteral.hasBody()) return null
val expectedType = context.expectedType val expectedType = context.expectedType
val functionTypeExpected = !noExpectedType(expectedType) && KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType) val functionTypeExpected = !noExpectedType(expectedType) && expectedType.isFunctionOrExtensionFunctionType
val functionDescriptor = createFunctionLiteralDescriptor(expression, context) val functionDescriptor = createFunctionLiteralDescriptor(expression, context)
expression.valueParameters.forEach { expression.valueParameters.forEach {
@@ -191,7 +193,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
functionDescriptor: SimpleFunctionDescriptorImpl, functionDescriptor: SimpleFunctionDescriptorImpl,
functionTypeExpected: Boolean functionTypeExpected: Boolean
): KotlinType { ): KotlinType {
val expectedReturnType = if (functionTypeExpected) KotlinBuiltIns.getReturnTypeFromFunctionType(context.expectedType) else null val expectedReturnType = if (functionTypeExpected) getReturnTypeFromFunctionType(context.expectedType) else null
val returnType = computeUnsafeReturnType(expression, context, functionDescriptor, expectedReturnType); val returnType = computeUnsafeReturnType(expression, context, functionDescriptor, expectedReturnType);
if (!expression.functionLiteral.hasDeclaredReturnType() && functionTypeExpected) { if (!expression.functionLiteral.hasDeclaredReturnType() && functionTypeExpected) {
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.tower package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExactExtensionFunctionType
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
@@ -141,7 +141,7 @@ private class InvokeExtensionScopeTowerProcessor<C>(
private fun ScopeTower.getExtensionInvokeCandidateDescriptor( private fun ScopeTower.getExtensionInvokeCandidateDescriptor(
extensionFunctionReceiver: ReceiverValue extensionFunctionReceiver: ReceiverValue
): CandidateWithBoundDispatchReceiver<FunctionDescriptor>? { ): CandidateWithBoundDispatchReceiver<FunctionDescriptor>? {
if (!KotlinBuiltIns.isExactExtensionFunctionType(extensionFunctionReceiver.type)) return null if (!extensionFunctionReceiver.type.isExactExtensionFunctionType) return null
val invokeDescriptor = extensionFunctionReceiver.type.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, location).single() val invokeDescriptor = extensionFunctionReceiver.type.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, location).single()
val synthesizedInvoke = createSynthesizedInvokes(listOf(invokeDescriptor)).single() val synthesizedInvoke = createSynthesizedInvokes(listOf(invokeDescriptor)).single()
@@ -815,10 +815,6 @@ public abstract class KotlinBuiltIns {
Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap(), SourceElement.NO_SOURCE); Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap(), SourceElement.NO_SOURCE);
} }
private static boolean isTypeAnnotatedWithExtension(@NotNull KotlinType type) {
return type.getAnnotations().findAnnotation(FQ_NAMES.extensionFunctionType) != null;
}
@NotNull @NotNull
public KotlinType getFunctionType( public KotlinType getFunctionType(
@NotNull Annotations annotations, @NotNull Annotations annotations,
@@ -892,111 +888,6 @@ public abstract class KotlinBuiltIns {
return getPrimitiveTypeByFqName(getFqName(descriptor)) != null; return getPrimitiveTypeByFqName(getFqName(descriptor)) != null;
} }
// Functions
public static boolean isFunctionOrExtensionFunctionType(@NotNull KotlinType type) {
return isFunctionType(type) || isExtensionFunctionType(type);
}
public static boolean isFunctionType(@NotNull KotlinType type) {
if (isExactFunctionType(type)) return true;
for (KotlinType superType : type.getConstructor().getSupertypes()) {
if (isFunctionType(superType)) return true;
}
return false;
}
public static boolean isExtensionFunctionType(@NotNull KotlinType type) {
if (isExactExtensionFunctionType(type)) return true;
for (KotlinType superType : type.getConstructor().getSupertypes()) {
if (isExtensionFunctionType(superType)) return true;
}
return false;
}
public static boolean isExactFunctionOrExtensionFunctionType(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
return descriptor != null && isNumberedFunctionClassFqName(getFqName(descriptor));
}
public static boolean isExactFunctionType(@NotNull KotlinType type) {
return isExactFunctionOrExtensionFunctionType(type) && !isTypeAnnotatedWithExtension(type);
}
public static boolean isExactExtensionFunctionType(@NotNull KotlinType type) {
return isExactFunctionOrExtensionFunctionType(type) && isTypeAnnotatedWithExtension(type);
}
/**
* @return true if this is an FQ name of a fictitious class representing the function type,
* e.g. kotlin.Function1 (but NOT kotlin.reflect.KFunction1)
*/
public static boolean isNumberedFunctionClassFqName(@NotNull FqNameUnsafe fqName) {
List<Name> segments = fqName.pathSegments();
if (segments.size() != 2) return false;
if (!BUILT_INS_PACKAGE_NAME.equals(first(segments))) return false;
String shortName = last(segments).asString();
return BuiltInFictitiousFunctionClassFactory.isFunctionClassName(shortName, BUILT_INS_PACKAGE_FQ_NAME);
}
@Nullable
public static KotlinType getReceiverType(@NotNull KotlinType type) {
assert isFunctionOrExtensionFunctionType(type) : type;
if (isExtensionFunctionType(type)) {
// TODO: this is incorrect when a class extends from an extension function and swaps type arguments
return type.getArguments().get(0).getType();
}
return null;
}
@NotNull
public static List<ValueParameterDescriptor> getValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull KotlinType type) {
assert isFunctionOrExtensionFunctionType(type);
List<TypeProjection> parameterTypes = getParameterTypeProjectionsFromFunctionType(type);
List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(parameterTypes.size());
for (int i = 0; i < parameterTypes.size(); i++) {
TypeProjection parameterType = parameterTypes.get(i);
ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
functionDescriptor, null, i, Annotations.Companion.getEMPTY(),
Name.identifier("p" + (i + 1)), parameterType.getType(),
/* declaresDefaultValue = */ false,
/* isCrossinline = */ false,
/* isNoinline = */ false,
null, SourceElement.NO_SOURCE
);
valueParameters.add(valueParameterDescriptor);
}
return valueParameters;
}
@NotNull
public static KotlinType getReturnTypeFromFunctionType(@NotNull KotlinType type) {
assert isFunctionOrExtensionFunctionType(type);
List<TypeProjection> arguments = type.getArguments();
return arguments.get(arguments.size() - 1).getType();
}
@NotNull
public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType(@NotNull KotlinType type) {
assert isFunctionOrExtensionFunctionType(type);
List<TypeProjection> arguments = type.getArguments();
int first = isExtensionFunctionType(type) ? 1 : 0;
int last = arguments.size() - 2;
// TODO: fix bugs associated with this here and in neighboring methods, see KT-9820
assert first <= last + 1 : "Not an exact function type: " + type;
List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1);
for (int i = first; i <= last; i++) {
parameterTypes.add(arguments.get(i));
}
return parameterTypes;
}
private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
return descriptor instanceof ClassDescriptor && classFqNameEquals(descriptor, fqName); return descriptor instanceof ClassDescriptor && classFqNameEquals(descriptor, fqName);
@@ -117,7 +117,7 @@ class ReflectionTypes(private val module: ModuleDescriptor) {
} }
fun isCallableType(type: KotlinType): Boolean = fun isCallableType(type: KotlinType): Boolean =
KotlinBuiltIns.isFunctionOrExtensionFunctionType(type) || isKCallableType(type) type.isFunctionOrExtensionFunctionType || isKCallableType(type)
private fun isKCallableType(type: KotlinType): Boolean = private fun isKCallableType(type: KotlinType): Boolean =
isExactKCallableType(type) || isExactKCallableType(type) ||
@@ -0,0 +1,110 @@
/*
* Copyright 2010-2016 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.builtins
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection
import java.util.*
val KotlinType.isFunctionOrExtensionFunctionType: Boolean
get() = isFunctionType || isExtensionFunctionType
val KotlinType.isFunctionType: Boolean
get() = isExactFunctionType || constructor.supertypes.any(KotlinType::isFunctionType)
val KotlinType.isExtensionFunctionType: Boolean
get() = isExactExtensionFunctionType || constructor.supertypes.any(KotlinType::isExtensionFunctionType)
val KotlinType.isExactFunctionOrExtensionFunctionType: Boolean
get() {
val descriptor = constructor.declarationDescriptor
return descriptor != null && isNumberedFunctionClassFqName(descriptor.fqNameUnsafe)
}
val KotlinType.isExactFunctionType: Boolean
get() = isExactFunctionOrExtensionFunctionType && !isTypeAnnotatedWithExtension
val KotlinType.isExactExtensionFunctionType: Boolean
get() = isExactFunctionOrExtensionFunctionType && isTypeAnnotatedWithExtension
private val KotlinType.isTypeAnnotatedWithExtension: Boolean
get() = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.extensionFunctionType) != null
/**
* @return true if this is an FQ name of a fictitious class representing the function type,
* e.g. kotlin.Function1 (but NOT kotlin.reflect.KFunction1)
*/
fun isNumberedFunctionClassFqName(fqName: FqNameUnsafe): Boolean {
val segments = fqName.pathSegments()
if (segments.size != 2) return false
if (KotlinBuiltIns.BUILT_INS_PACKAGE_NAME != segments.first()) return false
val shortName = segments.last().asString()
return BuiltInFictitiousFunctionClassFactory.isFunctionClassName(shortName, KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)
}
fun getReceiverTypeFromFunctionType(type: KotlinType): KotlinType? {
assert(type.isFunctionOrExtensionFunctionType) { type }
if (type.isExtensionFunctionType) {
// TODO: this is incorrect when a class extends from an extension function and swaps type arguments
return type.arguments[0].type
}
return null
}
fun getValueParametersFromFunctionType(functionDescriptor: FunctionDescriptor, type: KotlinType): List<ValueParameterDescriptor> {
assert(type.isFunctionOrExtensionFunctionType) { type }
return getParameterTypeProjectionsFromFunctionType(type).mapIndexed { i, typeProjection ->
ValueParameterDescriptorImpl(
functionDescriptor, null, i, Annotations.EMPTY,
Name.identifier("p${i + 1}"), typeProjection.type,
/* declaresDefaultValue = */ false,
/* isCrossinline = */ false,
/* isNoinline = */ false,
null, SourceElement.NO_SOURCE
)
}
}
fun getReturnTypeFromFunctionType(type: KotlinType): KotlinType {
assert(type.isFunctionOrExtensionFunctionType) { type }
return type.arguments.last().type
}
fun getParameterTypeProjectionsFromFunctionType(type: KotlinType): List<TypeProjection> {
assert(type.isFunctionOrExtensionFunctionType) { type }
val arguments = type.arguments
val first = if (type.isExtensionFunctionType) 1 else 0
val last = arguments.size - 2
// TODO: fix bugs associated with this here and in neighboring methods, see KT-9820
assert(first <= last + 1) { "Not an exact function type: $type" }
val parameterTypes = ArrayList<TypeProjection>(last - first + 1)
for (i in first..last) {
parameterTypes.add(arguments[i])
}
return parameterTypes
}
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.renderer package org.jetbrains.kotlin.renderer
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
@@ -183,7 +183,7 @@ internal class DescriptorRendererImpl(
} }
private fun shouldRenderAsPrettyFunctionType(type: KotlinType): Boolean { private fun shouldRenderAsPrettyFunctionType(type: KotlinType): Boolean {
return KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type) && type.arguments.none { it.isStarProjection } return type.isExactFunctionOrExtensionFunctionType && type.arguments.none { it.isStarProjection }
} }
private fun renderFlexibleType(type: KotlinType): String { private fun renderFlexibleType(type: KotlinType): String {
@@ -305,7 +305,7 @@ internal class DescriptorRendererImpl(
val isNullable = type.isMarkedNullable val isNullable = type.isMarkedNullable
if (isNullable) append("(") if (isNullable) append("(")
val receiverType = KotlinBuiltIns.getReceiverType(type) val receiverType = getReceiverTypeFromFunctionType(type)
if (receiverType != null) { if (receiverType != null) {
val surroundReceiver = shouldRenderAsPrettyFunctionType(receiverType) && !receiverType.isMarkedNullable val surroundReceiver = shouldRenderAsPrettyFunctionType(receiverType) && !receiverType.isMarkedNullable
if (surroundReceiver) { if (surroundReceiver) {
@@ -319,9 +319,9 @@ internal class DescriptorRendererImpl(
} }
append("(") append("(")
appendTypeProjections(KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(type), this) appendTypeProjections(getParameterTypeProjectionsFromFunctionType(type), this)
append(") ").append(arrow()).append(" ") append(") ").append(arrow()).append(" ")
append(renderNormalizedType(KotlinBuiltIns.getReturnTypeFromFunctionType(type))) append(renderNormalizedType(getReturnTypeFromFunctionType(type)))
if (isNullable) append(")?") if (isNullable) append(")?")
} }
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.stubs.StubElement import com.intellij.psi.stubs.StubElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isNumberedFunctionClassFqName
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.FlagsToModifiers.* import org.jetbrains.kotlin.idea.decompiler.stubBuilder.FlagsToModifiers.*
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
@@ -116,7 +117,7 @@ private class ClassClsStubBuilder(
val shortName = fqName.shortName().ref() val shortName = fqName.shortName().ref()
val superTypeRefs = supertypeIds.filterNot { val superTypeRefs = supertypeIds.filterNot {
//TODO: filtering function types should go away //TODO: filtering function types should go away
KotlinBuiltIns.isNumberedFunctionClassFqName(it.asSingleFqName().toUnsafe()) isNumberedFunctionClassFqName(it.asSingleFqName().toUnsafe())
}.map { it.shortClassName.ref() }.toTypedArray() }.map { it.shortClassName.ref() }.toTypedArray()
return when (classKind) { return when (classKind) {
ProtoBuf.Class.Kind.OBJECT, ProtoBuf.Class.Kind.COMPANION_OBJECT -> { ProtoBuf.Class.Kind.OBJECT, ProtoBuf.Class.Kind.COMPANION_OBJECT -> {
@@ -20,6 +20,7 @@ import com.google.protobuf.MessageLite
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.stubs.StubElement import com.intellij.psi.stubs.StubElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isNumberedFunctionClassFqName
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.ANNOTATIONS_COPIED_TO_TYPES import org.jetbrains.kotlin.load.java.ANNOTATIONS_COPIED_TO_TYPES
@@ -77,7 +78,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
} }
val classId = c.nameResolver.getClassId(type.className) val classId = c.nameResolver.getClassId(type.className)
val shouldBuildAsFunctionType = KotlinBuiltIns.isNumberedFunctionClassFqName(classId.asSingleFqName().toUnsafe()) val shouldBuildAsFunctionType = isNumberedFunctionClassFqName(classId.asSingleFqName().toUnsafe())
&& type.argumentList.none { it.projection == Projection.STAR } && type.argumentList.none { it.projection == Projection.STAR }
if (shouldBuildAsFunctionType) { if (shouldBuildAsFunctionType) {
val extension = annotations.any { annotation -> val extension = annotations.any { annotation ->
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.idea.highlighter;
import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
@@ -74,7 +74,7 @@ public class FunctionsHighlightingVisitor extends AfterAnalysisHighlightingVisit
DeclarationDescriptor container = calleeDescriptor.getContainingDeclaration(); DeclarationDescriptor container = calleeDescriptor.getContainingDeclaration();
boolean containedInFunctionClassOrSubclass = boolean containedInFunctionClassOrSubclass =
container instanceof ClassDescriptor && container instanceof ClassDescriptor &&
KotlinBuiltIns.isFunctionOrExtensionFunctionType(((ClassDescriptor) container).getDefaultType()); FunctionTypesKt.isFunctionOrExtensionFunctionType(((ClassDescriptor) container).getDefaultType());
NameHighlighter.highlightName(holder, callee, containedInFunctionClassOrSubclass NameHighlighter.highlightName(holder, callee, containedInFunctionClassOrSubclass
? KotlinHighlightingColors.VARIABLE_AS_FUNCTION_CALL ? KotlinHighlightingColors.VARIABLE_AS_FUNCTION_CALL
: KotlinHighlightingColors.VARIABLE_AS_FUNCTION_LIKE_CALL); : KotlinHighlightingColors.VARIABLE_AS_FUNCTION_LIKE_CALL);
@@ -24,6 +24,7 @@ import com.intellij.patterns.ElementPattern
import com.intellij.patterns.StandardPatterns import com.intellij.patterns.StandardPatterns
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.KotlinIcons import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.completion.handlers.CastReceiverInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.CastReceiverInsertHandler
@@ -298,7 +299,7 @@ fun breakOrContinueExpressionItems(position: KtElement, breakOrContinue: String)
fun BasicLookupElementFactory.createLookupElementForType(type: KotlinType): LookupElement? { fun BasicLookupElementFactory.createLookupElementForType(type: KotlinType): LookupElement? {
if (type.isError) return null if (type.isError) return null
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type)) { if (type.isExactFunctionOrExtensionFunctionType) {
val text = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type) val text = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
val baseLookupElement = LookupElementBuilder.create(text).withIcon(KotlinIcons.LAMBDA) val baseLookupElement = LookupElementBuilder.create(text).withIcon(KotlinIcons.LAMBDA)
return BaseTypeLookupElement(type, baseLookupElement) return BaseTypeLookupElement(type, baseLookupElement)
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.completion
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.util.SmartList import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
@@ -39,7 +39,7 @@ class RealContextVariablesProvider(
) : ContextVariablesProvider { ) : ContextVariablesProvider {
val allFunctionTypeVariables by lazy { val allFunctionTypeVariables by lazy {
collectVariables().filter { KotlinBuiltIns.isFunctionOrExtensionFunctionType(it.type) } collectVariables().filter { it.type.isFunctionOrExtensionFunctionType }
} }
private fun collectVariables(): Collection<VariableDescriptor> { private fun collectVariables(): Collection<VariableDescriptor> {
@@ -68,4 +68,4 @@ class CollectRequiredTypesContextVariablesProvider : ContextVariablesProvider {
_requiredTypes.add(requiredType) _requiredTypes.add(requiredType)
return emptyList() return emptyList()
} }
} }
@@ -20,7 +20,7 @@ import com.intellij.codeInsight.completion.InsertionContext
import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementDecorator import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.codeInsight.lookup.LookupElementPresentation import com.intellij.codeInsight.lookup.LookupElementPresentation
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.util.CallType import org.jetbrains.kotlin.idea.util.CallType
@@ -45,7 +45,7 @@ class ExtensionFunctionTypeValueCompletion(
for (variable in variablesProvider.allFunctionTypeVariables) { for (variable in variablesProvider.allFunctionTypeVariables) {
val variableType = variable.type val variableType = variable.type
if (!KotlinBuiltIns.isExtensionFunctionType(variableType)) continue if (!variableType.isExtensionFunctionType) continue
val invokes = variableType.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_IDE) val invokes = variableType.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_IDE)
for (invoke in createSynthesizedInvokes(invokes)) { for (invoke in createSynthesizedInvokes(invokes)) {
@@ -96,4 +96,4 @@ class ExtensionFunctionTypeValueCompletion(
return results return results
} }
} }
@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.idea.completion
import com.intellij.codeInsight.completion.InsertHandler import com.intellij.codeInsight.completion.InsertHandler
import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.completion.handlers.* import org.jetbrains.kotlin.idea.completion.handlers.*
import org.jetbrains.kotlin.idea.core.ExpectedInfo import org.jetbrains.kotlin.idea.core.ExpectedInfo
@@ -51,8 +53,8 @@ class InsertHandlerProvider(
1 -> { 1 -> {
if (callType != CallType.SUPER_MEMBERS) { // for super call we don't suggest to generate "super.foo { ... }" (seems to be non-typical use) if (callType != CallType.SUPER_MEMBERS) { // for super call we don't suggest to generate "super.foo { ... }" (seems to be non-typical use)
val parameterType = parameters.single().type val parameterType = parameters.single().type
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(parameterType)) { if (parameterType.isExactFunctionOrExtensionFunctionType) {
val parameterCount = KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(parameterType).size val parameterCount = getParameterTypeProjectionsFromFunctionType(parameterType).size
if (parameterCount <= 1) { if (parameterCount <= 1) {
// otherwise additional item with lambda template is to be added // otherwise additional item with lambda template is to be added
return KotlinFunctionInsertHandler.Normal(needTypeArguments, inputValueArguments = false, lambdaInfo = GenerateLambdaInfo(parameterType, false)) return KotlinFunctionInsertHandler.Normal(needTypeArguments, inputValueArguments = false, lambdaInfo = GenerateLambdaInfo(parameterType, false))
@@ -96,9 +98,9 @@ class InsertHandlerProvider(
potentiallyInferred.add(descriptor) potentiallyInferred.add(descriptor)
} }
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type) && KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(type).size <= 1) { if (type.isExactFunctionOrExtensionFunctionType && getParameterTypeProjectionsFromFunctionType(type).size <= 1) {
// do not rely on inference from input of function type with one or no arguments - use only return type of functional type // do not rely on inference from input of function type with one or no arguments - use only return type of functional type
addPotentiallyInferred(KotlinBuiltIns.getReturnTypeFromFunctionType(type)) addPotentiallyInferred(getReturnTypeFromFunctionType(type))
return return
} }
@@ -22,7 +22,8 @@ import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.codeInsight.lookup.LookupElementPresentation import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer import com.intellij.codeInsight.lookup.impl.LookupCellRenderer
import com.intellij.util.SmartList import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.completion.handlers.GenerateLambdaInfo import org.jetbrains.kotlin.idea.completion.handlers.GenerateLambdaInfo
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
@@ -67,7 +68,7 @@ class LookupElementFactory(
companion object { companion object {
fun hasSingleFunctionTypeParameter(descriptor: FunctionDescriptor): Boolean { fun hasSingleFunctionTypeParameter(descriptor: FunctionDescriptor): Boolean {
val parameter = descriptor.original.valueParameters.singleOrNull() ?: return false val parameter = descriptor.original.valueParameters.singleOrNull() ?: return false
return KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(parameter.type) return parameter.type.isExactFunctionOrExtensionFunctionType
} }
} }
@@ -107,11 +108,11 @@ class LookupElementFactory(
val lastParameter = descriptor.valueParameters.lastOrNull() ?: return val lastParameter = descriptor.valueParameters.lastOrNull() ?: return
if (!descriptor.valueParameters.all { it == lastParameter || it.hasDefaultValue() }) return if (!descriptor.valueParameters.all { it == lastParameter || it.hasDefaultValue() }) return
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(lastParameter.original.type)) { if (lastParameter.original.type.isExactFunctionOrExtensionFunctionType) {
val isSingleParameter = descriptor.valueParameters.size == 1 val isSingleParameter = descriptor.valueParameters.size == 1
val parameterType = lastParameter.type val parameterType = lastParameter.type
val functionParameterCount = KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(parameterType).size val functionParameterCount = getParameterTypeProjectionsFromFunctionType(parameterType).size
// we don't need special item inserting lambda for single functional parameter that does not need multiple arguments because the default item will be special in this case // we don't need special item inserting lambda for single functional parameter that does not need multiple arguments because the default item will be special in this case
if (!isSingleParameter || functionParameterCount > 1) { if (!isSingleParameter || functionParameterCount > 1) {
add(createFunctionCallElementWithLambda(descriptor, parameterType, functionParameterCount > 1, useReceiverTypes)) add(createFunctionCallElementWithLambda(descriptor, parameterType, functionParameterCount > 1, useReceiverTypes))
@@ -25,7 +25,8 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.ExpectedInfos import org.jetbrains.kotlin.idea.core.ExpectedInfos
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
@@ -83,12 +84,12 @@ private fun needExplicitParameterTypes(context: InsertionContext, placeholderRan
val functionTypes = expectedInfos val functionTypes = expectedInfos
.mapNotNull { it.fuzzyType?.type } .mapNotNull { it.fuzzyType?.type }
.filter { KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it) } .filter(KotlinType::isExactFunctionOrExtensionFunctionType)
.toSet() .toSet()
if (functionTypes.size <= 1) return false if (functionTypes.size <= 1) return false
val lambdaParameterCount = KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(lambdaType).size val lambdaParameterCount = getParameterTypeProjectionsFromFunctionType(lambdaType).size
return functionTypes.filter { KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(it).size == lambdaParameterCount }.size > 1 return functionTypes.filter { getParameterTypeProjectionsFromFunctionType(it).size == lambdaParameterCount }.size > 1
} }
private fun buildTemplate(lambdaType: KotlinType, explicitParameterTypes: Boolean, project: Project): Template { private fun buildTemplate(lambdaType: KotlinType, explicitParameterTypes: Boolean, project: Project): Template {
@@ -128,4 +129,4 @@ private class ParameterNameExpression(val nameSuggestions: Array<String>) : Expr
} }
fun functionParameterTypes(functionType: KotlinType): List<KotlinType> fun functionParameterTypes(functionType: KotlinType): List<KotlinType>
= KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(functionType).map { it.type } = getParameterTypeProjectionsFromFunctionType(functionType).map { it.type }
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.idea.completion.smart
import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType
import org.jetbrains.kotlin.idea.completion.handlers.insertLambdaTemplate import org.jetbrains.kotlin.idea.completion.handlers.insertLambdaTemplate
import org.jetbrains.kotlin.idea.completion.handlers.lambdaPresentation import org.jetbrains.kotlin.idea.completion.handlers.lambdaPresentation
import org.jetbrains.kotlin.idea.completion.suppressAutoInsertion import org.jetbrains.kotlin.idea.completion.suppressAutoInsertion
@@ -43,7 +43,7 @@ object LambdaItems {
.toSet() .toSet()
val singleType = if (distinctTypes.size == 1) distinctTypes.single() else null val singleType = if (distinctTypes.size == 1) distinctTypes.single() else null
val singleSignatureLength = singleType?.let { KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(it).size } val singleSignatureLength = singleType?.let { getParameterTypeProjectionsFromFunctionType(it).size }
val offerNoParametersLambda = singleSignatureLength == 0 || singleSignatureLength == 1 val offerNoParametersLambda = singleSignatureLength == 0 || singleSignatureLength == 1
if (offerNoParametersLambda) { if (offerNoParametersLambda) {
val lookupElement = LookupElementBuilder.create(lambdaPresentation(null)) val lookupElement = LookupElementBuilder.create(lambdaPresentation(null))
@@ -26,6 +26,7 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ClassInheritorsSearch import com.intellij.psi.search.searches.ClassInheritorsSearch
import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
@@ -80,7 +81,7 @@ class TypeInstantiationItems(
fuzzyType: FuzzyType, fuzzyType: FuzzyType,
tail: Tail? tail: Tail?
) { ) {
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(fuzzyType.type)) return // do not show "object: ..." for function types if (fuzzyType.type.isExactFunctionOrExtensionFunctionType) return // do not show "object: ..." for function types
val classifier = fuzzyType.type.constructor.declarationDescriptor val classifier = fuzzyType.type.constructor.declarationDescriptor
if (classifier !is ClassDescriptor) return if (classifier !is ClassDescriptor) return
@@ -22,8 +22,8 @@ import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementDecorator import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.codeInsight.lookup.LookupElementPresentation import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.idea.completion.handlers.WithExpressionPrefixInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.WithExpressionPrefixInsertHandler
@@ -308,8 +308,7 @@ fun DeclarationDescriptor.fuzzyTypesForSmartCompletion(
} }
fun Collection<ExpectedInfo>.filterFunctionExpected() fun Collection<ExpectedInfo>.filterFunctionExpected()
= filter { it.fuzzyType != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.fuzzyType!!.type) } = filter { it.fuzzyType != null && it.fuzzyType!!.type.isExactFunctionOrExtensionFunctionType }
fun Collection<ExpectedInfo>.filterCallableExpected() fun Collection<ExpectedInfo>.filterCallableExpected()
= filter { it.fuzzyType != null && ReflectionTypes.isCallableType(it.fuzzyType!!.type) } = filter { it.fuzzyType != null && ReflectionTypes.isCallableType(it.fuzzyType!!.type) }
@@ -17,7 +17,8 @@
package org.jetbrains.kotlin.idea.core package org.jetbrains.kotlin.idea.core
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.ideService import org.jetbrains.kotlin.idea.resolve.ideService
@@ -319,7 +320,7 @@ class ExpectedInfos(
if (parameter.hasDefaultValue()) return false // parameter is optional if (parameter.hasDefaultValue()) return false // parameter is optional
if (parameter.varargElementType != null) return false // vararg arguments list can be empty if (parameter.varargElementType != null) return false // vararg arguments list can be empty
// last parameter of functional type can be placed outside parenthesis: // last parameter of functional type can be placed outside parenthesis:
if (!isArrayAccess && parameter == parameters.last() && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(parameter.type)) return false if (!isArrayAccess && parameter == parameters.last() && parameter.type.isExactFunctionOrExtensionFunctionType) return false
return true return true
} }
@@ -363,7 +364,7 @@ class ExpectedInfos(
parameter.type parameter.type
if (isFunctionLiteralArgument) { if (isFunctionLiteralArgument) {
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(parameterType)) { if (parameterType.isExactFunctionOrExtensionFunctionType) {
add(ExpectedInfo.createForArgument(parameterType, expectedName, null, argumentPositionData)) add(ExpectedInfo.createForArgument(parameterType, expectedName, null, argumentPositionData))
} }
} }
@@ -482,9 +483,9 @@ class ExpectedInfos(
val literalExpression = functionLiteral.parent as KtLambdaExpression val literalExpression = functionLiteral.parent as KtLambdaExpression
return calculate(literalExpression) return calculate(literalExpression)
.mapNotNull { it.fuzzyType } .mapNotNull { it.fuzzyType }
.filter { KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.type) } .filter { it.type.isExactFunctionOrExtensionFunctionType }
.map { .map {
val returnType = KotlinBuiltIns.getReturnTypeFromFunctionType(it.type) val returnType = getReturnTypeFromFunctionType(it.type)
ExpectedInfo(FuzzyType(returnType, it.freeParameters), null, Tail.RBRACE) ExpectedInfo(FuzzyType(returnType, it.freeParameters), null, Tail.RBRACE)
} }
} }
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.core
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.lexer.KotlinLexer import org.jetbrains.kotlin.lexer.KotlinLexer
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -215,7 +216,7 @@ object KotlinNameSuggester {
} }
} }
} }
else if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type)) { else if (type.isExactFunctionOrExtensionFunctionType) {
addName("function", validator) addName("function", validator)
} }
else { else {
@@ -34,6 +34,8 @@ import com.intellij.usages.UsageTarget
import com.intellij.usages.UsageViewManager import com.intellij.usages.UsageViewManager
import com.intellij.usages.UsageViewPresentation import com.intellij.usages.UsageViewPresentation
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -129,7 +131,7 @@ class FindImplicitNothingAction : AnAction() {
return when { return when {
KotlinBuiltIns.isNothing(this) -> true KotlinBuiltIns.isNothing(this) -> true
KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(this) -> KotlinBuiltIns.getReturnTypeFromFunctionType(this).isNothingOrNothingFunctionType() this.isExactFunctionOrExtensionFunctionType -> getReturnTypeFromFunctionType(this).isNothingOrNothingFunctionType()
else -> false else -> false
} }
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.idea.editor.fixers
import com.intellij.lang.SmartEnterProcessorWithFixers import com.intellij.lang.SmartEnterProcessorWithFixers
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.editor.KotlinSmartEnterHandler import org.jetbrains.kotlin.idea.editor.KotlinSmartEnterHandler
import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtCallExpression
@@ -38,7 +38,7 @@ class KotlinLastLambdaParameterFixer : SmartEnterProcessorWithFixers.Fixer<Kotli
if (resolvedCall.valueArguments.size == valueParameters.size - 1) { if (resolvedCall.valueArguments.size == valueParameters.size - 1) {
val type = valueParameters.last().type val type = valueParameters.last().type
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type)) { if (type.isExactFunctionOrExtensionFunctionType) {
val doc = editor.document val doc = editor.document
var offset = element.endOffset var offset = element.endOffset
@@ -53,4 +53,4 @@ class KotlinLastLambdaParameterFixer : SmartEnterProcessorWithFixers.Fixer<Kotli
} }
} }
} }
} }
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.idea.intentions package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
@@ -48,7 +48,7 @@ class MoveLambdaOutsideParenthesesIntention : SelfTargetingIntention<KtCallExpre
// if there are functions among candidates but none of them have last function parameter then not show the intention // if there are functions among candidates but none of them have last function parameter then not show the intention
if (candidates.isNotEmpty() && candidates.none { if (candidates.isNotEmpty() && candidates.none {
val lastParameter = it.valueParameters.lastOrNull() val lastParameter = it.valueParameters.lastOrNull()
lastParameter != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(lastParameter.type) lastParameter != null && lastParameter.type.isExactFunctionOrExtensionFunctionType
}) { }) {
return false return false
} }
@@ -17,7 +17,10 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import com.intellij.util.SmartList import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
@@ -25,6 +28,7 @@ import org.jetbrains.kotlin.idea.refactoring.getExtractionContainers
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.ifEmpty import org.jetbrains.kotlin.utils.ifEmpty
@@ -39,22 +43,27 @@ object CreateFunctionFromCallableReferenceActionFactory : CreateCallableMemberFr
val context = resolutionFacade.analyze(element, BodyResolveMode.PARTIAL) val context = resolutionFacade.analyze(element, BodyResolveMode.PARTIAL)
return element return element
.guessTypes(context, resolutionFacade.moduleDescriptor) .guessTypes(context, resolutionFacade.moduleDescriptor)
.filter(KotlinBuiltIns::isExactFunctionOrExtensionFunctionType) .filter(KotlinType::isExactFunctionOrExtensionFunctionType)
.mapNotNull { .mapNotNull {
val expectedReceiverType = KotlinBuiltIns.getReceiverType(it) val expectedReceiverType = getReceiverTypeFromFunctionType(it)
val actualReceiverTypeRef = element.typeReference val actualReceiverTypeRef = element.typeReference
val receiverTypeInfo = actualReceiverTypeRef?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo.Empty val receiverTypeInfo = actualReceiverTypeRef?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo.Empty
val returnTypeInfo = TypeInfo(KotlinBuiltIns.getReturnTypeFromFunctionType(it), Variance.OUT_VARIANCE) val returnTypeInfo = TypeInfo(getReturnTypeFromFunctionType(it), Variance.OUT_VARIANCE)
val containers = element.getExtractionContainers(includeAll = true).ifEmpty { return@mapNotNull null } val containers = element.getExtractionContainers(includeAll = true).ifEmpty { return@mapNotNull null }
val parameterInfos = SmartList<ParameterInfo>().apply { val parameterInfos = SmartList<ParameterInfo>().apply {
if (actualReceiverTypeRef == null && expectedReceiverType != null) { if (actualReceiverTypeRef == null && expectedReceiverType != null) {
add(ParameterInfo(TypeInfo(expectedReceiverType, Variance.IN_VARIANCE))) add(ParameterInfo(TypeInfo(expectedReceiverType, Variance.IN_VARIANCE)))
} }
KotlinBuiltIns getParameterTypeProjectionsFromFunctionType(it)
.getParameterTypeProjectionsFromFunctionType(it) .let {
.let { if (actualReceiverTypeRef != null && expectedReceiverType == null && it.isNotEmpty()) it.subList(1, it.size) else it } if (actualReceiverTypeRef != null && expectedReceiverType == null && it.isNotEmpty())
.mapTo(this) { ParameterInfo(TypeInfo(it.type, it.projectionKind)) } it.subList(1, it.size)
else it
}
.mapTo(this) {
ParameterInfo(TypeInfo(it.type, it.projectionKind))
}
} }
FunctionInfo(name, receiverTypeInfo, returnTypeInfo, containers, parameterInfos) FunctionInfo(name, receiverTypeInfo, returnTypeInfo, containers, parameterInfos)
@@ -29,13 +29,12 @@ import com.intellij.util.VisibilityUtil
import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod
import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExactFunctionType
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.getJavaOrKotlinMemberDescriptor import org.jetbrains.kotlin.idea.caches.resolve.getJavaOrKotlinMemberDescriptor
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor.Kind import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor.Kind
@@ -249,7 +248,7 @@ open class KotlinChangeInfo(
if (kind == Kind.FUNCTION) { if (kind == Kind.FUNCTION) {
receiverParameterInfo?.let { receiverParameterInfo?.let {
val typeInfo = it.currentTypeInfo val typeInfo = it.currentTypeInfo
if (typeInfo.type != null && KotlinBuiltIns.isExactFunctionType(typeInfo.type)) { if (typeInfo.type != null && typeInfo.type.isExactFunctionType) {
buffer.append("(${typeInfo.render()})") buffer.append("(${typeInfo.render()})")
} }
else { else {
@@ -22,11 +22,9 @@ import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.refactoring.BaseRefactoringProcessor import com.intellij.refactoring.BaseRefactoringProcessor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExactFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.core.*
import org.jetbrains.kotlin.idea.refactoring.isMultiLine
import org.jetbrains.kotlin.idea.refactoring.removeTemplateEntryBracesIfPossible
import org.jetbrains.kotlin.idea.intentions.ConvertToExpressionBodyIntention import org.jetbrains.kotlin.idea.intentions.ConvertToExpressionBodyIntention
import org.jetbrains.kotlin.idea.intentions.InfixCallToOrdinaryIntention import org.jetbrains.kotlin.idea.intentions.InfixCallToOrdinaryIntention
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
@@ -34,6 +32,8 @@ import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention
import org.jetbrains.kotlin.idea.refactoring.introduce.* import org.jetbrains.kotlin.idea.refactoring.introduce.*
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValue.* import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValue.*
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValueBoxer.AsTuple import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValueBoxer.AsTuple
import org.jetbrains.kotlin.idea.refactoring.isMultiLine
import org.jetbrains.kotlin.idea.refactoring.removeTemplateEntryBracesIfPossible
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.idea.util.psi.patternMatching.* import org.jetbrains.kotlin.idea.util.psi.patternMatching.*
@@ -86,7 +86,7 @@ private fun buildSignature(config: ExtractionGeneratorConfiguration, renderer: D
config.descriptor.receiverParameter?.let { config.descriptor.receiverParameter?.let {
val receiverType = it.getParameterType(config.descriptor.extractionData.options.allowSpecialClassNames) val receiverType = it.getParameterType(config.descriptor.extractionData.options.allowSpecialClassNames)
val receiverTypeAsString = receiverType.typeAsString() val receiverTypeAsString = receiverType.typeAsString()
val isFunctionType = KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(receiverType) val isFunctionType = receiverType.isExactFunctionOrExtensionFunctionType
receiver(if (isFunctionType) "($receiverTypeAsString)" else receiverTypeAsString) receiver(if (isFunctionType) "($receiverTypeAsString)" else receiverTypeAsString)
} }
@@ -20,7 +20,8 @@ import com.google.dart.compiler.backend.js.ast.*
import com.google.dart.compiler.backend.js.ast.metadata.inlineStrategy import com.google.dart.compiler.backend.js.ast.metadata.inlineStrategy
import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter
import com.intellij.util.containers.SLRUCache import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig import org.jetbrains.kotlin.js.config.LibrarySourcesConfig
import org.jetbrains.kotlin.js.inline.util.IdentitySet import org.jetbrains.kotlin.js.inline.util.IdentitySet
@@ -141,9 +142,9 @@ private fun JsFunction.markInlineArguments(descriptor: CallableDescriptor) {
if (!CallExpressionTranslator.shouldBeInlined(descriptor)) continue if (!CallExpressionTranslator.shouldBeInlined(descriptor)) continue
val type = param.type val type = param.type
if (!KotlinBuiltIns.isFunctionOrExtensionFunctionType(type)) continue if (!type.isFunctionOrExtensionFunctionType) continue
val namesSet = if (KotlinBuiltIns.isExtensionFunctionType(type)) inlineExtensionFuns else inlineFuns val namesSet = if (type.isExtensionFunctionType) inlineExtensionFuns else inlineFuns
namesSet.add(paramsJs[i + offset].name) namesSet.add(paramsJs[i + offset].name)
} }