diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
index 56bb170ee0e..d3e1b3394c1 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
@@ -450,5 +450,81 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
public void testNestedClassFromSupertypes6() throws Exception {
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/nestedClassFromSupertypes6.kt");
}
+
+ @Nested
+ @TestMetadata("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions")
+ @TestDataPath("$PROJECT_ROOT")
+ public class ClassHeaderPositions {
+ @Test
+ public void testAllFilesPresentInClassHeaderPositions() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions"), Pattern.compile("^(.+)\\.kt$"), null, true);
+ }
+
+ @Test
+ @TestMetadata("annotationOnClass.kt")
+ public void testAnnotationOnClass() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.kt");
+ }
+
+ @Test
+ @TestMetadata("annotationOnConstructor.kt")
+ public void testAnnotationOnConstructor() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.kt");
+ }
+
+ @Test
+ @TestMetadata("annotationOnParameter.kt")
+ public void testAnnotationOnParameter() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.kt");
+ }
+
+ @Test
+ @TestMetadata("contextReceiver.kt")
+ public void testContextReceiver() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.kt");
+ }
+
+ @Test
+ @TestMetadata("primaryConstructorParameter.kt")
+ public void testPrimaryConstructorParameter() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.kt");
+ }
+
+ @Test
+ @TestMetadata("superType.kt")
+ public void testSuperType() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeConstructor.kt")
+ public void testSuperTypeConstructor() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeConstructorArgument.kt")
+ public void testSuperTypeConstructorArgument() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeDelegation.kt")
+ public void testSuperTypeDelegation() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeTypeArguments.kt")
+ public void testSuperTypeTypeArguments() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.kt");
+ }
+
+ @Test
+ @TestMetadata("typeBound.kt")
+ public void testTypeBound() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.kt");
+ }
+ }
}
}
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
index 28af2064540..d68f6164f61 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java
@@ -450,5 +450,81 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
public void testNestedClassFromSupertypes6() throws Exception {
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/nestedClassFromSupertypes6.kt");
}
+
+ @Nested
+ @TestMetadata("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions")
+ @TestDataPath("$PROJECT_ROOT")
+ public class ClassHeaderPositions {
+ @Test
+ public void testAllFilesPresentInClassHeaderPositions() throws Exception {
+ KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions"), Pattern.compile("^(.+)\\.kt$"), null, true);
+ }
+
+ @Test
+ @TestMetadata("annotationOnClass.kt")
+ public void testAnnotationOnClass() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.kt");
+ }
+
+ @Test
+ @TestMetadata("annotationOnConstructor.kt")
+ public void testAnnotationOnConstructor() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.kt");
+ }
+
+ @Test
+ @TestMetadata("annotationOnParameter.kt")
+ public void testAnnotationOnParameter() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.kt");
+ }
+
+ @Test
+ @TestMetadata("contextReceiver.kt")
+ public void testContextReceiver() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.kt");
+ }
+
+ @Test
+ @TestMetadata("primaryConstructorParameter.kt")
+ public void testPrimaryConstructorParameter() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.kt");
+ }
+
+ @Test
+ @TestMetadata("superType.kt")
+ public void testSuperType() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeConstructor.kt")
+ public void testSuperTypeConstructor() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeConstructorArgument.kt")
+ public void testSuperTypeConstructorArgument() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeDelegation.kt")
+ public void testSuperTypeDelegation() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.kt");
+ }
+
+ @Test
+ @TestMetadata("superTypeTypeArguments.kt")
+ public void testSuperTypeTypeArguments() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.kt");
+ }
+
+ @Test
+ @TestMetadata("typeBound.kt")
+ public void testTypeBound() throws Exception {
+ runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.kt");
+ }
+ }
}
}
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.kt
new file mode 100644
index 00000000000..d8d31a9eb80
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.kt
@@ -0,0 +1,8 @@
+// FILE: main.kt
+
+abstract class Outer {
+ annotation class Ann
+}
+
+@Outer.Ann
+class Foo : Outer()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.txt
new file mode 100644
index 00000000000..99590352ea3
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnClass.txt
@@ -0,0 +1,7 @@
+Before shortening: @Outer.Ann
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+with SHORTEN_AND_IMPORT:
+[type] Outer.Ann
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Ann
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.kt
new file mode 100644
index 00000000000..5818c7cb5e8
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.kt
@@ -0,0 +1,7 @@
+// FILE: main.kt
+
+abstract class Outer {
+ annotation class Ann
+}
+
+class Foo @Outer.Ann constructor() : Outer()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.txt
new file mode 100644
index 00000000000..8309708d818
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnConstructor.txt
@@ -0,0 +1,8 @@
+Before shortening: @Outer.Ann
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+[type] Outer.Ann
+with SHORTEN_AND_IMPORT:
+[type] Outer.Ann
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Ann
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.kt
new file mode 100644
index 00000000000..d92629cdd41
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.kt
@@ -0,0 +1,7 @@
+// FILE: main.kt
+
+abstract class Outer {
+ annotation class Ann
+}
+
+class Foo(@Outer.Ann val p: Any) : Outer()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.txt
new file mode 100644
index 00000000000..8309708d818
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/annotationOnParameter.txt
@@ -0,0 +1,8 @@
+Before shortening: @Outer.Ann
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+[type] Outer.Ann
+with SHORTEN_AND_IMPORT:
+[type] Outer.Ann
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Ann
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.kt
new file mode 100644
index 00000000000..cfa775c24ce
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.kt
@@ -0,0 +1,8 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested : Outer()
+}
+
+context(Outer.Nested)
+class Foo : Outer.Nested()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.txt
new file mode 100644
index 00000000000..cea78ad2998
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/contextReceiver.txt
@@ -0,0 +1,7 @@
+Before shortening: Outer.Nested
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+with SHORTEN_AND_IMPORT:
+[type] Outer.Nested
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Nested
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.kt
new file mode 100644
index 00000000000..6f77b2a0a48
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.kt
@@ -0,0 +1,7 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested : Outer()
+}
+
+class Foo(val param: Outer.Nested = Outer.Nested()) : Outer.Nested()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.txt
new file mode 100644
index 00000000000..37a1ca8b41a
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/primaryConstructorParameter.txt
@@ -0,0 +1,11 @@
+Before shortening: val param: Outer.Nested = Outer.Nested()
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+[type] Outer.Nested
+[qualifier] Outer.Nested()
+with SHORTEN_AND_IMPORT:
+[type] Outer.Nested
+[qualifier] Outer.Nested()
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Nested
+[qualifier] Outer.Nested()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.kt
new file mode 100644
index 00000000000..92d03b98805
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.kt
@@ -0,0 +1,7 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested : Outer()
+}
+
+class Foo : Outer.Nested { constructor(): super() }
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.txt
new file mode 100644
index 00000000000..a2fb1f83063
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superType.txt
@@ -0,0 +1,7 @@
+Before shortening: class Foo : Outer.Nested { constructor(): super() }
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+with SHORTEN_AND_IMPORT:
+[type] Outer.Nested
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Nested
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.kt
new file mode 100644
index 00000000000..a7382166afb
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.kt
@@ -0,0 +1,7 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested : Outer()
+}
+
+class Foo : Outer.Nested()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.txt
new file mode 100644
index 00000000000..1f19e2f1305
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructor.txt
@@ -0,0 +1,7 @@
+Before shortening: class Foo : Outer.Nested()
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+with SHORTEN_AND_IMPORT:
+[type] Outer.Nested
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Nested
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.kt
new file mode 100644
index 00000000000..aafb86644d8
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.kt
@@ -0,0 +1,9 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested(a: Any) : Outer()
+
+ class OtherNested
+}
+
+class Foo : Outer.Nested(Outer.OtherNested())
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.txt
new file mode 100644
index 00000000000..ff0aa61cffa
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeConstructorArgument.txt
@@ -0,0 +1,8 @@
+Before shortening: Outer.OtherNested()
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+[qualifier] Outer.OtherNested()
+with SHORTEN_AND_IMPORT:
+[qualifier] Outer.OtherNested()
+with SHORTEN_AND_STAR_IMPORT:
+[qualifier] Outer.OtherNested()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.kt
new file mode 100644
index 00000000000..c821a58f887
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.kt
@@ -0,0 +1,11 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested : Outer(), Marker
+
+ interface class Marker
+
+ class MarkerImpl() : Marker
+}
+
+class Foo : Outer.Nested(), Outer.Marker by Outer.MarkerImpl()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.txt
new file mode 100644
index 00000000000..85e44222f72
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeDelegation.txt
@@ -0,0 +1,10 @@
+Before shortening: Outer.Marker by Outer.MarkerImpl()
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+[qualifier] Outer.MarkerImpl()
+with SHORTEN_AND_IMPORT:
+[type] Outer.Marker
+[qualifier] Outer.MarkerImpl()
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Marker
+[qualifier] Outer.MarkerImpl()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.kt
new file mode 100644
index 00000000000..3765ee8d86d
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.kt
@@ -0,0 +1,9 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested : Outer()
+
+ class OtherNested
+}
+
+class Foo : Outer.Nested { constructor(): super() }
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.txt
new file mode 100644
index 00000000000..e83bd4d747b
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/superTypeTypeArguments.txt
@@ -0,0 +1,9 @@
+Before shortening: Outer.Nested
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+with SHORTEN_AND_IMPORT:
+[type] Outer.Nested
+[type] Outer.OtherNested
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Nested
+[type] Outer.OtherNested
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.kt
new file mode 100644
index 00000000000..bc8120bb561
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.kt
@@ -0,0 +1,7 @@
+// FILE: main.kt
+
+abstract class Outer {
+ abstract class Nested : Outer()
+}
+
+class FooOuter.Nested> : Outer.Nested()
diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.txt
new file mode 100644
index 00000000000..cea78ad2998
--- /dev/null
+++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses/classHeaderPositions/typeBound.txt
@@ -0,0 +1,7 @@
+Before shortening: Outer.Nested
+with DO_NOT_SHORTEN:
+with SHORTEN_IF_ALREADY_IMPORTED:
+with SHORTEN_AND_IMPORT:
+[type] Outer.Nested
+with SHORTEN_AND_STAR_IMPORT:
+[type] Outer.Nested
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirTowerDataContextCollector.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirTowerDataContextCollector.kt
index 9ce4911a613..8cdf5dbe8bf 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirTowerDataContextCollector.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirTowerDataContextCollector.kt
@@ -9,11 +9,14 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
+import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTowerDataContext
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector
import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
+import org.jetbrains.kotlin.utils.addIfNotNull
interface FirTowerContextProvider {
fun getClosestAvailableParentContext(ktElement: KtElement): FirTowerDataContext?
@@ -30,6 +33,14 @@ internal class FileTowerProvider(
internal class FirTowerDataContextAllElementsCollector : FirTowerDataContextCollector, FirTowerContextProvider {
private val elementsToContext: MutableMap = hashMapOf()
+ /**
+ * Class headers have context which is different from the context inside of the class, so we have
+ * to collect the scopes for it separately.
+ *
+ * See [containsInHeader] for more info.
+ */
+ private val classesToClassHeaderContext: MutableMap = hashMapOf()
+
override fun addFileContext(file: FirFile, context: FirTowerDataContext) {
val ktFile = file.psi as? KtFile ?: return
elementsToContext[ktFile] = context
@@ -43,14 +54,26 @@ internal class FirTowerDataContextAllElementsCollector : FirTowerDataContextColl
override fun addDeclarationContext(declaration: FirDeclaration, context: FirTowerDataContext) {
val psi = declaration.psi as? KtElement ?: return
+
+ // FIR creates a fake field declaration for the delegated super calls,
+ // and it makes handling class headers more difficult, so
+ // we do not collect contexts for such declarations
+ if (psi is KtDelegatedSuperTypeEntry) return
+
elementsToContext[psi] = context
}
+ override fun addClassHeaderContext(declaration: FirRegularClass, context: FirTowerDataContext) {
+ val psi = declaration.psi as? KtElement ?: return
+ if (psi !is KtClassOrObject) return
+ classesToClassHeaderContext[psi] = context
+ }
+
override fun getClosestAvailableParentContext(ktElement: KtElement): FirTowerDataContext? {
var current: PsiElement? = ktElement
while (current != null) {
if (current is KtElement) {
- getContextForElement(current)?.let { return it }
+ getContextForElementOnPosition(current, ktElement)?.let { return it }
}
if (current is KtFile) {
break
@@ -60,12 +83,26 @@ internal class FirTowerDataContextAllElementsCollector : FirTowerDataContextColl
return null
}
- private fun getContextForElement(element: KtElement): FirTowerDataContext? {
- elementsToContext[element]?.let { return it }
+ /**
+ * N.B. It is expected that [element] contains [position].
+ */
+ private fun getContextForElementOnPosition(element: KtElement, position: KtElement): FirTowerDataContext? {
+ val contextMapping =
+ if (element is KtClassOrObject && element.containsInHeader(position)) {
+ classesToClassHeaderContext
+ } else {
+ elementsToContext
+ }
+
+ return getContextForElement(element, contextMapping)
+ }
+
+ private fun getContextForElement(element: KtElement, contextMapping: Map): FirTowerDataContext? {
+ contextMapping[element]?.let { return it }
if (element is KtDeclaration) {
val originalDeclaration = element.originalDeclaration
- originalDeclaration?.let { elementsToContext[it] }?.let { return it }
+ originalDeclaration?.let { contextMapping[it] }?.let { return it }
}
return null
@@ -77,3 +114,28 @@ private tailrec fun PsiElement.closestBlockLevelOrInitializerExpression(): KtExp
this is KtExpression && (parent is KtBlockExpression || parent is KtDeclarationWithInitializer) -> this
else -> parent?.closestBlockLevelOrInitializerExpression()
}
+
+/**
+ * Returns true if [element] is considered to be a part of [this] class header.
+ *
+ * Here by "header" we understand the parts of the class declaration which resolution is not affected
+ * by the class own supertypes.
+ */
+private fun KtClassOrObject.containsInHeader(element: PsiElement): Boolean {
+ if (this == element) return false
+
+ val classHeaderParts = buildSet {
+ addIfNotNull(getContextReceiverList())
+ addIfNotNull(modifierList) // for annotations declared on class
+ addIfNotNull(typeParameterList)
+
+ for (superTypeEntry in superTypeListEntries) {
+ addIfNotNull(superTypeEntry.typeReference)
+ }
+ }
+
+ if (classHeaderParts.isEmpty()) return false
+
+ val elementParentsUntilClass = element.parentsWithSelf.takeWhile { it != this }
+ return elementParentsUntilClass.any { it in classHeaderParts }
+}
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt
index 04d69dec681..55b2c95fe4c 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.getExplicitBackingField
import org.jetbrains.kotlin.fir.expressions.*
@@ -128,6 +129,9 @@ private class LLFirBodyTargetResolver(
}
private fun resolveMembersForControlFlowGraph(target: FirRegularClass) {
+ withTypeArguments(target) {
+ transformer.firTowerDataContextCollector?.addClassHeaderContext(target, transformer.context.towerDataContext)
+ }
withRegularClass(target) {
transformer.firTowerDataContextCollector?.addDeclarationContext(target, transformer.context.towerDataContext)
@@ -173,6 +177,13 @@ private class LLFirBodyTargetResolver(
else -> throwUnexpectedFirElementError(target)
}
}
+
+ private inline fun withTypeArguments(regularClass: FirRegularClass, action: () -> Unit) {
+ @OptIn(PrivateForInline::class)
+ transformer.declarationsTransformer.context.withTypeParametersOf(regularClass) {
+ action()
+ }
+ }
}
internal object BodyStateKeepers {
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirTowerDataContextCollector.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirTowerDataContextCollector.kt
index fa34b23ffcc..33df2297ebe 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirTowerDataContextCollector.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirTowerDataContextCollector.kt
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
+import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTowerDataContext
import org.jetbrains.kotlin.fir.expressions.FirStatement
@@ -17,4 +18,21 @@ interface FirTowerDataContextCollector {
fun addFileContext(file: FirFile, context: FirTowerDataContext)
fun addStatementContext(statement: FirStatement, context: FirTowerDataContext)
fun addDeclarationContext(declaration: FirDeclaration, context: FirTowerDataContext)
+
+ /**
+ * Here by "header" we understand the parts of the class declaration which resolution is not affected
+ * by the class own supertypes.
+ *
+ * It includes any type reference mentioned before the body of the class, except for:
+ * - primary constructor declaration with annotations
+ * - super type constructor **value arguments** with annotations
+ *
+ * Also, it includes class type parameters, because they are available anywhere inside the class declaration.
+ *
+ * N.B. We collect header contexts only for [FirRegularClass]es, ignoring
+ * [org.jetbrains.kotlin.fir.declarations.FirAnonymousObject]s. That's because anonymous objects are in
+ * fact expressions, and it should be enough for [FirTowerDataContextCollector] to have a context for
+ * the containing declaration to correctly process everything inside anonymous objects.
+ */
+ fun addClassHeaderContext(declaration: FirRegularClass, context: FirTowerDataContext)
}