From a9a30a1b7d388c3b3ee44bad27b5d3a294c6e597 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 19 Dec 2014 20:54:09 +0300 Subject: [PATCH] PSI Pattern Matching: Respect type arguments when matching calls #KT-6496 Fixed --- .../util/psi/patternMatching/JetPsiUnifier.kt | 21 ++++++++++++++++++- .../FunctionLiteralWithExtraArgs.kt | 4 ++++ .../FunctionLiteralWithExtraArgs.kt.after | 5 +++++ .../calls/callTypeArgumentsRuntime.kt | 19 +++++++++++++++++ .../calls/callTypeArgumentsRuntime.kt.match | 3 +++ .../JetExtractionTestGenerated.java | 6 ++++++ .../JetPsiUnifierTestGenerated.java | 6 ++++++ 7 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt create mode 100644 idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt.after create mode 100644 idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt create mode 100644 idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt.match diff --git a/idea/src/org/jetbrains/jet/plugin/util/psi/patternMatching/JetPsiUnifier.kt b/idea/src/org/jetbrains/jet/plugin/util/psi/patternMatching/JetPsiUnifier.kt index 25e8f10297d..64649d91d94 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/psi/patternMatching/JetPsiUnifier.kt +++ b/idea/src/org/jetbrains/jet/plugin/util/psi/patternMatching/JetPsiUnifier.kt @@ -276,12 +276,30 @@ public class JetPsiUnifier( } } + fun checkTypeArguments(): Status? { + val typeArgs1 = rc1.getTypeArguments().toList() + val typeArgs2 = rc2.getTypeArguments().toList() + if (typeArgs1.size() != typeArgs2.size()) return UNMATCHED + + for ((typeArg1, typeArg2) in (typeArgs1 zip typeArgs2)) { + if (!matchDescriptors(typeArg1.first, typeArg2.first)) return UNMATCHED + + val s = matchTypes(typeArg1.second, typeArg2.second) + if (s != MATCHED) return s + } + + return MATCHED + } + return when { !checkSpecialOperations() -> UNMATCHED !matchDescriptors(rc1.getCandidateDescriptor(), rc2.getCandidateDescriptor()) -> UNMATCHED !checkReceivers() -> UNMATCHED rc1.isSafeCall() != rc2.isSafeCall() -> UNMATCHED - else -> checkArguments() + else -> { + val s = checkTypeArguments() + if (s != MATCHED) s else checkArguments() + } } } @@ -337,6 +355,7 @@ public class JetPsiUnifier( private fun matchTypes(type1: JetType?, type2: JetType?): Status? { if (type1 != null && type2 != null) { + if (type1.isError() || type2.isError()) return null if (TypeUtils.equalTypes(type1, type2)) return MATCHED if (type1.isMarkedNullable() != type2.isMarkedNullable()) return UNMATCHED diff --git a/idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt b/idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt new file mode 100644 index 00000000000..fb7fbd1904b --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt @@ -0,0 +1,4 @@ +// WITH_RUNTIME +fun foo(c : Collection){ + c.filterTo(ArrayList()){ it.length() > 1 } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt.after b/idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt.after new file mode 100644 index 00000000000..2978314b7bd --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt.after @@ -0,0 +1,5 @@ +// WITH_RUNTIME +fun foo(c : Collection){ + val function: (String) -> Boolean = { it.length() > 1 } + c.filterTo(ArrayList(), function) +} \ No newline at end of file diff --git a/idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt b/idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt new file mode 100644 index 00000000000..ba54690bf35 --- /dev/null +++ b/idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt @@ -0,0 +1,19 @@ +// DISABLE-ERRORS +class A +class B + +fun foo(klass: Class) { + +} + +fun bar(klass: Class) { + +} + +fun main() { + foo(javaClass()) + foo(javaClass()) + bar(javaClass()) + bar(javaClass()) + javaClass() +} \ No newline at end of file diff --git a/idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt.match b/idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt.match new file mode 100644 index 00000000000..45f0e273efd --- /dev/null +++ b/idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt.match @@ -0,0 +1,3 @@ +javaClass() + +javaClass() \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java index d174a96314d..6d310d2f436 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java @@ -93,6 +93,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doIntroduceVariableTest(fileName); } + @TestMetadata("FunctionLiteralWithExtraArgs.kt") + public void testFunctionLiteralWithExtraArgs() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/FunctionLiteralWithExtraArgs.kt"); + doIntroduceVariableTest(fileName); + } + @TestMetadata("IfCondition.kt") public void testIfCondition() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/IfCondition.kt"); diff --git a/idea/tests/org/jetbrains/jet/psi/patternMatching/JetPsiUnifierTestGenerated.java b/idea/tests/org/jetbrains/jet/psi/patternMatching/JetPsiUnifierTestGenerated.java index 2eb95019fae..276f38a62a1 100644 --- a/idea/tests/org/jetbrains/jet/psi/patternMatching/JetPsiUnifierTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/psi/patternMatching/JetPsiUnifierTestGenerated.java @@ -396,6 +396,12 @@ public class JetPsiUnifierTestGenerated extends AbstractJetPsiUnifierTest { doTest(fileName); } + @TestMetadata("callTypeArgumentsRuntime.kt") + public void testCallTypeArgumentsRuntime() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/unifier/equivalence/expressions/calls/callTypeArgumentsRuntime.kt"); + doTest(fileName); + } + @TestMetadata("externalArgumentsRuntime.kt") public void testExternalArgumentsRuntime() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/unifier/equivalence/expressions/calls/externalArgumentsRuntime.kt");