Skip to content

Commit 9b3d974

Browse files
author
Michael Bogdanov
committed
Prohibit super calls with default parameters
1 parent c48c3fc commit 9b3d974

File tree

9 files changed

+103
-13
lines changed

9 files changed

+103
-13
lines changed

compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,22 +2294,11 @@ protected FunctionDescriptor accessibleFunctionDescriptor(@NotNull ResolvedCall<
22942294
descriptor = originalIfSamAdapter;
22952295
}
22962296
// $default method is not private, so you need no accessor to call it
2297-
return usesDefaultArguments(resolvedCall)
2297+
return CallUtilKt.usesDefaultArguments(resolvedCall)
22982298
? descriptor
22992299
: context.accessibleDescriptor(descriptor, getSuperCallTarget(resolvedCall.getCall()));
23002300
}
23012301

2302-
private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
2303-
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
2304-
if (valueArguments == null) return false;
2305-
2306-
for (ResolvedValueArgument argument : valueArguments) {
2307-
if (argument instanceof DefaultValueArgument) return true;
2308-
}
2309-
2310-
return false;
2311-
}
2312-
23132302
@NotNull
23142303
public StackValue invokeFunction(@NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
23152304
return invokeFunction(resolvedCall.getCall(), resolvedCall, receiver);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2010-2016 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.resolve.jvm.checkers
18+
19+
import org.jetbrains.kotlin.descriptors.CallableDescriptor
20+
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getSuperCallExpression
21+
import org.jetbrains.kotlin.resolve.calls.callUtil.usesDefaultArguments
22+
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
23+
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
24+
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
25+
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
26+
27+
class SuperCallWithDefaultArgumentsChecker : CallChecker {
28+
override fun <F : CallableDescriptor> check(resolvedCall: ResolvedCall<F>, context: BasicCallResolutionContext) {
29+
val superCallExpression = getSuperCallExpression(resolvedCall.call)
30+
if (superCallExpression == null || !resolvedCall.usesDefaultArguments()) return
31+
context.trace.report(ErrorsJvm.SUPER_CALL_WITH_DEFAULT_PARAMETERS.on(superCallExpression.parent, resolvedCall.resultingDescriptor.name.asString()))
32+
}
33+
}

compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ public String render(@NotNull ConflictingJvmDeclarationsData data) {
100100
MAP.put(ErrorsJvm.UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of a type parameter cannot be an array");
101101

102102
MAP.put(ErrorsJvm.INAPPLICABLE_JVM_FIELD, "{0}", Renderers.TO_STRING);
103+
104+
MAP.put(ErrorsJvm.SUPER_CALL_WITH_DEFAULT_PARAMETERS, "Super-calls with default arguments are not allowed. Please specify all arguments of ''super.{0}'' explicitly", Renderers.TO_STRING);
103105
}
104106

105107
@NotNull

compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public interface ErrorsJvm {
8080

8181
DiagnosticFactory0<PsiElement> UPPER_BOUND_CANNOT_BE_ARRAY = DiagnosticFactory0.create(ERROR);
8282

83+
DiagnosticFactory1<PsiElement, String> SUPER_CALL_WITH_DEFAULT_PARAMETERS = DiagnosticFactory1.create(ERROR);
84+
8385
enum NullabilityInformationSource {
8486
KOTLIN {
8587
@NotNull

compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.jvm.RuntimeAssertionsTypeChecker
2222
import org.jetbrains.kotlin.load.kotlin.JavaAnnotationCallChecker
2323
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeFunChecker
2424
import org.jetbrains.kotlin.resolve.*
25+
import org.jetbrains.kotlin.resolve.jvm.checkers.SuperCallWithDefaultArgumentsChecker
2526
import org.jetbrains.kotlin.resolve.jvm.JvmOverloadFilter
2627
import org.jetbrains.kotlin.resolve.jvm.checkers.*
2728
import org.jetbrains.kotlin.synthetic.JavaSyntheticScopes
@@ -48,7 +49,8 @@ object JvmPlatformConfigurator : PlatformConfigurator(
4849
TraitDefaultMethodCallChecker(),
4950
JavaClassOnCompanionChecker(),
5051
ProtectedInSuperClassCompanionCallChecker(),
51-
UnsupportedSyntheticCallableReferenceChecker()
52+
UnsupportedSyntheticCallableReferenceChecker(),
53+
SuperCallWithDefaultArgumentsChecker()
5254
),
5355

5456
additionalTypeCheckers = listOf(

compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
3131
import org.jetbrains.kotlin.resolve.calls.CallTransformer
3232
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
3333
import org.jetbrains.kotlin.resolve.calls.model.*
34+
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
3435
import org.jetbrains.kotlin.utils.sure
3536

3637
// resolved call
@@ -65,6 +66,11 @@ fun <D : CallableDescriptor> ResolvedCall<D>.getParameterForArgument(valueArgume
6566
return (valueArgument?.let { getArgumentMapping(it) } as? ArgumentMatch)?.valueParameter
6667
}
6768

69+
fun <D : CallableDescriptor> ResolvedCall<D>.usesDefaultArguments(): Boolean {
70+
return valueArgumentsByIndex?.any { it is DefaultValueArgument } ?: false
71+
}
72+
73+
6874
// call
6975

7076
fun <C: ResolutionContext<C>> Call.hasUnresolvedArguments(context: ResolutionContext<C>): Boolean {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// !DIAGNOSTICS: -UNUSED_PARAMETER -ABSTRACT_SUPER_CALL
2+
3+
abstract class A {
4+
open fun foo(a: String = "default") {
5+
}
6+
7+
final fun foo2(a: String = "default") {
8+
}
9+
10+
abstract fun foo3(a: String = "default")
11+
}
12+
13+
open class B : A() {
14+
fun test() {
15+
super.foo("123")
16+
<!SUPER_CALL_WITH_DEFAULT_PARAMETERS!>super.foo()<!>
17+
18+
super.foo2("123")
19+
<!SUPER_CALL_WITH_DEFAULT_PARAMETERS!>super.foo2()<!>
20+
21+
super.foo3("123")
22+
<!SUPER_CALL_WITH_DEFAULT_PARAMETERS!>super.foo3()<!>
23+
}
24+
25+
override fun foo3(a: String) {
26+
throw UnsupportedOperationException()
27+
}
28+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package
2+
3+
public abstract class A {
4+
public constructor A()
5+
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
6+
public open fun foo(/*0*/ a: kotlin.String = ...): kotlin.Unit
7+
public final fun foo2(/*0*/ a: kotlin.String = ...): kotlin.Unit
8+
public abstract fun foo3(/*0*/ a: kotlin.String = ...): kotlin.Unit
9+
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
10+
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
11+
}
12+
13+
public open class B : A {
14+
public constructor B()
15+
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
16+
public open override /*1*/ /*fake_override*/ fun foo(/*0*/ a: kotlin.String = ...): kotlin.Unit
17+
public final override /*1*/ /*fake_override*/ fun foo2(/*0*/ a: kotlin.String = ...): kotlin.Unit
18+
public open override /*1*/ fun foo3(/*0*/ a: kotlin.String = ...): kotlin.Unit
19+
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
20+
public final fun test(): kotlin.Unit
21+
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
22+
}

compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4439,6 +4439,12 @@ public void testKt5232() throws Exception {
44394439
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/defaultArguments/kt5232.kt");
44404440
doTest(fileName);
44414441
}
4442+
4443+
@TestMetadata("superCall.kt")
4444+
public void testSuperCall() throws Exception {
4445+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/defaultArguments/superCall.kt");
4446+
doTest(fileName);
4447+
}
44424448
}
44434449

44444450
@TestMetadata("compiler/testData/diagnostics/tests/delegatedProperty")

0 commit comments

Comments
 (0)