IR: minor optimizations to IR validation

This commit is contained in:
Alexander Udalov
2020-08-12 21:13:06 +02:00
parent 7468518f35
commit 469b164555
3 changed files with 14 additions and 27 deletions
@@ -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()
@@ -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)
}
}