[compiler] introduce dedicated Fir declaration for dangling modifier lists (KTIJ-23008)
ensure fir annotations are included in FirDanglingModifierList and resolved, dedicated DanglingTopLevelModifierListStructureElement exists for top level lists only, class level lists are processed by containing structure element
This commit is contained in:
+40
@@ -718,6 +718,40 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DanglingAnnotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInDanglingAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedAnonymous.kt")
|
||||
public void testDanglingAnnotationsResolvedAnonymous() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedClass.kt")
|
||||
public void testDanglingAnnotationsResolvedClass() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedLocal.kt")
|
||||
public void testDanglingAnnotationsResolvedLocal() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedTopLevel.kt")
|
||||
public void testDanglingAnnotationsResolvedTopLevel() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@@ -1609,6 +1643,12 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotations.kt")
|
||||
public void testDanglingAnnotations() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DeprecatedHidden.kt")
|
||||
public void testDeprecatedHidden() throws Exception {
|
||||
|
||||
+40
@@ -718,6 +718,40 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DanglingAnnotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInDanglingAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedAnonymous.kt")
|
||||
public void testDanglingAnnotationsResolvedAnonymous() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedClass.kt")
|
||||
public void testDanglingAnnotationsResolvedClass() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedLocal.kt")
|
||||
public void testDanglingAnnotationsResolvedLocal() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedTopLevel.kt")
|
||||
public void testDanglingAnnotationsResolvedTopLevel() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@@ -1609,6 +1643,12 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotations.kt")
|
||||
public void testDanglingAnnotations() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DeprecatedHidden.kt")
|
||||
public void testDeprecatedHidden() throws Exception {
|
||||
|
||||
+34
@@ -690,6 +690,40 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DanglingAnnotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInDanglingAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true, "withErrors");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedAnonymous.kt")
|
||||
public void testDanglingAnnotationsResolvedAnonymous() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedClass.kt")
|
||||
public void testDanglingAnnotationsResolvedClass() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedLocal.kt")
|
||||
public void testDanglingAnnotationsResolvedLocal() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedTopLevel.kt")
|
||||
public void testDanglingAnnotationsResolvedTopLevel() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+40
@@ -718,6 +718,40 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DanglingAnnotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInDanglingAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedAnonymous.kt")
|
||||
public void testDanglingAnnotationsResolvedAnonymous() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedClass.kt")
|
||||
public void testDanglingAnnotationsResolvedClass() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedLocal.kt")
|
||||
public void testDanglingAnnotationsResolvedLocal() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedTopLevel.kt")
|
||||
public void testDanglingAnnotationsResolvedTopLevel() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@@ -1609,6 +1643,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotations.kt")
|
||||
public void testDanglingAnnotations() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DeprecatedHidden.kt")
|
||||
public void testDeprecatedHidden() throws Exception {
|
||||
|
||||
+40
@@ -718,6 +718,40 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class DanglingAnnotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInDanglingAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedAnonymous.kt")
|
||||
public void testDanglingAnnotationsResolvedAnonymous() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedClass.kt")
|
||||
public void testDanglingAnnotationsResolvedClass() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedLocal.kt")
|
||||
public void testDanglingAnnotationsResolvedLocal() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotationsResolvedTopLevel.kt")
|
||||
public void testDanglingAnnotationsResolvedTopLevel() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@@ -1609,6 +1643,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingAnnotations.kt")
|
||||
public void testDanglingAnnotations() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DeprecatedHidden.kt")
|
||||
public void testDeprecatedHidden() throws Exception {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// COMPILATION_ERRORS
|
||||
annotation class Ann0
|
||||
interface I
|
||||
class Foo {
|
||||
fun foo() {
|
||||
val i = object : I {
|
||||
@<caret>Ann0 @Suppress
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Ann0) constructor()
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// COMPILATION_ERRORS
|
||||
annotation class Ann0
|
||||
interface I
|
||||
class Foo {
|
||||
@<caret>Ann0 @Suppress
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Ann0) constructor()
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// COMPILATION_ERRORS
|
||||
annotation class Ann0
|
||||
class Foo {
|
||||
fun foo() {
|
||||
class Local {
|
||||
@<caret>Ann0 @Suppress
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Ann0) constructor()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
// COMPILATION_ERRORS
|
||||
annotation class Ann0
|
||||
@<caret>Ann0 @Suppress
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Ann0) constructor()
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// UNRESOLVED_REFERENCE
|
||||
class Foo {
|
||||
fun foo() {
|
||||
class Local {
|
||||
@<caret>Ann0
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -18,11 +18,15 @@ import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
|
||||
import org.jetbrains.kotlin.fir.java.javaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
||||
import org.jetbrains.kotlin.fir.containingClass
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
|
||||
import org.jetbrains.kotlin.fir.java.javaSymbolProvider
|
||||
|
||||
class FirDesignationWithFile(
|
||||
path: List<FirRegularClass>,
|
||||
@@ -92,6 +96,11 @@ private fun collectDesignationPath(target: FirElementWithResolvePhase): List<Fir
|
||||
outerClassId?.let(target.moduleData.session.firProvider::getFirClassifierByFqName)
|
||||
?: outerClassId?.let(target.moduleData.session.javaSymbolProvider::getClassLikeSymbolByClassId)?.fir
|
||||
}
|
||||
is FirDanglingModifierList -> {
|
||||
val klass = target.containingClass() ?: return emptyList()
|
||||
if (klass.classId.isLocal) return null
|
||||
klass.toFirRegularClassFromSameSession(target.moduleData.session)
|
||||
}
|
||||
else -> return null
|
||||
} ?: return emptyList()
|
||||
|
||||
|
||||
+3
-4
@@ -12,10 +12,8 @@ import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.containingClass
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.resolve.SessionHolder
|
||||
|
||||
@@ -61,6 +59,7 @@ internal object PersistenceContextCollector {
|
||||
val isLocal = when (declaration) {
|
||||
is FirClassLikeDeclaration -> declaration.symbol.classId.isLocal
|
||||
is FirCallableDeclaration -> declaration.symbol.callableId.isLocal
|
||||
is FirDanglingModifierList -> declaration.containingClass()?.classId?.isLocal == true
|
||||
else -> error("Unsupported declaration ${declaration.renderWithType()}")
|
||||
}
|
||||
require(!isLocal) {
|
||||
|
||||
+34
-6
@@ -6,12 +6,17 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiErrorElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceByTraversingWholeTree
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
@@ -36,14 +41,23 @@ internal class FileStructure private constructor(
|
||||
|
||||
private val firProvider = firFile.moduleData.session.firProvider
|
||||
|
||||
private val structureElements = ConcurrentHashMap<KtAnnotated, FileStructureElement>()
|
||||
private val structureElements = ConcurrentHashMap<KtElement, FileStructureElement>()
|
||||
|
||||
fun getStructureElementFor(element: KtElement): FileStructureElement {
|
||||
val container: KtAnnotated = element.getNonLocalContainingOrThisDeclaration() ?: element.containingKtFile
|
||||
val declaration = element.getNonLocalContainingOrThisDeclaration()
|
||||
val container: KtElement
|
||||
if (declaration != null) {
|
||||
container = declaration
|
||||
} else {
|
||||
val modifierList = PsiTreeUtil.getParentOfType(element, KtModifierList::class.java, false)
|
||||
container = if (modifierList != null && modifierList.nextSibling is PsiErrorElement) {
|
||||
modifierList
|
||||
} else element.containingKtFile
|
||||
}
|
||||
return getStructureElementForDeclaration(container)
|
||||
}
|
||||
|
||||
private fun getStructureElementForDeclaration(declaration: KtAnnotated): FileStructureElement {
|
||||
private fun getStructureElementForDeclaration(declaration: KtElement): FileStructureElement {
|
||||
@Suppress("CANNOT_CHECK_FOR_ERASED")
|
||||
val structureElement = structureElements.compute(declaration) { _, structureElement ->
|
||||
when {
|
||||
@@ -91,6 +105,12 @@ internal class FileStructure private constructor(
|
||||
dcl.acceptChildren(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitModifierList(list: KtModifierList) {
|
||||
if (list.parent == ktFile) {
|
||||
structureElements += getStructureElementFor(list)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return structureElements
|
||||
@@ -112,8 +132,15 @@ internal class FileStructure private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun createStructureElement(container: KtAnnotated): FileStructureElement = when (container) {
|
||||
is KtFile -> {
|
||||
private fun createDanglingModifierListStructure(container: KtElement): FileStructureElement {
|
||||
val firDanglingModifierList = container.findSourceByTraversingWholeTree(moduleComponents.firFileBuilder, firFile) as? FirDanglingModifierList
|
||||
?: errorWithFirSpecificEntries("No dangling modifier found", psi = container)
|
||||
firDanglingModifierList.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
||||
return DanglingTopLevelModifierListStructureElement(firFile, firDanglingModifierList, moduleComponents, container.containingKtFile)
|
||||
}
|
||||
|
||||
private fun createStructureElement(container: KtElement): FileStructureElement = when {
|
||||
container is KtFile -> {
|
||||
val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
||||
moduleComponents.firModuleLazyDeclarationResolver.lazyResolve(
|
||||
target = firFile.annotationsContainer,
|
||||
@@ -123,7 +150,8 @@ internal class FileStructure private constructor(
|
||||
|
||||
RootStructureElement(firFile, container, moduleComponents)
|
||||
}
|
||||
is KtDeclaration -> createDeclarationStructure(container)
|
||||
container is KtDeclaration -> createDeclarationStructure(container)
|
||||
container is KtModifierList && container.nextSibling is PsiErrorElement -> createDanglingModifierListStructure(container)
|
||||
else -> error("Invalid container $container")
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -226,6 +226,12 @@ internal class NonReanalyzableDeclarationStructureElement(
|
||||
}
|
||||
}
|
||||
|
||||
internal class DanglingTopLevelModifierListStructureElement(firFile: FirFile, val fir: FirDeclaration, moduleComponents: LLFirModuleResolveComponents, override val psi: KtAnnotated) :
|
||||
FileStructureElement(firFile, moduleComponents) {
|
||||
override val mappings = KtToFirMapping(fir, FirElementsRecorder())
|
||||
|
||||
override val diagnostics = FileStructureElementDiagnostics(firFile, SingleNonLocalDeclarationDiagnosticRetriever(fir), moduleComponents)
|
||||
}
|
||||
|
||||
internal class RootStructureElement(
|
||||
firFile: FirFile,
|
||||
@@ -246,4 +252,4 @@ internal class RootStructureElement(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -116,6 +116,7 @@ internal open class FirElementsRecorder : FirVisitor<Unit, MutableMap<KtElement,
|
||||
it.kind == KtFakeSourceElementKind.DesugaredPrefixNameReference ||
|
||||
it.kind == KtFakeSourceElementKind.DesugaredPostfixNameReference ||
|
||||
it.kind == KtFakeSourceElementKind.SmartCastExpression ||
|
||||
it.kind == KtFakeSourceElementKind.DanglingModifierList ||
|
||||
it.isSourceForCompoundAccess(element)
|
||||
}.psi as? KtElement
|
||||
?: return
|
||||
|
||||
+16
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirFirProv
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformerExecutor
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ktDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.rethrowExceptionWithDetails
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
@@ -29,6 +30,11 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirImportResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.util.SourceCodeAnalysisException
|
||||
import org.jetbrains.kotlin.util.shouldIjPlatformExceptionBeRethrown
|
||||
import org.jetbrains.kotlin.psi.KtClassBody
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
@@ -224,7 +230,16 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
val designation: FirDesignationWithFile
|
||||
val neededPhase: FirResolvePhase
|
||||
|
||||
if (requestedDeclarationDesignation != null) {
|
||||
if (target is FirDanglingModifierList) {
|
||||
neededPhase = toPhase
|
||||
val ktFile = target.psi?.containingFile as? KtFile
|
||||
?: error("File for dangling modifier list cannot be null")
|
||||
designation = FirDesignationWithFile(
|
||||
emptyList(),
|
||||
target,
|
||||
moduleComponents.cache.getCachedFirFile(ktFile) ?: error("Fir file for dandling modifier list cannot be null")
|
||||
)
|
||||
} else if (requestedDeclarationDesignation != null) {
|
||||
designation = requestedDeclarationDesignation
|
||||
neededPhase = toPhase
|
||||
} else {
|
||||
|
||||
+2
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
@@ -20,6 +21,7 @@ fun FirElementWithResolvePhase.getContainingFile(): FirFile? {
|
||||
is FirValueParameter -> containingFunctionSymbol.fir.getContainingFile()
|
||||
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
|
||||
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(symbol)
|
||||
is FirDanglingModifierList -> null
|
||||
else -> errorWithFirSpecificEntries("Unsupported declaration ${this::class.java}", fir = this)
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -28,7 +28,7 @@ internal fun KtDeclaration.findSourceNonLocalFirDeclaration(
|
||||
): FirDeclaration {
|
||||
//TODO test what way faster
|
||||
findSourceNonLocalFirDeclarationByProvider(firFileBuilder, provider, containerFirFile)?.let { return it }
|
||||
findSourceOfNonLocalFirDeclarationByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it }
|
||||
findSourceByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it }
|
||||
errorWithFirSpecificEntries("No fir element was found for", psi = this)
|
||||
}
|
||||
|
||||
@@ -56,14 +56,15 @@ internal inline fun <reified F : FirDeclaration> KtDeclaration.findFirDeclaratio
|
||||
return fir
|
||||
}
|
||||
|
||||
private fun KtDeclaration.findSourceOfNonLocalFirDeclarationByTraversingWholeTree(
|
||||
internal fun KtElement.findSourceByTraversingWholeTree(
|
||||
firFileBuilder: LLFirFileBuilder,
|
||||
containerFirFile: FirFile?,
|
||||
): FirDeclaration? {
|
||||
val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile)
|
||||
val originalDeclaration = originalDeclaration
|
||||
val originalDeclaration = (this as? KtDeclaration)?.originalDeclaration
|
||||
val isDeclaration = this is KtDeclaration
|
||||
return FirElementFinder.findElementIn(firFile, canGoInside = { it is FirRegularClass }) { firDeclaration ->
|
||||
firDeclaration.psi == this || firDeclaration.psi == originalDeclaration
|
||||
firDeclaration.psi == this || isDeclaration && firDeclaration.psi == originalDeclaration
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
class Foo {/* NonReanalyzableDeclarationStructureElement */
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
class Bar {/* NonReanalyzableDeclarationStructureElement */
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
class Outer {/* NonReanalyzableDeclarationStructureElement */
|
||||
class Inner {/* NonReanalyzableDeclarationStructureElement */
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
fun foo() {/* ReanalyzableFunctionStructureElement */
|
||||
class Local {
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
@Suppress("") @MustBeDocumented/* DanglingTopLevelModifierListStructureElement */
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
// WITH_STDLIB
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
<expr>@Suppress("")</expr> @MustBeDocumented
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
KT element: KtAnnotationEntry
|
||||
FIR element: FirAnnotationCallImpl
|
||||
FIR source kind: KtRealSourceElementKind
|
||||
|
||||
FIR element rendered:
|
||||
@R|kotlin/Suppress|(names = vararg(String()))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
class F {
|
||||
<expr>@Suppress("")</expr> @MustBeDocumented
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
KT element: KtAnnotationEntry
|
||||
FIR element: FirAnnotationCallImpl
|
||||
FIR source kind: KtRealSourceElementKind
|
||||
|
||||
FIR element rendered:
|
||||
@R|kotlin/Suppress|(names = vararg(String()))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
annotation class JsQualifier : kotlin.Annotation {
|
||||
public constructor JsQualifier(<expr>value</expr>: kotlin.String)
|
||||
|
||||
public final val value: kotlin.String { get; }
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
KT element: KtDeclarationModifierList
|
||||
FIR element: FirDanglingModifierListImpl
|
||||
FIR source kind: DanglingModifierList
|
||||
|
||||
FIR element rendered:
|
||||
<DANGLING MODIFIER: Top level declaration expected>
|
||||
+12
@@ -75,6 +75,18 @@ public class FirLazyBodiesCalculatorTestGenerated extends AbstractFirLazyBodiesC
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationsClassLevel.kt")
|
||||
public void testDanglingAnnotationsClassLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationsFileLevel.kt")
|
||||
public void testDanglingAnnotationsFileLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegates.kt")
|
||||
public void testDelegates() throws Exception {
|
||||
|
||||
+18
@@ -69,6 +69,18 @@ public class GetOrBuildFirTestGenerated extends AbstractGetOrBuildFirTest {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/annotationApplicationWithArgumentsOnCallSite.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotation.kt")
|
||||
public void testDanglingAnnotation() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationInClass.kt")
|
||||
public void testDanglingAnnotationInClass() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("fileAnnotation.kt")
|
||||
public void testFileAnnotation() throws Exception {
|
||||
@@ -572,6 +584,12 @@ public class GetOrBuildFirTestGenerated extends AbstractGetOrBuildFirTest {
|
||||
public void testJavaClassLiteral() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/javaClassLiteral.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("secondaryConstructor.kt")
|
||||
public void testSecondaryConstructor() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+3
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getDiagnostics
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.BeforeElementDiagnosticCollectionHandler
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistenceContextCollector
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.DanglingTopLevelModifierListStructureElement
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureElement
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.NonReanalyzableDeclarationStructureElement
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.ReanalyzableStructureElement
|
||||
@@ -62,6 +64,7 @@ abstract class AbstractFirContextCollectionTest : AbstractLowLevelApiSingleFileT
|
||||
is NonReanalyzableDeclarationStructureElement -> fir
|
||||
is ReanalyzableStructureElement<*, *> -> firSymbol.fir
|
||||
is RootStructureElement -> firFile
|
||||
is DanglingTopLevelModifierListStructureElement -> fir
|
||||
}
|
||||
|
||||
|
||||
|
||||
+12
@@ -36,6 +36,18 @@ public class FirContextCollectionTestGenerated extends AbstractFirContextCollect
|
||||
runTest("analysis/low-level-api-fir/testdata/fileStructure/classMemberProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationClassLevel.kt")
|
||||
public void testDanglingAnnotationClassLevel() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationTopLevel.kt")
|
||||
public void testDanglingAnnotationTopLevel() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("declarationsInPropertyInit.kt")
|
||||
public void testDeclarationsInPropertyInit() throws Exception {
|
||||
|
||||
+11
-1
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiErrorElement
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession
|
||||
@@ -32,7 +34,8 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() {
|
||||
val comment = structureElement.createComment()
|
||||
when (ktDeclaration) {
|
||||
is KtClassOrObject -> {
|
||||
val lBrace = ktDeclaration.body?.lBrace
|
||||
val body = ktDeclaration.body
|
||||
val lBrace = body?.lBrace
|
||||
if (lBrace != null) {
|
||||
elementToComment[lBrace] = comment
|
||||
} else {
|
||||
@@ -62,6 +65,13 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() {
|
||||
}
|
||||
}
|
||||
|
||||
PsiTreeUtil.getChildrenOfTypeAsList(ktFile, KtModifierList::class.java).forEach {
|
||||
if (it.nextSibling is PsiErrorElement) {
|
||||
val structureElement = declarationToStructureElement[ktFile] ?: return@forEach
|
||||
val comment = structureElement.createComment()
|
||||
elementToComment[it] = comment
|
||||
}
|
||||
}
|
||||
|
||||
val text = buildString {
|
||||
ktFile.accept(object : PsiElementVisitor() {
|
||||
|
||||
+12
@@ -36,6 +36,18 @@ public class FileStructureTestGenerated extends AbstractFileStructureTest {
|
||||
runTest("analysis/low-level-api-fir/testdata/fileStructure/classMemberProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationClassLevel.kt")
|
||||
public void testDanglingAnnotationClassLevel() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationTopLevel.kt")
|
||||
public void testDanglingAnnotationTopLevel() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("declarationsInPropertyInit.kt")
|
||||
public void testDeclarationsInPropertyInit() throws Exception {
|
||||
|
||||
+1
-1
@@ -154,7 +154,7 @@ object FirOptInUsageBaseChecker {
|
||||
fir.loadCallableSpecificExperimentalities(this, context, visited, fromSetter, dispatchReceiverType, result)
|
||||
is FirClassLikeDeclaration ->
|
||||
fir.loadClassLikeSpecificExperimentalities(this, context, visited, result)
|
||||
is FirAnonymousInitializer, is FirFile, is FirTypeParameter, is FirScript -> {}
|
||||
is FirAnonymousInitializer, is FirDanglingModifierList, is FirFile, is FirTypeParameter, is FirScript -> {}
|
||||
}
|
||||
|
||||
fir.loadExperimentalitiesFromAnnotationTo(session, result, fromSupertype)
|
||||
|
||||
+23
-1
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDanglingModifierOnTopLevel
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
@@ -97,6 +98,7 @@ class DeclarationsConverter(
|
||||
var fileAnnotationContainer: FirFileAnnotationsContainer? = null
|
||||
val importList = mutableListOf<FirImport>()
|
||||
val firDeclarationList = mutableListOf<FirDeclaration>()
|
||||
val modifierList = mutableListOf<LighterASTNode>()
|
||||
context.packageFqName = FqName.ROOT
|
||||
var packageDirective: FirPackageDirective? = null
|
||||
file.forEachChildren { child ->
|
||||
@@ -116,9 +118,14 @@ class DeclarationsConverter(
|
||||
SCRIPT -> {
|
||||
// TODO: scripts aren't supported yet
|
||||
}
|
||||
MODIFIER_LIST -> modifierList += child
|
||||
}
|
||||
}
|
||||
|
||||
modifierList.forEach {
|
||||
firDeclarationList += buildErrorTopLevelDeclarationForDanglingModifierList(it)
|
||||
}
|
||||
|
||||
return buildFile {
|
||||
symbol = fileSymbol
|
||||
source = file.toFirSourceElement()
|
||||
@@ -839,7 +846,8 @@ class DeclarationsConverter(
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumClassBody
|
||||
*/
|
||||
private fun convertClassBody(classBody: LighterASTNode, classWrapper: ClassWrapper): List<FirDeclaration> {
|
||||
return classBody.forEachChildrenReturnList { node, container ->
|
||||
val modifierLists = mutableListOf<LighterASTNode>()
|
||||
var firDeclarations = classBody.forEachChildrenReturnList { node, container ->
|
||||
@Suppress("RemoveRedundantQualifierName")
|
||||
when (node.tokenType) {
|
||||
ENUM_ENTRY -> container += convertEnumEntry(node, classWrapper)
|
||||
@@ -850,8 +858,22 @@ class DeclarationsConverter(
|
||||
OBJECT_DECLARATION -> container += convertClass(node)
|
||||
CLASS_INITIALIZER -> container += convertAnonymousInitializer(node) //anonymousInitializer
|
||||
SECONDARY_CONSTRUCTOR -> container += convertSecondaryConstructor(node, classWrapper)
|
||||
MODIFIER_LIST -> modifierLists += node
|
||||
}
|
||||
}
|
||||
for (node in modifierLists) {
|
||||
firDeclarations += buildErrorTopLevelDeclarationForDanglingModifierList(node)
|
||||
}
|
||||
return firDeclarations
|
||||
}
|
||||
|
||||
private fun buildErrorTopLevelDeclarationForDanglingModifierList(node: LighterASTNode) = buildDanglingModifierList {
|
||||
this.source = node.toFirSourceElement(KtFakeSourceElementKind.DanglingModifierList)
|
||||
moduleData = baseModuleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
diagnostic = ConeDanglingModifierOnTopLevel
|
||||
symbol = FirDanglingModifierSymbol()
|
||||
annotations += convertModifierList(node).annotations
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+10
@@ -76,6 +76,16 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("danglingAnnotationsClassLevel.kt")
|
||||
public void testDanglingAnnotationsClassLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("danglingAnnotationsFileLevel.kt")
|
||||
public void testDanglingAnnotationsFileLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegates.kt")
|
||||
public void testDelegates() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/delegates.kt");
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.builder
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.util.AstLoadingFilter
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.*
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD
|
||||
@@ -1057,6 +1058,10 @@ open class RawFirBuilder(
|
||||
else -> declaration.convert()
|
||||
}
|
||||
}
|
||||
|
||||
for (danglingModifierList in PsiTreeUtil.getChildrenOfTypeAsList(file, KtModifierList::class.java)) {
|
||||
declarations += buildErrorTopLevelDeclarationForDanglingModifierList(danglingModifierList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1269,7 +1274,14 @@ open class RawFirBuilder(
|
||||
classOrObject,
|
||||
this,
|
||||
typeParameters
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
for (danglingModifier in PsiTreeUtil.getChildrenOfTypeAsList(classOrObject.body, KtModifierList::class.java)) {
|
||||
addDeclaration(
|
||||
buildErrorTopLevelDeclarationForDanglingModifierList(danglingModifier).apply {
|
||||
containingClassAttr = currentDispatchReceiverType()?.lookupTag
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1361,6 +1373,12 @@ open class RawFirBuilder(
|
||||
ownerTypeParameters = emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
for (danglingModifier in PsiTreeUtil.getChildrenOfTypeAsList(objectDeclaration.body, KtModifierList::class.java)) {
|
||||
declarations += buildErrorTopLevelDeclarationForDanglingModifierList(danglingModifier).apply {
|
||||
containingClassAttr = currentDispatchReceiverType()?.lookupTag
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
it.delegateFieldsMap = delegatedFieldsMap
|
||||
}
|
||||
@@ -2730,6 +2748,17 @@ open class RawFirBuilder(
|
||||
this += typeArgument.convert<FirTypeProjection>()
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildErrorTopLevelDeclarationForDanglingModifierList(modifierList : KtModifierList) = buildDanglingModifierList {
|
||||
this.source = modifierList.toFirSourceElement(KtFakeSourceElementKind.DanglingModifierList)
|
||||
moduleData = baseModuleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
diagnostic = ConeDanglingModifierOnTopLevel
|
||||
symbol = FirDanglingModifierSymbol()
|
||||
for (annotationEntry in modifierList.getAnnotationEntries()) {
|
||||
annotations += annotationEntry.convert<FirAnnotation>()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
class A {
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
class B {
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
class Outer {
|
||||
class Inner {
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
|
||||
fun withLocal() {
|
||||
class Local {
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
|
||||
val r : I = object : I {
|
||||
@Suppress("") @MustBeDocumented
|
||||
}
|
||||
}
|
||||
}
|
||||
interface I {}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
FILE: danglingAnnotationsClassLevel.kt
|
||||
public? final? class A : R|kotlin/Any| {
|
||||
public? constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
public? final? class B : R|kotlin/Any| {
|
||||
public? constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
public? final? class Outer : R|kotlin/Any| {
|
||||
public? constructor(): R|Outer| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public? final? class Inner : R|kotlin/Any| {
|
||||
public? constructor(): R|Outer.Inner| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
|
||||
public? final? fun withLocal(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
}
|
||||
public? final? interface I : R|kotlin/Any| {
|
||||
}
|
||||
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
FILE: danglingAnnotationsClassLevel.kt
|
||||
public? final? class A : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=A] constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
public? final? class B : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=B] constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
public? final? class Outer : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=Outer] constructor(): R|Outer| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public? final? class Inner : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=Inner] constructor(): R|Outer.Inner| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
|
||||
public? final? fun withLocal(): R|kotlin/Unit| {
|
||||
local final? [ContainingClassKey=Outer] class Local : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=Local] constructor(): R|Outer.Local| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
|
||||
lval r: I = object : I {
|
||||
private [ContainingClassKey=<anonymous>] constructor(): R|<anonymous>| {
|
||||
super<<implicit>>()
|
||||
}
|
||||
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public? final? interface I : R|kotlin/Any| {
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
@Suppress("") @MustBeDocumented
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
FILE: danglingAnnotationsFileLevel.kt
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
FILE: danglingAnnotationsFileLevel.kt
|
||||
@Suppress(String()) @MustBeDocumented() <DANGLING MODIFIER: Top level declaration expected>
|
||||
+10
@@ -76,6 +76,16 @@ public class RawFirBuilderLazyBodiesTestCaseGenerated extends AbstractRawFirBuil
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("danglingAnnotationsClassLevel.kt")
|
||||
public void testDanglingAnnotationsClassLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("danglingAnnotationsFileLevel.kt")
|
||||
public void testDanglingAnnotationsFileLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegates.kt")
|
||||
public void testDelegates() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/delegates.kt");
|
||||
|
||||
+10
@@ -76,6 +76,16 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("danglingAnnotationsClassLevel.kt")
|
||||
public void testDanglingAnnotationsClassLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("danglingAnnotationsFileLevel.kt")
|
||||
public void testDanglingAnnotationsFileLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegates.kt")
|
||||
public void testDelegates() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/delegates.kt");
|
||||
|
||||
+1
-4
@@ -18,10 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.addDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeUnderscoreIsReserved
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirDanglingModifierSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
abstract class FirDanglingModifierList : FirDeclaration(), FirDiagnosticHolder {
|
||||
abstract override val source: KtSourceElement?
|
||||
abstract override val resolvePhase: FirResolvePhase
|
||||
abstract override val annotations: List<FirAnnotation>
|
||||
abstract override val moduleData: FirModuleData
|
||||
abstract override val origin: FirDeclarationOrigin
|
||||
abstract override val attributes: FirDeclarationAttributes
|
||||
abstract override val diagnostic: ConeDiagnostic
|
||||
abstract override val symbol: FirDanglingModifierSymbol
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitDanglingModifierList(this, data)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||
transformer.transformDanglingModifierList(this, data) as E
|
||||
|
||||
abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase)
|
||||
|
||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||
|
||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirDanglingModifierList
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.fir.declarations.builder
|
||||
|
||||
import kotlin.contracts.*
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDanglingModifierListImpl
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirDanglingModifierSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
@FirBuilderDsl
|
||||
class FirDanglingModifierListBuilder : FirAnnotationContainerBuilder {
|
||||
override var source: KtSourceElement? = null
|
||||
var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
|
||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||
lateinit var moduleData: FirModuleData
|
||||
lateinit var origin: FirDeclarationOrigin
|
||||
var attributes: FirDeclarationAttributes = FirDeclarationAttributes()
|
||||
lateinit var diagnostic: ConeDiagnostic
|
||||
lateinit var symbol: FirDanglingModifierSymbol
|
||||
|
||||
override fun build(): FirDanglingModifierList {
|
||||
return FirDanglingModifierListImpl(
|
||||
source,
|
||||
resolvePhase,
|
||||
annotations.toMutableOrEmpty(),
|
||||
moduleData,
|
||||
origin,
|
||||
attributes,
|
||||
diagnostic,
|
||||
symbol,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun buildDanglingModifierList(init: FirDanglingModifierListBuilder.() -> Unit): FirDanglingModifierList {
|
||||
contract {
|
||||
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return FirDanglingModifierListBuilder().apply(init).build()
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.fir.declarations.impl
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirDanglingModifierSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.fir.MutableOrEmptyList
|
||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
internal class FirDanglingModifierListImpl(
|
||||
override val source: KtSourceElement?,
|
||||
@Volatile
|
||||
override var resolvePhase: FirResolvePhase,
|
||||
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
||||
override val moduleData: FirModuleData,
|
||||
override val origin: FirDeclarationOrigin,
|
||||
override val attributes: FirDeclarationAttributes,
|
||||
override val diagnostic: ConeDiagnostic,
|
||||
override val symbol: FirDanglingModifierSymbol,
|
||||
) : FirDanglingModifierList() {
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
annotations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirDanglingModifierListImpl {
|
||||
transformAnnotations(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirDanglingModifierListImpl {
|
||||
annotations.transformInplace(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) {
|
||||
resolvePhase = newResolvePhase
|
||||
}
|
||||
|
||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
||||
annotations = newAnnotations.toMutableOrEmpty()
|
||||
}
|
||||
}
|
||||
@@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
|
||||
@@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
|
||||
@@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
@@ -514,6 +515,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
|
||||
return transformElement(errorProperty, data)
|
||||
}
|
||||
|
||||
open fun transformDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: D): FirDanglingModifierList {
|
||||
return transformElement(danglingModifierList, data)
|
||||
}
|
||||
|
||||
open fun transformQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: D): FirStatement {
|
||||
return transformElement(qualifiedAccessExpression, data)
|
||||
}
|
||||
@@ -1086,6 +1091,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
|
||||
return transformErrorProperty(errorProperty, data)
|
||||
}
|
||||
|
||||
final override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: D): FirDanglingModifierList {
|
||||
return transformDanglingModifierList(danglingModifierList, data)
|
||||
}
|
||||
|
||||
final override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: D): FirStatement {
|
||||
return transformQualifiedAccessExpression(qualifiedAccessExpression, data)
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
@@ -335,6 +336,8 @@ abstract class FirVisitor<out R, in D> {
|
||||
|
||||
open fun visitErrorProperty(errorProperty: FirErrorProperty, data: D): R = visitElement(errorProperty, data)
|
||||
|
||||
open fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: D): R = visitElement(danglingModifierList, data)
|
||||
|
||||
open fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: D): R = visitElement(qualifiedAccessExpression, data)
|
||||
|
||||
open fun visitQualifiedErrorAccessExpression(qualifiedErrorAccessExpression: FirQualifiedErrorAccessExpression, data: D): R = visitElement(qualifiedErrorAccessExpression, data)
|
||||
|
||||
@@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
@@ -513,6 +514,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitElement(errorProperty)
|
||||
}
|
||||
|
||||
open fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList) {
|
||||
visitElement(danglingModifierList)
|
||||
}
|
||||
|
||||
open fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {
|
||||
visitElement(qualifiedAccessExpression)
|
||||
}
|
||||
@@ -1085,6 +1090,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitErrorProperty(errorProperty)
|
||||
}
|
||||
|
||||
final override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: Nothing?) {
|
||||
visitDanglingModifierList(danglingModifierList)
|
||||
}
|
||||
|
||||
final override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: Nothing?) {
|
||||
visitQualifiedAccessExpression(qualifiedAccessExpression)
|
||||
}
|
||||
|
||||
@@ -37,9 +37,13 @@ fun FirCallableDeclaration.containingClassLookupTag(): ConeClassLikeLookupTag? =
|
||||
fun FirRegularClass.containingClassForLocal(): ConeClassLikeLookupTag? =
|
||||
if (isLocal) containingClassForLocalAttr else null
|
||||
|
||||
fun FirDanglingModifierList.containingClass(): ConeClassLikeLookupTag? =
|
||||
containingClassAttr
|
||||
|
||||
private object ContainingClassKey : FirDeclarationDataKey()
|
||||
var FirCallableDeclaration.containingClassForStaticMemberAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
|
||||
var FirRegularClass.containingClassForLocalAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
|
||||
var FirDanglingModifierList.containingClassAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
|
||||
|
||||
private object IsNewPlaceForBodyGeneration : FirDeclarationDataKey()
|
||||
var FirRegularClass.isNewPlaceForBodyGeneration: Boolean? by FirDeclarationDataRegistry.data(IsNewPlaceForBodyGeneration)
|
||||
|
||||
@@ -46,6 +46,11 @@ object ConeDestructuringDeclarationsOnTopLevel : ConeDiagnostic {
|
||||
get() = "Destructuring declarations are only allowed for local variables/values"
|
||||
}
|
||||
|
||||
object ConeDanglingModifierOnTopLevel : ConeDiagnostic {
|
||||
override val reason: String
|
||||
get() = "Top level declaration expected"
|
||||
}
|
||||
|
||||
enum class DiagnosticKind {
|
||||
Syntax,
|
||||
ExpressionExpected,
|
||||
|
||||
@@ -387,6 +387,11 @@ class FirRenderer(
|
||||
bodyRenderer?.renderBody(anonymousInitializer.body)
|
||||
}
|
||||
|
||||
override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList) {
|
||||
annotationRenderer?.render(danglingModifierList)
|
||||
print("<DANGLING MODIFIER: ${danglingModifierList.diagnostic.reason}>")
|
||||
}
|
||||
|
||||
override fun visitBlock(block: FirBlock) {
|
||||
bodyRenderer?.renderBody(block)
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.fir.symbols.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
|
||||
class FirDanglingModifierSymbol : FirBasedSymbol<FirDanglingModifierList>() {
|
||||
override fun toString(): String = "${this::class.simpleName}"
|
||||
}
|
||||
+1
@@ -118,6 +118,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
|
||||
val errorExpression by element(Expression, expression, diagnosticHolder)
|
||||
val errorFunction by element(Declaration, function, diagnosticHolder)
|
||||
val errorProperty by element(Declaration, variable, diagnosticHolder)
|
||||
val danglingModifierList by element(Declaration, declaration, diagnosticHolder)
|
||||
val qualifiedAccessExpression by element(Expression, expression, qualifiedAccess)
|
||||
val qualifiedErrorAccessExpression by element(Expression, expression, diagnosticHolder)
|
||||
val propertyAccessExpression by element(Expression, qualifiedAccessExpression)
|
||||
|
||||
+1
@@ -43,6 +43,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
}
|
||||
|
||||
impl(anonymousObject)
|
||||
impl(danglingModifierList)
|
||||
noImpl(anonymousObjectExpression)
|
||||
|
||||
impl(typeAlias)
|
||||
|
||||
+4
@@ -456,6 +456,10 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+field("dispatchReceiverType", coneSimpleKotlinTypeType, nullable = true)
|
||||
}
|
||||
|
||||
danglingModifierList.configure {
|
||||
+symbol("FirDanglingModifierSymbol")
|
||||
}
|
||||
|
||||
file.configure {
|
||||
+field("annotationsContainer", fileAnnotationsContainer).withTransform()
|
||||
+field("packageDirective", packageDirective)
|
||||
|
||||
@@ -57,6 +57,9 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
|
||||
// with a fake sources which refers to the target expression
|
||||
object GeneratedLambdaLabel : KtFakeSourceElementKind()
|
||||
|
||||
// for error element which is created for dangling modifier lists
|
||||
object DanglingModifierList : KtFakeSourceElementKind()
|
||||
|
||||
// for lambdas & functions with expression bodies the return statement is added
|
||||
// with a fake sources which refers to the return target
|
||||
sealed class ImplicitReturn : KtFakeSourceElementKind() {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
annotation class Ann
|
||||
annotation class Ann2
|
||||
|
||||
class C {
|
||||
fun foo() {
|
||||
class Local {
|
||||
@Ann0
|
||||
@Ann @Ann3
|
||||
@Ann2(1)
|
||||
@Ann4<!SYNTAX!><!>
|
||||
}
|
||||
}
|
||||
@Ann0
|
||||
@Ann @Ann3
|
||||
@Ann2(1)
|
||||
@Ann4<!SYNTAX!><!>
|
||||
}
|
||||
|
||||
@Ann0
|
||||
@Ann @Ann3
|
||||
@Ann2(1)
|
||||
@Ann4<!SYNTAX!><!>
|
||||
@@ -1,6 +1,7 @@
|
||||
// FIR_IDENTICAL
|
||||
annotation class Ann
|
||||
annotation class Ann2
|
||||
|
||||
interface I {}
|
||||
class C {
|
||||
fun foo() {
|
||||
class Local {
|
||||
@@ -9,6 +10,12 @@ class C {
|
||||
@Ann2(<!TOO_MANY_ARGUMENTS!>1<!>)
|
||||
@<!UNRESOLVED_REFERENCE!>Ann4<!><!SYNTAX!><!>
|
||||
}
|
||||
val i = object : I {
|
||||
@<!UNRESOLVED_REFERENCE!>Ann0<!>
|
||||
@Ann @<!UNRESOLVED_REFERENCE!>Ann3<!>
|
||||
@Ann2(<!TOO_MANY_ARGUMENTS!>1<!>)
|
||||
@<!UNRESOLVED_REFERENCE!>Ann4<!><!SYNTAX!><!>
|
||||
}
|
||||
}
|
||||
@<!UNRESOLVED_REFERENCE!>Ann0<!>
|
||||
@Ann @<!UNRESOLVED_REFERENCE!>Ann3<!>
|
||||
|
||||
@@ -21,3 +21,10 @@ public final class C {
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface I {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -75,6 +75,18 @@ public class FirVisualizerForRawFirDataGenerated extends AbstractFirVisualizerTe
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationsClassLevel.kt")
|
||||
public void testDanglingAnnotationsClassLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationsFileLevel.kt")
|
||||
public void testDanglingAnnotationsFileLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegates.kt")
|
||||
public void testDelegates() throws Exception {
|
||||
|
||||
+12
@@ -75,6 +75,18 @@ public class PsiVisualizerForRawFirDataGenerated extends AbstractPsiVisualizerTe
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationsClassLevel.kt")
|
||||
public void testDanglingAnnotationsClassLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("danglingAnnotationsFileLevel.kt")
|
||||
public void testDanglingAnnotationsFileLevel() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegates.kt")
|
||||
public void testDelegates() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user