[FIR] Microoptimizations and clearing
This commit is contained in:
+2
-2
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.filterIsInstanceWithChecker
|
||||
|
||||
object FirImportsChecker : FirFileChecker() {
|
||||
override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -97,8 +98,7 @@ object FirImportsChecker : FirFileChecker() {
|
||||
|
||||
private fun checkConflictingImports(imports: List<FirImport>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val interestingImports = imports
|
||||
.filterIsInstance<FirResolvedImport>()
|
||||
.filter { import ->
|
||||
.filterIsInstanceWithChecker<FirResolvedImport> { import ->
|
||||
!import.isAllUnder &&
|
||||
import.importedName?.identifierOrNullIfSpecial?.isNotEmpty() == true &&
|
||||
import.resolvesToClass(context)
|
||||
|
||||
+1
-24
@@ -12,9 +12,7 @@ import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.load.kotlin.MemberSignature
|
||||
import org.jetbrains.kotlin.load.kotlin.*
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
@@ -248,27 +246,6 @@ class JvmBinaryAnnotationDeserializer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPropertySignature(
|
||||
proto: ProtoBuf.Property,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable,
|
||||
field: Boolean = false,
|
||||
synthetic: Boolean = false,
|
||||
requireHasFieldFlagForField: Boolean = true
|
||||
): MemberSignature? {
|
||||
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null
|
||||
|
||||
if (field) {
|
||||
val fieldSignature =
|
||||
JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable, requireHasFieldFlagForField) ?: return null
|
||||
return MemberSignature.fromJvmMemberSignature(fieldSignature)
|
||||
} else if (synthetic && signature.hasSyntheticMethod()) {
|
||||
return MemberSignature.fromMethod(nameResolver, signature.syntheticMethod)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun findJvmBinaryClassAndLoadMemberAnnotations(
|
||||
memberSignature: MemberSignature, searchInDefaultImpls: Boolean = false
|
||||
): List<FirAnnotation> {
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ class FirSignatureEnhancement(
|
||||
}.symbol
|
||||
}
|
||||
else -> {
|
||||
if (original is FirPropertySymbol || original is FirSyntheticPropertySymbol) return original
|
||||
if (original is FirPropertySymbol) return original
|
||||
error("Can't make enhancement for $original: `${firElement.render()}`")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,30 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.java.enhancement
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.collectEnumEntries
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import org.jetbrains.kotlin.utils.extractRadix
|
||||
|
||||
internal fun ConeKotlinType.enhance(session: FirSession, qualifiers: IndexedJavaTypeQualifiers): ConeKotlinType? =
|
||||
enhanceConeKotlinType(session, qualifiers, 0, mutableListOf<Int>().apply { computeSubtreeSizes(this) })
|
||||
@@ -167,54 +150,3 @@ private fun ConeClassifierLookupTag.enhanceMutability(
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String): FirExpression? {
|
||||
val lookupTagBasedType = when (this) {
|
||||
is ConeLookupTagBasedType -> this
|
||||
is ConeFlexibleType -> return lowerBound.lexicalCastFrom(session, value)
|
||||
else -> return null
|
||||
}
|
||||
val lookupTag = lookupTagBasedType.lookupTag
|
||||
val firElement = lookupTag.toSymbol(session)?.fir
|
||||
if (firElement is FirRegularClass && firElement.classKind == ClassKind.ENUM_CLASS) {
|
||||
val name = Name.identifier(value)
|
||||
val firEnumEntry = firElement.collectEnumEntries().find { it.name == name }
|
||||
|
||||
return if (firEnumEntry != null) buildPropertyAccessExpression {
|
||||
calleeReference = buildResolvedNamedReference {
|
||||
this.name = name
|
||||
resolvedSymbol = firEnumEntry.symbol
|
||||
}
|
||||
} else if (firElement is FirJavaClass) {
|
||||
val firStaticProperty = firElement.declarations.filterIsInstance<FirJavaField>().find {
|
||||
it.isStatic && it.modality == Modality.FINAL && it.name == name
|
||||
}
|
||||
if (firStaticProperty != null) {
|
||||
buildPropertyAccessExpression {
|
||||
calleeReference = buildResolvedNamedReference {
|
||||
this.name = name
|
||||
resolvedSymbol = firStaticProperty.symbol
|
||||
}
|
||||
}
|
||||
} else null
|
||||
} else null
|
||||
}
|
||||
|
||||
if (lookupTag !is ConeClassLikeLookupTag) return null
|
||||
val classId = lookupTag.classId
|
||||
if (classId.packageFqName != FqName("kotlin")) return null
|
||||
|
||||
val (number, radix) = extractRadix(value)
|
||||
return when (classId.relativeClassName.asString()) {
|
||||
"Boolean" -> buildConstExpression(null, ConstantValueKind.Boolean, value.toBoolean())
|
||||
"Char" -> buildConstExpression(null, ConstantValueKind.Char, value.singleOrNull() ?: return null)
|
||||
"Byte" -> buildConstExpression(null, ConstantValueKind.Byte, number.toByteOrNull(radix) ?: return null)
|
||||
"Short" -> buildConstExpression(null, ConstantValueKind.Short, number.toShortOrNull(radix) ?: return null)
|
||||
"Int" -> buildConstExpression(null, ConstantValueKind.Int, number.toIntOrNull(radix) ?: return null)
|
||||
"Long" -> buildConstExpression(null, ConstantValueKind.Long, number.toLongOrNull(radix) ?: return null)
|
||||
"Float" -> buildConstExpression(null, ConstantValueKind.Float, value.toFloatOrNull() ?: return null)
|
||||
"Double" -> buildConstExpression(null, ConstantValueKind.Double, value.toDoubleOrNull() ?: return null)
|
||||
"String" -> buildConstExpression(null, ConstantValueKind.String, value)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,11 +220,7 @@ class FirCallResolver(
|
||||
origin = origin
|
||||
)
|
||||
towerResolver.reset()
|
||||
val result = if (collector != null) {
|
||||
towerResolver.runResolver(info, resolutionContext, collector)
|
||||
} else {
|
||||
towerResolver.runResolver(info, resolutionContext)
|
||||
}
|
||||
val result = towerResolver.runResolver(info, resolutionContext, collector)
|
||||
val bestCandidates = result.bestCandidates()
|
||||
|
||||
fun chooseMostSpecific(): Set<Candidate> {
|
||||
|
||||
+5
-3
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.filterIsInstanceWithChecker
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class ConstraintSystemCompleter(components: BodyResolveComponents, private val context: BodyResolveContext) {
|
||||
@@ -92,9 +93,10 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
|
||||
break
|
||||
|
||||
val postponedArgumentsWithRevisableType = postponedArguments
|
||||
.filterIsInstance<PostponedAtomWithRevisableExpectedType>()
|
||||
// NB: FE 1.0 does not perform this check
|
||||
.filter { it.revisedExpectedType == null }
|
||||
.filterIsInstanceWithChecker<PostponedAtomWithRevisableExpectedType> {
|
||||
// NB: FE 1.0 does not perform this check
|
||||
it.revisedExpectedType == null
|
||||
}
|
||||
val dependencyProvider =
|
||||
TypeVariableDependencyInformationProvider(notFixedTypeVariables, postponedArguments, topLevelType, this)
|
||||
|
||||
|
||||
+9
-9
@@ -170,6 +170,7 @@ class PostponedArgumentsAnalyzer(
|
||||
|
||||
returnArguments.forEach { c.addSubsystemFromExpression(it) }
|
||||
val checkerSink: CheckerSink = CheckerSinkImpl(candidate)
|
||||
val builder = c.getBuilder()
|
||||
|
||||
val lastExpression = lambda.atom.body?.statements?.lastOrNull() as? FirExpression
|
||||
var hasExpressionInReturnArguments = false
|
||||
@@ -183,9 +184,9 @@ class PostponedArgumentsAnalyzer(
|
||||
val lastExpressionCoercedToUnit =
|
||||
it == lastExpression && expectedReturnType?.isUnitOrFlexibleUnit == true && !it.typeRef.coneType.isUnitOrFlexibleUnit
|
||||
// No constraint for the last expression of lambda if it will be coerced to Unit.
|
||||
if (!lastExpressionCoercedToUnit && !c.getBuilder().hasContradiction) {
|
||||
if (!lastExpressionCoercedToUnit && !builder.hasContradiction) {
|
||||
candidate.resolveArgumentExpression(
|
||||
c.getBuilder(),
|
||||
builder,
|
||||
it,
|
||||
lambdaReturnType,
|
||||
lambda.atom.returnTypeRef, // TODO: proper ref
|
||||
@@ -198,7 +199,7 @@ class PostponedArgumentsAnalyzer(
|
||||
}
|
||||
|
||||
if (!hasExpressionInReturnArguments && lambdaReturnType != null) {
|
||||
c.getBuilder().addSubtypeConstraint(
|
||||
builder.addSubtypeConstraint(
|
||||
components.session.builtinTypes.unitType.type,
|
||||
lambdaReturnType,
|
||||
ConeLambdaArgumentConstraintPosition(lambda.atom)
|
||||
@@ -209,20 +210,19 @@ class PostponedArgumentsAnalyzer(
|
||||
lambda.returnStatements = returnArguments
|
||||
|
||||
if (inferenceSession != null) {
|
||||
val constraintSystemBuilder = c.getBuilder()
|
||||
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, constraintSystemBuilder, completionMode)
|
||||
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, builder, completionMode)
|
||||
|
||||
if (postponedVariables == null) {
|
||||
c.getBuilder().removePostponedVariables()
|
||||
builder.removePostponedVariables()
|
||||
return
|
||||
}
|
||||
|
||||
for ((constructor, resultType) in postponedVariables) {
|
||||
val variableWithConstraints = constraintSystemBuilder.currentStorage().notFixedTypeVariables[constructor] ?: continue
|
||||
val variableWithConstraints = builder.currentStorage().notFixedTypeVariables[constructor] ?: continue
|
||||
val variable = variableWithConstraints.typeVariable as ConeTypeVariable
|
||||
|
||||
c.getBuilder().unmarkPostponedVariable(variable)
|
||||
c.getBuilder().addSubtypeConstraint(resultType, variable.defaultType(c), BuilderInferencePosition)
|
||||
builder.unmarkPostponedVariable(variable)
|
||||
builder.addSubtypeConstraint(resultType, variable.defaultType(c), BuilderInferencePosition)
|
||||
}
|
||||
|
||||
c.removePostponedTypeVariablesFromConstraints(postponedVariables.keys)
|
||||
|
||||
+13
-14
@@ -548,15 +548,15 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
): List<ConeKotlinType> {
|
||||
val declaration = candidate.symbol.fir as? FirCallableDeclaration ?: return emptyList()
|
||||
|
||||
return declaration.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }
|
||||
.map { candidate.substitutor.substituteOrSelf(it) }
|
||||
.map {
|
||||
finalSubstitutor.substituteOrSelf(it).let { substitutedType ->
|
||||
typeApproximator.approximateToSuperType(
|
||||
substitutedType, TypeApproximatorConfiguration.TypeArgumentApproximation,
|
||||
) ?: substitutedType
|
||||
}
|
||||
return declaration.typeParameters.map {
|
||||
val typeParameter = ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||
val substitution = candidate.substitutor.substituteOrSelf(typeParameter)
|
||||
finalSubstitutor.substituteOrSelf(substitution).let { substitutedType ->
|
||||
typeApproximator.approximateToSuperType(
|
||||
substitutedType, TypeApproximatorConfiguration.TypeArgumentApproximation,
|
||||
) ?: substitutedType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformAnonymousFunctionExpression(
|
||||
@@ -651,17 +651,16 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
expression.transform<FirElement, ExpectedArgumentType?>(this, finalType?.toExpectedType())
|
||||
}
|
||||
|
||||
val resultFunction = result
|
||||
if (resultFunction.returnTypeRef.coneTypeSafe<ConeIntegerLiteralType>() != null) {
|
||||
if (result.returnTypeRef.coneTypeSafe<ConeIntegerLiteralType>() != null) {
|
||||
val lastExpressionType =
|
||||
(returnExpressionsOfAnonymousFunction.lastOrNull() as? FirExpression)
|
||||
?.typeRef?.coneTypeSafe<ConeKotlinType>()
|
||||
|
||||
val newReturnTypeRef = resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType)
|
||||
resultFunction.replaceReturnTypeRef(newReturnTypeRef)
|
||||
val newReturnTypeRef = result.returnTypeRef.withReplacedConeType(lastExpressionType)
|
||||
result.replaceReturnTypeRef(newReturnTypeRef)
|
||||
val resolvedTypeRef =
|
||||
resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||
resultFunction.replaceTypeRef(resolvedTypeRef)
|
||||
result.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||
result.replaceTypeRef(resolvedTypeRef)
|
||||
session.lookupTracker?.let {
|
||||
it.recordTypeResolveAsLookup(newReturnTypeRef, anonymousFunction.source, context.file.source)
|
||||
it.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, context.file.source)
|
||||
|
||||
+8
-10
@@ -570,18 +570,16 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
val returnType =
|
||||
dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(result)
|
||||
.firstNotNullOfOrNull { (it as? FirExpression)?.resultType?.coneTypeSafe() }
|
||||
|
||||
if (returnType != null) {
|
||||
result.transformReturnTypeRef(transformer, withExpectedType(returnType))
|
||||
val resolutionMode = if (returnType != null) {
|
||||
withExpectedType(returnType)
|
||||
} else {
|
||||
result.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(buildErrorTypeRef {
|
||||
diagnostic =
|
||||
ConeSimpleDiagnostic("Unresolved lambda return type", DiagnosticKind.InferenceError)
|
||||
})
|
||||
)
|
||||
withExpectedType(buildErrorTypeRef {
|
||||
diagnostic =
|
||||
ConeSimpleDiagnostic("Unresolved lambda return type", DiagnosticKind.InferenceError)
|
||||
})
|
||||
}
|
||||
|
||||
result.transformReturnTypeRef(transformer, resolutionMode)
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
+21
-21
@@ -253,27 +253,6 @@ abstract class AbstractBinaryClassAnnotationLoader<A : Any, S : AbstractBinaryCl
|
||||
return null
|
||||
}
|
||||
|
||||
protected fun getPropertySignature(
|
||||
proto: ProtoBuf.Property,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable,
|
||||
field: Boolean = false,
|
||||
synthetic: Boolean = false,
|
||||
requireHasFieldFlagForField: Boolean = true
|
||||
): MemberSignature? {
|
||||
val signature = proto.getExtensionOrNull(propertySignature) ?: return null
|
||||
|
||||
if (field) {
|
||||
val fieldSignature =
|
||||
JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable, requireHasFieldFlagForField) ?: return null
|
||||
return MemberSignature.fromJvmMemberSignature(fieldSignature)
|
||||
} else if (synthetic && signature.hasSyntheticMethod()) {
|
||||
return MemberSignature.fromMethod(nameResolver, signature.syntheticMethod)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
protected fun getCallableSignature(
|
||||
proto: MessageLite,
|
||||
nameResolver: NameResolver,
|
||||
@@ -319,3 +298,24 @@ abstract class AbstractBinaryClassAnnotationLoader<A : Any, S : AbstractBinaryCl
|
||||
abstract val memberAnnotations: Map<MemberSignature, List<A>>
|
||||
}
|
||||
}
|
||||
|
||||
fun getPropertySignature(
|
||||
proto: ProtoBuf.Property,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable,
|
||||
field: Boolean = false,
|
||||
synthetic: Boolean = false,
|
||||
requireHasFieldFlagForField: Boolean = true
|
||||
): MemberSignature? {
|
||||
val signature = proto.getExtensionOrNull(propertySignature) ?: return null
|
||||
|
||||
if (field) {
|
||||
val fieldSignature =
|
||||
JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable, requireHasFieldFlagForField) ?: return null
|
||||
return MemberSignature.fromJvmMemberSignature(fieldSignature)
|
||||
} else if (synthetic && signature.hasSyntheticMethod()) {
|
||||
return MemberSignature.fromMethod(nameResolver, signature.syntheticMethod)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user