IR: minor optimizations to IR validation
This commit is contained in:
+11
-23
@@ -18,17 +18,19 @@ package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType
|
||||
import org.jetbrains.kotlin.ir.util.getInlinedClass
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
|
||||
typealias ReportError = (element: IrElement, message: String) -> Unit
|
||||
|
||||
@@ -38,17 +40,12 @@ class CheckIrElementVisitor(
|
||||
val reportError: ReportError,
|
||||
val config: IrValidatorConfig
|
||||
) : IrElementVisitorVoid {
|
||||
|
||||
val set = mutableSetOf<IrElement>()
|
||||
val checkedTypes = mutableSetOf<IrType>()
|
||||
private val visitedElements = hashSetOf<IrElement>()
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
if (config.ensureAllNodesAreDifferent) {
|
||||
if (set.contains(element))
|
||||
reportError(element, "Duplicate IR node: ${element.render()}")
|
||||
set.add(element)
|
||||
if (config.ensureAllNodesAreDifferent && !visitedElements.add(element)) {
|
||||
reportError(element, "Duplicate IR node: ${element.render()}")
|
||||
}
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
private fun IrExpression.ensureTypesEqual(actualType: IrType, expectedType: IrType) {
|
||||
@@ -74,7 +71,7 @@ class CheckIrElementVisitor(
|
||||
|
||||
private fun IrSymbol.ensureBound(expression: IrExpression) {
|
||||
if (!this.isBound && expression.type !is IrDynamicType) {
|
||||
reportError(expression, "Unbound symbol ${this}")
|
||||
reportError(expression, "Unbound symbol $this")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,8 +147,8 @@ class CheckIrElementVisitor(
|
||||
val fieldType = expression.symbol.owner.type
|
||||
// TODO: We don't have the proper type substitution yet, so skip generics for now.
|
||||
if (fieldType is IrSimpleType &&
|
||||
fieldType.classifier is IrClassSymbol &&
|
||||
fieldType.arguments.isEmpty()
|
||||
fieldType.classifier is IrClassSymbol &&
|
||||
fieldType.arguments.isEmpty()
|
||||
) {
|
||||
expression.ensureTypeIs(fieldType)
|
||||
}
|
||||
@@ -298,10 +295,6 @@ class CheckIrElementVisitor(
|
||||
override fun visitDeclarationReference(expression: IrDeclarationReference) {
|
||||
super.visitDeclarationReference(expression)
|
||||
|
||||
// TODO: Fix unbound external declarations
|
||||
if (expression.symbol.descriptor.isEffectivelyExternal())
|
||||
return
|
||||
|
||||
// TODO: Fix unbound dynamic filed declarations
|
||||
if (expression is IrFieldAccessExpression) {
|
||||
val receiverType = expression.receiver?.type
|
||||
@@ -359,9 +352,6 @@ class CheckIrElementVisitor(
|
||||
}
|
||||
|
||||
private fun checkType(type: IrType, element: IrElement) {
|
||||
if (type in checkedTypes)
|
||||
return
|
||||
|
||||
when (type) {
|
||||
is IrSimpleType -> {
|
||||
if (!type.classifier.isBound) {
|
||||
@@ -369,7 +359,5 @@ class CheckIrElementVisitor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkedTypes.add(type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,8 +436,6 @@ fun MemberDescriptor.isEffectivelyExternal(): Boolean {
|
||||
return containingClass != null && containingClass.isEffectivelyExternal()
|
||||
}
|
||||
|
||||
fun DeclarationDescriptor.isEffectivelyExternal() = this is MemberDescriptor && this.isEffectivelyExternal()
|
||||
|
||||
fun isParameterOfAnnotation(parameterDescriptor: ParameterDescriptor): Boolean =
|
||||
parameterDescriptor.containingDeclaration.isAnnotationConstructor()
|
||||
|
||||
|
||||
+3
-2
@@ -167,7 +167,8 @@ object JsExportDeclarationChecker : DeclarationChecker {
|
||||
KotlinBuiltIns.isPrimitiveArray(type)
|
||||
) return true
|
||||
|
||||
val descriptor: ClassifierDescriptor = type.constructor.declarationDescriptor ?: return false
|
||||
return descriptor.isEffectivelyExternal() || AnnotationsUtils.isExportedObject(descriptor, bindingContext)
|
||||
val descriptor = type.constructor.declarationDescriptor ?: return false
|
||||
return descriptor is MemberDescriptor && descriptor.isEffectivelyExternal() ||
|
||||
AnnotationsUtils.isExportedObject(descriptor, bindingContext)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user