Reformat: UsePropertyAccessSyntaxIntention
This commit is contained in:
committed by
Mikhail Glukhikh
parent
c12bd9b506
commit
240b9fd97a
@@ -57,7 +57,8 @@ import org.jetbrains.kotlin.types.TypeUtils
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
|
|
||||||
class UsePropertyAccessSyntaxInspection : IntentionBasedInspection<KtCallExpression>(UsePropertyAccessSyntaxIntention::class), CleanupLocalInspectionTool {
|
class UsePropertyAccessSyntaxInspection : IntentionBasedInspection<KtCallExpression>(UsePropertyAccessSyntaxIntention::class),
|
||||||
|
CleanupLocalInspectionTool {
|
||||||
|
|
||||||
val fqNameList = mutableListOf<FqNameUnsafe>()
|
val fqNameList = mutableListOf<FqNameUnsafe>()
|
||||||
|
|
||||||
@@ -89,14 +90,14 @@ class NotPropertiesServiceImpl(private val project: Project) : NotPropertiesServ
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val default = listOf(
|
val default = listOf(
|
||||||
"java.net.Socket.getInputStream",
|
"java.net.Socket.getInputStream",
|
||||||
"java.net.Socket.getOutputStream",
|
"java.net.Socket.getOutputStream",
|
||||||
"java.net.URLConnection.getInputStream",
|
"java.net.URLConnection.getInputStream",
|
||||||
"java.net.URLConnection.getOutputStream",
|
"java.net.URLConnection.getOutputStream",
|
||||||
"java.util.concurrent.atomic.AtomicInteger.getAndIncrement",
|
"java.util.concurrent.atomic.AtomicInteger.getAndIncrement",
|
||||||
"java.util.concurrent.atomic.AtomicInteger.getAndDecrement",
|
"java.util.concurrent.atomic.AtomicInteger.getAndDecrement",
|
||||||
"java.util.concurrent.atomic.AtomicLong.getAndIncrement",
|
"java.util.concurrent.atomic.AtomicLong.getAndIncrement",
|
||||||
"java.util.concurrent.atomic.AtomicLong.getAndDecrement"
|
"java.util.concurrent.atomic.AtomicLong.getAndDecrement"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -104,7 +105,8 @@ class NotPropertiesServiceImpl(private val project: Project) : NotPropertiesServ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention<KtCallExpression>(KtCallExpression::class.java, "Use property access syntax") {
|
class UsePropertyAccessSyntaxIntention :
|
||||||
|
SelfTargetingOffsetIndependentIntention<KtCallExpression>(KtCallExpression::class.java, "Use property access syntax") {
|
||||||
override fun isApplicableTo(element: KtCallExpression): Boolean {
|
override fun isApplicableTo(element: KtCallExpression): Boolean {
|
||||||
return detectPropertyNameToUse(element) != null
|
return detectPropertyNameToUse(element) != null
|
||||||
}
|
}
|
||||||
@@ -135,8 +137,8 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
|||||||
|
|
||||||
val function = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return null
|
val function = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return null
|
||||||
|
|
||||||
val notProperties = (inspection as? UsePropertyAccessSyntaxInspection)?.fqNameList?.toSet() ?:
|
val notProperties =
|
||||||
NotPropertiesService.getNotProperties(callExpression)
|
(inspection as? UsePropertyAccessSyntaxInspection)?.fqNameList?.toSet() ?: NotPropertiesService.getNotProperties(callExpression)
|
||||||
if (function.shouldNotConvertToProperty(notProperties)) return null
|
if (function.shouldNotConvertToProperty(notProperties)) return null
|
||||||
|
|
||||||
val resolutionScope = callExpression.getResolutionScope(bindingContext, resolutionFacade)
|
val resolutionScope = callExpression.getResolutionScope(bindingContext, resolutionFacade)
|
||||||
@@ -146,7 +148,16 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
|||||||
val qualifiedExpression = callExpression.getQualifiedExpressionForSelectorOrThis()
|
val qualifiedExpression = callExpression.getQualifiedExpressionForSelectorOrThis()
|
||||||
val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, qualifiedExpression] ?: TypeUtils.NO_EXPECTED_TYPE
|
val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, qualifiedExpression] ?: TypeUtils.NO_EXPECTED_TYPE
|
||||||
|
|
||||||
if (!checkWillResolveToProperty(resolvedCall, property, bindingContext, resolutionScope, dataFlowInfo, expectedType, resolutionFacade)) return null
|
if (!checkWillResolveToProperty(
|
||||||
|
resolvedCall,
|
||||||
|
property,
|
||||||
|
bindingContext,
|
||||||
|
resolutionScope,
|
||||||
|
dataFlowInfo,
|
||||||
|
expectedType,
|
||||||
|
resolutionFacade
|
||||||
|
)
|
||||||
|
) return null
|
||||||
|
|
||||||
val isSetUsage = callExpression.valueArguments.size == 1
|
val isSetUsage = callExpression.valueArguments.size == 1
|
||||||
|
|
||||||
@@ -159,16 +170,17 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
|||||||
|
|
||||||
if (isSetUsage && property.type != function.valueParameters.single().type) {
|
if (isSetUsage && property.type != function.valueParameters.single().type) {
|
||||||
val qualifiedExpressionCopy = qualifiedExpression.copied()
|
val qualifiedExpressionCopy = qualifiedExpression.copied()
|
||||||
val callExpressionCopy = ((qualifiedExpressionCopy as? KtQualifiedExpression)?.selectorExpression ?: qualifiedExpressionCopy) as KtCallExpression
|
val callExpressionCopy =
|
||||||
|
((qualifiedExpressionCopy as? KtQualifiedExpression)?.selectorExpression ?: qualifiedExpressionCopy) as KtCallExpression
|
||||||
val newExpression = applyTo(callExpressionCopy, property.name, reformat = false)
|
val newExpression = applyTo(callExpressionCopy, property.name, reformat = false)
|
||||||
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace")
|
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace")
|
||||||
val newBindingContext = newExpression.analyzeInContext(
|
val newBindingContext = newExpression.analyzeInContext(
|
||||||
resolutionScope,
|
resolutionScope,
|
||||||
contextExpression = callExpression,
|
contextExpression = callExpression,
|
||||||
trace = bindingTrace,
|
trace = bindingTrace,
|
||||||
dataFlowInfo = dataFlowInfo,
|
dataFlowInfo = dataFlowInfo,
|
||||||
expectedType = expectedType,
|
expectedType = expectedType,
|
||||||
isStatement = true
|
isStatement = true
|
||||||
)
|
)
|
||||||
if (newBindingContext.diagnostics.any { it.severity == Severity.ERROR }) return null
|
if (newBindingContext.diagnostics.any { it.severity == Severity.ERROR }) return null
|
||||||
}
|
}
|
||||||
@@ -177,13 +189,13 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkWillResolveToProperty(
|
private fun checkWillResolveToProperty(
|
||||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||||
property: SyntheticJavaPropertyDescriptor,
|
property: SyntheticJavaPropertyDescriptor,
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
resolutionScope: LexicalScope,
|
resolutionScope: LexicalScope,
|
||||||
dataFlowInfo: DataFlowInfo,
|
dataFlowInfo: DataFlowInfo,
|
||||||
expectedType: KotlinType,
|
expectedType: KotlinType,
|
||||||
facade: ResolutionFacade
|
facade: ResolutionFacade
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val project = resolvedCall.call.callElement.project
|
val project = resolvedCall.call.callElement.project
|
||||||
val newCall = object : DelegatingCall(resolvedCall.call) {
|
val newCall = object : DelegatingCall(resolvedCall.call) {
|
||||||
@@ -196,10 +208,12 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
|||||||
}
|
}
|
||||||
|
|
||||||
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace")
|
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace")
|
||||||
val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, expectedType, dataFlowInfo,
|
val context = BasicCallResolutionContext.create(
|
||||||
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
bindingTrace, resolutionScope, newCall, expectedType, dataFlowInfo,
|
||||||
false, facade.frontendService<LanguageVersionSettings>(),
|
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
facade.frontendService<DataFlowValueFactory>())
|
false, facade.frontendService<LanguageVersionSettings>(),
|
||||||
|
facade.frontendService<DataFlowValueFactory>()
|
||||||
|
)
|
||||||
val callResolver = facade.frontendService<CallResolver>()
|
val callResolver = facade.frontendService<CallResolver>()
|
||||||
val result = callResolver.resolveSimpleProperty(context)
|
val result = callResolver.resolveSimpleProperty(context)
|
||||||
return result.isSuccess && result.resultingDescriptor.original == property
|
return result.isSuccess && result.resultingDescriptor.original == property
|
||||||
@@ -228,8 +242,8 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
|||||||
ConvertToBlockBodyIntention.convert(callParent)
|
ConvertToBlockBodyIntention.convert(callParent)
|
||||||
val firstStatement = (callParent.bodyExpression as? KtBlockExpression)?.statements?.first()
|
val firstStatement = (callParent.bodyExpression as? KtBlockExpression)?.statements?.first()
|
||||||
callToConvert = (firstStatement as? KtQualifiedExpression)?.selectorExpression as? KtCallExpression
|
callToConvert = (firstStatement as? KtQualifiedExpression)?.selectorExpression as? KtCallExpression
|
||||||
?: firstStatement as? KtCallExpression
|
?: firstStatement as? KtCallExpression
|
||||||
?: throw IllegalStateException("Unexpected contents of function after conversion: ${callParent.text}")
|
?: throw IllegalStateException("Unexpected contents of function after conversion: ${callParent.text}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val qualifiedExpression = callToConvert.getQualifiedExpressionForSelector()
|
val qualifiedExpression = callToConvert.getQualifiedExpressionForSelector()
|
||||||
@@ -241,16 +255,16 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
|||||||
else -> error(qualifiedExpression) //TODO: make it sealed?
|
else -> error(qualifiedExpression) //TODO: make it sealed?
|
||||||
}
|
}
|
||||||
val newExpression = KtPsiFactory(callToConvert).createExpressionByPattern(
|
val newExpression = KtPsiFactory(callToConvert).createExpressionByPattern(
|
||||||
pattern,
|
pattern,
|
||||||
qualifiedExpression.receiverExpression,
|
qualifiedExpression.receiverExpression,
|
||||||
propertyName,
|
propertyName,
|
||||||
argument.getArgumentExpression()!!,
|
argument.getArgumentExpression()!!,
|
||||||
reformat = reformat
|
reformat = reformat
|
||||||
)
|
)
|
||||||
return qualifiedExpression.replaced(newExpression)
|
return qualifiedExpression.replaced(newExpression)
|
||||||
}
|
} else {
|
||||||
else {
|
val newExpression =
|
||||||
val newExpression = KtPsiFactory(callToConvert).createExpressionByPattern("$0=$1", propertyName, argument.getArgumentExpression()!!)
|
KtPsiFactory(callToConvert).createExpressionByPattern("$0=$1", propertyName, argument.getArgumentExpression()!!)
|
||||||
return callToConvert.replaced(newExpression)
|
return callToConvert.replaced(newExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user