getElementOfTypAtCaret(file: KtFile, caretName: String? = null): P {
+ val offset = getCaretPosition(file, caretName)
return file.findElementAt(offset)
?.parentOfType()
?: error("No expression found at caret")
@@ -98,6 +107,33 @@ class ExpressionMarkerProvider : TestService {
.dropLastWhile { it is PsiWhiteSpace }
}
+@PrivateForInline
+class CaretProvider {
+ private val caretToFile = mutableMapOf()
+
+ fun getCaretOffset(filename: String, caretTag: String?): Int? {
+ val cartsInFile = caretToFile[filename] ?: return null
+ return cartsInFile.getCaretOffsetByTag(caretTag)
+ }
+
+ fun addCaret(filename: String, caretTag: String?, caretOffset: Int) {
+ val cartsInFile = caretToFile.getOrPut(filename) { CaretsInFile() }
+ cartsInFile.addCaret(caretTag, caretOffset)
+ }
+
+ private class CaretsInFile {
+ private val carets = mutableMapOf()
+
+ fun getCaretOffsetByTag(tag: String?): Int? {
+ return carets[tag.orEmpty()]
+ }
+
+ fun addCaret(caretTag: String?, caretOffset: Int) {
+ carets[caretTag.orEmpty()] = caretOffset
+ }
+ }
+}
+
val TestServices.expressionMarkerProvider: ExpressionMarkerProvider by TestServices.testServiceAccessor()
fun String.indexOfOrNull(substring: String) =
diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/symbolDeclarationOverridesProvider/AbstractIsSubclassOfTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/symbolDeclarationOverridesProvider/AbstractIsSubclassOfTest.kt
new file mode 100644
index 00000000000..41d90364dfa
--- /dev/null
+++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/symbolDeclarationOverridesProvider/AbstractIsSubclassOfTest.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.analysis.api.impl.base.test.components.symbolDeclarationOverridesProvider
+
+import org.jetbrains.kotlin.analysis.api.impl.barebone.test.expressionMarkerProvider
+import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleModuleTest
+import org.jetbrains.kotlin.psi.KtClassOrObject
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.test.model.TestModule
+import org.jetbrains.kotlin.test.services.TestServices
+import org.jetbrains.kotlin.test.services.assertions
+
+abstract class AbstractIsSubclassOfTest : AbstractHLApiSingleModuleTest() {
+ override fun doTestByFileStructure(ktFiles: List, module: TestModule, testServices: TestServices) {
+ val subClass = testServices.expressionMarkerProvider.getElementOfTypAtCaret(ktFiles.first(), "sub")
+ val superClass = testServices.expressionMarkerProvider.getElementOfTypAtCaret(ktFiles.first(), "super")
+
+ val actual = executeOnPooledThreadInReadAction {
+ analyseForTest(subClass) {
+ val subClassSymbol = subClass.getClassOrObjectSymbol()
+ val superClassSymbol = superClass.getClassOrObjectSymbol()
+
+ val isSubClass = subClassSymbol.isSubClassOf(superClassSymbol)
+ val isDirectSubClass = subClassSymbol.isDirectSubClassOf(superClassSymbol)
+
+ buildString {
+ appendLine("IS_SUBCLASS: $isSubClass")
+ appendLine("IS_DIRECT_SUBCLASS: $isDirectSubClass")
+ }
+ }
+ }
+ testServices.assertions.assertEqualsToTestDataFileSibling(actual)
+ }
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/symbolDeclarationOverridesProvider/isSubclassOf/localClasses.kt b/analysis/analysis-api/testData/components/symbolDeclarationOverridesProvider/isSubclassOf/localClasses.kt
new file mode 100644
index 00000000000..74807b27809
--- /dev/null
+++ b/analysis/analysis-api/testData/components/symbolDeclarationOverridesProvider/isSubclassOf/localClasses.kt
@@ -0,0 +1,5 @@
+fun foo() {
+ open class A
+
+ open class T : A()
+}
diff --git a/analysis/analysis-api/testData/components/symbolDeclarationOverridesProvider/isSubclassOf/localClasses.txt b/analysis/analysis-api/testData/components/symbolDeclarationOverridesProvider/isSubclassOf/localClasses.txt
new file mode 100644
index 00000000000..d624aa1c04d
--- /dev/null
+++ b/analysis/analysis-api/testData/components/symbolDeclarationOverridesProvider/isSubclassOf/localClasses.txt
@@ -0,0 +1,2 @@
+IS_SUBCLASS: true
+IS_DIRECT_SUBCLASS: true
diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt
index 6efa657f90e..979370d8645 100644
--- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt
+++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.components.expressionTyp
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.expressionTypeProvider.AbstractExpectedExpressionTypeTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.expressionTypeProvider.AbstractHLExpressionTypeTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.smartCastProvider.AbstractHLSmartCastInfoTest
+import org.jetbrains.kotlin.analysis.api.impl.base.test.components.symbolDeclarationOverridesProvider.AbstractIsSubclassOfTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.symbolDeclarationOverridesProvider.AbstractOverriddenDeclarationProviderTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.symbolDeclarationRenderer.AbstractRendererTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.typeCreator.AbstractTypeParameterTypeTest
@@ -195,6 +196,10 @@ private fun TestGroupSuite.generateAnalysisApiComponentsTests() {
test(AbstractOverriddenDeclarationProviderTest::class) {
model("overriddenSymbols")
}
+
+ test(AbstractIsSubclassOfTest::class) {
+ model("isSubclassOf")
+ }
}
component("symbolDeclarationRenderer") {