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); } }
@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); }