Disable slow assertions in type checker everywhere except for tests

This commit is contained in:
Denis Zharkov
2019-06-14 16:06:52 +03:00
parent 46d8f45c11
commit fdebb38706
6 changed files with 68 additions and 27 deletions
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.w3c.dom.Node import org.w3c.dom.Node
import org.w3c.dom.NodeList import org.w3c.dom.NodeList
import java.io.File import java.io.File
@@ -32,6 +33,16 @@ private fun NodeList.toList(): List<Node> {
private val Node.childNodesList get() = childNodes.toList() private val Node.childNodesList get() = childNodes.toList()
abstract class AbstractModularizedTest : KtUsefulTestCase() { abstract class AbstractModularizedTest : KtUsefulTestCase() {
override fun setUp() {
super.setUp()
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = false
}
override fun tearDown() {
super.tearDown()
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true
}
private fun loadModule(file: File): ModuleData { private fun loadModule(file: File): ModuleData {
val factory = DocumentBuilderFactory.newInstance() val factory = DocumentBuilderFactory.newInstance()
@@ -253,6 +253,7 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
AbstractTypeChecker.isSubtypeOf(this as AbstractTypeCheckerContext, subType, superType) AbstractTypeChecker.isSubtypeOf(this as AbstractTypeCheckerContext, subType, superType)
private fun assertInputTypes(subType: KotlinTypeMarker, superType: KotlinTypeMarker) { private fun assertInputTypes(subType: KotlinTypeMarker, superType: KotlinTypeMarker) {
if (!AbstractTypeChecker.RUN_SLOW_ASSERTIONS) return
fun correctSubType(subType: SimpleTypeMarker) = fun correctSubType(subType: SimpleTypeMarker) =
subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || isMyTypeVariable(subType) || subType.isError() || subType.isIntegerLiteralType() subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || isMyTypeVariable(subType) || subType.isError() || subType.isIntegerLiteralType()
@@ -88,13 +88,15 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
"original lower type: '${capturedType.lowerType}" "original lower type: '${capturedType.lowerType}"
) )
typeConstructor.supertypes.forEach { supertype -> if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
substitute(supertype, keepAnnotation, runCapturedChecks = false)?.let { typeConstructor.supertypes.forEach { supertype ->
throw IllegalStateException( substitute(supertype, keepAnnotation, runCapturedChecks = false)?.let {
"Illegal type substitutor: $this, " + throw IllegalStateException(
"because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," + "Illegal type substitutor: $this, " +
"original supertype: '$supertype'" "because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," +
) "original supertype: '$supertype'"
)
}
} }
} }
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.test.testFramework; package org.jetbrains.kotlin.test.testFramework;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
import com.intellij.diagnostic.PerformanceWatcher; import com.intellij.diagnostic.PerformanceWatcher;
import com.intellij.openapi.Disposable; import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application; import com.intellij.openapi.application.Application;
@@ -51,6 +49,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.test.IdeaSystemPropertiesForParallelRunConfigurator; import org.jetbrains.kotlin.test.IdeaSystemPropertiesForParallelRunConfigurator;
import org.jetbrains.kotlin.testFramework.MockComponentManagerCreationTracer; import org.jetbrains.kotlin.testFramework.MockComponentManagerCreationTracer;
import org.jetbrains.kotlin.types.AbstractTypeChecker;
import org.jetbrains.kotlin.types.FlexibleTypeImpl; import org.jetbrains.kotlin.types.FlexibleTypeImpl;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt; import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import org.junit.Assert; import org.junit.Assert;
@@ -100,6 +99,7 @@ public abstract class KtUsefulTestCase extends TestCase {
System.setProperty("apple.awt.UIElement", "true"); System.setProperty("apple.awt.UIElement", "true");
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true; FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true;
} }
protected boolean shouldContainTempFiles() { protected boolean shouldContainTempFiles() {
@@ -18,11 +18,15 @@ package org.jetbrains.kotlin.jvm.compiler
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.test.KotlinTestWithEnvironmentManagement import org.jetbrains.kotlin.test.KotlinTestWithEnvironmentManagement
import org.jetbrains.kotlin.types.AbstractNullabilityChecker
import org.jetbrains.kotlin.types.KotlinTypeFactory import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeIntersector
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext
class FlexibleTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() { class SlowTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() {
fun testAssertionsAreOn() { fun testAssertionsForFlexibleTypesAreOn() {
val builtIns = DefaultBuiltIns.Instance val builtIns = DefaultBuiltIns.Instance
try { try {
@@ -34,4 +38,21 @@ class FlexibleTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement()
fail("Assertion error expected") fail("Assertion error expected")
} }
fun testAssertionsForTypeCheckerAreOn() {
val builtIns = DefaultBuiltIns.Instance
try {
val superType = TypeIntersector.intersectTypes(listOf(builtIns.charSequence.defaultType, builtIns.comparable.defaultType))
AbstractNullabilityChecker.isPossibleSubtype(
ClassicTypeCheckerContext(errorTypeEqualsToAnything = true), builtIns.annotationType,
superType as SimpleType
)
} catch (e: AssertionError) {
assertEquals("Not singleClassifierType superType: {CharSequence & Comparable<T>}", e.message)
return
}
fail("Assertion error expected")
}
} }
@@ -144,6 +144,8 @@ abstract class AbstractTypeCheckerContext : TypeSystemContext {
} }
object AbstractTypeChecker { object AbstractTypeChecker {
@JvmField
var RUN_SLOW_ASSERTIONS = false
fun isSubtypeOf(context: TypeCheckerProviderContext, subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean { fun isSubtypeOf(context: TypeCheckerProviderContext, subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
return AbstractTypeChecker.isSubtypeOf(context.newBaseTypeCheckerContext(true), subType, superType) return AbstractTypeChecker.isSubtypeOf(context.newBaseTypeCheckerContext(true), subType, superType)
@@ -223,11 +225,13 @@ object AbstractTypeChecker {
} }
private fun AbstractTypeCheckerContext.isSubtypeOfForSingleClassifierType(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean { private fun AbstractTypeCheckerContext.isSubtypeOfForSingleClassifierType(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean {
assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) { if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
"Not singleClassifierType and not intersection subType: $subType" assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) {
} "Not singleClassifierType and not intersection subType: $subType"
assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) { }
"Not singleClassifierType superType: $superType" assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) {
"Not singleClassifierType superType: $superType"
}
} }
if (!AbstractNullabilityChecker.isPossibleSubtype(this, subType, superType)) return false if (!AbstractNullabilityChecker.isPossibleSubtype(this, subType, superType)) return false
@@ -469,12 +473,14 @@ object AbstractNullabilityChecker {
} }
private fun AbstractTypeCheckerContext.runIsPossibleSubtype(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean { private fun AbstractTypeCheckerContext.runIsPossibleSubtype(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean {
// it makes for case String? & Any <: String if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) { // it makes for case String? & Any <: String
"Not singleClassifierType and not intersection subType: $subType" assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) {
} "Not singleClassifierType and not intersection subType: $subType"
assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) { }
"Not singleClassifierType superType: $superType" assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) {
"Not singleClassifierType superType: $superType"
}
} }
// superType is actually nullable // superType is actually nullable