New J2K: do not use global write action for some post-processings which may use resolving while applying
Also, modify that post-processings & inspections to explicitly use write action when modifying PSI elements #KT-33875 fixed
This commit is contained in:
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
|
|||||||
import org.jetbrains.kotlin.idea.imports.getImportableTargets
|
import org.jetbrains.kotlin.idea.imports.getImportableTargets
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.util.*
|
import org.jetbrains.kotlin.idea.util.*
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
@@ -207,20 +208,24 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
processors.forEach { it.analyzeCollectedElements(bindingContext) }
|
processors.forEach { it.analyzeCollectedElements(bindingContext) }
|
||||||
|
|
||||||
// step 3: shorten elements that can be shortened right now
|
// step 3: shorten elements that can be shortened right now
|
||||||
processors.forEach { it.shortenElements(elementSetToUpdate = elementsToUse, options = options) }
|
runWriteAction {
|
||||||
|
processors.forEach { it.shortenElements(elementSetToUpdate = elementsToUse, options = options) }
|
||||||
|
}
|
||||||
|
|
||||||
// step 4: try to import descriptors needed to shorten other elements
|
// step 4: try to import descriptors needed to shorten other elements
|
||||||
val descriptorsToImport = processors.flatMap { it.getDescriptorsToImport() }.toSet()
|
val descriptorsToImport = processors.flatMap { it.getDescriptorsToImport() }.toSet()
|
||||||
var anyChange = false
|
var anyChange = false
|
||||||
for (descriptor in descriptorsToImport) {
|
runWriteAction {
|
||||||
assert(descriptor !in failedToImportDescriptors)
|
for (descriptor in descriptorsToImport) {
|
||||||
|
assert(descriptor !in failedToImportDescriptors)
|
||||||
|
|
||||||
val result = helper.importDescriptor(file, descriptor)
|
val result = helper.importDescriptor(file, descriptor)
|
||||||
if (result != ImportDescriptorResult.ALREADY_IMPORTED) {
|
if (result != ImportDescriptorResult.ALREADY_IMPORTED) {
|
||||||
anyChange = true
|
anyChange = true
|
||||||
}
|
}
|
||||||
if (result == ImportDescriptorResult.FAIL) {
|
if (result == ImportDescriptorResult.FAIL) {
|
||||||
failedToImportDescriptors.add(descriptor)
|
failedToImportDescriptors.add(descriptor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!anyChange) break
|
if (!anyChange) break
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.refactoring.withExpectedActuals
|
import org.jetbrains.kotlin.idea.refactoring.withExpectedActuals
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.idea.util.nameIdentifierTextRangeInThis
|
import org.jetbrains.kotlin.idea.util.nameIdentifierTextRangeInThis
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
@@ -28,8 +29,11 @@ class AddOperatorModifierInspection : AbstractApplicabilityBasedInspection<KtNam
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: KtNamedFunction, project: Project, editor: Editor?) {
|
override fun applyTo(element: KtNamedFunction, project: Project, editor: Editor?) {
|
||||||
for (declaration in element.withExpectedActuals()) {
|
val declarations = element.withExpectedActuals()
|
||||||
declaration.addModifier(KtTokens.OPERATOR_KEYWORD)
|
runWriteAction {
|
||||||
|
for (declaration in declarations) {
|
||||||
|
declaration.addModifier(KtTokens.OPERATOR_KEYWORD)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-12
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.idea.intentions.branchedTransformations.expressionCo
|
|||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.fromIfKeywordToRightParenthesisTextRangeInThis
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.fromIfKeywordToRightParenthesisTextRangeInThis
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.shouldBeTransformed
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.shouldBeTransformed
|
||||||
import org.jetbrains.kotlin.idea.util.CommentSaver
|
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.idea.util.hasComments
|
import org.jetbrains.kotlin.idea.util.hasComments
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -86,19 +87,21 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti
|
|||||||
val pattern = elvisPattern(declaration.textLength + ifNullExpr.textLength + 5 >= margin || element.then?.hasComments() == true)
|
val pattern = elvisPattern(declaration.textLength + ifNullExpr.textLength + 5 >= margin || element.then?.hasComments() == true)
|
||||||
|
|
||||||
val elvis = factory.createExpressionByPattern(pattern, initializer, ifNullExpr) as KtBinaryExpression
|
val elvis = factory.createExpressionByPattern(pattern, initializer, ifNullExpr) as KtBinaryExpression
|
||||||
if (typeReference != null) {
|
|
||||||
elvis.left!!.replace(factory.createExpressionByPattern("$0 as? $1", initializer, typeReference))
|
return runWriteAction {
|
||||||
|
if (typeReference != null) {
|
||||||
|
elvis.left!!.replace(factory.createExpressionByPattern("$0 as? $1", initializer, typeReference))
|
||||||
|
}
|
||||||
|
val newElvis = initializer.replaced(elvis)
|
||||||
|
element.delete()
|
||||||
|
|
||||||
|
if (explicitTypeToSet != null && !explicitTypeToSet.isError) {
|
||||||
|
declaration.setType(explicitTypeToSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
commentSaver.restore(childRangeAfter)
|
||||||
|
newElvis
|
||||||
}
|
}
|
||||||
val newElvis = initializer.replaced(elvis)
|
|
||||||
element.delete()
|
|
||||||
|
|
||||||
if (explicitTypeToSet != null && !explicitTypeToSet.isError) {
|
|
||||||
declaration.setType(explicitTypeToSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
commentSaver.restore(childRangeAfter)
|
|
||||||
|
|
||||||
return newElvis
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calcData(ifExpression: KtIfExpression): Data? {
|
private fun calcData(ifExpression: KtIfExpression): Data? {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
@@ -47,7 +48,10 @@ open class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentInte
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
||||||
element.replaced(buildReplacement(element))
|
val replacement = buildReplacement(element)
|
||||||
|
runWriteAction {
|
||||||
|
element.replaced(replacement)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.core.isVisible
|
|||||||
import org.jetbrains.kotlin.idea.findUsages.ReferencesSearchScopeHelper
|
import org.jetbrains.kotlin.idea.findUsages.ReferencesSearchScopeHelper
|
||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -89,9 +90,12 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
|||||||
else {
|
else {
|
||||||
name ?: KotlinNameSuggester.suggestNameByName(descriptor.name.asString(), validator)
|
name ?: KotlinNameSuggester.suggestNameByName(descriptor.name.asString(), validator)
|
||||||
}
|
}
|
||||||
variableToDrop?.delete()
|
|
||||||
usagesToReplace.forEach {
|
runWriteAction {
|
||||||
it.replace(factory.createExpression(suggestedName))
|
variableToDrop?.delete()
|
||||||
|
usagesToReplace.forEach {
|
||||||
|
it.replace(factory.createExpression(suggestedName))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
names.add(suggestedName)
|
names.add(suggestedName)
|
||||||
}
|
}
|
||||||
@@ -100,31 +104,42 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
|||||||
when (element) {
|
when (element) {
|
||||||
is KtParameter -> {
|
is KtParameter -> {
|
||||||
val loopRange = (element.parent as? KtForExpression)?.loopRange
|
val loopRange = (element.parent as? KtForExpression)?.loopRange
|
||||||
element.replace(factory.createDestructuringParameter("($joinedNames)"))
|
runWriteAction {
|
||||||
if (removeSelectorInLoopRange && loopRange is KtDotQualifiedExpression) {
|
element.replace(factory.createDestructuringParameter("($joinedNames)"))
|
||||||
loopRange.replace(loopRange.receiverExpression)
|
if (removeSelectorInLoopRange && loopRange is KtDotQualifiedExpression) {
|
||||||
|
loopRange.replace(loopRange.receiverExpression)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is KtFunctionLiteral -> {
|
is KtFunctionLiteral -> {
|
||||||
val lambda = element.parent as KtLambdaExpression
|
val lambda = element.parent as KtLambdaExpression
|
||||||
SpecifyExplicitLambdaSignatureIntention().applyTo(lambda, editor)
|
SpecifyExplicitLambdaSignatureIntention().applyTo(lambda, editor)
|
||||||
lambda.functionLiteral.valueParameters.singleOrNull()?.replace(
|
runWriteAction {
|
||||||
|
lambda.functionLiteral.valueParameters.singleOrNull()?.replace(
|
||||||
factory.createDestructuringParameter("($joinedNames)")
|
factory.createDestructuringParameter("($joinedNames)")
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is KtVariableDeclaration -> {
|
is KtVariableDeclaration -> {
|
||||||
val rangeAfterEq = PsiChildRange(element.initializer, element.lastChild)
|
val rangeAfterEq = PsiChildRange(element.initializer, element.lastChild)
|
||||||
val modifierList = element.modifierList
|
val modifierList = element.modifierList
|
||||||
if (modifierList == null) {
|
runWriteAction {
|
||||||
element.replace(factory.createDestructuringDeclarationByPattern(
|
if (modifierList == null) {
|
||||||
"val ($joinedNames) = $0", rangeAfterEq))
|
element.replace(
|
||||||
}
|
factory.createDestructuringDeclarationByPattern(
|
||||||
else {
|
"val ($joinedNames) = $0", rangeAfterEq
|
||||||
val rangeBeforeVal = PsiChildRange(element.firstChild, modifierList)
|
)
|
||||||
element.replace(factory.createDestructuringDeclarationByPattern(
|
)
|
||||||
"$0:'@xyz' val ($joinedNames) = $1", rangeBeforeVal, rangeAfterEq))
|
} else {
|
||||||
|
val rangeBeforeVal = PsiChildRange(element.firstChild, modifierList)
|
||||||
|
element.replace(
|
||||||
|
factory.createDestructuringDeclarationByPattern(
|
||||||
|
"$0:'@xyz' val ($joinedNames) = $1", rangeBeforeVal, rangeAfterEq
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
|||||||
import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection
|
import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection
|
||||||
import org.jetbrains.kotlin.idea.util.CommentSaver
|
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -157,21 +158,22 @@ class ObjectLiteralToLambdaIntention : SelfTargetingRangeIntention<KtObjectLiter
|
|||||||
appendFixedText("}")
|
appendFixedText("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val replaced = element.replaced(newExpression)
|
val replaced = runWriteAction { element.replaced(newExpression) }
|
||||||
val callee = replaced.getCalleeExpressionIfAny()!! as KtNameReferenceExpression
|
val callee = replaced.getCalleeExpressionIfAny()!! as KtNameReferenceExpression
|
||||||
val callExpression = callee.parent as KtCallExpression
|
val callExpression = callee.parent as KtCallExpression
|
||||||
val functionLiteral = callExpression.lambdaArguments.single().getLambdaExpression()!!
|
val functionLiteral = callExpression.lambdaArguments.single().getLambdaExpression()!!
|
||||||
|
|
||||||
val returnLabel = callee.getReferencedNameAsName()
|
val returnLabel = callee.getReferencedNameAsName()
|
||||||
returnSaver.restore(functionLiteral, returnLabel)
|
runWriteAction {
|
||||||
commentSaver.restore(replaced, forceAdjustIndent = true/* by some reason lambda body is sometimes not properly indented */)
|
returnSaver.restore(functionLiteral, returnLabel)
|
||||||
|
commentSaver.restore(replaced, forceAdjustIndent = true/* by some reason lambda body is sometimes not properly indented */)
|
||||||
|
}
|
||||||
val parentCall = ((replaced.parent as? KtValueArgument)
|
val parentCall = ((replaced.parent as? KtValueArgument)
|
||||||
?.parent as? KtValueArgumentList)
|
?.parent as? KtValueArgumentList)
|
||||||
?.parent as? KtCallExpression
|
?.parent as? KtCallExpression
|
||||||
if (parentCall != null && RedundantSamConstructorInspection.samConstructorCallsToBeConverted(parentCall).singleOrNull() == callExpression) {
|
if (parentCall != null && RedundantSamConstructorInspection.samConstructorCallsToBeConverted(parentCall).singleOrNull() == callExpression) {
|
||||||
RedundantSamConstructorInspection.replaceSamConstructorCall(callExpression)
|
RedundantSamConstructorInspection.replaceSamConstructorCall(callExpression)
|
||||||
if (parentCall.canMoveLambdaOutsideParentheses()) {
|
if (parentCall.canMoveLambdaOutsideParentheses()) runWriteAction {
|
||||||
parentCall.moveFunctionLiteralOutsideParentheses()
|
parentCall.moveFunctionLiteralOutsideParentheses()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||||
import org.jetbrains.kotlin.psi.KtParameterList
|
import org.jetbrains.kotlin.psi.KtParameterList
|
||||||
@@ -85,8 +86,10 @@ open class SpecifyExplicitLambdaSignatureIntention : SelfTargetingOffsetIndepend
|
|||||||
val psiFactory = KtPsiFactory(element)
|
val psiFactory = KtPsiFactory(element)
|
||||||
val functionLiteral = element.functionLiteral
|
val functionLiteral = element.functionLiteral
|
||||||
val newParameterList = psiFactory.createLambdaParameterListIfAny(parameterString)
|
val newParameterList = psiFactory.createLambdaParameterListIfAny(parameterString)
|
||||||
functionLiteral.setParameterListIfAny(psiFactory, newParameterList)
|
runWriteAction {
|
||||||
ShortenReferences.DEFAULT.process(element.valueParameters)
|
functionLiteral.setParameterListIfAny(psiFactory, newParameterList)
|
||||||
|
ShortenReferences.DEFAULT.process(element.valueParameters)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.core.replaced
|
|||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||||
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.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
import org.jetbrains.kotlin.idea.util.shouldNotConvertToProperty
|
import org.jetbrains.kotlin.idea.util.shouldNotConvertToProperty
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -131,7 +132,10 @@ class UsePropertyAccessSyntaxIntention :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: KtCallExpression, editor: Editor?) {
|
override fun applyTo(element: KtCallExpression, editor: Editor?) {
|
||||||
applyTo(element, detectPropertyNameToUse(element)!!, reformat = true)
|
val propertyName = detectPropertyNameToUse(element) ?: return
|
||||||
|
runWriteAction {
|
||||||
|
applyTo(element, propertyName, reformat = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun applyTo(element: KtCallExpression, propertyName: Name, reformat: Boolean): KtExpression {
|
fun applyTo(element: KtCallExpression, propertyName: Name, reformat: Boolean): KtExpression {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
|||||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingIntention
|
import org.jetbrains.kotlin.idea.intentions.SelfTargetingIntention
|
||||||
import org.jetbrains.kotlin.idea.search.allScope
|
import org.jetbrains.kotlin.idea.search.allScope
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.idea.util.findAnnotation
|
import org.jetbrains.kotlin.idea.util.findAnnotation
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -52,9 +53,12 @@ class AddConstModifierFix(val property: KtProperty) : AddModifierFix(property, K
|
|||||||
private val removeAnnotations = listOf(FqName("kotlin.jvm.JvmStatic"), FqName("kotlin.jvm.JvmField"))
|
private val removeAnnotations = listOf(FqName("kotlin.jvm.JvmStatic"), FqName("kotlin.jvm.JvmField"))
|
||||||
|
|
||||||
fun addConstModifier(property: KtProperty) {
|
fun addConstModifier(property: KtProperty) {
|
||||||
|
val annotationsToRemove = removeAnnotations.mapNotNull { property.findAnnotation(it) }
|
||||||
replaceReferencesToGetterByReferenceToField(property)
|
replaceReferencesToGetterByReferenceToField(property)
|
||||||
property.addModifier(KtTokens.CONST_KEYWORD)
|
runWriteAction {
|
||||||
removeAnnotations.mapNotNull { property.findAnnotation(it) }.forEach(KtAnnotationEntry::delete)
|
property.addModifier(KtTokens.CONST_KEYWORD)
|
||||||
|
annotationsToRemove.forEach(KtAnnotationEntry::delete)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,11 +114,13 @@ fun replaceReferencesToGetterByReferenceToField(property: KtProperty) {
|
|||||||
val factory = PsiElementFactory.SERVICE.getInstance(project)
|
val factory = PsiElementFactory.SERVICE.getInstance(project)
|
||||||
val fieldFQName = backingField.containingClass!!.qualifiedName + "." + backingField.name
|
val fieldFQName = backingField.containingClass!!.qualifiedName + "." + backingField.name
|
||||||
|
|
||||||
getterUsages.forEach {
|
runWriteAction {
|
||||||
val call = it.element.getNonStrictParentOfType<PsiMethodCallExpression>()
|
getterUsages.forEach {
|
||||||
if (call != null && it.element == call.methodExpression) {
|
val call = it.element.getNonStrictParentOfType<PsiMethodCallExpression>()
|
||||||
val fieldRef = factory.createExpressionFromText(fieldFQName, it.element)
|
if (call != null && it.element == call.methodExpression) {
|
||||||
call.replace(fieldRef)
|
val fieldRef = factory.createExpressionFromText(fieldFQName, it.element)
|
||||||
|
call.replace(fieldRef)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.postProcessing
|
package org.jetbrains.kotlin.nj2k.postProcessing
|
||||||
|
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
|
||||||
import com.intellij.openapi.editor.RangeMarker
|
import com.intellij.openapi.editor.RangeMarker
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
@@ -13,7 +12,6 @@ import com.intellij.psi.PsiRecursiveElementVisitor
|
|||||||
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
|
||||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|
||||||
import org.jetbrains.kotlin.j2k.ConverterSettings
|
import org.jetbrains.kotlin.j2k.ConverterSettings
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
|||||||
+29
-7
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.idea.quickfix.AddConstModifierFix
|
|||||||
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.references.readWriteAccess
|
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||||
|
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
import org.jetbrains.kotlin.j2k.ConverterSettings
|
import org.jetbrains.kotlin.j2k.ConverterSettings
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -127,13 +129,29 @@ class RemoveRedundantOverrideVisibilityProcessing :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UseExpressionBodyProcessing : InspectionLikeProcessingForElement<KtPropertyAccessor>(KtPropertyAccessor::class) {
|
class ReplaceGetterBodyWithSingleReturnStatementWithExpressionBody :
|
||||||
private val inspection = UseExpressionBodyInspection(convertEmptyToUnit = false)
|
InspectionLikeProcessingForElement<KtPropertyAccessor>(KtPropertyAccessor::class) {
|
||||||
override fun isApplicableTo(element: KtPropertyAccessor, settings: ConverterSettings?): Boolean =
|
|
||||||
inspection.isActiveFor(element)
|
private fun KtPropertyAccessor.singleBodyStatementExpression() =
|
||||||
|
bodyBlockExpression?.statements
|
||||||
|
?.singleOrNull()
|
||||||
|
?.safeAs<KtReturnExpression>()
|
||||||
|
?.takeIf { it.labeledExpression == null }
|
||||||
|
?.returnedExpression
|
||||||
|
|
||||||
|
override fun isApplicableTo(element: KtPropertyAccessor, settings: ConverterSettings?): Boolean {
|
||||||
|
if (!element.isGetter) return false
|
||||||
|
return element.singleBodyStatementExpression() != null
|
||||||
|
}
|
||||||
|
|
||||||
override fun apply(element: KtPropertyAccessor) {
|
override fun apply(element: KtPropertyAccessor) {
|
||||||
inspection.simplify(element, false)
|
val body = element.bodyExpression ?: return
|
||||||
|
val returnedExpression = element.singleBodyStatementExpression() ?: return
|
||||||
|
|
||||||
|
val commentSaver = CommentSaver(body)
|
||||||
|
element.addBefore(KtPsiFactory(element).createEQ(), body)
|
||||||
|
val newBody = body.replaced(returnedExpression)
|
||||||
|
commentSaver.restore(newBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,13 +174,17 @@ class RemoveRedundantCastToNullableProcessing :
|
|||||||
|
|
||||||
class RemoveRedundantSamAdaptersProcessing :
|
class RemoveRedundantSamAdaptersProcessing :
|
||||||
InspectionLikeProcessingForElement<KtCallExpression>(KtCallExpression::class) {
|
InspectionLikeProcessingForElement<KtCallExpression>(KtCallExpression::class) {
|
||||||
|
override val writeActionNeeded = false
|
||||||
|
|
||||||
override fun isApplicableTo(element: KtCallExpression, settings: ConverterSettings?): Boolean =
|
override fun isApplicableTo(element: KtCallExpression, settings: ConverterSettings?): Boolean =
|
||||||
RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element).isNotEmpty()
|
RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element).isNotEmpty()
|
||||||
|
|
||||||
override fun apply(element: KtCallExpression) {
|
override fun apply(element: KtCallExpression) {
|
||||||
RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element).forEach { call ->
|
val callsToBeConverted = RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element)
|
||||||
RedundantSamConstructorInspection.replaceSamConstructorCall(call)
|
runWriteAction {
|
||||||
|
for (call in callsToBeConverted) {
|
||||||
|
RedundantSamConstructorInspection.replaceSamConstructorCall(call)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
import com.intellij.psi.CommonClassNames
|
import com.intellij.psi.CommonClassNames
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||||
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS
|
import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||||
|
|
||||||
class ImportStorage {
|
class ImportStorage {
|
||||||
private val imports = mutableSetOf<FqName>()
|
private val imports = mutableSetOf<FqName>()
|
||||||
@@ -27,6 +31,16 @@ class ImportStorage {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isImportNeededForCall(qualifiedExpression: KtQualifiedExpression): Boolean {
|
||||||
|
val shortName = qualifiedExpression.getCalleeExpressionIfAny()?.text ?: return true
|
||||||
|
if (shortName !in SHORT_NAMES) return true
|
||||||
|
val fqName = qualifiedExpression.selectorExpression?.mainReference?.resolve()?.getKotlinFqName() ?: return true
|
||||||
|
return isImportNeeded(fqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isImportNeeded(fqName: String): Boolean = isImportNeeded(FqName(fqName))
|
||||||
|
|
||||||
|
|
||||||
private val JAVA_TYPE_WRAPPERS_WHICH_HAVE_CONFLICTS_WITH_KOTLIN_ONES = setOf(
|
private val JAVA_TYPE_WRAPPERS_WHICH_HAVE_CONFLICTS_WITH_KOTLIN_ONES = setOf(
|
||||||
FqName(CommonClassNames.JAVA_LANG_BYTE),
|
FqName(CommonClassNames.JAVA_LANG_BYTE),
|
||||||
FqName(CommonClassNames.JAVA_LANG_SHORT),
|
FqName(CommonClassNames.JAVA_LANG_SHORT),
|
||||||
@@ -35,6 +49,9 @@ class ImportStorage {
|
|||||||
FqName(CommonClassNames.JAVA_LANG_DOUBLE)
|
FqName(CommonClassNames.JAVA_LANG_DOUBLE)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun isImportNeeded(fqName: String): Boolean = isImportNeeded(FqName(fqName))
|
private val SHORT_NAMES =
|
||||||
|
(NULLABILITY_ANNOTATIONS + JAVA_TYPE_WRAPPERS_WHICH_HAVE_CONFLICTS_WITH_KOTLIN_ONES)
|
||||||
|
.map { it.shortName().asString() }
|
||||||
|
.toSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user