Reformat and clean up idea.actions.internal

This commit is contained in:
Nikolay Krasko
2019-04-18 16:26:16 +03:00
parent f9012cf637
commit 07ea0ffe16
12 changed files with 138 additions and 121 deletions
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.storage.CacheResetOnProcessCanceled
class CacheResetOnProcessCanceledToggleAction : ToggleAction() { class CacheResetOnProcessCanceledToggleAction : ToggleAction() {
override fun isSelected(e: AnActionEvent): Boolean = override fun isSelected(e: AnActionEvent): Boolean =
CacheResetOnProcessCanceled.enabled CacheResetOnProcessCanceled.enabled
override fun setSelected(e: AnActionEvent, state: Boolean) { override fun setSelected(e: AnActionEvent, state: Boolean) {
CacheResetOnProcessCanceled.enabled = state CacheResetOnProcessCanceled.enabled = state
@@ -42,20 +42,21 @@ class CheckComponentsUsageSearchAction : AnAction() {
val selectedKotlinFiles = selectedKotlinFiles(e).toList() val selectedKotlinFiles = selectedKotlinFiles(e).toList()
ProgressManager.getInstance().runProcessWithProgressSynchronously( ProgressManager.getInstance().runProcessWithProgressSynchronously(
{ {
runReadAction { process(selectedKotlinFiles, project) } runReadAction { process(selectedKotlinFiles, project) }
}, },
"Checking Data Classes", "Checking Data Classes",
true, true,
project) project
)
} }
private fun process(files: Collection<KtFile>, project: Project) { private fun process(files: Collection<KtFile>, project: Project) {
val dataClasses = files.asSequence() val dataClasses = files.asSequence()
.flatMap { it.declarations.asSequence() } .flatMap { it.declarations.asSequence() }
.filterIsInstance<KtClass>() .filterIsInstance<KtClass>()
.filter { it.isData() } .filter { it.isData() }
.toList() .toList()
val progressIndicator = ProgressManager.getInstance().progressIndicator val progressIndicator = ProgressManager.getInstance().progressIndicator
for ((i, dataClass) in dataClasses.withIndex()) { for ((i, dataClass) in dataClasses.withIndex()) {
@@ -67,24 +68,31 @@ class CheckComponentsUsageSearchAction : AnAction() {
try { try {
var smartRefsCount = 0 var smartRefsCount = 0
var goldRefsCount = 0 var goldRefsCount = 0
ProgressManager.getInstance().runProcess({ ProgressManager.getInstance().runProcess(
ExpressionsOfTypeProcessor.mode = ExpressionsOfTypeProcessor.Mode.ALWAYS_SMART {
ExpressionsOfTypeProcessor.mode =
ExpressionsOfTypeProcessor.Mode.ALWAYS_SMART
smartRefsCount = ReferencesSearch.search(parameter).findAll().size smartRefsCount = ReferencesSearch.search(parameter).findAll().size
ExpressionsOfTypeProcessor.mode = ExpressionsOfTypeProcessor.Mode.ALWAYS_PLAIN ExpressionsOfTypeProcessor.mode =
ExpressionsOfTypeProcessor.Mode.ALWAYS_PLAIN
goldRefsCount = ReferencesSearch.search(parameter).findAll().size goldRefsCount = ReferencesSearch.search(parameter).findAll().size
}, EmptyProgressIndicator()) }, EmptyProgressIndicator()
)
if (smartRefsCount != goldRefsCount) { if (smartRefsCount != goldRefsCount) {
SwingUtilities.invokeLater { SwingUtilities.invokeLater {
Messages.showInfoMessage(project, "Difference found for data class ${dataClass.fqName?.asString()}. Found $smartRefsCount usage(s) but $goldRefsCount expected", "Error") Messages.showInfoMessage(
project,
"Difference found for data class ${dataClass.fqName?.asString()}. Found $smartRefsCount usage(s) but $goldRefsCount expected",
"Error"
)
} }
return return
} }
} } finally {
finally {
ExpressionsOfTypeProcessor.mode = ExpressionsOfTypeProcessor.Mode.PLAIN_WHEN_NEEDED ExpressionsOfTypeProcessor.mode = ExpressionsOfTypeProcessor.Mode.PLAIN_WHEN_NEEDED
} }
} }
@@ -101,8 +109,7 @@ class CheckComponentsUsageSearchAction : AnAction() {
if (!ApplicationManager.getApplication().isInternal) { if (!ApplicationManager.getApplication().isInternal) {
e.presentation.isVisible = false e.presentation.isVisible = false
e.presentation.isEnabled = false e.presentation.isEnabled = false
} } else {
else {
e.presentation.isVisible = true e.presentation.isVisible = true
e.presentation.isEnabled = true e.presentation.isEnabled = true
} }
@@ -117,8 +124,8 @@ class CheckComponentsUsageSearchAction : AnAction() {
private fun allKotlinFiles(filesOrDirs: Array<VirtualFile>, project: Project): Sequence<KtFile> { private fun allKotlinFiles(filesOrDirs: Array<VirtualFile>, project: Project): Sequence<KtFile> {
val manager = PsiManager.getInstance(project) val manager = PsiManager.getInstance(project)
return allFiles(filesOrDirs) return allFiles(filesOrDirs)
.asSequence() .asSequence()
.mapNotNull { manager.findFile(it) as? KtFile } .mapNotNull { manager.findFile(it) as? KtFile }
} }
private fun allFiles(filesOrDirs: Array<VirtualFile>): Collection<VirtualFile> { private fun allFiles(filesOrDirs: Array<VirtualFile>): Collection<VirtualFile> {
@@ -21,10 +21,9 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.caches.resolve.*
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import java.awt.* import java.awt.Toolkit
import java.awt.datatransfer.StringSelection import java.awt.datatransfer.StringSelection
class CopyAsDiagnosticTestAction : AnAction() { class CopyAsDiagnosticTestAction : AnAction() {
@@ -39,7 +39,7 @@ class CopyKotlinProjectOverviewAction : AnAction() {
val clipboard = Toolkit.getDefaultToolkit().systemClipboard val clipboard = Toolkit.getDefaultToolkit().systemClipboard
clipboard.setContents(StringSelection(result), EmptyClipboardOwner.INSTANCE) clipboard.setContents(StringSelection(result), EmptyClipboardOwner.INSTANCE)
} catch (_: IndexNotReadyException) { } catch (_: IndexNotReadyException) {
DumbService.getInstance(project).showDumbModeNotification("Can't finish while indexing is in progress"); DumbService.getInstance(project).showDumbModeNotification("Can't finish while indexing is in progress")
} }
} }
@@ -19,7 +19,7 @@ import com.intellij.util.TimeoutUtil
import java.util.* import java.util.*
import kotlin.random.Random import kotlin.random.Random
class DumbModeTrembleAction: DumbAwareAction() { class DumbModeTrembleAction : DumbAwareAction() {
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return val project = e.project ?: return
@@ -48,17 +48,20 @@ import java.util.*
import javax.swing.SwingUtilities import javax.swing.SwingUtilities
class FindImplicitNothingAction : AnAction() { class FindImplicitNothingAction : AnAction() {
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.actions.internal.FindImplicitNothingAction") companion object {
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.actions.internal.FindImplicitNothingAction")
}
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val selectedFiles = selectedKotlinFiles(e).toList() val selectedFiles = selectedKotlinFiles(e).toList()
val project = CommonDataKeys.PROJECT.getData(e.dataContext)!! val project = CommonDataKeys.PROJECT.getData(e.dataContext)!!
ProgressManager.getInstance().runProcessWithProgressSynchronously( ProgressManager.getInstance().runProcessWithProgressSynchronously(
Runnable { find(selectedFiles, project) }, { find(selectedFiles, project) },
"Finding Implicit Nothing's", "Finding Implicit Nothing's",
true, true,
project) project
)
} }
private fun find(files: Collection<KtFile>, project: Project) { private fun find(files: Collection<KtFile>, project: Project) {
@@ -84,11 +87,9 @@ class FindImplicitNothingAction : AnAction() {
if (KotlinBuiltIns.isNothing(type) && !expression.hasExplicitNothing(bindingContext)) { //TODO: what about nullable Nothing? if (KotlinBuiltIns.isNothing(type) && !expression.hasExplicitNothing(bindingContext)) { //TODO: what about nullable Nothing?
found.add(expression) found.add(expression)
} }
} } catch (e: ProcessCanceledException) {
catch(e: ProcessCanceledException) {
throw e throw e
} } catch (t: Throwable) { // do not stop on internal error
catch(t: Throwable) { // do not stop on internal error
LOG.error(t) LOG.error(t)
} }
} }
@@ -103,14 +104,14 @@ class FindImplicitNothingAction : AnAction() {
val presentation = UsageViewPresentation() val presentation = UsageViewPresentation()
presentation.tabName = "Implicit Nothing's" presentation.tabName = "Implicit Nothing's"
UsageViewManager.getInstance(project).showUsages(arrayOf<UsageTarget>(), usages, presentation) UsageViewManager.getInstance(project).showUsages(arrayOf<UsageTarget>(), usages, presentation)
} } else {
else {
Messages.showInfoMessage(project, "Not found in ${files.size} file(s)", "Not Found") Messages.showInfoMessage(project, "Not found in ${files.size} file(s)", "Not Found")
} }
} }
} }
private fun KtExpression.hasExplicitNothing(bindingContext: BindingContext): Boolean { private fun KtExpression.hasExplicitNothing(bindingContext: BindingContext): Boolean {
@Suppress("MoveVariableDeclarationIntoWhen")
val callee = getCalleeExpressionIfAny() ?: return false val callee = getCalleeExpressionIfAny() ?: return false
when (callee) { when (callee) {
is KtSimpleNameExpression -> { is KtSimpleNameExpression -> {
@@ -130,7 +131,7 @@ class FindImplicitNothingAction : AnAction() {
private fun KotlinType.isNothingOrNothingFunctionType(): Boolean { private fun KotlinType.isNothingOrNothingFunctionType(): Boolean {
return KotlinBuiltIns.isNothing(this) || return KotlinBuiltIns.isNothing(this) ||
(isFunctionType && this.getReturnTypeFromFunctionType().isNothingOrNothingFunctionType()) (isFunctionType && this.getReturnTypeFromFunctionType().isNothingOrNothingFunctionType())
} }
override fun update(e: AnActionEvent) { override fun update(e: AnActionEvent) {
@@ -147,8 +148,8 @@ class FindImplicitNothingAction : AnAction() {
private fun allKotlinFiles(filesOrDirs: Array<VirtualFile>, project: Project): Sequence<KtFile> { private fun allKotlinFiles(filesOrDirs: Array<VirtualFile>, project: Project): Sequence<KtFile> {
val manager = PsiManager.getInstance(project) val manager = PsiManager.getInstance(project)
return allFiles(filesOrDirs) return allFiles(filesOrDirs)
.asSequence() .asSequence()
.mapNotNull { manager.findFile(it) as? KtFile } .mapNotNull { manager.findFile(it) as? KtFile }
} }
private fun allFiles(filesOrDirs: Array<VirtualFile>): Collection<VirtualFile> { private fun allFiles(filesOrDirs: Array<VirtualFile>): Collection<VirtualFile> {
@@ -47,21 +47,21 @@ class SearchNotPropertyCandidatesAction : AnAction() {
val packageDesc = try { val packageDesc = try {
val fqName = FqName.fromSegments(result!!.split('.')) val fqName = FqName.fromSegments(result!!.split('.'))
desc.getPackage(fqName) desc.getPackage(fqName)
} } catch (e: Exception) {
catch (e: Exception) {
return return
} }
ProgressManager.getInstance().runProcessWithProgressSynchronously( ProgressManager.getInstance().runProcessWithProgressSynchronously(
{ {
runReadAction { runReadAction {
ProgressManager.getInstance().progressIndicator!!.isIndeterminate = true ProgressManager.getInstance().progressIndicator!!.isIndeterminate = true
processAllDescriptors(packageDesc, project) processAllDescriptors(packageDesc, project)
} }
}, },
"Searching for Not Property candidates", "Searching for Not Property candidates",
true, true,
project) project
)
} }
@@ -84,7 +84,8 @@ class SearchNotPropertyCandidatesAction : AnAction() {
val name = desc.fqNameUnsafe.shortName().asString() val name = desc.fqNameUnsafe.shortName().asString()
if (name.length > 3 && if (name.length > 3 &&
((name.startsWith("get") && desc.valueParameters.isEmpty() && desc.returnType != null) || ((name.startsWith("get") && desc.valueParameters.isEmpty() && desc.returnType != null) ||
(name.startsWith("set") && desc.valueParameters.size == 1))) { (name.startsWith("set") && desc.valueParameters.size == 1))
) {
if (desc in matchedDescriptors) return if (desc in matchedDescriptors) return
matchedDescriptors += desc matchedDescriptors += desc
} }
@@ -116,22 +117,22 @@ class SearchNotPropertyCandidatesAction : AnAction() {
var i = 0 var i = 0
resultDescriptors.forEach { descriptor -> resultDescriptors.forEach { functionDescriptor ->
progress("Step 2: ${i++} of ${resultDescriptors.size}", "$descriptor") progress("Step 2: ${i++} of ${resultDescriptors.size}", "$functionDescriptor")
val source = DescriptorToSourceUtilsIde.getAllDeclarations(project, descriptor) val source = DescriptorToSourceUtilsIde.getAllDeclarations(project, functionDescriptor)
.filterIsInstance<PsiMethod>() .filterIsInstance<PsiMethod>()
.firstOrNull() ?: return@forEach .firstOrNull() ?: return@forEach
val abstract = source.modifierList.hasModifierProperty(PsiModifier.ABSTRACT) val abstract = source.modifierList.hasModifierProperty(PsiModifier.ABSTRACT)
if (!abstract) { if (!abstract) {
if (!source.isTrivial()) { if (!source.isTrivial()) {
descriptorToPsiBinding[descriptor] = source descriptorToPsiBinding[functionDescriptor] = source
} }
} }
} }
val nonTrivial = mutableSetOf<FunctionDescriptor>() val nonTrivial = mutableSetOf<FunctionDescriptor>()
i = 0 i = 0
descriptorToPsiBinding.forEach { t, u -> descriptorToPsiBinding.forEach { (t, u) ->
progress("Step 3: ${i++} of ${descriptorToPsiBinding.size}", "$t") progress("Step 3: ${i++} of ${descriptorToPsiBinding.size}", "$t")
val descriptors = t.overriddenDescriptors val descriptors = t.overriddenDescriptors
var impl = false var impl = false
@@ -155,8 +156,7 @@ class SearchNotPropertyCandidatesAction : AnAction() {
if (!ApplicationManager.getApplication().isInternal) { if (!ApplicationManager.getApplication().isInternal) {
e.presentation.isVisible = false e.presentation.isVisible = false
e.presentation.isEnabled = false e.presentation.isEnabled = false
} } else {
else {
e.presentation.isVisible = true e.presentation.isVisible = true
e.presentation.isEnabled = e.getData(CommonDataKeys.PSI_FILE) is KtFile e.presentation.isEnabled = e.getData(CommonDataKeys.PSI_FILE) is KtFile
} }
@@ -22,7 +22,8 @@ import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.kotlin.utils.WrappedValues import org.jetbrains.kotlin.utils.WrappedValues
class StoredExceptionsThrowToggleAction : ToggleAction("Internal: toggle throwing cached PCE", "Rethrow stored PCE as a new runtime exception", null) { class StoredExceptionsThrowToggleAction :
ToggleAction("Internal: toggle throwing cached PCE", "Rethrow stored PCE as a new runtime exception", null) {
override fun isSelected(e: AnActionEvent): Boolean { override fun isSelected(e: AnActionEvent): Boolean {
return WrappedValues.throwWrappedProcessCanceledException return WrappedValues.throwWrappedProcessCanceledException
} }
@@ -64,20 +64,23 @@ abstract class AbstractCompletionBenchmarkAction : AnAction() {
} }
} }
internal abstract fun createBenchmarkScenario(project: Project, benchmarkSink: CompletionBenchmarkSink.Impl): AbstractCompletionBenchmarkScenario? internal abstract fun createBenchmarkScenario(
project: Project,
benchmarkSink: CompletionBenchmarkSink.Impl
): AbstractCompletionBenchmarkScenario?
companion object { companion object {
fun showPopup(project: Project, text: String) { fun showPopup(project: Project, text: String) {
val statusBar = WindowManager.getInstance().getStatusBar(project) val statusBar = WindowManager.getInstance().getStatusBar(project)
JBPopupFactory.getInstance() JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder(text, MessageType.ERROR, null) .createHtmlTextBalloonBuilder(text, MessageType.ERROR, null)
.setFadeoutTime(5000) .setFadeoutTime(5000)
.createBalloon().showInCenterOf(statusBar.component) .createBalloon().showInCenterOf(statusBar.component)
} }
internal fun <T> List<T>.randomElement(random: Random): T? = if (this.isNotEmpty()) this[random.nextInt(this.size)] else null internal fun <T> List<T>.randomElement(random: Random): T? = if (this.isNotEmpty()) this[random.nextInt(this.size)] else null
internal fun <T> Array<T>.randomElement(random: Random): T? = if (this.isNotEmpty()) this[random.nextInt(this.size)] else null internal fun <T : Any> List<T>.shuffledSequence(random: Random): Sequence<T> =
internal fun <T : Any> List<T>.shuffledSequence(random: Random): Sequence<T> = generateSequence { this.randomElement(random) }.distinct() generateSequence { this.randomElement(random) }.distinct()
internal fun collectSuitableKotlinFiles(project: Project, filePredicate: (KtFile) -> Boolean): MutableList<KtFile> { internal fun collectSuitableKotlinFiles(project: Project, filePredicate: (KtFile) -> Boolean): MutableList<KtFile> {
val scope = object : DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) { val scope = object : DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
@@ -93,12 +96,12 @@ abstract class AbstractCompletionBenchmarkAction : AnAction() {
val kotlinVFiles = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, scope) val kotlinVFiles = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, scope)
return kotlinVFiles return kotlinVFiles
.asSequence() .asSequence()
.mapNotNull { vfile -> (vfile.toPsiFile(project) as? KtFile) } .mapNotNull { vfile -> (vfile.toPsiFile(project) as? KtFile) }
.filterTo(mutableListOf()) { it.isUsableForBenchmark() && filePredicate(it) } .filterTo(mutableListOf()) { it.isUsableForBenchmark() && filePredicate(it) }
} }
internal fun JPanel.addBoxWithLabel(tooltip: String, label: String = tooltip + ":", default: String, i: Int): JBTextField { internal fun JPanel.addBoxWithLabel(tooltip: String, label: String = "$tooltip:", default: String, i: Int): JBTextField {
this.add(JBLabel(label), GridConstraints().apply { row = i; column = 0 }) this.add(JBLabel(label), GridConstraints().apply { row = i; column = 0 })
val textField = JBTextField().apply { val textField = JBTextField().apply {
text = default text = default
@@ -115,8 +118,9 @@ abstract class AbstractCompletionBenchmarkAction : AnAction() {
} }
internal abstract class AbstractCompletionBenchmarkScenario( internal abstract class AbstractCompletionBenchmarkScenario(
val project: Project, val benchmarkSink: CompletionBenchmarkSink.Impl, val project: Project, private val benchmarkSink: CompletionBenchmarkSink.Impl,
val random: Random = Random(), val timeout: Long = 15000) { val random: Random = Random(), private val timeout: Long = 15000
) {
sealed class Result { sealed class Result {
@@ -148,8 +152,8 @@ internal abstract class AbstractCompletionBenchmarkScenario(
protected suspend fun typeAtOffsetAndGetResult(text: String, offset: Int, file: KtFile): Result { protected suspend fun typeAtOffsetAndGetResult(text: String, offset: Int, file: KtFile): Result {
NavigationUtil.openFileWithPsiElement(file.navigationElement, false, true) NavigationUtil.openFileWithPsiElement(file.navigationElement, false, true)
val document = PsiDocumentManager.getInstance(project).getDocument(file) ?: val document =
return Result.ErrorResult("${file.virtualFile.path}:O$offset") PsiDocumentManager.getInstance(project).getDocument(file) ?: return Result.ErrorResult("${file.virtualFile.path}:O$offset")
val location = "${file.virtualFile.path}:${document.getLineNumber(offset)}" val location = "${file.virtualFile.path}:${document.getLineNumber(offset)}"
@@ -173,8 +177,7 @@ internal abstract class AbstractCompletionBenchmarkScenario(
val result = try { val result = try {
withTimeout(timeout) { collectResult(file, location) } withTimeout(timeout) { collectResult(file, location) }
} } catch (_: CancellationException) {
catch (_: CancellationException) {
Result.ErrorResult(location) Result.ErrorResult(location)
} }
@@ -189,7 +192,7 @@ internal abstract class AbstractCompletionBenchmarkScenario(
return result return result
} }
protected suspend fun collectResult(file: KtFile, location: String): Result { private suspend fun collectResult(file: KtFile, location: String): Result {
val results = benchmarkSink.channel.receive() val results = benchmarkSink.channel.receive()
return Result.SuccessResult(file.getLineCount(), location, results.firstFlush, results.full) return Result.SuccessResult(file.getLineCount(), location, results.firstFlush, results.full)
} }
@@ -56,7 +56,7 @@ class HighlightingBenchmarkAction : AnAction() {
fun collectFiles(): List<KtFile>? { fun collectFiles(): List<KtFile>? {
val ktFiles = collectSuitableKotlinFiles(project, { it.getLineCount() >= settings.lines }) val ktFiles = collectSuitableKotlinFiles(project) { it.getLineCount() >= settings.lines }
if (ktFiles.size < settings.files) { if (ktFiles.size < settings.files) {
AbstractCompletionBenchmarkAction.showPopup(project, "Number of attempts > then files in project, ${ktFiles.size}") AbstractCompletionBenchmarkAction.showPopup(project, "Number of attempts > then files in project, ${ktFiles.size}")
@@ -81,15 +81,14 @@ class HighlightingBenchmarkAction : AnAction() {
try { try {
delay(100) delay(100)
ktFiles ktFiles
.shuffledSequence(random) .shuffledSequence(random)
.take(settings.files) .take(settings.files)
.forEach { file -> .forEach { file ->
results += openFileAndMeasureTimeToHighlight(file, project, finishListener) results += openFileAndMeasureTimeToHighlight(file, project, finishListener)
} }
saveResults(results, project) saveResults(results, project)
} } finally {
finally {
connection.disconnect() connection.disconnect()
finishListener.channel.close() finishListener.channel.close()
} }
@@ -188,10 +187,10 @@ class HighlightingBenchmarkAction : AnAction() {
val severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project) val severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project)
val maxSeverity = model.allHighlighters val maxSeverity = model.allHighlighters
.mapNotNull { highlighter -> .mapNotNull { highlighter ->
val info = highlighter.errorStripeTooltip as? HighlightInfo ?: return@mapNotNull null val info = highlighter.errorStripeTooltip as? HighlightInfo ?: return@mapNotNull null
info.severity info.severity
}.maxWith(Comparator { o1, o2 -> severityRegistrar.compare(o1, o2) }) }.maxWith(Comparator { o1, o2 -> severityRegistrar.compare(o1, o2) })
return Result.Success(location, lines, analysisTime, maxSeverity?.myName ?: "clean") return Result.Success(location, lines, analysisTime, maxSeverity?.myName ?: "clean")
} }
@@ -34,7 +34,10 @@ import kotlin.properties.Delegates
class LocalCompletionBenchmarkAction : AbstractCompletionBenchmarkAction() { class LocalCompletionBenchmarkAction : AbstractCompletionBenchmarkAction() {
override fun createBenchmarkScenario(project: Project, benchmarkSink: CompletionBenchmarkSink.Impl): AbstractCompletionBenchmarkScenario? { override fun createBenchmarkScenario(
project: Project,
benchmarkSink: CompletionBenchmarkSink.Impl
): AbstractCompletionBenchmarkScenario? {
val settings = showSettingsDialog() ?: return null val settings = showSettingsDialog() ?: return null
@@ -84,27 +87,28 @@ class LocalCompletionBenchmarkAction : AbstractCompletionBenchmarkAction() {
dialogBuilder.centerPanel(jPanel) dialogBuilder.centerPanel(jPanel)
if (!dialogBuilder.showAndGet()) return null if (!dialogBuilder.showAndGet()) return null
return Settings(cSeed.text.toLong(), return Settings(
cLines.text.toInt(), cSeed.text.toLong(),
cFiles.text.toInt(), cLines.text.toInt(),
cFunctions.text.toInt()) cFiles.text.toInt(),
cFunctions.text.toInt()
)
} }
} }
internal class LocalCompletionBenchmarkScenario( internal class LocalCompletionBenchmarkScenario(
val files: List<KtFile>, val files: List<KtFile>,
val settings: LocalCompletionBenchmarkAction.Settings, val settings: LocalCompletionBenchmarkAction.Settings,
project: Project, benchmarkSink: CompletionBenchmarkSink.Impl, project: Project, benchmarkSink: CompletionBenchmarkSink.Impl,
random: Random) : AbstractCompletionBenchmarkScenario(project, benchmarkSink, random) { random: Random
suspend override fun doBenchmark() { ) : AbstractCompletionBenchmarkScenario(project, benchmarkSink, random) {
override suspend fun doBenchmark() {
val allResults = mutableListOf<Result>() val allResults = mutableListOf<Result>()
files.forEach { file -> files.forEach { file ->
val functions = file.collectDescendantsOfType<KtFunction> { it.hasBlockBody() && it.bodyExpression != null }.toMutableList() val functions = file.collectDescendantsOfType<KtFunction> { it.hasBlockBody() && it.bodyExpression != null }.toMutableList()
val randomFunctions = generateSequence { functions.randomElement(random).also { functions.remove(it) } } val randomFunctions = generateSequence { functions.randomElement(random).also { functions.remove(it) } }
randomFunctions.take(settings.functions).forEach { randomFunctions.take(settings.functions).forEach { function ->
function ->
val offset = function.bodyExpression!!.endOffset - 1 val offset = function.bodyExpression!!.endOffset - 1
allResults += typeAtOffsetAndGetResult("listOf(1).", offset, file) allResults += typeAtOffsetAndGetResult("listOf(1).", offset, file)
} }
@@ -16,14 +16,11 @@
package org.jetbrains.kotlin.idea.actions.internal.benchmark package org.jetbrains.kotlin.idea.actions.internal.benchmark
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogBuilder import com.intellij.openapi.ui.DialogBuilder
import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.PsiWhiteSpace
import com.intellij.ui.components.JBLabel
import com.intellij.ui.components.JBPanel import com.intellij.ui.components.JBPanel
import com.intellij.ui.components.JBTextField import com.intellij.ui.components.JBTextField
import com.intellij.uiDesigner.core.GridConstraints
import com.intellij.uiDesigner.core.GridLayoutManager import com.intellij.uiDesigner.core.GridLayoutManager
import org.jetbrains.kotlin.idea.actions.internal.benchmark.AbstractCompletionBenchmarkAction.Companion.randomElement import org.jetbrains.kotlin.idea.actions.internal.benchmark.AbstractCompletionBenchmarkAction.Companion.randomElement
import org.jetbrains.kotlin.idea.completion.CompletionBenchmarkSink import org.jetbrains.kotlin.idea.completion.CompletionBenchmarkSink
@@ -39,7 +36,10 @@ import kotlin.properties.Delegates
class TopLevelCompletionBenchmarkAction : AbstractCompletionBenchmarkAction() { class TopLevelCompletionBenchmarkAction : AbstractCompletionBenchmarkAction() {
override fun createBenchmarkScenario(project: Project, benchmarkSink: CompletionBenchmarkSink.Impl): AbstractCompletionBenchmarkScenario? { override fun createBenchmarkScenario(
project: Project,
benchmarkSink: CompletionBenchmarkSink.Impl
): AbstractCompletionBenchmarkScenario? {
val settings = showSettingsDialog() ?: return null val settings = showSettingsDialog() ?: return null
@@ -85,19 +85,22 @@ class TopLevelCompletionBenchmarkAction : AbstractCompletionBenchmarkAction() {
dialogBuilder.centerPanel(jPanel) dialogBuilder.centerPanel(jPanel)
if (!dialogBuilder.showAndGet()) return null if (!dialogBuilder.showAndGet()) return null
return Settings(cSeed.text.toLong(), return Settings(
cLines.text.toInt(), cSeed.text.toLong(),
cFiles.text.toInt()) cLines.text.toInt(),
cFiles.text.toInt()
)
} }
} }
internal class TopLevelCompletionBenchmarkScenario( internal class TopLevelCompletionBenchmarkScenario(
val files: List<KtFile>, val files: List<KtFile>,
val settings: TopLevelCompletionBenchmarkAction.Settings, val settings: TopLevelCompletionBenchmarkAction.Settings,
project: Project, benchmarkSink: CompletionBenchmarkSink.Impl, project: Project, benchmarkSink: CompletionBenchmarkSink.Impl,
random: Random) : AbstractCompletionBenchmarkScenario(project, benchmarkSink, random) { random: Random
suspend override fun doBenchmark() { ) : AbstractCompletionBenchmarkScenario(project, benchmarkSink, random) {
override suspend fun doBenchmark() {
val allResults = mutableListOf<Result>() val allResults = mutableListOf<Result>()
files.forEach { file -> files.forEach { file ->
@@ -108,8 +111,8 @@ internal class TopLevelCompletionBenchmarkScenario(
} }
run { run {
val classes = file.collectDescendantsOfType<KtClassOrObject> { it.getBody() != null } val classes = file.collectDescendantsOfType<KtClassOrObject> { it.body != null }
val body = classes.randomElement(random)?.getBody() ?: return@run val body = classes.randomElement(random)?.body ?: return@run
val offset = body.endOffset - 1 val offset = body.endOffset - 1
allResults += typeAtOffsetAndGetResult("fun Str", offset, file) allResults += typeAtOffsetAndGetResult("fun Str", offset, file)
} }