@NotNull public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) { ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(2); ClassDescriptor classDescriptor; if (receiverParameter != null) { classDescriptor = extensionFunctionImpl; typeArguments.add(new TypeProjectionImpl(receiverParameter.getType())); } else { classDescriptor = functionImpl; } //noinspection ConstantConditions typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType())); JetType functionImplType = new JetTypeImpl( classDescriptor.getDefaultType().getAnnotations(), classDescriptor.getTypeConstructor(), false, typeArguments, classDescriptor.getMemberScope(typeArguments)); JetType functionType = KotlinBuiltIns.getInstance() .getFunctionType( Annotations.EMPTY, receiverParameter == null ? null : receiverParameter.getType(), DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()), descriptor.getReturnType()); return Arrays.asList(functionImplType, functionType); }
/* FUNCTIONS */ private void renderFunction( @NotNull FunctionDescriptor function, @NotNull StringBuilder builder) { if (!startFromName) { renderAnnotations(function, builder); renderVisibility(function.getVisibility(), builder); renderModalityForCallable(function, builder); renderOverride(function, builder); renderMemberKind(function, builder); builder.append(renderKeyword("fun")).append(" "); renderTypeParameters(function.getTypeParameters(), builder, true); ReceiverParameterDescriptor receiver = function.getReceiverParameter(); if (receiver != null) { builder.append(escape(renderType(receiver.getType()))).append("."); } } renderName(function, builder); renderValueParameters(function, builder); JetType returnType = function.getReturnType(); if (unitReturnType || !KotlinBuiltIns.getInstance().isUnit(returnType)) { builder.append(": ").append(returnType == null ? "[NULL]" : escape(renderType(returnType))); } renderWhereSuffix(function.getTypeParameters(), builder); }
@NotNull public JetTypeInfo getSimpleNameExpressionTypeInfo( @NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context) { boolean[] result = new boolean[1]; TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create(context.trace, "trace to resolve as variable", nameExpression); JetType type = getVariableType( nameExpression, receiver, callOperationNode, context.replaceBindingTrace(traceForVariable), result); if (result[0]) { traceForVariable.commit(); if (type instanceof NamespaceType && context.expressionPosition == ExpressionPosition.FREE) { type = null; } return JetTypeInfo.create(type, context.dataFlowInfo); } Call call = CallMaker.makeCall( nameExpression, receiver, callOperationNode, nameExpression, Collections.<ValueArgument>emptyList()); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression); ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction( call, nameExpression, receiver, context, ResolveMode.TOP_LEVEL_CALL, ResolutionResultsCache.create(), result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; context.trace.report( FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters)); type = functionDescriptor != null ? functionDescriptor.getReturnType() : null; return JetTypeInfo.create(type, context.dataFlowInfo); } traceForVariable.commit(); return JetTypeInfo.create(null, context.dataFlowInfo); }
@NotNull public Collection<JetType> getSupertypesForCallableReference( @NotNull FunctionDescriptor descriptor) { ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject(); List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(2); ClassDescriptor classDescriptor; JetType receiverType; if (receiverParameter != null) { classDescriptor = kExtensionFunctionImpl; receiverType = receiverParameter.getType(); typeArguments.add(new TypeProjectionImpl(receiverType)); } else if (expectedThisObject != null) { classDescriptor = kMemberFunctionImpl; receiverType = expectedThisObject.getType(); typeArguments.add(new TypeProjectionImpl(receiverType)); } else { classDescriptor = kFunctionImpl; receiverType = null; } //noinspection ConstantConditions typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType())); JetType kFunctionImplType = new JetTypeImpl( classDescriptor.getDefaultType().getAnnotations(), classDescriptor.getTypeConstructor(), false, typeArguments, classDescriptor.getMemberScope(typeArguments)); JetType kFunctionType = reflectionTypes.getKFunctionType( Annotations.EMPTY, receiverType, DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()), descriptor.getReturnType(), receiverParameter != null); return Arrays.asList(kFunctionImplType, kFunctionType); }
private void resolveFunctionBody( @NotNull BindingTrace trace, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @NotNull JetScope declaringScope) { if (!context.completeAnalysisNeeded(function)) return; JetExpression bodyExpression = function.getBodyExpression(); JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(declaringScope, functionDescriptor, trace); if (bodyExpression != null) { expressionTypingServices.checkFunctionReturnType( functionInnerScope, function, functionDescriptor, trace); } List<JetParameter> valueParameters = function.getValueParameters(); List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters(); checkDefaultParameterValues(valueParameters, valueParameterDescriptors, functionInnerScope); assert functionDescriptor.getReturnType() != null; }
@NotNull public TypeInfoForCall getCallExpressionTypeInfoForCallWithoutFinalTypeCheck( @NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode) { boolean[] result = new boolean[1]; Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create( context.trace, "trace to resolve as function call", callExpression); ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction( call, callExpression, receiver, context.replaceBindingTrace(traceForFunction), resolveMode, result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); if (callExpression.getValueArgumentList() == null && callExpression.getFunctionLiteralArguments().isEmpty()) { // there are only type arguments boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; context.trace.report( FUNCTION_CALL_EXPECTED.on(callExpression, callExpression, hasValueParameters)); } if (functionDescriptor == null) { return TypeInfoForCall.create(null, context.dataFlowInfo); } JetType type = functionDescriptor.getReturnType(); return TypeInfoForCall.create( type, resolvedCall.getDataFlowInfo(), resolvedCall, call, context, resolveMode); } JetExpression calleeExpression = callExpression.getCalleeExpression(); if (calleeExpression instanceof JetSimpleNameExpression && callExpression.getTypeArgumentList() == null) { TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create( context.trace, "trace to resolve as variable with 'invoke' call", callExpression); JetType type = getVariableType( (JetSimpleNameExpression) calleeExpression, receiver, callOperationNode, context.replaceBindingTrace(traceForVariable), result); if (result[0]) { traceForVariable.commit(); context.trace.report( FUNCTION_EXPECTED.on( (JetReferenceExpression) calleeExpression, calleeExpression, type != null ? type : ErrorUtils.createErrorType(""))); return TypeInfoForCall.create(null, context.dataFlowInfo); } } traceForFunction.commit(); return TypeInfoForCall.create(null, context.dataFlowInfo); }
@Nullable public static JetType getSubstitutedReturnType( @NotNull FunctionDescriptor functionDescriptor, TypeSubstitutor substitutor) { return substitutor.substitute(functionDescriptor.getReturnType(), Variance.OUT_VARIANCE); }