diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 4872a05023d17311e928ff09618215301f187771..ae9ab6987e398335acb24de38bd3a0d5fc4385e8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -24,13 +24,14 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors.* +import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.codeFragmentUtil.debugTypeInfo import org.jetbrains.kotlin.psi.debugText.getDebugText import org.jetbrains.kotlin.resolve.PossiblyBareType.type import org.jetbrains.kotlin.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider -import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope +import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil import org.jetbrains.kotlin.resolve.lazy.LazyEntity import org.jetbrains.kotlin.resolve.scopes.JetScope @@ -239,6 +240,7 @@ public class TypeResolver( val receiverTypeRef = type.getReceiverTypeReference() val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef) + type.parameters.forEach { checkParameterInFunctionType(it) } val parameterTypes = type.getParameters().map { resolveType(c.noBareTypes(), it.getTypeReference()!!) } val returnTypeRef = type.getReturnTypeReference() @@ -262,6 +264,31 @@ public class TypeResolver( override fun visitJetElement(element: JetElement) { c.trace.report(UNSUPPORTED.on(element, "Self-types are not supported yet")) } + + private fun checkParameterInFunctionType(param: JetParameter) { + if (param.hasDefaultValue()) { + c.trace.report(Errors.UNSUPPORTED.on(param.defaultValue!!, "default value of parameter in function type")) + } + + if (param.nameIdentifier != null) { + for (annotationEntry in param.annotationEntries) { + c.trace.report(Errors.UNSUPPORTED.on(annotationEntry, "annotation on parameter in function type")) + } + } + + val modifierList = param.modifierList + if (modifierList != null) { + JetTokens.MODIFIER_KEYWORDS_ARRAY + .map { modifierList.getModifier(it) } + .filterNotNull() + .forEach { c.trace.report(Errors.UNSUPPORTED.on(it, "modifier on parameter in function type")) + } + } + + param.valOrVarKeyword?.let { + c.trace.report(Errors.UNSUPPORTED.on(it, "val or val on parameter in function type")) + } + } }) return result ?: type(ErrorUtils.createErrorType(typeElement?.getDebugText() ?: "No type element")) diff --git a/compiler/testData/diagnostics/tests/DefaultValueForParameterInFunctionType.kt b/compiler/testData/diagnostics/tests/DefaultValueForParameterInFunctionType.kt new file mode 100644 index 0000000000000000000000000000000000000000..f9b0f6f68ac208b424ad80d3a6766186c0cf160a --- /dev/null +++ b/compiler/testData/diagnostics/tests/DefaultValueForParameterInFunctionType.kt @@ -0,0 +1,20 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +fun f(x: Int = 0) {} + +val inVal: (x: Int = 0)->Unit = {} + +fun inParam(fn: (x: Int = 0)->Unit) {} + +fun inParamNested(fn1: (fn2: (n: Int = 0)->Unit)->Unit) {} + +fun inReturn(): (x: Int = 0)->Unit = {} + +class A : (x: Int = 0)->Unit { + override fun invoke(p1: Int) { + var lambda: (x: Int = 0)->Unit = {} + } + + val prop: (x: Int = 0)->Unit + get(): (x: Int = 0)->Unit = {} +} diff --git a/compiler/testData/diagnostics/tests/DefaultValueForParameterInFunctionType.txt b/compiler/testData/diagnostics/tests/DefaultValueForParameterInFunctionType.txt new file mode 100644 index 0000000000000000000000000000000000000000..bbe0664d451b8da90a3b20d40de51183f7df2dad --- /dev/null +++ b/compiler/testData/diagnostics/tests/DefaultValueForParameterInFunctionType.txt @@ -0,0 +1,16 @@ +package + +public val inVal: (kotlin.Int) -> kotlin.Unit +public fun f(/*0*/ x: kotlin.Int = ...): kotlin.Unit +public fun inParam(/*0*/ fn: (kotlin.Int) -> kotlin.Unit): kotlin.Unit +public fun inParamNested(/*0*/ fn1: ((kotlin.Int) -> kotlin.Unit) -> kotlin.Unit): kotlin.Unit +public fun inReturn(): (kotlin.Int) -> kotlin.Unit + +public final class A : (kotlin.Int) -> kotlin.Unit { + public constructor A() + public final val prop: (kotlin.Int) -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun invoke(/*0*/ p1: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/annotations/annotationOnParameterInFunctionType.kt b/compiler/testData/diagnostics/tests/annotations/annotationOnParameterInFunctionType.kt new file mode 100644 index 0000000000000000000000000000000000000000..a105dfc5bfa0b61066771ae2971687ae729d735d --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/annotationOnParameterInFunctionType.kt @@ -0,0 +1,29 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +annotation class Ann + +fun f(@Ann x: Int) {} + +val inVal: (@Ann x: Int)->Unit = {} + +fun inParam(fn: (@Ann x: Int)->Unit) {} + +fun inParamNested(fn1: (fn2: (@Ann n: Int)->Unit)->Unit) {} + +fun inReturn(): (@Ann x: Int)->Unit = {} + +class A : (@Ann Int)->Unit { + override fun invoke(p1: Int) { + var lambda: (@Ann x: Int)->Unit = {} + } + + val prop: (@Ann x: Int)->Unit + get(): (@Ann x: Int)->Unit = {} +} + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn + +val onType: (@TypeAnn A).(@Ann a: @TypeAnn A, @TypeAnn A)->@TypeAnn A? = { null } + +fun (@TypeAnn A).extFun(@Ann a: @TypeAnn A): @TypeAnn A? = null \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/annotationOnParameterInFunctionType.txt b/compiler/testData/diagnostics/tests/annotations/annotationOnParameterInFunctionType.txt new file mode 100644 index 0000000000000000000000000000000000000000..ef3339c5fdada18cb42b89cdc184a1bc9001b2e6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/annotationOnParameterInFunctionType.txt @@ -0,0 +1,32 @@ +package + +public val inVal: (kotlin.Int) -> kotlin.Unit +public val onType: @TypeAnn() A.(@TypeAnn() A, A) -> A? +public fun f(/*0*/ @Ann() x: kotlin.Int): kotlin.Unit +public fun inParam(/*0*/ fn: (kotlin.Int) -> kotlin.Unit): kotlin.Unit +public fun inParamNested(/*0*/ fn1: ((kotlin.Int) -> kotlin.Unit) -> kotlin.Unit): kotlin.Unit +public fun inReturn(): (kotlin.Int) -> kotlin.Unit +public fun @TypeAnn() A.extFun(/*0*/ @Ann() a: @TypeAnn() A): A? + +public final class A : (kotlin.Int) -> kotlin.Unit { + public constructor A() + public final val prop: (kotlin.Int) -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun invoke(/*0*/ p1: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.annotation() public final class Ann : kotlin.Annotation { + public constructor Ann() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) @kotlin.annotation.annotation() public final class TypeAnn : kotlin.Annotation { + public constructor TypeAnn() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.kt b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.kt index c8f114d1c624d91ac2b035bf84f6accb659e770d..d01e25e24dcffc081563c34f2e9d93b0f2965530 100644 --- a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.kt +++ b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.kt @@ -1,4 +1,3 @@ package typeReferenceError -class Pair<:(val c: fun main() - +class Pair<:(val c: fun main() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.kt b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.kt new file mode 100644 index 0000000000000000000000000000000000000000..10a3ad8302f5cc5ed91c22de9f25bce1c9411fa1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.kt @@ -0,0 +1,52 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +fun f(vararg x: Int) {} + +val inVal: (vararg x: Int)->Unit = {} + +fun inParam(fn: (vararg x: Int)->Unit) {} + +fun inParamNested(fn1: (fn2: (vararg n: Int)->Unit)->Unit) {} + +fun inReturn(): (vararg x: Int)->Unit = {} + +class A : (vararg x: Int)->Unit { + override fun invoke(p1: Int) { + var lambda: (vararg x: Int)->Unit = {} + } + + val prop: (vararg x: Int)->Unit + get(): (vararg x: Int)->Unit = {} +} + +val allProhibited: (abstract + annotation + companion + const + crossinline + data + enum + external + final + in + inline + inner + internal + lateinit + noinline + open + operator + out + override + private + protected + public + reified + sealed + tailrec + vararg + + x: Int)->Unit = {} + +val valProhibited: (val x: Int)->Unit = {} +val varProhibited: (var x: Int)->Unit = {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.txt b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.txt new file mode 100644 index 0000000000000000000000000000000000000000..94ed5d88f43ff05b0e326fe3ce931793806d82cc --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.txt @@ -0,0 +1,19 @@ +package + +public val allProhibited: (kotlin.Int) -> kotlin.Unit +public val inVal: (kotlin.Int) -> kotlin.Unit +public val valProhibited: (kotlin.Int) -> kotlin.Unit +public val varProhibited: (kotlin.Int) -> kotlin.Unit +public fun f(/*0*/ vararg x: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit +public fun inParam(/*0*/ fn: (kotlin.Int) -> kotlin.Unit): kotlin.Unit +public fun inParamNested(/*0*/ fn1: ((kotlin.Int) -> kotlin.Unit) -> kotlin.Unit): kotlin.Unit +public fun inReturn(): (kotlin.Int) -> kotlin.Unit + +public final class A : (kotlin.Int) -> kotlin.Unit { + public constructor A() + public final val prop: (kotlin.Int) -> kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun invoke(/*0*/ p1: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 8879a5e32e16ed5604760e621f549e61094410cf..fd9dd0ef3d5a3e112f1a6acc4bc7f2dff2f6ea14 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -175,6 +175,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("DefaultValueForParameterInFunctionType.kt") + public void testDefaultValueForParameterInFunctionType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DefaultValueForParameterInFunctionType.kt"); + doTest(fileName); + } + @TestMetadata("DefaultValuesTypechecking.kt") public void testDefaultValuesTypechecking() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DefaultValuesTypechecking.kt"); @@ -777,6 +783,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("annotationOnParameterInFunctionType.kt") + public void testAnnotationOnParameterInFunctionType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/annotationOnParameterInFunctionType.kt"); + doTest(fileName); + } + @TestMetadata("AnnotationsForClasses.kt") public void testAnnotationsForClasses() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/AnnotationsForClasses.kt"); @@ -9411,6 +9423,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("modifierOnParameterInFunctionType.kt") + public void testModifierOnParameterInFunctionType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.kt"); + doTest(fileName); + } + @TestMetadata("NoLocalVisibility.kt") public void testNoLocalVisibility() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/NoLocalVisibility.kt");