From b17b3f4c6314208b3103fa42b5bf1a50886b4cb2 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Fri, 14 Apr 2017 16:10:52 +0300 Subject: [PATCH] Resolve local function parameters with function inner scope This allows to use type parameters and value paramters in default value expressions #KT-7984 Fixed #KT-7985 Fixed --- .../types/expressions/FunctionsTypingVisitor.kt | 4 ++-- .../box/localFunctions/parameterAsDefaultValue.kt | 11 +++++++++++ .../parameterAsDefaultValueInLocalFunction.kt | 6 ++++++ .../parameterAsDefaultValueInLocalFunction.txt | 3 +++ .../typeParameterInDefaultValueInLocalFunction.kt | 7 +++++++ ...typeParameterInDefaultValueInLocalFunction.txt | 4 ++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 15 +++++++++++++++ .../kotlin/checkers/DiagnosticsTestGenerated.java | 12 ++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 15 +++++++++++++++ .../codegen/LightAnalysisModeTestGenerated.java | 15 +++++++++++++++ .../functions/localFunctionParameters.kt | 1 + .../functions/localFunctionParameters.kt.after | 7 +++++++ .../localFunctionParameters.kt.conflicts | 1 - .../localFunctionParametersWithLambda.kt | 1 + .../localFunctionParametersWithLambda.kt.after | 7 +++++++ ...localFunctionParametersWithLambda.kt.conflicts | 1 - .../test/semantics/JsCodegenBoxTestGenerated.java | 15 +++++++++++++++ 17 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.txt create mode 100644 compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.txt create mode 100644 idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.after delete mode 100644 idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.conflicts create mode 100644 idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.after delete mode 100644 idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.conflicts 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 6fb37bf6873..2ab831b5a46 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt @@ -101,18 +101,18 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre // Necessary for local functions ForceResolveUtil.forceResolveAllContents(functionDescriptor.annotations) + val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace, components.overloadChecker) if (!function.hasDeclaredReturnType() && !function.hasBlockBody()) { ForceResolveUtil.forceResolveAllContents(functionDescriptor.returnType) } else { - val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace, components.overloadChecker) components.expressionTypingServices.checkFunctionReturnType( functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace ) } components.valueParameterResolver.resolveValueParameters( - function.valueParameters, functionDescriptor.valueParameters, context.scope, context.dataFlowInfo, context.trace + function.valueParameters, functionDescriptor.valueParameters, functionInnerScope, context.dataFlowInfo, context.trace ) components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(function, functionDescriptor) diff --git a/compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt b/compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt new file mode 100644 index 00000000000..e90fe97fede --- /dev/null +++ b/compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt @@ -0,0 +1,11 @@ +fun foo(): String { + fun bar(x: String, y: String = x): String { + return y + } + + return bar("OK") +} + +fun box(): String { + return foo() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.kt b/compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.kt new file mode 100644 index 00000000000..5d10ec7a338 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.kt @@ -0,0 +1,6 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun foo() { + fun bar(x: String, y: String = x) {} + fun baz(x: Int = y, y: Int) {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.txt b/compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.txt new file mode 100644 index 00000000000..65a6ac47e1f --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.txt @@ -0,0 +1,3 @@ +package + +public fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.kt b/compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.kt new file mode 100644 index 00000000000..e08e089c0ad --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.kt @@ -0,0 +1,7 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun foo() { + fun bar(x: List = listOf()) {} +} + +fun listOf(): List = TODO() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.txt b/compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.txt new file mode 100644 index 00000000000..f0d9ba98386 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.txt @@ -0,0 +1,4 @@ +package + +public fun foo(): kotlin.Unit +public fun listOf(): kotlin.collections.List diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 501b1f4a446..10bcf64b91c 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10398,6 +10398,21 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/localFunctions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class LocalFunctions extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInLocalFunctions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 50cff0711d6..332e6528d2e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -17164,6 +17164,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("parameterAsDefaultValueInLocalFunction.kt") + public void testParameterAsDefaultValueInLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/parameterAsDefaultValueInLocalFunction.kt"); + doTest(fileName); + } + @TestMetadata("resolveAnnotatedLambdaArgument.kt") public void testResolveAnnotatedLambdaArgument() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt"); @@ -17218,6 +17224,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("typeParameterInDefaultValueInLocalFunction.kt") + public void testTypeParameterInDefaultValueInLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.kt"); + doTest(fileName); + } + @TestMetadata("wrongNumberOfTypeArguments.kt") public void testWrongNumberOfTypeArguments() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/wrongNumberOfTypeArguments.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 771308b1b4e..95652efcd78 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -10398,6 +10398,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/localFunctions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class LocalFunctions extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInLocalFunctions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4810de987d9..52b0163942f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10398,6 +10398,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/localFunctions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class LocalFunctions extends AbstractLightAnalysisModeTest { + public void testAllFilesPresentInLocalFunctions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt index 9660d918d3b..e5192e07eb9 100644 --- a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt +++ b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt @@ -1,4 +1,5 @@ // PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: value-parameter a: kotlin.Int defined in bar.foo fun bar(n: Int) { fun foo(a: Int, b: Int = a + n) = a + b - n - 1 } \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.after b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.after new file mode 100644 index 00000000000..c0eff07b6c2 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.after @@ -0,0 +1,7 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: value-parameter a: kotlin.Int defined in bar.foo +fun bar(n: Int) { + fun i(a: Int) = a + n + + fun foo(a: Int, b: Int = i(a)) = a + b - n - 1 +} diff --git a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.conflicts b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.conflicts deleted file mode 100644 index ecdc4331d76..00000000000 --- a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParameters.kt.conflicts +++ /dev/null @@ -1 +0,0 @@ -Cannot generate function with erroneous return type \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt index 7d297563fea..dbfe01f5212 100644 --- a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt +++ b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt @@ -1,4 +1,5 @@ // PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: value-parameter a: kotlin.Int defined in bar.foo fun bar(n: Int) { fun foo(a: Int, b: Int = { a + n }.invoke()) = a + b - n - 1 } \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.after b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.after new file mode 100644 index 00000000000..1a8cc6226f1 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.after @@ -0,0 +1,7 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: value-parameter a: kotlin.Int defined in bar.foo +fun bar(n: Int) { + fun i(a: Int) = a + n + + fun foo(a: Int, b: Int = { i(a) }.invoke()) = a + b - n - 1 +} diff --git a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.conflicts b/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.conflicts deleted file mode 100644 index ecdc4331d76..00000000000 --- a/idea/testData/refactoring/extractFunction/initializers/functions/localFunctionParametersWithLambda.kt.conflicts +++ /dev/null @@ -1 +0,0 @@ -Cannot generate function with erroneous return type \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 2156cbe4569..fded6e22a09 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11941,6 +11941,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/localFunctions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class LocalFunctions extends AbstractJsCodegenBoxTest { + public void testAllFilesPresentInLocalFunctions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("parameterAsDefaultValue.kt") + public void testParameterAsDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/localFunctions/parameterAsDefaultValue.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/mangling") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)