[FIR JS] Implement FirJsExternalChecker

The JsAllowValueClassesInExternals feature is enabled explicitly,
because otherwise it's enabled
implicitly depending on the backend. See:
org/jetbrains/kotlin/test/builders/LanguageVersionSettingsBuilder.kt:90

A property may have a fake source return kind, while its accessor
has a real source kind. In this case we can't "just copy"
the property return type down to the accessor.
This commit is contained in:
Nikolay Lunyak
2023-01-04 16:42:00 +02:00
committed by Space Team
parent 7b8f5f9980
commit a20e29e8b7
54 changed files with 758 additions and 456 deletions
@@ -6,12 +6,9 @@
package org.jetbrains.kotlin.fir
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtRealPsiSourceElement
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.declarations.FirFile
@@ -32,11 +29,15 @@ import org.jetbrains.kotlin.util.wrapIntoSourceCodeAnalysisExceptionIfNeeded
// TODO: rewrite
fun FirBlock.returnExpressions(): List<FirExpression> = listOfNotNull(statements.lastOrNull() as? FirExpression)
// do we need a deep copy here ?
fun <R : FirTypeRef> R.copyWithNewSourceKind(newKind: KtFakeSourceElementKind): R {
if (source == null) return this
if (source?.kind == newKind) return this
val newSource = source?.fakeElement(newKind)
return copyWithNewSource(source?.fakeElement(newKind))
}
// do we need a deep copy here ?
fun <R : FirTypeRef> R.copyWithNewSource(newSource: KtSourceElement?): R {
if (source?.kind == newSource?.kind) return this
@Suppress("UNCHECKED_CAST")
return when (val typeRef = this) {
@@ -63,7 +64,7 @@ fun <R : FirTypeRef> R.copyWithNewSourceKind(newKind: KtFakeSourceElementKind):
isMarkedNullable = typeRef.isMarkedNullable
annotations += typeRef.annotations
}
is FirImplicitBuiltinTypeRef -> typeRef.withFakeSource(newKind)
is FirImplicitBuiltinTypeRef -> typeRef.withNewSource(newSource)
is FirIntersectionTypeRef -> buildIntersectionTypeRef {
source = newSource
isMarkedNullable = typeRef.isMarkedNullable
@@ -43,3 +43,5 @@ val FirDeclaration.isNonLocal
is FirClassLikeDeclaration -> !symbol.classId.isLocal
else -> false
}
val FirCallableDeclaration.isExtension get() = receiverParameter != null
@@ -183,10 +183,9 @@ class FirImplicitKMutableProperty2TypeRef(
arrayOf(dispatchReceiverTypeArgument, extensionReceiverTypeArgument, propertyTypeArgument)
)
fun FirImplicitBuiltinTypeRef.withFakeSource(kind: KtFakeSourceElementKind): FirImplicitBuiltinTypeRef {
fun FirImplicitBuiltinTypeRef.withNewSource(newSource: KtSourceElement?): FirImplicitBuiltinTypeRef {
val source = source ?: return this
if (source.kind == kind) return this
val newSource = source.fakeElement(kind)
if (source.kind == newSource?.kind) return this
return when (this) {
is FirImplicitUnitTypeRef -> FirImplicitUnitTypeRef(newSource)
is FirImplicitAnyTypeRef -> FirImplicitAnyTypeRef(newSource)