Renames
This commit is contained in:
Generated
+1
-1
@@ -44,13 +44,13 @@
|
|||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" filepath="$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" filepath="$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-android/idea-android.iml" filepath="$PROJECT_DIR$/idea/idea-android/idea-android.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-android/idea-android.iml" filepath="$PROJECT_DIR$/idea/idea-android/idea-android.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" filepath="$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" filepath="$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" group="ide" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-code-inliner/idea-replacement-engine.iml" filepath="$PROJECT_DIR$/idea/idea-code-inliner/idea-replacement-engine.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" filepath="$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" filepath="$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" filepath="$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" filepath="$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" filepath="$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" filepath="$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-replacement-engine/idea-replacement-engine.iml" filepath="$PROJECT_DIR$/idea/idea-replacement-engine/idea-replacement-engine.iml" group="ide" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea-runner/idea-runner.iml" filepath="$PROJECT_DIR$/idea-runner/idea-runner.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea-runner/idea-runner.iml" filepath="$PROJECT_DIR$/idea-runner/idea-runner.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" filepath="$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" group="ide" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" filepath="$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" group="ide" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" filepath="$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" group="compiler/cli" />
|
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" filepath="$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" group="compiler/cli" />
|
||||||
|
|||||||
+3
-3
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
|||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
class CallableUsageReplacementStrategy(
|
class CallableUsageReplacementStrategy(
|
||||||
private val replacement: ReplacementCode
|
private val replacement: CodeToInline
|
||||||
) : UsageReplacementStrategy {
|
) : UsageReplacementStrategy {
|
||||||
|
|
||||||
override fun createReplacer(usage: KtSimpleNameExpression): (() -> KtElement?)? {
|
override fun createReplacer(usage: KtSimpleNameExpression): (() -> KtElement?)? {
|
||||||
@@ -44,7 +44,7 @@ class CallableUsageReplacementStrategy(
|
|||||||
createReplacer(nameExpression)!!.invoke()
|
createReplacer(nameExpression)!!.invoke()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CallReplacementEngine(usage, bindingContext, resolvedCall, callElement, replacement).performReplacement()
|
CodeInliner(usage, bindingContext, resolvedCall, callElement, replacement).doInline()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.check
|
|||||||
|
|
||||||
class ClassUsageReplacementStrategy(
|
class ClassUsageReplacementStrategy(
|
||||||
typeReplacement: KtUserType?,
|
typeReplacement: KtUserType?,
|
||||||
constructorReplacement: ReplacementCode?,
|
constructorReplacement: CodeToInline?,
|
||||||
project: Project
|
project: Project
|
||||||
) : UsageReplacementStrategy {
|
) : UsageReplacementStrategy {
|
||||||
|
|
||||||
+37
-37
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
@@ -45,18 +45,18 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CallReplacementEngine<TCallElement : KtElement>(
|
class CodeInliner<TCallElement : KtElement>(
|
||||||
private val nameExpression: KtSimpleNameExpression,
|
private val nameExpression: KtSimpleNameExpression,
|
||||||
private val bindingContext: BindingContext,
|
private val bindingContext: BindingContext,
|
||||||
private val resolvedCall: ResolvedCall<out CallableDescriptor>,
|
private val resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||||
private val callElement: TCallElement,
|
private val callElement: TCallElement,
|
||||||
replacement: ReplacementCode
|
codeToInline: CodeToInline
|
||||||
) {
|
) {
|
||||||
private val replacement = replacement.toMutable()
|
private val codeToInline = codeToInline.toMutable()
|
||||||
private val project = nameExpression.project
|
private val project = nameExpression.project
|
||||||
private val psiFactory = KtPsiFactory(project)
|
private val psiFactory = KtPsiFactory(project)
|
||||||
|
|
||||||
fun performReplacement(): KtElement? {
|
fun doInline(): KtElement? {
|
||||||
val descriptor = resolvedCall.resultingDescriptor
|
val descriptor = resolvedCall.resultingDescriptor
|
||||||
val file = nameExpression.getContainingKtFile()
|
val file = nameExpression.getContainingKtFile()
|
||||||
|
|
||||||
@@ -82,9 +82,9 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
receiver?.mark(RECEIVER_VALUE_KEY)
|
receiver?.mark(RECEIVER_VALUE_KEY)
|
||||||
|
|
||||||
//TODO: this@
|
//TODO: this@
|
||||||
for (thisExpression in replacement.collectDescendantsOfType<KtThisExpression>()) {
|
for (thisExpression in codeToInline.collectDescendantsOfType<KtThisExpression>()) {
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
replacement.replaceExpression(thisExpression, receiver)
|
codeToInline.replaceExpression(thisExpression, receiver)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thisExpression.mark(RECEIVER_VALUE_KEY)
|
thisExpression.mark(RECEIVER_VALUE_KEY)
|
||||||
@@ -104,25 +104,25 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
|
|
||||||
if (elementToBeReplaced is KtExpression) {
|
if (elementToBeReplaced is KtExpression) {
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
val thisReplaced = replacement.collectDescendantsOfType<KtExpression> { it[RECEIVER_VALUE_KEY] }
|
val thisReplaced = codeToInline.collectDescendantsOfType<KtExpression> { it[RECEIVER_VALUE_KEY] }
|
||||||
if (receiver.shouldKeepValue(thisReplaced.size)) {
|
if (receiver.shouldKeepValue(thisReplaced.size)) {
|
||||||
replacement.introduceValue(receiver, receiverType, thisReplaced, elementToBeReplaced)
|
codeToInline.introduceValue(receiver, receiverType, thisReplaced, elementToBeReplaced)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((parameter, value, valueType) in introduceValuesForParameters) {
|
for ((parameter, value, valueType) in introduceValuesForParameters) {
|
||||||
val usagesReplaced = replacement.collectDescendantsOfType<KtExpression> { it[PARAMETER_VALUE_KEY] == parameter }
|
val usagesReplaced = codeToInline.collectDescendantsOfType<KtExpression> { it[PARAMETER_VALUE_KEY] == parameter }
|
||||||
replacement.introduceValue(value, valueType, usagesReplaced, elementToBeReplaced, nameSuggestion = parameter.name.asString())
|
codeToInline.introduceValue(value, valueType, usagesReplaced, elementToBeReplaced, nameSuggestion = parameter.name.asString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replacement.fqNamesToImport
|
codeToInline.fqNamesToImport
|
||||||
.flatMap { file.resolveImportReference(it) }
|
.flatMap { file.resolveImportReference(it) }
|
||||||
.forEach { ImportInsertHelper.getInstance(project).importDescriptor(file, it) }
|
.forEach { ImportInsertHelper.getInstance(project).importDescriptor(file, it) }
|
||||||
|
|
||||||
val replacementPerformer = when (elementToBeReplaced) {
|
val replacementPerformer = when (elementToBeReplaced) {
|
||||||
is KtExpression -> ExpressionReplacementPerformer(replacement, elementToBeReplaced)
|
is KtExpression -> ExpressionReplacementPerformer(codeToInline, elementToBeReplaced)
|
||||||
is KtAnnotationEntry -> AnnotationEntryReplacementPerformer(replacement, elementToBeReplaced)
|
is KtAnnotationEntry -> AnnotationEntryReplacementPerformer(codeToInline, elementToBeReplaced)
|
||||||
else -> error("Unsupported element")
|
else -> error("Unsupported element")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,8 +146,8 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
argument.expression.put(PARAMETER_VALUE_KEY, parameter)
|
argument.expression.put(PARAMETER_VALUE_KEY, parameter)
|
||||||
|
|
||||||
val parameterName = parameter.name
|
val parameterName = parameter.name
|
||||||
val usages = replacement.collectDescendantsOfType<KtExpression> {
|
val usages = codeToInline.collectDescendantsOfType<KtExpression> {
|
||||||
it[ReplacementCode.PARAMETER_USAGE_KEY] == parameterName
|
it[CodeToInline.PARAMETER_USAGE_KEY] == parameterName
|
||||||
}
|
}
|
||||||
usages.forEach {
|
usages.forEach {
|
||||||
val usageArgument = it.parent as? KtValueArgument
|
val usageArgument = it.parent as? KtValueArgument
|
||||||
@@ -157,7 +157,7 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
if (argument.isDefaultValue) {
|
if (argument.isDefaultValue) {
|
||||||
usageArgument?.mark(DEFAULT_PARAMETER_VALUE_KEY)
|
usageArgument?.mark(DEFAULT_PARAMETER_VALUE_KEY)
|
||||||
}
|
}
|
||||||
replacement.replaceExpression(it, argument.expression)
|
codeToInline.replaceExpression(it, argument.expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: sometimes we need to add explicit type arguments here because we don't have expected type in the new context
|
//TODO: sometimes we need to add explicit type arguments here because we don't have expected type in the new context
|
||||||
@@ -185,8 +185,8 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
|
|
||||||
for ((index, typeParameter) in typeParameters.withIndex()) {
|
for ((index, typeParameter) in typeParameters.withIndex()) {
|
||||||
val parameterName = typeParameter.name
|
val parameterName = typeParameter.name
|
||||||
val usages = replacement.collectDescendantsOfType<KtExpression> {
|
val usages = codeToInline.collectDescendantsOfType<KtExpression> {
|
||||||
it[ReplacementCode.TYPE_PARAMETER_USAGE_KEY] == parameterName
|
it[CodeToInline.TYPE_PARAMETER_USAGE_KEY] == parameterName
|
||||||
}
|
}
|
||||||
|
|
||||||
val type = resolvedCall.typeArguments[typeParameter]!!
|
val type = resolvedCall.typeArguments[typeParameter]!!
|
||||||
@@ -207,7 +207,7 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
val arguments =
|
val arguments =
|
||||||
if (typeElement is KtUserType && KotlinBuiltIns.isArray(type)) typeElement.typeArgumentList?.text.orEmpty()
|
if (typeElement is KtUserType && KotlinBuiltIns.isArray(type)) typeElement.typeArgumentList?.text.orEmpty()
|
||||||
else ""
|
else ""
|
||||||
replacement.replaceExpression(usage, psiFactory.createExpression(
|
codeToInline.replaceExpression(usage, psiFactory.createExpression(
|
||||||
IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(typeClassifier) + arguments
|
IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(typeClassifier) + arguments
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -216,21 +216,21 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//TODO: tests for this?
|
//TODO: tests for this?
|
||||||
replacement.replaceExpression(usage, psiFactory.createExpression(typeElement.text))
|
codeToInline.replaceExpression(usage, psiFactory.createExpression(typeElement.text))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapCodeForSafeCall(receiver: KtExpression, receiverType: KotlinType?, expressionToBeReplaced: KtExpression) {
|
private fun wrapCodeForSafeCall(receiver: KtExpression, receiverType: KotlinType?, expressionToBeReplaced: KtExpression) {
|
||||||
if (replacement.statementsBefore.isEmpty()) {
|
if (codeToInline.statementsBefore.isEmpty()) {
|
||||||
val qualified = replacement.mainExpression as? KtQualifiedExpression
|
val qualified = codeToInline.mainExpression as? KtQualifiedExpression
|
||||||
if (qualified != null) {
|
if (qualified != null) {
|
||||||
if (qualified.receiverExpression[RECEIVER_VALUE_KEY]) {
|
if (qualified.receiverExpression[RECEIVER_VALUE_KEY]) {
|
||||||
if (qualified is KtSafeQualifiedExpression) return // already safe
|
if (qualified is KtSafeQualifiedExpression) return // already safe
|
||||||
val selector = qualified.selectorExpression
|
val selector = qualified.selectorExpression
|
||||||
if (selector != null) {
|
if (selector != null) {
|
||||||
replacement.mainExpression = psiFactory.createExpressionByPattern("$0?.$1", receiver, selector)
|
codeToInline.mainExpression = psiFactory.createExpressionByPattern("$0?.$1", receiver, selector)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,32 +238,32 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (expressionToBeReplaced.isUsedAsExpression(bindingContext)) {
|
if (expressionToBeReplaced.isUsedAsExpression(bindingContext)) {
|
||||||
val thisReplaced = replacement.collectDescendantsOfType<KtExpression> { it[RECEIVER_VALUE_KEY] }
|
val thisReplaced = codeToInline.collectDescendantsOfType<KtExpression> { it[RECEIVER_VALUE_KEY] }
|
||||||
replacement.introduceValue(receiver, receiverType, thisReplaced, expressionToBeReplaced, safeCall = true)
|
codeToInline.introduceValue(receiver, receiverType, thisReplaced, expressionToBeReplaced, safeCall = true)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val ifExpression = psiFactory.buildExpression {
|
val ifExpression = psiFactory.buildExpression {
|
||||||
appendFixedText("if (")
|
appendFixedText("if (")
|
||||||
appendExpression(receiver)
|
appendExpression(receiver)
|
||||||
appendFixedText("!=null) {")
|
appendFixedText("!=null) {")
|
||||||
replacement.statementsBefore.forEach {
|
codeToInline.statementsBefore.forEach {
|
||||||
appendExpression(it)
|
appendExpression(it)
|
||||||
appendFixedText("\n")
|
appendFixedText("\n")
|
||||||
}
|
}
|
||||||
replacement.mainExpression?.let {
|
codeToInline.mainExpression?.let {
|
||||||
appendExpression(it)
|
appendExpression(it)
|
||||||
appendFixedText("\n")
|
appendFixedText("\n")
|
||||||
}
|
}
|
||||||
appendFixedText("}")
|
appendFixedText("}")
|
||||||
}
|
}
|
||||||
replacement.mainExpression = ifExpression
|
codeToInline.mainExpression = ifExpression
|
||||||
replacement.statementsBefore.clear()
|
codeToInline.statementsBefore.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun keepInfixFormIfPossible() {
|
private fun keepInfixFormIfPossible() {
|
||||||
if (replacement.statementsBefore.isNotEmpty()) return
|
if (codeToInline.statementsBefore.isNotEmpty()) return
|
||||||
val dotQualified = replacement.mainExpression as? KtDotQualifiedExpression ?: return
|
val dotQualified = codeToInline.mainExpression as? KtDotQualifiedExpression ?: return
|
||||||
val receiver = dotQualified.receiverExpression
|
val receiver = dotQualified.receiverExpression
|
||||||
if (!receiver[RECEIVER_VALUE_KEY]) return
|
if (!receiver[RECEIVER_VALUE_KEY]) return
|
||||||
val call = dotQualified.selectorExpression as? KtCallExpression ?: return
|
val call = dotQualified.selectorExpression as? KtCallExpression ?: return
|
||||||
@@ -271,7 +271,7 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
val argument = call.valueArguments.singleOrNull() ?: return
|
val argument = call.valueArguments.singleOrNull() ?: return
|
||||||
if (argument.getArgumentName() != null) return
|
if (argument.getArgumentName() != null) return
|
||||||
val argumentExpression = argument.getArgumentExpression() ?: return
|
val argumentExpression = argument.getArgumentExpression() ?: return
|
||||||
replacement.mainExpression = psiFactory.createExpressionByPattern("$0 ${nameExpression.text} $1", receiver, argumentExpression)
|
codeToInline.mainExpression = psiFactory.createExpressionByPattern("$0 ${nameExpression.text} $1", receiver, argumentExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtExpression?.shouldKeepValue(usageCount: Int): Boolean {
|
private fun KtExpression?.shouldKeepValue(usageCount: Int): Boolean {
|
||||||
@@ -317,13 +317,13 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
val (expression, parameterUsages) = defaultValue
|
val (expression, parameterUsages) = defaultValue
|
||||||
|
|
||||||
for ((param, usages) in parameterUsages) {
|
for ((param, usages) in parameterUsages) {
|
||||||
usages.forEach { it.put(ReplacementCode.PARAMETER_USAGE_KEY, param.name) }
|
usages.forEach { it.put(CodeToInline.PARAMETER_USAGE_KEY, param.name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val expressionCopy = expression.copied()
|
val expressionCopy = expression.copied()
|
||||||
|
|
||||||
// clean up user data in original
|
// clean up user data in original
|
||||||
expression.forEachDescendantOfType<KtExpression> { it.clear(ReplacementCode.PARAMETER_USAGE_KEY) }
|
expression.forEachDescendantOfType<KtExpression> { it.clear(CodeToInline.PARAMETER_USAGE_KEY) }
|
||||||
|
|
||||||
return Argument(expressionCopy, null/*TODO*/, isDefaultValue = true)
|
return Argument(expressionCopy, null/*TODO*/, isDefaultValue = true)
|
||||||
}
|
}
|
||||||
@@ -395,8 +395,8 @@ class CallReplacementEngine<TCallElement : KtElement>(
|
|||||||
// clean up user data
|
// clean up user data
|
||||||
it.forEachDescendantOfType<KtExpression> {
|
it.forEachDescendantOfType<KtExpression> {
|
||||||
it.clear(USER_CODE_KEY)
|
it.clear(USER_CODE_KEY)
|
||||||
it.clear(ReplacementCode.PARAMETER_USAGE_KEY)
|
it.clear(CodeToInline.PARAMETER_USAGE_KEY)
|
||||||
it.clear(ReplacementCode.TYPE_PARAMETER_USAGE_KEY)
|
it.clear(CodeToInline.TYPE_PARAMETER_USAGE_KEY)
|
||||||
it.clear(PARAMETER_VALUE_KEY)
|
it.clear(PARAMETER_VALUE_KEY)
|
||||||
it.clear(RECEIVER_VALUE_KEY)
|
it.clear(RECEIVER_VALUE_KEY)
|
||||||
it.clear(WAS_FUNCTION_LITERAL_ARGUMENT_KEY)
|
it.clear(WAS_FUNCTION_LITERAL_ARGUMENT_KEY)
|
||||||
+6
-6
@@ -14,25 +14,25 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import org.jetbrains.kotlin.idea.replacement.ReplacementCode.Companion.PARAMETER_USAGE_KEY
|
import org.jetbrains.kotlin.idea.inliner.CodeToInline.Companion.PARAMETER_USAGE_KEY
|
||||||
import org.jetbrains.kotlin.idea.replacement.ReplacementCode.Companion.TYPE_PARAMETER_USAGE_KEY
|
import org.jetbrains.kotlin.idea.inliner.CodeToInline.Companion.TYPE_PARAMETER_USAGE_KEY
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an expression to replace usages of particular callable.
|
* Represents code to be inlined to replace usages of particular callable.
|
||||||
* The expression should be preprocessed in the following way:
|
* The expression should be preprocessed in the following way:
|
||||||
* * Type arguments for all calls should be made explicit
|
* * Type arguments for all calls should be made explicit
|
||||||
* * All external symbols to be imported should be either referenced via fully-qualified form or included into [fqNamesToImport]
|
* * All external symbols to be imported should be either referenced via fully-qualified form or included into [fqNamesToImport]
|
||||||
* * All usages of value parameters (of our callable) should be marked with [PARAMETER_USAGE_KEY] copyable user data (holds the name of the corresponding parameter)
|
* * All usages of value parameters (of our callable) should be marked with [PARAMETER_USAGE_KEY] copyable user data (holds the name of the corresponding parameter)
|
||||||
* * All usages of type parameters (of our callable) should be marked with [TYPE_PARAMETER_USAGE_KEY] copyable user data (holds the name of the corresponding type parameter)
|
* * All usages of type parameters (of our callable) should be marked with [TYPE_PARAMETER_USAGE_KEY] copyable user data (holds the name of the corresponding type parameter)
|
||||||
* Use [ReplacementBuilder.buildReplacementCode].
|
* Use [CodeToInlineBuilder.prepareCodeToInline].
|
||||||
*/
|
*/
|
||||||
class ReplacementCode(
|
class CodeToInline(
|
||||||
val mainExpression: KtExpression?,
|
val mainExpression: KtExpression?,
|
||||||
val statementsBefore: List<KtExpression>,
|
val statementsBefore: List<KtExpression>,
|
||||||
val fqNamesToImport: Collection<FqName>
|
val fqNamesToImport: Collection<FqName>
|
||||||
+7
-7
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
@@ -36,21 +36,21 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ReplacementBuilder(
|
class CodeToInlineBuilder(
|
||||||
private val targetCallable: CallableDescriptor,
|
private val targetCallable: CallableDescriptor,
|
||||||
private val resolutionFacade: ResolutionFacade
|
private val resolutionFacade: ResolutionFacade
|
||||||
) {
|
) {
|
||||||
private val psiFactory = KtPsiFactory(resolutionFacade.project)
|
private val psiFactory = KtPsiFactory(resolutionFacade.project)
|
||||||
|
|
||||||
fun buildReplacementCode(
|
fun prepareCodeToInline(
|
||||||
mainExpression: KtExpression?,
|
mainExpression: KtExpression?,
|
||||||
statementsBefore: List<KtExpression>,
|
statementsBefore: List<KtExpression>,
|
||||||
analyze: () -> BindingContext,
|
analyze: () -> BindingContext,
|
||||||
importFqNames: Collection<FqName> = emptyList()
|
importFqNames: Collection<FqName> = emptyList()
|
||||||
): ReplacementCode {
|
): CodeToInline {
|
||||||
var bindingContext = analyze()
|
var bindingContext = analyze()
|
||||||
|
|
||||||
val result = MutableReplacementCode(mainExpression, statementsBefore.toMutableList(), importFqNames.toMutableSet())
|
val result = MutableCodeToInline(mainExpression, statementsBefore.toMutableList(), importFqNames.toMutableSet())
|
||||||
|
|
||||||
val typeArgsToAdd = ArrayList<Pair<KtCallExpression, KtTypeArgumentList>>()
|
val typeArgsToAdd = ArrayList<Pair<KtCallExpression, KtTypeArgumentList>>()
|
||||||
result.forEachDescendantOfType<KtCallExpression> {
|
result.forEachDescendantOfType<KtCallExpression> {
|
||||||
@@ -80,10 +80,10 @@ class ReplacementBuilder(
|
|||||||
|
|
||||||
if (expression.getReceiverExpression() == null) {
|
if (expression.getReceiverExpression() == null) {
|
||||||
if (target is ValueParameterDescriptor && target.containingDeclaration == targetCallable) {
|
if (target is ValueParameterDescriptor && target.containingDeclaration == targetCallable) {
|
||||||
expression.putCopyableUserData(ReplacementCode.PARAMETER_USAGE_KEY, target.name)
|
expression.putCopyableUserData(CodeToInline.PARAMETER_USAGE_KEY, target.name)
|
||||||
}
|
}
|
||||||
else if (target is TypeParameterDescriptor && target.containingDeclaration == targetCallable) {
|
else if (target is TypeParameterDescriptor && target.containingDeclaration == targetCallable) {
|
||||||
expression.putCopyableUserData(ReplacementCode.TYPE_PARAMETER_USAGE_KEY, target.name)
|
expression.putCopyableUserData(CodeToInline.TYPE_PARAMETER_USAGE_KEY, target.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolvedCall = expression.getResolvedCall(bindingContext)
|
val resolvedCall = expression.getResolvedCall(bindingContext)
|
||||||
+8
-8
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
|||||||
|
|
||||||
private val POST_INSERTION_ACTION: Key<(KtElement) -> Unit> = Key("POST_INSERTION_ACTION")
|
private val POST_INSERTION_ACTION: Key<(KtElement) -> Unit> = Key("POST_INSERTION_ACTION")
|
||||||
|
|
||||||
internal class MutableReplacementCode(
|
internal class MutableCodeToInline(
|
||||||
var mainExpression: KtExpression?,
|
var mainExpression: KtExpression?,
|
||||||
val statementsBefore: MutableList<KtExpression>,
|
val statementsBefore: MutableList<KtExpression>,
|
||||||
val fqNamesToImport: MutableCollection<FqName>
|
val fqNamesToImport: MutableCollection<FqName>
|
||||||
@@ -81,22 +81,22 @@ internal class MutableReplacementCode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ReplacementCode.toMutable(): MutableReplacementCode {
|
internal fun CodeToInline.toMutable(): MutableCodeToInline {
|
||||||
return MutableReplacementCode(
|
return MutableCodeToInline(
|
||||||
mainExpression?.copied(),
|
mainExpression?.copied(),
|
||||||
statementsBefore.map { it.copied() }.toMutableList(),
|
statementsBefore.map { it.copied() }.toMutableList(),
|
||||||
fqNamesToImport.toMutableSet())
|
fqNamesToImport.toMutableSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun MutableReplacementCode.toNonMutable(): ReplacementCode {
|
internal fun MutableCodeToInline.toNonMutable(): CodeToInline {
|
||||||
return ReplacementCode(mainExpression, statementsBefore, fqNamesToImport)
|
return CodeToInline(mainExpression, statementsBefore, fqNamesToImport)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified T : PsiElement> MutableReplacementCode.collectDescendantsOfType(noinline predicate: (T) -> Boolean = { true }): List<T> {
|
internal inline fun <reified T : PsiElement> MutableCodeToInline.collectDescendantsOfType(noinline predicate: (T) -> Boolean = { true }): List<T> {
|
||||||
return expressions.flatMap { it.collectDescendantsOfType<T>({ true }, predicate) }
|
return expressions.flatMap { it.collectDescendantsOfType<T>({ true }, predicate) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified T : PsiElement> MutableReplacementCode.forEachDescendantOfType(noinline action: (T) -> Unit) {
|
internal inline fun <reified T : PsiElement> MutableCodeToInline.forEachDescendantOfType(noinline action: (T) -> Unit) {
|
||||||
expressions.forEach { it.forEachDescendantOfType<T>(action) }
|
expressions.forEach { it.forEachDescendantOfType<T>(action) }
|
||||||
}
|
}
|
||||||
|
|
||||||
+14
-14
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal abstract class ReplacementPerformer<TElement : KtElement>(
|
internal abstract class ReplacementPerformer<TElement : KtElement>(
|
||||||
protected val replacement: MutableReplacementCode,
|
protected val codeToInline: MutableCodeToInline,
|
||||||
protected var elementToBeReplaced: TElement
|
protected var elementToBeReplaced: TElement
|
||||||
) {
|
) {
|
||||||
protected val psiFactory = KtPsiFactory(elementToBeReplaced)
|
protected val psiFactory = KtPsiFactory(elementToBeReplaced)
|
||||||
@@ -40,18 +40,18 @@ internal abstract class ReplacementPerformer<TElement : KtElement>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class AnnotationEntryReplacementPerformer(
|
internal class AnnotationEntryReplacementPerformer(
|
||||||
replacement: MutableReplacementCode,
|
codeToInline: MutableCodeToInline,
|
||||||
elementToBeReplaced: KtAnnotationEntry
|
elementToBeReplaced: KtAnnotationEntry
|
||||||
) : ReplacementPerformer<KtAnnotationEntry>(replacement, elementToBeReplaced) {
|
) : ReplacementPerformer<KtAnnotationEntry>(codeToInline, elementToBeReplaced) {
|
||||||
|
|
||||||
override fun doIt(postProcessing: (PsiChildRange) -> PsiChildRange): KtAnnotationEntry {
|
override fun doIt(postProcessing: (PsiChildRange) -> PsiChildRange): KtAnnotationEntry {
|
||||||
assert(replacement.mainExpression != null)
|
assert(codeToInline.mainExpression != null)
|
||||||
assert(replacement.statementsBefore.isEmpty())
|
assert(codeToInline.statementsBefore.isEmpty())
|
||||||
|
|
||||||
val dummyAnnotationEntry = createByPattern("@Dummy($0)", replacement.mainExpression!!) { psiFactory.createAnnotationEntry(it) }
|
val dummyAnnotationEntry = createByPattern("@Dummy($0)", codeToInline.mainExpression!!) { psiFactory.createAnnotationEntry(it) }
|
||||||
val replaced = elementToBeReplaced.replace(dummyAnnotationEntry)
|
val replaced = elementToBeReplaced.replace(dummyAnnotationEntry)
|
||||||
|
|
||||||
replacement.performPostInsertionActions(replaced.singletonList())
|
codeToInline.performPostInsertionActions(replaced.singletonList())
|
||||||
|
|
||||||
var range = PsiChildRange.singleElement(replaced)
|
var range = PsiChildRange.singleElement(replaced)
|
||||||
range = postProcessing(range)
|
range = postProcessing(range)
|
||||||
@@ -65,13 +65,13 @@ internal class AnnotationEntryReplacementPerformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class ExpressionReplacementPerformer(
|
internal class ExpressionReplacementPerformer(
|
||||||
replacement: MutableReplacementCode,
|
codeToInline: MutableCodeToInline,
|
||||||
expressionToBeReplaced: KtExpression
|
expressionToBeReplaced: KtExpression
|
||||||
) : ReplacementPerformer<KtExpression>(replacement, expressionToBeReplaced) {
|
) : ReplacementPerformer<KtExpression>(codeToInline, expressionToBeReplaced) {
|
||||||
|
|
||||||
override fun doIt(postProcessing: (PsiChildRange) -> PsiChildRange): KtExpression? {
|
override fun doIt(postProcessing: (PsiChildRange) -> PsiChildRange): KtExpression? {
|
||||||
val insertedStatements = ArrayList<KtExpression>()
|
val insertedStatements = ArrayList<KtExpression>()
|
||||||
for (statement in replacement.statementsBefore) {
|
for (statement in codeToInline.statementsBefore) {
|
||||||
// copy the statement if it can get invalidated by findOrCreateBlockToInsertStatement()
|
// copy the statement if it can get invalidated by findOrCreateBlockToInsertStatement()
|
||||||
val statementToUse = if (statement.isPhysical) statement.copy() else statement
|
val statementToUse = if (statement.isPhysical) statement.copy() else statement
|
||||||
val anchor = findOrCreateBlockToInsertStatement()
|
val anchor = findOrCreateBlockToInsertStatement()
|
||||||
@@ -83,8 +83,8 @@ internal class ExpressionReplacementPerformer(
|
|||||||
insertedStatements.add(inserted)
|
insertedStatements.add(inserted)
|
||||||
}
|
}
|
||||||
|
|
||||||
val replaced = if (replacement.mainExpression != null) {
|
val replaced = if (codeToInline.mainExpression != null) {
|
||||||
elementToBeReplaced.replace(replacement.mainExpression!!)
|
elementToBeReplaced.replace(codeToInline.mainExpression!!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val bindingContext = elementToBeReplaced.analyze(BodyResolveMode.FULL)
|
val bindingContext = elementToBeReplaced.analyze(BodyResolveMode.FULL)
|
||||||
@@ -98,7 +98,7 @@ internal class ExpressionReplacementPerformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replacement.performPostInsertionActions(insertedStatements + replaced.singletonOrEmptyList())
|
codeToInline.performPostInsertionActions(insertedStatements + replaced.singletonOrEmptyList())
|
||||||
|
|
||||||
var range = if (replaced != null) {
|
var range = if (replaced != null) {
|
||||||
if (insertedStatements.isEmpty()) {
|
if (insertedStatements.isEmpty()) {
|
||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.progress.ProgressIndicator
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
+6
-6
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.replacement
|
package org.jetbrains.kotlin.idea.inliner
|
||||||
|
|
||||||
import org.jetbrains.kotlin.idea.analysis.computeTypeInContext
|
import org.jetbrains.kotlin.idea.analysis.computeTypeInContext
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
@@ -38,17 +38,17 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifies [MutableReplacementCode] introducing a variable initialized by [value] and replacing all of [usages] with its use.
|
* Modifies [MutableCodeToInline] introducing a variable initialized by [value] and replacing all of [usages] with its use.
|
||||||
* The variable must be initialized (and so the value is calculated) before any other code in [MutableReplacementCode].
|
* The variable must be initialized (and so the value is calculated) before any other code in [MutableCodeToInline].
|
||||||
* @param value Value to use for variable initialization
|
* @param value Value to use for variable initialization
|
||||||
* @param valueType Type of the value
|
* @param valueType Type of the value
|
||||||
* @param usages Usages to be replaced. This collection can be empty and in this case the actual variable is not needed.
|
* @param usages Usages to be replaced. This collection can be empty and in this case the actual variable is not needed.
|
||||||
* But the expression [value] must be calculated because it may have side effects.
|
* But the expression [value] must be calculated because it may have side effects.
|
||||||
* @param expressionToBeReplaced Expression to be replaced by the [MutableReplacementCode].
|
* @param expressionToBeReplaced Expression to be replaced by the [MutableCodeToInline].
|
||||||
* @param nameSuggestion Name suggestion for the variable.
|
* @param nameSuggestion Name suggestion for the variable.
|
||||||
* @param safeCall If true, then the whole code must not be executed if the [value] evaluates to null.
|
* @param safeCall If true, then the whole code must not be executed if the [value] evaluates to null.
|
||||||
*/
|
*/
|
||||||
internal fun MutableReplacementCode.introduceValue(
|
internal fun MutableCodeToInline.introduceValue(
|
||||||
value: KtExpression,
|
value: KtExpression,
|
||||||
valueType: KotlinType?,
|
valueType: KotlinType?,
|
||||||
usages: Collection<KtExpression>,
|
usages: Collection<KtExpression>,
|
||||||
@@ -151,7 +151,7 @@ private fun variableNeedsExplicitType(
|
|||||||
return valueTypeWithoutExpectedType == null || ErrorUtils.containsErrorType(valueTypeWithoutExpectedType)
|
return valueTypeWithoutExpectedType == null || ErrorUtils.containsErrorType(valueTypeWithoutExpectedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectNameUsages(scope: MutableReplacementCode, name: String): List<KtSimpleNameExpression> {
|
private fun collectNameUsages(scope: MutableCodeToInline, name: String): List<KtSimpleNameExpression> {
|
||||||
return scope.expressions.flatMap { expression ->
|
return scope.expressions.flatMap { expression ->
|
||||||
expression.collectDescendantsOfType<KtSimpleNameExpression> { it.getReceiverExpression() == null && it.getReferencedName() == name }
|
expression.collectDescendantsOfType<KtSimpleNameExpression> { it.getReceiverExpression() == null && it.getReferencedName() == name }
|
||||||
}
|
}
|
||||||
+1
-1
@@ -55,6 +55,6 @@
|
|||||||
<orderEntry type="module" module-name="formatter" />
|
<orderEntry type="module" module-name="formatter" />
|
||||||
<orderEntry type="module" module-name="idea-maven" />
|
<orderEntry type="module" module-name="idea-maven" />
|
||||||
<orderEntry type="library" scope="TEST" name="native-platform-uberjar" level="project" />
|
<orderEntry type="library" scope="TEST" name="native-platform-uberjar" level="project" />
|
||||||
<orderEntry type="module" module-name="idea-replacement-engine" />
|
<orderEntry type="module" module-name="idea-code-inliner" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.idea.core.moveCaret
|
|||||||
import org.jetbrains.kotlin.idea.core.targetDescriptors
|
import org.jetbrains.kotlin.idea.core.targetDescriptors
|
||||||
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||||
import org.jetbrains.kotlin.idea.replacement.UsageReplacementStrategy
|
import org.jetbrains.kotlin.idea.inliner.UsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||||
|
|||||||
+3
-3
@@ -31,9 +31,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
|||||||
import org.jetbrains.kotlin.idea.core.OptionalParametersHelper
|
import org.jetbrains.kotlin.idea.core.OptionalParametersHelper
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.replacement.CallableUsageReplacementStrategy
|
import org.jetbrains.kotlin.idea.inliner.CallableUsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.idea.replacement.ClassUsageReplacementStrategy
|
import org.jetbrains.kotlin.idea.inliner.ClassUsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.idea.replacement.UsageReplacementStrategy
|
import org.jetbrains.kotlin.idea.inliner.UsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
|
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
|
|||||||
+2
-2
@@ -23,8 +23,8 @@ import com.intellij.psi.PsiFile
|
|||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.replacement.UsageReplacementStrategy
|
import org.jetbrains.kotlin.idea.inliner.UsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.idea.replacement.replaceUsagesInWholeProject
|
import org.jetbrains.kotlin.idea.inliner.replaceUsagesInWholeProject
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
|
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
|
|||||||
+6
-6
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.idea.analysis.analyzeInContext
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.replacement.ReplacementBuilder
|
import org.jetbrains.kotlin.idea.inliner.CodeToInlineBuilder
|
||||||
import org.jetbrains.kotlin.idea.replacement.ReplacementCode
|
import org.jetbrains.kotlin.idea.inliner.CodeToInline
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
import org.jetbrains.kotlin.idea.resolve.frontendService
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -50,7 +50,7 @@ object ReplaceWithAnnotationAnalyzer {
|
|||||||
annotation: ReplaceWith,
|
annotation: ReplaceWith,
|
||||||
symbolDescriptor: CallableDescriptor,
|
symbolDescriptor: CallableDescriptor,
|
||||||
resolutionFacade: ResolutionFacade
|
resolutionFacade: ResolutionFacade
|
||||||
): ReplacementCode? {
|
): CodeToInline? {
|
||||||
val originalDescriptor = (if (symbolDescriptor is CallableMemberDescriptor)
|
val originalDescriptor = (if (symbolDescriptor is CallableMemberDescriptor)
|
||||||
DescriptorUtils.unwrapFakeOverride(symbolDescriptor)
|
DescriptorUtils.unwrapFakeOverride(symbolDescriptor)
|
||||||
else
|
else
|
||||||
@@ -62,7 +62,7 @@ object ReplaceWithAnnotationAnalyzer {
|
|||||||
annotation: ReplaceWith,
|
annotation: ReplaceWith,
|
||||||
symbolDescriptor: CallableDescriptor,
|
symbolDescriptor: CallableDescriptor,
|
||||||
resolutionFacade: ResolutionFacade
|
resolutionFacade: ResolutionFacade
|
||||||
): ReplacementCode? {
|
): CodeToInline? {
|
||||||
val psiFactory = KtPsiFactory(resolutionFacade.project)
|
val psiFactory = KtPsiFactory(resolutionFacade.project)
|
||||||
val expression = try {
|
val expression = try {
|
||||||
psiFactory.createExpression(annotation.pattern)
|
psiFactory.createExpression(annotation.pattern)
|
||||||
@@ -89,8 +89,8 @@ object ReplaceWithAnnotationAnalyzer {
|
|||||||
return expression.analyzeInContext(scope, expressionTypingServices = expressionTypingServices)
|
return expression.analyzeInContext(scope, expressionTypingServices = expressionTypingServices)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReplacementBuilder(symbolDescriptor, resolutionFacade)
|
return CodeToInlineBuilder(symbolDescriptor, resolutionFacade)
|
||||||
.buildReplacementCode(expression, emptyList(), ::analyzeExpression, importFqNames = importFqNames(annotation))
|
.prepareCodeToInline(expression, emptyList(), ::analyzeExpression, importFqNames = importFqNames(annotation))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun analyzeClassReplacement(
|
fun analyzeClassReplacement(
|
||||||
|
|||||||
+7
-7
@@ -29,9 +29,9 @@ import org.jetbrains.kotlin.idea.analysis.analyzeInContext
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.core.copied
|
import org.jetbrains.kotlin.idea.core.copied
|
||||||
import org.jetbrains.kotlin.idea.replacement.CallableUsageReplacementStrategy
|
import org.jetbrains.kotlin.idea.inliner.CallableUsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.idea.replacement.ReplacementBuilder
|
import org.jetbrains.kotlin.idea.inliner.CodeToInlineBuilder
|
||||||
import org.jetbrains.kotlin.idea.replacement.replaceUsagesInWholeProject
|
import org.jetbrains.kotlin.idea.inliner.replaceUsagesInWholeProject
|
||||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
@@ -67,21 +67,21 @@ class KotlinInlineFunctionHandler: InlineActionHandler() {
|
|||||||
expectedType = expectedType)
|
expectedType = expectedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val replacementBuilder = ReplacementBuilder(descriptor, element.getResolutionFacade())
|
val replacementBuilder = CodeToInlineBuilder(descriptor, element.getResolutionFacade())
|
||||||
val replacement = if (element.hasBlockBody()) {
|
val replacement = if (element.hasBlockBody()) {
|
||||||
bodyCopy as KtBlockExpression
|
bodyCopy as KtBlockExpression
|
||||||
val statements = bodyCopy.statements
|
val statements = bodyCopy.statements
|
||||||
//TODO: check no other return's!
|
//TODO: check no other return's!
|
||||||
val lastReturn = statements.lastOrNull() as? KtReturnExpression
|
val lastReturn = statements.lastOrNull() as? KtReturnExpression
|
||||||
if (lastReturn != null) {
|
if (lastReturn != null) {
|
||||||
replacementBuilder.buildReplacementCode(lastReturn.returnedExpression, statements.dropLast(1), ::analyzeBodyCopy)
|
replacementBuilder.prepareCodeToInline(lastReturn.returnedExpression, statements.dropLast(1), ::analyzeBodyCopy)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
replacementBuilder.buildReplacementCode(null, statements, ::analyzeBodyCopy)
|
replacementBuilder.prepareCodeToInline(null, statements, ::analyzeBodyCopy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
replacementBuilder.buildReplacementCode(bodyCopy, emptyList(), ::analyzeBodyCopy)
|
replacementBuilder.prepareCodeToInline(bodyCopy, emptyList(), ::analyzeBodyCopy)
|
||||||
}
|
}
|
||||||
|
|
||||||
val commandName = RefactoringBundle.message("inline.command", element.name)
|
val commandName = RefactoringBundle.message("inline.command", element.name)
|
||||||
|
|||||||
Reference in New Issue
Block a user