Do not try to create a light class for classes in unexpected positions

Example of such class declaration would be `10 < class A` expression

The expression is uncompilable, but parsable. Unfortunately, the
FIR compiler does not save `class A` reference in it (because it
is not an expression, and only an expression can be a LHS or RHS of
binary expression `10 < ...`)

When we try to build light classes, we will try to find/build FIR
declaration for this class, but we won't be able to, and this will throw
an error

Adding this check should fix few
`FirKotlinHighlightingPassTestGenerated$Regression` tests
This commit is contained in:
Roman Golyshev
2021-07-01 23:42:43 +03:00
parent 584310615c
commit 7b1052296e
@@ -570,6 +570,7 @@ fun KtClassOrObject.shouldNotBeVisibleAsLightClass(): Boolean {
if (isLocal) {
if (containingFile.virtualFile == null) return true
if (hasParseErrorsAround(this) || PsiUtilCore.hasErrorElementChild(this)) return true
if (classDeclaredInUnexpectedPosition(this)) return true
}
if (isEnumEntryWithoutBody(this)) {
@@ -579,6 +580,23 @@ fun KtClassOrObject.shouldNotBeVisibleAsLightClass(): Boolean {
return false
}
/**
* If class is declared in some strange context (for example, in expression like `10 < class A`),
* we don't want to try to build a light class for it.
*
* The expression itself is incorrect and won't compile, but the parser is able the parse the class nonetheless.
*
* This does not concern objects, since object literals are expressions and can be used almost anywhere.
*/
private fun classDeclaredInUnexpectedPosition(classOrObject: KtClassOrObject): Boolean {
if (classOrObject is KtObjectDeclaration) return false
val classParent = classOrObject.parent
return classParent !is KtBlockExpression &&
classParent !is KtDeclarationContainer
}
private fun isEnumEntryWithoutBody(classOrObject: KtClassOrObject): Boolean {
if (classOrObject !is KtEnumEntry) {
return false