Support default arguments for expected declarations

#KT-21913 Fixed
This commit is contained in:
Alexander Udalov
2018-01-12 20:50:24 +01:00
parent d356f52873
commit db4ce703a6
36 changed files with 794 additions and 77 deletions
@@ -561,7 +561,6 @@ public interface Errors {
// Multi-platform projects
DiagnosticFactory0<KtDeclaration> EXPECTED_DECLARATION_WITH_BODY = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtParameter> EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtConstructorDelegationCall> EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtParameter> EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtConstructor<?>> EXPECTED_ENUM_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
@@ -571,7 +570,6 @@ public interface Errors {
DiagnosticFactory0<PsiElement> EXPECTED_LATEINIT_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> EXPECTED_PRIVATE_DECLARATION = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtDelegatedSuperTypeEntry> IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtTypeAlias> ACTUAL_TYPE_ALIAS_NOT_TO_CLASS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
@@ -579,6 +577,9 @@ public interface Errors {
ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtTypeAlias> ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtTypeAlias> ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<PsiElement> ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND = DiagnosticFactory0.create(ERROR);
DiagnosticFactory3<KtNamedDeclaration, MemberDescriptor, ModuleDescriptor,
Map<Incompatible, Collection<MemberDescriptor>>> NO_ACTUAL_FOR_EXPECT =
@@ -157,8 +157,7 @@ object PositioningStrategies {
callableDeclaration?.let { it.receiverTypeReference ?: it.valueParameterList }
}
ParameterCount, ParameterTypes, ParameterNames,
ValueParameterHasDefault, ValueParameterVararg,
ValueParameterNoinline, ValueParameterCrossinline -> {
ValueParameterVararg, ValueParameterNoinline, ValueParameterCrossinline -> {
callableDeclaration?.valueParameterList
}
ReturnType -> {
@@ -236,7 +236,6 @@ public class DefaultErrorMessages {
MAP.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE);
MAP.put(EXPECTED_DECLARATION_WITH_BODY, "Expected declaration must not have a body");
MAP.put(EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER, "Expected declaration cannot have parameters with default values");
MAP.put(EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL, "Explicit delegation call for constructor of an expected class is not allowed");
MAP.put(EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, "Expected class constructor cannot have a property parameter");
MAP.put(EXPECTED_ENUM_CONSTRUCTOR, "Expected enum class cannot have a constructor");
@@ -253,6 +252,11 @@ public class DefaultErrorMessages {
MAP.put(ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE, "Aliased class should not have type parameters with declaration-site variance");
MAP.put(ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE, "Right-hand side of actual type alias cannot contain use-site variance or star projections");
MAP.put(ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION, "Type arguments in the right-hand side of actual type alias should be its type parameters in the same order, e.g. 'actual typealias Foo<A, B> = Bar<A, B>'");
MAP.put(ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, "Actual function cannot have default argument values, they should be declared in the expected function");
MAP.put(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND,
"Expected function source is not found, therefore it's impossible to generate default argument values declared there. " +
"Please add the corresponding file to compilation sources");
MAP.put(NO_ACTUAL_FOR_EXPECT, "Expected {0} has no actual declaration in module{1}{2}", DECLARATION_NAME_WITH_KIND,
PLATFORM, PlatformIncompatibilityDiagnosticRenderer.TEXT);
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.types.*
@@ -246,6 +247,10 @@ class DeclarationsChecker(
checkVarargParameters(trace, constructorDescriptor)
checkConstructorVisibility(constructorDescriptor, declaration)
checkExpectedClassConstructor(constructorDescriptor, declaration)
if (constructorDescriptor.isActual) {
checkActualFunction(declaration, constructorDescriptor)
}
}
private fun checkExpectedClassConstructor(constructorDescriptor: ClassConstructorDescriptor, declaration: KtConstructor<*>) {
@@ -765,6 +770,9 @@ class DeclarationsChecker(
if (functionDescriptor.isExpect) {
checkExpectedFunction(function, functionDescriptor)
}
if (functionDescriptor.isActual) {
checkActualFunction(function, functionDescriptor)
}
shadowedExtensionChecker.checkDeclaration(function, functionDescriptor)
}
@@ -774,13 +782,17 @@ class DeclarationsChecker(
trace.report(EXPECTED_DECLARATION_WITH_BODY.on(function))
}
for (parameter in function.valueParameters) {
if (parameter.hasDefaultValue()) {
trace.report(EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER.on(parameter))
checkPrivateExpectedDeclaration(function, functionDescriptor)
}
private fun checkActualFunction(element: KtDeclaration, functionDescriptor: FunctionDescriptor) {
for (valueParameter in functionDescriptor.valueParameters) {
if (valueParameter.declaresDefaultValue()) {
trace.report(
ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS.on(DescriptorToSourceUtils.descriptorToDeclaration(valueParameter) ?: element)
)
}
}
checkPrivateExpectedDeclaration(function, functionDescriptor)
}
private fun checkImplicitCallableType(declaration: KtCallableDeclaration, descriptor: CallableDescriptor) {
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.AnalyzerExtensions
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
class InlineAnalyzerExtension(
private val reasonableInlineRules: Iterable<ReasonableInlineRule>,
@@ -95,9 +96,9 @@ class InlineAnalyzerExtension(
if (parameter.hasDefaultValue()) {
val ktParameter = ktParameters[parameter.index]
//Always report unsupported error on functional parameter with inherited default (there are some problems with inlining)
val inheritDefaultValues = !parameter.declaresDefaultValue()
if (checkInlinableParameter(parameter, ktParameter, functionDescriptor, null) || inheritDefaultValues) {
if (inheritDefaultValues || !languageVersionSettings.supportsFeature(LanguageFeature.InlineDefaultFunctionalParameters)) {
val inheritsDefaultValue = !parameter.declaresDefaultValue() && parameter.declaresOrInheritsDefaultValue()
if (checkInlinableParameter(parameter, ktParameter, functionDescriptor, null) || inheritsDefaultValue) {
if (inheritsDefaultValue || !languageVersionSettings.supportsFeature(LanguageFeature.InlineDefaultFunctionalParameters)) {
trace.report(
Errors.NOT_YET_SUPPORTED_IN_INLINE.on(
ktParameter,