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.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()
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user