From f709377735fbd2923a9e6ae3c5be7d5e04c659ba Mon Sep 17 00:00:00 2001 From: Vladimir Dolzhenko Date: Wed, 27 Nov 2019 13:59:27 +0100 Subject: [PATCH] Support incremental analysis of comment and kdoc #KT-35189 Fixed --- .../KotlinCodeBlockModificationListener.kt | 17 ++++++++++++++++- idea/testData/codeInsight/outOfBlock/Comment.kt | 7 +++++++ .../codeInsight/outOfBlock/InComment.kt | 7 +++++++ .../codeInsight/outOfBlock/InKDocComment.kt | 9 +++++++++ .../outOfBlock/InPropertyWithoutInference.kt | 4 ++++ .../AbstractOutOfBlockModificationTest.kt | 5 ++++- 6 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 idea/testData/codeInsight/outOfBlock/Comment.kt create mode 100644 idea/testData/codeInsight/outOfBlock/InComment.kt create mode 100644 idea/testData/codeInsight/outOfBlock/InKDocComment.kt create mode 100644 idea/testData/codeInsight/outOfBlock/InPropertyWithoutInference.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt index d6e8c9bfa83..e38cf8d1682 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt @@ -17,6 +17,7 @@ import com.intellij.pom.event.PomModelEvent import com.intellij.pom.event.PomModelListener import com.intellij.pom.tree.TreeAspect import com.intellij.pom.tree.events.TreeChangeEvent +import com.intellij.pom.tree.events.impl.ChangeInfoImpl import com.intellij.psi.* import com.intellij.psi.impl.PsiManagerImpl import com.intellij.psi.impl.PsiModificationTrackerImpl @@ -26,6 +27,7 @@ import com.intellij.psi.impl.PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGE import com.intellij.psi.impl.PsiTreeChangePreprocessor import com.intellij.psi.util.PsiModificationTracker import org.jetbrains.kotlin.idea.KotlinLanguage +import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentOfType import org.jetbrains.kotlin.psi.psiUtil.isAncestor @@ -92,6 +94,7 @@ class KotlinCodeBlockModificationListener( if (changedElements.isNotEmpty() && // ignore formatting (whitespaces etc) (isFormattingChange(changeSet) || + isCommentChange(changeSet) || changedElements.all { !it.psi.isPhysical }) ) return @@ -195,7 +198,19 @@ class KotlinCodeBlockModificationListener( fun isFormattingChange(changeSet: TreeChangeEvent): Boolean = changeSet.changedElements.all { - changeSet.getChangesByElement(it).affectedChildren.all { c -> (c is PsiWhiteSpace || c is PsiComment) } + changeSet.getChangesByElement(it).affectedChildren.all { c -> c is PsiWhiteSpace } + } + + fun isCommentChange(changeSet: TreeChangeEvent): Boolean = + changeSet.changedElements.all { changedElement -> + val changesByElement = changeSet.getChangesByElement(changedElement) + changesByElement.affectedChildren.all { affectedChild -> + val changeByChild = changesByElement.getChangeByChild(affectedChild) + return@all if (changeByChild is ChangeInfoImpl) { + changeByChild.oldChild is PsiComment && changeByChild.newChild is PsiComment || + changeByChild.oldChild is KDoc && changeByChild.newChild is KDoc + } else false + } } fun getInsideCodeBlockModificationScope(element: PsiElement): BlockModificationScopeElement? { diff --git a/idea/testData/codeInsight/outOfBlock/Comment.kt b/idea/testData/codeInsight/outOfBlock/Comment.kt new file mode 100644 index 00000000000..2acf9109b88 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/Comment.kt @@ -0,0 +1,7 @@ +// OUT_OF_CODE_BLOCK: FALSE +// TYPE: '//' +// ERROR: A 'return' expression required in a function with a block body ('{...}') + +fun comment(): String { + return "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InComment.kt b/idea/testData/codeInsight/outOfBlock/InComment.kt new file mode 100644 index 00000000000..e1f0c162957 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InComment.kt @@ -0,0 +1,7 @@ +// OUT_OF_CODE_BLOCK: FALSE +// TYPE: 'some text' + +// +fun comment(): String { + return "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InKDocComment.kt b/idea/testData/codeInsight/outOfBlock/InKDocComment.kt new file mode 100644 index 00000000000..d7b18a1bcc7 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InKDocComment.kt @@ -0,0 +1,9 @@ +// OUT_OF_CODE_BLOCK: FALSE +// TYPE: 'some text' + +/** + * + */ +fun kDoc(): String { + return "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InPropertyWithoutInference.kt b/idea/testData/codeInsight/outOfBlock/InPropertyWithoutInference.kt new file mode 100644 index 00000000000..d2d24664b6c --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InPropertyWithoutInference.kt @@ -0,0 +1,4 @@ +// OUT_OF_CODE_BLOCK: FALSE +class Test { + val a: String = "aasdf" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOutOfBlockModificationTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOutOfBlockModificationTest.kt index 1acbe766f1c..3e6ab3ffff6 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOutOfBlockModificationTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOutOfBlockModificationTest.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.codeInsight import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.PsiComment import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiManager import com.intellij.psi.impl.PsiModificationTrackerImpl @@ -18,6 +19,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.trackers.outOfBlockModificationCount import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.ResolveSession @@ -75,6 +77,7 @@ abstract class AbstractOutOfBlockModificationTest : KotlinLightCodeInsightFixtur .incOutOfCodeBlockModificationCounter() } val updateElement = myFixture.file.findElementAt(myFixture.caretOffset - 1) + val kDoc: KDoc? = PsiTreeUtil.getParentOfType(updateElement, KDoc::class.java, false) val ktExpression: KtExpression? = PsiTreeUtil.getParentOfType(updateElement, KtExpression::class.java, false) val ktDeclaration: KtDeclaration? = PsiTreeUtil.getParentOfType(updateElement, KtDeclaration::class.java, false) val ktElement = ktExpression ?: ktDeclaration ?: return @@ -91,7 +94,7 @@ abstract class AbstractOutOfBlockModificationTest : KotlinLightCodeInsightFixtur "Expected out-of-block should result expression analyzed and vise versa", expectedOutOfBlock, expressionProcessed ) - } else { + } else if (updateElement !is PsiComment && kDoc == null) { // comments could be ignored from analyze val declarationProcessed = context.get( BindingContext.DECLARATION_TO_DESCRIPTOR,