From 2deb7faf053f67987b7841c76051b51e626a3a93 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Sat, 16 May 2015 19:04:36 +0300 Subject: [PATCH] Deprecate function expressions with names --- .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../expressions/FunctionsTypingVisitor.kt | 5 +++++ .../tests/FunctionParameterWithoutType.kt | 2 +- .../tests/annotations/onFunctionParameter.kt | 2 +- .../tests/functionAsExpression/AutoLabels.kt | 6 +----- .../tests/functionAsExpression/AutoLabels.txt | 1 - .../tests/functionAsExpression/Common.kt | 2 -- .../tests/functionAsExpression/Common.txt | 2 -- .../DifficultInferenceForParameter.kt | 2 +- .../ForbiddenNonLocalReturn.kt | 5 ----- .../functionAsExpression/NameDeprecation.kt | 11 ++++++++++ .../functionAsExpression/NameDeprecation.txt | 3 +++ .../functionAsExpression/NoOverloadError.kt | 20 +++++++++---------- .../functionAsExpression/ReturnAndLabels.kt | 4 ---- .../functionAsExpression/ReturnAndLabels.txt | 1 - .../WithGenericParameters.kt | 8 ++++---- .../tests/functionAsExpression/WithoutBody.kt | 6 +++--- .../wrongReceiverForInvokeOnExpression.kt | 2 +- .../checkers/JetDiagnosticsTestGenerated.java | 6 ++++++ 20 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.kt create mode 100644 compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 0d006f41bb2..e7cb241c7ee 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -350,6 +350,7 @@ public interface Errors { DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 FUNCTION_DECLARATION_WITH_NO_NAME = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory0 FUNCTION_EXPRESSION_WITH_NAME = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 3aadfe8706f..4ca0dcfeb87 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -197,6 +197,7 @@ public class DefaultErrorMessages { MAP.put(NON_MEMBER_FUNCTION_NO_BODY, "Function ''{0}'' must have a body", NAME); MAP.put(FUNCTION_DECLARATION_WITH_NO_NAME, "Function declaration must have a name"); + MAP.put(FUNCTION_EXPRESSION_WITH_NAME, "Function expressions with names are deprecated"); MAP.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "\"open\" has no effect in a final class"); MAP.put(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, "Public or protected member should have specified type"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt index b1c9dea919b..87eeffa4ed3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt @@ -59,6 +59,11 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express if (!function.getTypeParameters().isEmpty()) { context.trace.report(TYPE_PARAMETERS_NOT_ALLOWED.on(function)) } + + if (function.getName() != null) { + context.trace.report(FUNCTION_EXPRESSION_WITH_NAME.on(function.getNameIdentifier())) + } + for (parameter in function.getValueParameters()) { if (parameter.hasDefaultValue()) { context.trace.report(FUNCTION_EXPRESSION_PARAMETER_WITH_DEFAULT_VALUE.on(parameter)) diff --git a/compiler/testData/diagnostics/tests/FunctionParameterWithoutType.kt b/compiler/testData/diagnostics/tests/FunctionParameterWithoutType.kt index 430f8918eaf..6945941c99c 100644 --- a/compiler/testData/diagnostics/tests/FunctionParameterWithoutType.kt +++ b/compiler/testData/diagnostics/tests/FunctionParameterWithoutType.kt @@ -5,7 +5,7 @@ fun test(a) { class A(a) -val bar = fun test(a){} +val bar = fun(a){} val la = { a -> } val las = { a: Int -> } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/onFunctionParameter.kt b/compiler/testData/diagnostics/tests/annotations/onFunctionParameter.kt index cbf9a208e8b..33eceb5b8a0 100644 --- a/compiler/testData/diagnostics/tests/annotations/onFunctionParameter.kt +++ b/compiler/testData/diagnostics/tests/annotations/onFunctionParameter.kt @@ -4,6 +4,6 @@ fun test(@ann p: Int) { } -val bar = fun test(@ann g: Int) {} +val bar = fun(@ann g: Int) {} val bas = { (@ann t: Int) -> } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.kt b/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.kt index 616d199753d..79866b22e2c 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.kt @@ -6,10 +6,6 @@ fun autolabel(l: List) = l.map (fun (i: Int): Int { return@map 4 }) -fun unresolvedMapLabel(l: List) = l.map (fun test(i: Int): Int { +fun unresolvedMapLabel(l: List) = l.map (l@ fun(i: Int): Int { return@map 4 }) - -fun labelToFunName(l: List) = l.map (fun test(i: Int): Int { - return@test 4 -}) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.txt b/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.txt index 621934e82e3..20e86cfd41c 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.txt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/AutoLabels.txt @@ -1,6 +1,5 @@ package internal fun autolabel(/*0*/ l: kotlin.List): kotlin.List -internal fun labelToFunName(/*0*/ l: kotlin.List): kotlin.List internal fun unresolvedMapLabel(/*0*/ l: kotlin.List): kotlin.List internal fun kotlin.Iterable.map(/*0*/ transform: (T) -> R): kotlin.List diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt b/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt index 11534e39e6e..63f0e9dbc16 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/Common.kt @@ -6,8 +6,6 @@ val ok = "OK" class A -val withName = fun name() {} -val extensionWithName = fun A.name() {} val withoutName = fun () {} val extensionWithoutName = fun A.() {} diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt b/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt index 2ac715e9b26..850048ccdce 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/Common.txt @@ -1,13 +1,11 @@ package -internal val extensionWithName: A.() -> kotlin.Unit internal val extensionWithoutName: A.() -> kotlin.Unit internal val funfun: () -> () -> kotlin.Int internal val ok: kotlin.String = "OK" internal val parentesized: () -> kotlin.Unit internal val parentesizedWithType: () -> kotlin.Unit internal val withExpression: () -> kotlin.Int -internal val withName: () -> kotlin.Unit internal val withReturn: () -> kotlin.Int internal val withType: () -> kotlin.Unit internal val withoutName: () -> kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/DifficultInferenceForParameter.kt b/compiler/testData/diagnostics/tests/functionAsExpression/DifficultInferenceForParameter.kt index 1a46ccb279e..1c940b44ac6 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/DifficultInferenceForParameter.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/DifficultInferenceForParameter.kt @@ -3,5 +3,5 @@ fun foo(f : (T) -> T) : T = throw Exception() fun test() { - val a : Int = foo(fun f(x) = x) + val a : Int = foo(fun (x) = x) } diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/ForbiddenNonLocalReturn.kt b/compiler/testData/diagnostics/tests/functionAsExpression/ForbiddenNonLocalReturn.kt index 9ba5d3c91aa..274d3e57aa1 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/ForbiddenNonLocalReturn.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/ForbiddenNonLocalReturn.kt @@ -19,9 +19,4 @@ fun foo() { } return@bag } - val bag = fun name() { - val bar = fun () { - return@name - } - } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.kt b/compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.kt new file mode 100644 index 00000000000..99f47c46497 --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.kt @@ -0,0 +1,11 @@ +fun foo() { + fun run(block: () -> Unit) = block() + + class A + fun bar() {} + (fun bar() {}) + fun A.foo() {} + (fun A.foo() {}) + + run(fun foo() {}) +} diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.txt b/compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.txt new file mode 100644 index 00000000000..093bfc34070 --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.txt @@ -0,0 +1,3 @@ +package + +internal fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt b/compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt index b018c444f65..13610785b58 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt @@ -1,18 +1,18 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -val bar = fun name() {} -val bas = fun name() {} +val bar = fun() {} +val bas = fun() {} -fun gar(p: Any?) = fun name() {} -fun gas(p: Any?) = fun name() {} +fun gar(p: Any?) = fun() {} +fun gas(p: Any?) = fun() {} fun outer() { - val bar = fun name() {} - val bas = fun name() {} + val bar = fun() {} + val bas = fun() {} - fun gar(p: Any?) = fun name() {} - fun gas(p: Any?) = fun name() {} + fun gar(p: Any?) = fun() {} + fun gas(p: Any?) = fun() {} - gar(fun name() {}) - gar(fun name() {}) + gar(fun() {}) + gar(fun() {}) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.kt b/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.kt index 72eb1b423fa..519b889788a 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.kt @@ -7,7 +7,3 @@ val label_fun = label@ fun () { val parenthesized_label_fun = (label@ fun () { return@label }) - -val fun_with_name = fun name() { - return@name -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.txt b/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.txt index ac8c8eb23c6..03712b79ae8 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.txt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/ReturnAndLabels.txt @@ -1,5 +1,4 @@ package -internal val fun_with_name: () -> kotlin.Unit internal val label_fun: () -> kotlin.Unit internal val parenthesized_label_fun: () -> kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/WithGenericParameters.kt b/compiler/testData/diagnostics/tests/functionAsExpression/WithGenericParameters.kt index 118af628948..74b74e8c350 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/WithGenericParameters.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/WithGenericParameters.kt @@ -11,8 +11,8 @@ fun fun_with_where() = fun T.(t: T): T whe fun outer() { devNull(fun () {}) - devNull(fun T.name() {}) - devNull(fun name(): T = null!!) - devNull(fun name(t: T) {}) - devNull(fun name() where T:A {}) + devNull(fun T.() {}) + devNull(fun (): T = null!!) + devNull(fun (t: T) {}) + devNull(fun () where T:A {}) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/WithoutBody.kt b/compiler/testData/diagnostics/tests/functionAsExpression/WithoutBody.kt index 07692a43fd2..a80a8ac283e 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/WithoutBody.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/WithoutBody.kt @@ -3,10 +3,10 @@ annotation class ann val bas = fun () -fun bar(a: Any) = fun name() +fun bar(a: Any) = fun () fun outer() { bar(fun ()) - bar(fun name()) - bar(@ann fun name()) + bar(l@ fun ()) + bar(@ann fun ()) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.kt b/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.kt index bacdd1929d9..7a85f50e76d 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.kt @@ -1,6 +1,6 @@ fun test1() { 1. (fun String.(i: Int) = i )(1) - 1.(fun String.label(i: Int) = i )(1) + 1.(label@ fun String.(i: Int) = i )(1) } fun test2(f: String.(Int) -> Unit) { diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index a6c2cf7fd66..57c2a35dce8 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -4785,6 +4785,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("NameDeprecation.kt") + public void testNameDeprecation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionAsExpression/NameDeprecation.kt"); + doTest(fileName); + } + @TestMetadata("NoOverloadError.kt") public void testNoOverloadError() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt");