Refactor PSI for destructuring declarations in for: they are now children of KtParameter and not instead of it
This commit is contained in:
+1
-1
@@ -62,7 +62,7 @@ class DestructuringDeclarationReferenceSearcher(
|
||||
|
||||
is KtContainerNode -> {
|
||||
if (parent.node.elementType == KtNodeTypes.LOOP_RANGE) {
|
||||
(parent.parent as KtForExpression).destructuringParameter
|
||||
(parent.parent as KtForExpression).destructuringDeclaration
|
||||
}
|
||||
else {
|
||||
null
|
||||
|
||||
+1
-1
@@ -543,7 +543,7 @@ class ExpressionsOfTypeProcessor(
|
||||
is KtContainerNode -> {
|
||||
if (parent.node.elementType == KtNodeTypes.LOOP_RANGE) { // "for (x in <expr>) ..."
|
||||
val forExpression = parent.parent as KtForExpression
|
||||
(forExpression.destructuringParameter ?: forExpression.loopParameter as KtDeclaration?)?.let {
|
||||
(forExpression.destructuringDeclaration ?: forExpression.loopParameter as KtDeclaration?)?.let {
|
||||
processSuspiciousDeclaration(it)
|
||||
}
|
||||
break@ParentsLoop
|
||||
|
||||
@@ -396,7 +396,7 @@ class KotlinBreadcrumbsInfoProvider : BreadcrumbsInfoProvider() {
|
||||
|
||||
private fun KtContainerNode.buildText(kind: TextKind): String {
|
||||
with (bodyOwner() as KtForExpression) {
|
||||
val parameterText = loopParameter?.nameAsName?.render() ?: destructuringParameter?.text ?: return "for"
|
||||
val parameterText = loopParameter?.nameAsName?.render() ?: destructuringDeclaration?.text ?: return "for"
|
||||
val collectionText = loopRange?.text ?: ""
|
||||
val text = (parameterText + " in " + collectionText).truncateEnd(kind)
|
||||
return labelText() + "for($text)"
|
||||
|
||||
@@ -23,7 +23,7 @@ class KotlinForConditionFixer: MissingConditionFixer<KtForExpression>() {
|
||||
override val keyword = "for"
|
||||
override fun getElement(element: PsiElement?) = element as? KtForExpression
|
||||
override fun getCondition(element: KtForExpression) =
|
||||
element.loopRange ?: element.loopParameter ?: element.destructuringParameter
|
||||
element.loopRange ?: element.loopParameter ?: element.destructuringDeclaration
|
||||
override fun getLeftParenthesis(element: KtForExpression) = element.leftParenthesis
|
||||
override fun getRightParenthesis(element: KtForExpression) = element.rightParenthesis
|
||||
override fun getBody(element: KtForExpression) = element.body
|
||||
|
||||
@@ -64,7 +64,7 @@ class AddForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(
|
||||
|
||||
loopRange.replace(createWithIndexExpression(loopRange))
|
||||
|
||||
var multiParameter = (psiFactory.createExpressionByPattern("for((index, $0) in x){}", loopParameter.text) as KtForExpression).destructuringParameter!!
|
||||
var multiParameter = (psiFactory.createExpressionByPattern("for((index, $0) in x){}", loopParameter.text) as KtForExpression).destructuringDeclaration!!
|
||||
|
||||
multiParameter = loopParameter.replaced(multiParameter)
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
||||
names.add(name)
|
||||
}
|
||||
if (forLoop != null) {
|
||||
element.replace(factory.createDestructuringParameter("(${names.joinToString()})"))
|
||||
element.replace(factory.createDestructuringParameterForLoop("(${names.joinToString()})"))
|
||||
|
||||
if (removeSelectorInLoopRange && loopRange is KtDotQualifiedExpression) {
|
||||
loopRange.replace(loopRange.receiverExpression)
|
||||
|
||||
@@ -81,14 +81,14 @@ class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(KtExpres
|
||||
}
|
||||
|
||||
val paramPattern = (names.singleOrNull()?.first()
|
||||
?: psiFactory.createDestructuringParameter(names.indices.joinToString(prefix = "(", postfix = ")") { "p$it" }))
|
||||
?: psiFactory.createDestructuringParameterForLoop(names.indices.joinToString(prefix = "(", postfix = ")") { "p$it" }))
|
||||
var forExpression = psiFactory.createExpressionByPattern("for($0 in $1) {\nx\n}", paramPattern, element) as KtForExpression
|
||||
forExpression = element.replaced(forExpression)
|
||||
|
||||
PsiDocumentManager.getInstance(forExpression.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
|
||||
val bodyPlaceholder = (forExpression.body as KtBlockExpression).statements.single()
|
||||
val parameters = forExpression.loopParameter?.singletonList() ?: forExpression.destructuringParameter!!.entries
|
||||
val parameters = forExpression.destructuringDeclaration?.entries ?: forExpression.loopParameter!!.singletonList()
|
||||
|
||||
val templateBuilder = TemplateBuilderImpl(forExpression)
|
||||
for ((parameter, parameterNames) in (parameters zip names)) {
|
||||
|
||||
@@ -45,7 +45,7 @@ class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpressio
|
||||
|
||||
override fun applicabilityRange(element: KtForExpression): TextRange? {
|
||||
val loopRange = element.loopRange as? KtDotQualifiedExpression ?: return null
|
||||
val multiParameter = element.destructuringParameter ?: return null
|
||||
val multiParameter = element.destructuringDeclaration ?: return null
|
||||
if (multiParameter.entries.size != 2) return null
|
||||
|
||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
||||
@@ -60,12 +60,12 @@ class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpressio
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtForExpression, editor: Editor?) {
|
||||
val multiParameter = element.destructuringParameter!!
|
||||
val multiParameter = element.destructuringDeclaration!!
|
||||
val loopRange = element.loopRange as KtDotQualifiedExpression
|
||||
|
||||
val elementVar = multiParameter.entries[1]
|
||||
val loop = KtPsiFactory(element).createExpressionByPattern("for ($0 in _) {}", elementVar.text) as KtForExpression
|
||||
multiParameter.replace(loop.loopParameter!!)
|
||||
element.loopParameter!!.replace(loop.loopParameter!!)
|
||||
|
||||
loopRange.replace(loopRange.receiverExpression)
|
||||
}
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ class UseWithIndexIntention : SelfTargetingRangeIntention<KtForExpression>(
|
||||
val newLoopRange = factory.createExpressionByPattern("$0.withIndex()", loopRange)
|
||||
loopRange.replace(newLoopRange)
|
||||
|
||||
val multiParameter = (factory.createExpressionByPattern("for(($0, $1) in x){}", indexVariable.nameAsSafeName, loopParameter.text) as KtForExpression).destructuringParameter!!
|
||||
val multiParameter = (factory.createExpressionByPattern("for(($0, $1) in x){}", indexVariable.nameAsSafeName, loopParameter.text) as KtForExpression).loopParameter!!
|
||||
loopParameter.replace(multiParameter)
|
||||
|
||||
initializationStatement.delete()
|
||||
|
||||
@@ -185,7 +185,7 @@ data class LoopData(
|
||||
private fun extractLoopData(loop: KtForExpression): LoopData? {
|
||||
val loopRange = loop.loopRange ?: return null
|
||||
|
||||
val destructuringParameter = loop.destructuringParameter
|
||||
val destructuringParameter = loop.destructuringDeclaration
|
||||
if (destructuringParameter != null && destructuringParameter.entries.size == 2) {
|
||||
val qualifiedExpression = loopRange as? KtDotQualifiedExpression
|
||||
if (qualifiedExpression != null) {
|
||||
|
||||
@@ -184,7 +184,6 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
VAL_OR_VAR_ON_FUN_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||
VAL_OR_VAR_ON_LOOP_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||
VAL_OR_VAR_ON_LOOP_MULTI_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||
VAL_OR_VAR_ON_CATCH_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||
VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER.registerFactory(RemoveValVarFromParameterFix)
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.types.Variance
|
||||
object CreateComponentFunctionActionFactory : CreateCallableMemberFromUsageFactory<KtDestructuringDeclaration>() {
|
||||
override fun getElementOfInterest(diagnostic: Diagnostic): KtDestructuringDeclaration? {
|
||||
QuickFixUtil.getParentElementOfType(diagnostic, KtDestructuringDeclaration::class.java)?.let { return it }
|
||||
return QuickFixUtil.getParentElementOfType(diagnostic, KtForExpression::class.java)?.destructuringParameter
|
||||
return QuickFixUtil.getParentElementOfType(diagnostic, KtForExpression::class.java)?.destructuringDeclaration
|
||||
}
|
||||
|
||||
override fun createCallableInfo(element: KtDestructuringDeclaration, diagnostic: Diagnostic): CallableInfo? {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ object CreateIteratorFunctionActionFactory : CreateCallableMemberFromUsageFactor
|
||||
override fun createCallableInfo(element: KtForExpression, diagnostic: Diagnostic): CallableInfo? {
|
||||
val file = diagnostic.psiFile as? KtFile ?: return null
|
||||
val iterableExpr = element.loopRange ?: return null
|
||||
val variableExpr: KtExpression = ((element.loopParameter ?: element.destructuringParameter) ?: return null) as KtExpression
|
||||
val variableExpr: KtExpression = ((element.loopParameter ?: element.destructuringDeclaration) ?: return null) as KtExpression
|
||||
val iterableType = TypeInfo(iterableExpr, Variance.IN_VARIANCE)
|
||||
|
||||
val (bindingContext, moduleDescriptor) = file.analyzeFullyAndGetResult()
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ object CreateNextFunctionActionFactory : CreateCallableMemberFromUsageFactory<Kt
|
||||
val diagnosticWithParameters = DiagnosticFactory.cast(diagnostic, Errors.NEXT_MISSING, Errors.NEXT_NONE_APPLICABLE)
|
||||
val ownerType = TypeInfo(diagnosticWithParameters.a, Variance.IN_VARIANCE)
|
||||
|
||||
val variableExpr = element.loopParameter ?: element.destructuringParameter ?: return null
|
||||
val variableExpr = element.loopParameter ?: element.destructuringDeclaration ?: return null
|
||||
val returnType = TypeInfo(variableExpr as KtExpression, Variance.OUT_VARIANCE)
|
||||
return FunctionInfo(OperatorNameConventions.NEXT.asString(), ownerType, returnType, isOperator = true)
|
||||
}
|
||||
|
||||
+2
-1
@@ -40,7 +40,8 @@ class KotlinComponentUsageInDestructuring(element: KtDestructuringDeclarationEnt
|
||||
|
||||
val newDestructuring = KtPsiFactory(element).buildDestructuringDeclaration {
|
||||
val lastIndex = newParameterInfos.indexOfLast { it.oldIndex in currentEntries.indices }
|
||||
val nameValidator = CollectingNameValidator(filter = NewDeclarationNameValidator(declaration.parent, null, Target.VARIABLES))
|
||||
val nameValidator = CollectingNameValidator(
|
||||
filter = NewDeclarationNameValidator(declaration.parent.parent, null, Target.VARIABLES))
|
||||
|
||||
appendFixedText("val (")
|
||||
for (i in 0..lastIndex) {
|
||||
|
||||
@@ -198,7 +198,7 @@ fun KtElement.renderTrimmed(): String {
|
||||
|
||||
override fun visitForExpression(expression: KtForExpression) {
|
||||
builder.append("for (")
|
||||
(expression.loopParameter ?: expression.destructuringParameter)?.accept(this)
|
||||
(expression.loopParameter ?: expression.destructuringDeclaration)?.accept(this)
|
||||
builder.append(" in ")
|
||||
expression.loopRange?.accept(this)
|
||||
builder.append(")")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
data class XY(val x: Int, val y: Int)
|
||||
|
||||
fun convert(xy: XY, f: (XY) -> Int) = f(xy)
|
||||
|
||||
fun foo() = <error>convert</error> { (<error>x</error><error><error>,</error> y)</error> }
|
||||
@@ -502,6 +502,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("DestructuringDeclarationInLambda.kt")
|
||||
public void testDestructuringDeclarationInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/DestructuringDeclarationInLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("DollarsInName.kt")
|
||||
public void testDollarsInName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/DollarsInName.kt");
|
||||
|
||||
Reference in New Issue
Block a user