@Nullable public static List<ValueParameterDescriptor> getSubstitutedValueParameters( FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) { List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(); List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); // TODO : Lazy? JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE); JetType varargElementType = unsubstitutedValueParameter.getVarargElementType(); JetType substituteVarargElementType = varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE); if (substitutedType == null) return null; result.add( new ValueParameterDescriptorImpl( substitutedDescriptor, unsubstitutedValueParameter, unsubstitutedValueParameter.getAnnotations(), unsubstitutedValueParameter.isVar(), substitutedType, substituteVarargElementType)); } return result; }
@NotNull private VarargCheckResult checkVarargInSuperFunctions( @NotNull ValueParameterDescriptor originalParam) { boolean someSupersVararg = false; boolean someSupersNotVararg = false; for (FunctionDescriptor superFunction : superFunctions) { if (superFunction.getValueParameters().get(originalParam.getIndex()).getVarargElementType() != null) { someSupersVararg = true; } else { someSupersNotVararg = true; } } JetType originalVarargElementType = originalParam.getVarargElementType(); JetType originalType = originalParam.getType(); if (someSupersVararg && someSupersNotVararg) { reportError("Incompatible super methods: some have vararg parameter, some have not"); return new VarargCheckResult(originalType, originalVarargElementType != null); } KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); if (someSupersVararg && originalVarargElementType == null) { // convert to vararg assert isArrayType(originalType); if (builtIns.isPrimitiveArray(originalType)) { // replace IntArray? with IntArray return new VarargCheckResult(TypeUtils.makeNotNullable(originalType), true); } // replace Array<out Foo>? with Array<Foo> JetType varargElementType = builtIns.getArrayElementType(originalType); return new VarargCheckResult(builtIns.getArrayType(INVARIANT, varargElementType), true); } else if (someSupersNotVararg && originalVarargElementType != null) { // convert to non-vararg assert isArrayType(originalType); if (builtIns.isPrimitiveArray(originalType)) { // replace IntArray with IntArray? return new VarargCheckResult(TypeUtils.makeNullable(originalType), false); } // replace Array<Foo> with Array<out Foo>? return new VarargCheckResult( TypeUtils.makeNullable( builtIns.getArrayType(Variance.OUT_VARIANCE, originalVarargElementType)), false); } return new VarargCheckResult(originalType, originalVarargElementType != null); }
private List<ValueParameterDescriptor> createValueParameterDescriptors( ExpressionTypingContext context, JetFunctionLiteral functionLiteral, FunctionDescriptorImpl functionDescriptor, boolean functionTypeExpected) { List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList(); List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters(); List<ValueParameterDescriptor> expectedValueParameters = (functionTypeExpected) ? JetStandardClasses.getValueParameters(functionDescriptor, context.expectedType) : null; boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null; if (functionTypeExpected && !hasDeclaredValueParameters && expectedValueParameters.size() == 1) { ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0); ValueParameterDescriptor it = new ValueParameterDescriptorImpl( functionDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), "it", false, valueParameterDescriptor.getOutType(), valueParameterDescriptor.hasDefaultValue(), valueParameterDescriptor.getVarargElementType()); valueParameterDescriptors.add(it); context.trace.record(AUTO_CREATED_IT, it); } else { for (int i = 0; i < declaredValueParameters.size(); i++) { JetParameter declaredParameter = declaredValueParameters.get(i); JetTypeReference typeReference = declaredParameter.getTypeReference(); JetType type; if (typeReference != null) { type = context.getTypeResolver().resolveType(context.scope, typeReference); } else { if (expectedValueParameters != null && i < expectedValueParameters.size()) { type = expectedValueParameters.get(i).getOutType(); } else { context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter)); type = ErrorUtils.createErrorType("Cannot be inferred"); } } ValueParameterDescriptor valueParameterDescriptor = context .getDescriptorResolver() .resolveValueParameterDescriptor(functionDescriptor, declaredParameter, i, type); valueParameterDescriptors.add(valueParameterDescriptor); } } return valueParameterDescriptors; }
@NotNull private static List<ValueParameterDescriptor> createValueParameterDescriptors( @NotNull ExpressionTypingContext context, @NotNull JetFunctionLiteral functionLiteral, @NotNull FunctionDescriptorImpl functionDescriptor, boolean functionTypeExpected) { List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList(); List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters(); List<ValueParameterDescriptor> expectedValueParameters = (functionTypeExpected) ? KotlinBuiltIns.getInstance() .getValueParameters(functionDescriptor, context.expectedType) : null; JetParameterList valueParameterList = functionLiteral.getValueParameterList(); boolean hasDeclaredValueParameters = valueParameterList != null; if (functionTypeExpected && !hasDeclaredValueParameters && expectedValueParameters.size() == 1) { ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0); ValueParameterDescriptor it = new ValueParameterDescriptorImpl( functionDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("it"), valueParameterDescriptor.getType(), valueParameterDescriptor.hasDefaultValue(), valueParameterDescriptor.getVarargElementType()); valueParameterDescriptors.add(it); context.trace.record(AUTO_CREATED_IT, it); } else { if (expectedValueParameters != null && declaredValueParameters.size() != expectedValueParameters.size()) { List<JetType> expectedParameterTypes = DescriptorUtils.getValueParametersTypes(expectedValueParameters); context.trace.report( EXPECTED_PARAMETERS_NUMBER_MISMATCH.on( functionLiteral, expectedParameterTypes.size(), expectedParameterTypes)); } for (int i = 0; i < declaredValueParameters.size(); i++) { ValueParameterDescriptor valueParameterDescriptor = createValueParameterDescriptor( context, functionDescriptor, declaredValueParameters, expectedValueParameters, i); valueParameterDescriptors.add(valueParameterDescriptor); } } return valueParameterDescriptors; }
private void checkDefaultParameterValues( List<JetParameter> valueParameters, List<ValueParameterDescriptor> valueParameterDescriptors, JetScope declaringScope) { for (int i = 0; i < valueParameters.size(); i++) { ValueParameterDescriptor valueParameterDescriptor = valueParameterDescriptors.get(i); if (valueParameterDescriptor.hasDefaultValue()) { JetParameter jetParameter = valueParameters.get(i); JetExpression defaultValue = jetParameter.getDefaultValue(); if (defaultValue != null) { expressionTypingServices.getType( declaringScope, defaultValue, valueParameterDescriptor.getType(), trace); } } } }
/* VARIABLES */ private void renderValueParameter( @NotNull ValueParameterDescriptor valueParameter, @NotNull StringBuilder builder, boolean topLevel) { if (topLevel) { builder.append(renderKeyword("value-parameter")).append(" "); } if (verbose) { builder.append("/*").append(valueParameter.getIndex()).append("*/ "); } renderAnnotations(valueParameter, builder); renderVariable(valueParameter, builder, topLevel); boolean withDefaultValue = debugMode ? valueParameter.declaresDefaultValue() : valueParameter.hasDefaultValue(); if (withDefaultValue) { builder.append(" = ..."); } }
private JavaDescriptorResolver.ValueParameterDescriptors modifyValueParametersAccordingToSuperMethods( @NotNull JavaDescriptorResolver.ValueParameterDescriptors parameters // descriptors built by parameters resolver ) { // we are not processing receiver type specifically: // if this function comes from Kotlin, then we don't need to do it, if it doesn't, then it can't // have receiver List<ValueParameterDescriptor> resultParameters = Lists.newArrayList(); for (ValueParameterDescriptor originalParam : parameters.getDescriptors()) { final int index = originalParam.getIndex(); List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map( superFunctions, new Function<FunctionDescriptor, TypeAndVariance>() { @Override public TypeAndVariance fun(FunctionDescriptor superFunction) { return new TypeAndVariance( superFunction.getValueParameters().get(index).getType(), INVARIANT); } }); VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam); JetType altType = modifyTypeAccordingToSuperMethods( varargCheckResult.parameterType, typesFromSuperMethods, MEMBER_SIGNATURE_CONTRAVARIANT); resultParameters.add( new ValueParameterDescriptorImpl( originalParam.getContainingDeclaration(), index, originalParam.getAnnotations(), originalParam.getName(), altType, originalParam.declaresDefaultValue(), varargCheckResult.isVararg ? KotlinBuiltIns.getInstance().getArrayElementType(altType) : null)); } JetType originalReceiverType = parameters.getReceiverType(); if (originalReceiverType != null) { JetType substituted = SignaturesUtil.createSubstitutorForFunctionTypeParameters(autoTypeParameterToModified) .substitute(originalReceiverType, INVARIANT); assert substituted != null; return new JavaDescriptorResolver.ValueParameterDescriptors(substituted, resultParameters); } else { return new JavaDescriptorResolver.ValueParameterDescriptors(null, resultParameters); } }
@Override public JetType visitFunctionLiteralExpression( JetFunctionLiteralExpression expression, ExpressionTypingContext context) { JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); JetBlockExpression bodyExpression = functionLiteral.getBodyExpression(); if (bodyExpression == null) return null; JetType expectedType = context.expectedType; boolean functionTypeExpected = expectedType != TypeUtils.NO_EXPECTED_TYPE && JetStandardClasses.isFunctionType(expectedType); NamedFunctionDescriptorImpl functionDescriptor = createFunctionDescriptor(expression, context, functionTypeExpected); List<JetType> parameterTypes = Lists.newArrayList(); List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters(); for (ValueParameterDescriptor valueParameter : valueParameters) { parameterTypes.add(valueParameter.getOutType()); } ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); JetType receiver = receiverParameter != NO_RECEIVER ? receiverParameter.getType() : null; JetType returnType = TypeUtils.NO_EXPECTED_TYPE; JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope( context.scope, functionDescriptor, context.trace); JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef(); if (returnTypeRef != null) { returnType = context.getTypeResolver().resolveType(context.scope, returnTypeRef); context .getServices() .checkFunctionReturnType( expression, context .replaceScope(functionInnerScope) .replaceExpectedType(returnType) .replaceExpectedReturnType(returnType) .replaceDataFlowInfo(context.dataFlowInfo)); } else { if (functionTypeExpected) { returnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType); } returnType = context .getServices() .getBlockReturnedType( functionInnerScope, bodyExpression, CoercionStrategy.COERCION_TO_UNIT, context.replaceExpectedType(returnType).replaceExpectedReturnType(returnType)); } JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType; functionDescriptor.setReturnType(safeReturnType); boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null; if (!hasDeclaredValueParameters && functionTypeExpected) { JetType expectedReturnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType); if (JetStandardClasses.isUnit(expectedReturnType)) { functionDescriptor.setReturnType(JetStandardClasses.getUnitType()); return DataFlowUtils.checkType( JetStandardClasses.getFunctionType( Collections.<AnnotationDescriptor>emptyList(), receiver, parameterTypes, JetStandardClasses.getUnitType()), expression, context); } } return DataFlowUtils.checkType( JetStandardClasses.getFunctionType( Collections.<AnnotationDescriptor>emptyList(), receiver, parameterTypes, safeReturnType), expression, context); }