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