diff --git a/.idea/dictionaries/valentin.xml b/.idea/dictionaries/valentin.xml
index 8615d4e262c..990faa769a7 100644
--- a/.idea/dictionaries/valentin.xml
+++ b/.idea/dictionaries/valentin.xml
@@ -9,6 +9,7 @@
inserter
negatable
pparent
+ precheck
prioritizer
processings
rbrace
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallKindHandler.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallKindHandler.kt
new file mode 100644
index 00000000000..ebd4b0418a7
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallKindHandler.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.quickfix.replaceWith
+
+import org.jetbrains.kotlin.idea.core.replaced
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
+
+internal interface CallKindHandler {
+ val elementToReplace: JetElement
+
+ fun precheckReplacementPattern(pattern: ReplaceWithAnnotationAnalyzer.ReplacementExpression): Boolean
+
+ fun wrapGeneratedExpression(expression: JetExpression): JetElement
+
+ fun unwrapResult(result: JetElement): JetElement
+}
+
+internal class CallExpressionHandler(callElement: JetExpression) : CallKindHandler {
+ override val elementToReplace = callElement.getQualifiedExpressionForSelectorOrThis()
+
+ override fun precheckReplacementPattern(pattern: ReplaceWithAnnotationAnalyzer.ReplacementExpression) = true
+
+ override fun wrapGeneratedExpression(expression: JetExpression) = expression
+
+ override fun unwrapResult(result: JetElement) = result
+}
+
+internal class AnnotationEntryHandler(annotationEntry: JetAnnotationEntry) : CallKindHandler {
+ override val elementToReplace = annotationEntry
+
+ override fun precheckReplacementPattern(pattern: ReplaceWithAnnotationAnalyzer.ReplacementExpression): Boolean {
+ //TODO
+ return true
+ }
+
+ //TODO: how to prohibit wrapping replacement expression into anything?
+
+ override fun wrapGeneratedExpression(expression: JetExpression): JetAnnotationEntry {
+ return createByPattern("@Dummy($0)", expression) { JetPsiFactory(expression).createAnnotationEntry(it) }
+ }
+
+ override fun unwrapResult(result: JetElement): JetAnnotationEntry {
+ result as JetAnnotationEntry
+ val text = result.valueArguments.single().getArgumentExpression()!!.text
+ return result.replaced(JetPsiFactory(result).createAnnotationEntry("@" + text))
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt
index f67836f815c..7590fcd7c84 100644
--- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt
@@ -60,9 +60,23 @@ class CallableUsageReplacementStrategy(
val bindingContext = usage.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = usage.getResolvedCall(bindingContext) ?: return null
if (!resolvedCall.isReallySuccess()) return null
+
+ val callElement = resolvedCall.call.callElement
+ val callTypeHandler = callTypeHandler(callElement) ?: return null
+
+ if (!callTypeHandler.precheckReplacementPattern(replacement)) return null
+
return {
// copy replacement expression because it is modified by performCallReplacement
- performCallReplacement(usage, bindingContext, resolvedCall, replacement.copy())
+ performCallReplacement(usage, bindingContext, resolvedCall, callElement, callTypeHandler, replacement.copy())
+ }
+ }
+
+ private fun callTypeHandler(callElement: JetElement): CallKindHandler? {
+ return when (callElement) {
+ is JetExpression -> CallExpressionHandler(callElement)
+ is JetAnnotationEntry -> AnnotationEntryHandler(callElement)
+ else -> null
}
}
}
@@ -71,15 +85,16 @@ private fun performCallReplacement(
element: JetSimpleNameExpression,
bindingContext: BindingContext,
resolvedCall: ResolvedCall,
+ callElement: JetElement,
+ callKindHandler: CallKindHandler,
replacement: ReplaceWithAnnotationAnalyzer.ReplacementExpression
): JetElement {
val project = element.project
val psiFactory = JetPsiFactory(project)
val descriptor = resolvedCall.resultingDescriptor
- val callElement = resolvedCall.call.callElement
val qualifiedExpression = callElement.getQualifiedExpressionForSelector()
- val elementToBeReplaced = qualifiedExpression ?: callElement
+ val elementToBeReplaced = callKindHandler.elementToReplace
val commentSaver = CommentSaver(elementToBeReplaced, saveLineBreaks = true)
@@ -137,7 +152,8 @@ private fun performCallReplacement(
}
}
- var result = elementToBeReplaced.replaceCallElement(wrapper.expression)
+ val wrappedExpression = callKindHandler.wrapGeneratedExpression(wrapper.expression)
+ var result = elementToBeReplaced.replace(wrappedExpression) as JetElement
val file = result.getContainingJetFile()
replacement.fqNamesToImport
@@ -153,27 +169,8 @@ private fun performCallReplacement(
commentSaver.restore(resultRange)
- var resultElement = resultRange.last as JetElement
-
- if (resultElement is JetAnnotationEntry) { // unwrap "@Dummy(...)"
- val text = resultElement.valueArguments.single().getArgumentExpression()!!.text
- resultElement = resultElement.replaced(JetPsiFactory(project).createAnnotationEntry("@" + text)) //TODO: what if it does not work?
- }
-
- return resultElement
-}
-
-private fun JetElement.replaceCallElement(generatedExpression: JetExpression): JetElement {
- when (this) {
- is JetExpression -> return replace(generatedExpression) as JetExpression
-
- is JetAnnotationEntry -> {
- val dummyAnnotation = createByPattern("@Dummy($0)", generatedExpression) { JetPsiFactory(project).createAnnotationEntry(it) }
- return replace(dummyAnnotation) as JetElement
- }
-
- else -> throw UnsupportedOperationException() //TODO: check it before!!
- }
+ @Suppress("UNCHECKED_CAST")
+ return callKindHandler.unwrapResult(resultRange.last as JetElement)
}
private fun ConstructedExpressionWrapper.processValueParameterUsages(