Skip to content

Commit

Permalink
Light class test: avoid checking method visibility when NoLaziness is…
Browse files Browse the repository at this point in the history
… not specified

Allows to avoid putting NoLaziness flag on every test that mentions 'override' modifier
  • Loading branch information
PVTalanov committed Apr 9, 2017
1 parent 32d3a1b commit 69c250a
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,15 @@ class KtLightModifierList(
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
dummyDelegate != null -> {
when {
name in visibilityModifiers && isOverride() ->
name in visibilityModifiers && isMethodOverride() ->
clsDelegate.hasModifierProperty(name)
else -> dummyDelegate.hasModifierProperty(name)
}
}
else -> clsDelegate.hasModifierProperty(name)
}

private fun isOverride() = owner.kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false
private fun isMethodOverride() = owner is KtLightMethod && owner.kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false

private fun isImplementationInInterface()
= owner.containingClass.isInterface && owner is KtLightMethod && owner.kotlinOrigin?.hasBody() ?: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,4 @@ interface I1 {

interface I2 {
fun bar() = "bar"
}

// LAZINESS:NoLaziness
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ interface Tr {
class C: Tr {
override fun foo() = 1
override val v = 1
}

// LAZINESS:NoLaziness
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,35 +194,35 @@ object LightClassLazinessChecker {
}

// collect api method call results on light members that should not trigger exact context evaluation
val lazinessInfo = LazinessInfo(lightClass)
val lazinessInfo = LazinessInfo(lightClass, lazinessMode)

tracker.allowLevel(EXACT)

lightClass.clsDelegate // trigger exact context

tracker.checkLevel(EXACT)

// still running code above to catch possible exceptions
if (lazinessMode == Mode.NoConsistency) return

lazinessInfo.checkConsistency()
}

private class LazinessInfo(val lightClass: KtLightClass) {
private class LazinessInfo(private val lightClass: KtLightClass, private val lazinessMode: Mode) {
val classInfo = classInfo(lightClass)
val fieldsToInfo = lightClass.fields.asList().keysToMap { fieldInfo(it) }
val methodsToInfo = lightClass.methods.asList().keysToMap { methodInfo(it) }
val innerClasses = lightClass.innerClasses.map { LazinessInfo(it as KtLightClass) }
val methodsToInfo = lightClass.methods.asList().keysToMap { methodInfo(it, lazinessMode) }
val innerClasses = lightClass.innerClasses.map { LazinessInfo(it as KtLightClass, lazinessMode) }

fun checkConsistency() {
// still collecting data to trigger possible exceptions
if (lazinessMode == Mode.NoConsistency) return

// check collected data against delegates which should contain correct data
for ((field, lightFieldInfo) in fieldsToInfo) {
val delegate = (field as KtLightField).clsDelegate
assertEquals(fieldInfo(delegate), lightFieldInfo)
}
for ((method, lightMethodInfo) in methodsToInfo) {
val delegate = (method as KtLightMethod).clsDelegate
assertEquals(methodInfo(delegate), lightMethodInfo)
assertEquals(methodInfo(delegate, lazinessMode), lightMethodInfo)
}

assertEquals(classInfo(lightClass.clsDelegate), classInfo)
Expand Down Expand Up @@ -260,23 +260,30 @@ object LightClassLazinessChecker {
val isVarargs: Boolean
)

private fun methodInfo(method: PsiMethod) = with(method) {
private fun methodInfo(method: PsiMethod, lazinessMode: Mode) = with(method) {
MethodInfo(
name, relevantModifiers(),
name, relevantModifiers(lazinessMode),
isConstructor, method.parameterList.parametersCount, isVarArgs
)
}

private fun PsiMethod.relevantModifiers()
= when { containingClass!!.isInterface ->
PsiModifier.MODIFIERS.filter { it != PsiModifier.ABSTRACT && it != PsiModifier.DEFAULT }
private fun PsiMethod.relevantModifiers(lazinessMode: Mode) = when {
containingClass!!.isInterface -> PsiModifier.MODIFIERS.filter {
// we have custom strategy for interface members with implementation
it !in modifiersHackedForInterfaceMembersWithImplementation
}
else -> PsiModifier.MODIFIERS.asList()
}.filter {
// cannot compute visibility for overrides without proper resolve, we check consistency if laziness is turned off
lazinessMode == Mode.NoLaziness || it !in visibilityModifiers
}.filter { modifierList.hasModifierProperty(it) }


private fun Array<out PsiMember>.names() = mapTo(LinkedHashSet()) { it.name!! }
}

private val modifiersHackedForInterfaceMembersWithImplementation = listOf(PsiModifier.ABSTRACT, PsiModifier.DEFAULT)
private val visibilityModifiers = listOf(PsiModifier.PRIVATE, PsiModifier.PROTECTED, PsiModifier.PUBLIC)

private fun String.removeLinesStartingWith(prefix: String): String {
return lines().filterNot { it.trimStart().startsWith(prefix) }.joinToString(separator = "\n")
}

0 comments on commit 69c250a

Please sign in to comment.