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 e38cf8d1682..557ef2eea79 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 @@ -26,6 +26,7 @@ import com.intellij.psi.impl.PsiTreeChangeEventImpl.PsiEventType.CHILD_MOVED import com.intellij.psi.impl.PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGED import com.intellij.psi.impl.PsiTreeChangePreprocessor import com.intellij.psi.util.PsiModificationTracker +import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.psi.* @@ -283,12 +284,24 @@ class KotlinCodeBlockModificationListener( blockDeclaration .takeIf { it.isAncestor(element) } ?.let { ktClassInitializer -> - (KtPsiUtil.getTopmostParentOfTypes(blockDeclaration, KtClass::class.java) as? KtElement)?.let { + (PsiTreeUtil.getParentOfType(blockDeclaration, KtClass::class.java) as? KtElement)?.let { return BlockModificationScopeElement(it, ktClassInitializer) } } } + is KtSecondaryConstructor -> { + blockDeclaration + ?.takeIf { + it.bodyExpression?.isAncestor(element) ?: false || it.getDelegationCallOrNull()?.isAncestor(element) ?: false + } + ?.let { ktConstructor -> + (PsiTreeUtil.getParentOfType(blockDeclaration, KtClass::class.java) as? KtElement)?.let { + return BlockModificationScopeElement(it, ktConstructor) + } + } + } + // TODO: still under consideration - is it worth to track changes of private properties / methods // problem could be in diagnostics - it is worth to manage it with modTracker // is KtClass -> { @@ -315,6 +328,7 @@ class KotlinCodeBlockModificationListener( KtProperty::class.java, KtNamedFunction::class.java, KtClassInitializer::class.java, + KtSecondaryConstructor::class.java, KtScriptInitializer::class.java ) diff --git a/idea/testData/codeInsight/outOfBlock/InDelegateCallOfSecondaryConstructor.kt b/idea/testData/codeInsight/outOfBlock/InDelegateCallOfSecondaryConstructor.kt new file mode 100644 index 00000000000..13e0c1a39ea --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InDelegateCallOfSecondaryConstructor.kt @@ -0,0 +1,10 @@ +// TYPE: 'n.toString()' +// OUT_OF_CODE_BLOCK: FALSE + +class InSecondaryConstructor(val name: String) { + init { + } + + constructor(n: Int): this() { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InDelegateCallOfSecondaryConstructorInLocalClass.kt b/idea/testData/codeInsight/outOfBlock/InDelegateCallOfSecondaryConstructorInLocalClass.kt new file mode 100644 index 00000000000..e05bdff92f8 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InDelegateCallOfSecondaryConstructorInLocalClass.kt @@ -0,0 +1,11 @@ +// TYPE: '4' +// OUT_OF_CODE_BLOCK: FALSE + +fun bar() { + class InnerBoo(val someValue: Int) { + constructor() : this() { + } + } + + val b = InnerBoo() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InPrimaryConstructor.kt b/idea/testData/codeInsight/outOfBlock/InPrimaryConstructor.kt new file mode 100644 index 00000000000..789e7d5e9df --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InPrimaryConstructor.kt @@ -0,0 +1,10 @@ +// TYPE: 'z' +// OUT_OF_CODE_BLOCK: TRUE +// TODO: Investigate +// SKIP_ANALYZE_CHECK + +data class Intz(val q: String) + +class InPrimaryConstructor(val x: Int) { + +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InSecondaryConstructorBody.kt b/idea/testData/codeInsight/outOfBlock/InSecondaryConstructorBody.kt new file mode 100644 index 00000000000..5d23eb67267 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InSecondaryConstructorBody.kt @@ -0,0 +1,16 @@ +// TYPE: 'n' +// OUT_OF_CODE_BLOCK: FALSE + +fun println(s: String) { + +} + +class InSecondaryConstructor { + init { + println("Init block") + } + + constructor(i: Int) { + printl("Constructor") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InSecondaryConstructorParameter.kt b/idea/testData/codeInsight/outOfBlock/InSecondaryConstructorParameter.kt new file mode 100644 index 00000000000..7b5af44ba32 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InSecondaryConstructorParameter.kt @@ -0,0 +1,13 @@ +// TYPE: 'z' +// OUT_OF_CODE_BLOCK: TRUE + +data class Intz(val q: String) + +class InSecondaryConstructor { + init { + } + + constructor(i: Int) { + } +} +// SKIP_ANALYZE_CHECK \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InitBlockInLocalClass.kt b/idea/testData/codeInsight/outOfBlock/InitBlockInLocalClass.kt new file mode 100644 index 00000000000..7cda2b12338 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InitBlockInLocalClass.kt @@ -0,0 +1,14 @@ +// OUT_OF_CODE_BLOCK: FALSE +// TYPE: '4' + +fun boo() { + class InnerBoo() { + val someValue: Int + + init { + someValue = + } + } + + val b = InnerBoo() +}