add ultra-light classes/members that work without backend in simple cases

This commit is contained in:
peter
2018-10-25 17:58:05 +02:00
parent 387efc3791
commit ebc998d710
48 changed files with 2502 additions and 98 deletions
@@ -0,0 +1,73 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.perf
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtVisitorVoid
import java.util.*
import kotlin.system.measureNanoTime
class WholeProjectLightClassTest : WholeProjectPerformanceTest(), WholeProjectKotlinFileProvider {
override fun doTest(file: VirtualFile): PerFileTestResult {
val results = mutableMapOf<String, Long>()
var totalNs = 0L
val psiFile = file.toPsiFile(project) ?: run {
return WholeProjectPerformanceTest.PerFileTestResult(results, totalNs, listOf(AssertionError("PsiFile not found for $file")))
}
val errors = mutableListOf<Throwable>()
fun buildAllLightClasses(name: String, predicate: (KtClassOrObject) -> Boolean) {
val result = measureNanoTime {
try {
// Build light class by PsiFile
psiFile.acceptRecursively(object : KtVisitorVoid() {
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
if (!predicate(classOrObject)) return
val lightClass = classOrObject.toLightClass() as? KtLightClassForSourceDeclaration ?: return
Arrays.hashCode(lightClass.superTypes)
Arrays.hashCode(lightClass.fields)
Arrays.hashCode(lightClass.methods)
// Just to be sure: access types
lightClass.fields.map { it.type }.hashCode()
lightClass.methods.map { it.returnType }.hashCode()
lightClass.hashCode()
}
})
} catch (t: Throwable) {
t.printStackTrace()
errors += t
}
}
results[name] = result
totalNs += result
}
buildAllLightClasses("LightClasses_Top") {
it.containingDeclarationForPseudocode == null
}
buildAllLightClasses("LightClasses_Members") {
!it.isLocal && it.containingDeclarationForPseudocode is KtClassOrObject
}
return PerFileTestResult(results, totalNs, errors)
}
fun testUltraLightPerformance() {
Registry.get("kotlin.use.ultra.light.classes").setValue(true, testRootDisposable)
testWholeProjectPerformance()
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.perf
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.psi.KtFile
import kotlin.system.measureNanoTime
// abstract so that it doesn't run in CI until known issues (JDK absence in the test project, different module names in mangled methods) are addressed
abstract class WholeProjectUltraLightClassTest : WholeProjectPerformanceTest(), WholeProjectKotlinFileProvider {
override fun doTest(file: VirtualFile): PerFileTestResult {
val psiFile = file.toPsiFile(project) as? KtFile ?: run {
return WholeProjectPerformanceTest.PerFileTestResult(mapOf(), 0, listOf(AssertionError("PsiFile not found for $file")))
}
val errors = mutableListOf<Throwable>()
val elapsed = measureNanoTime {
try {
UltraLightChecker.checkClassEquivalence(psiFile)
} catch (t: Throwable) {
t.printStackTrace()
errors += t
}
}
return PerFileTestResult(mapOf("ultraLightEquivalence" to elapsed), elapsed, errors)
}
}