New J2K: add FUS statistics for J2K conversions

This commit is contained in:
Ilya Kirillov
2019-06-17 15:08:25 +03:00
committed by Anton Yalyshev
parent cf885789ff
commit 01c866632d
4 changed files with 119 additions and 37 deletions
@@ -36,6 +36,7 @@ import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.ex.MessagesEx import com.intellij.openapi.ui.ex.MessagesEx
import com.intellij.openapi.ui.popup.JBPopupFactory import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileVisitor import com.intellij.openapi.vfs.VirtualFileVisitor
@@ -52,13 +53,16 @@ import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.isRunningInCidrIde import org.jetbrains.kotlin.idea.util.isRunningInCidrIde
import org.jetbrains.kotlin.j2k.ConversionType
import org.jetbrains.kotlin.j2k.ConverterSettings import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.FilesResult import org.jetbrains.kotlin.j2k.FilesResult
import org.jetbrains.kotlin.j2k.logJ2kConversionStatistics
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.UserDataProperty import org.jetbrains.kotlin.psi.UserDataProperty
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
import kotlin.system.measureTimeMillis
var VirtualFile.pathBeforeJ2K: String? by UserDataProperty(Key.create<String>("PATH_BEFORE_J2K_CONVERSION")) var VirtualFile.pathBeforeJ2K: String? by UserDataProperty(Key.create<String>("PATH_BEFORE_J2K_CONVERSION"))
@@ -129,9 +133,23 @@ class JavaToKotlinAction : AnAction() {
) )
} }
fun convertWithStatistics() {
val conversionTime = measureTimeMillis {
convert()
}
val linesCount = javaFiles.sumBy { StringUtil.getLineBreakCount(it.text) }
logJ2kConversionStatistics(
ConversionType.FILES,
JavaToKotlinConverterFactory.isNewJ2k,
conversionTime,
linesCount,
javaFiles.size
)
}
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously( if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
::convert, ::convertWithStatistics,
title, title,
true, true,
project project
@@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Ref import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.ThrowableComputable import com.intellij.openapi.util.ThrowableComputable
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.actions.JavaToKotlinAction import org.jetbrains.kotlin.idea.actions.JavaToKotlinAction
@@ -43,10 +44,7 @@ import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.util.module import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.j2k.AfterConversionPass import org.jetbrains.kotlin.j2k.*
import org.jetbrains.kotlin.j2k.ConverterContext
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.ParseContext
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -57,6 +55,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import java.awt.datatransfer.Transferable import java.awt.datatransfer.Transferable
import java.util.* import java.util.*
import kotlin.system.measureTimeMillis
class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferableData>() { class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferableData>() {
private val LOG = Logger.getInstance(ConvertJavaCopyPasteProcessor::class.java) private val LOG = Logger.getInstance(ConvertJavaCopyPasteProcessor::class.java)
@@ -98,8 +97,9 @@ class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferab
val converterContext: ConverterContext? val converterContext: ConverterContext?
) )
val dataForConversion = DataForConversion.prepare(data, project)
fun doConversion(): Result { fun doConversion(): Result {
val dataForConversion = DataForConversion.prepare(data, project)
val result = dataForConversion.elementsAndTexts.convertCodeToKotlin(project, targetModule) val result = dataForConversion.elementsAndTexts.convertCodeToKotlin(project, targetModule)
val referenceData = buildReferenceData(result.text, result.parseContext, dataForConversion.importsAndPackage, targetFile) val referenceData = buildReferenceData(result.text, result.parseContext, dataForConversion.importsAndPackage, targetFile)
val text = if (result.textChanged) result.text else null val text = if (result.textChanged) result.text else null
@@ -144,7 +144,7 @@ class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferab
if (doConversionAndInsertImportsIfUnchanged()) return if (doConversionAndInsertImportsIfUnchanged()) return
} }
if (confirmConvertJavaOnPaste(project, isPlainText = false)) { fun convert() {
if (conversionResult == null) { if (conversionResult == null) {
if (doConversionAndInsertImportsIfUnchanged()) return if (doConversionAndInsertImportsIfUnchanged()) return
} }
@@ -152,14 +152,14 @@ class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferab
text!! // otherwise we should get true from doConversionAndInsertImportsIfUnchanged and return above text!! // otherwise we should get true from doConversionAndInsertImportsIfUnchanged and return above
val boundsAfterReplace = val boundsAfterReplace =
runWriteAction { runWriteAction {
val startOffset = bounds.startOffset val startOffset = bounds.startOffset
document.replaceString(startOffset, bounds.endOffset, text) document.replaceString(startOffset, bounds.endOffset, text)
val endOffsetAfterCopy = startOffset + text.length val endOffsetAfterCopy = startOffset + text.length
editor.caretModel.moveToOffset(endOffsetAfterCopy) editor.caretModel.moveToOffset(endOffsetAfterCopy)
TextRange(startOffset, endOffsetAfterCopy) TextRange(startOffset, endOffsetAfterCopy)
} }
val newBounds = insertImports(boundsAfterReplace, referenceData, explicitImports) val newBounds = insertImports(boundsAfterReplace, referenceData, explicitImports)
@@ -168,6 +168,19 @@ class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferab
conversionPerformed = true conversionPerformed = true
} }
if (confirmConvertJavaOnPaste(project, isPlainText = false)) {
val conversionTime = measureTimeMillis {
convert()
}
logJ2kConversionStatistics(
ConversionType.PSI_EXPRESSION,
JavaToKotlinConverterFactory.isNewJ2k,
conversionTime,
dataForConversion.elementsAndTexts.linesCount(),
filesCount = 1
)
}
} }
private fun buildReferenceData(text: String, parseContext: ParseContext, importsAndPackage: String, targetFile: KtFile): Collection<KotlinReferenceData> { private fun buildReferenceData(text: String, parseContext: ParseContext, importsAndPackage: String, targetFile: KtFile): Collection<KotlinReferenceData> {
@@ -304,6 +317,11 @@ internal fun confirmConvertJavaOnPaste(project: Project, isPlainText: Boolean):
} }
fun ElementAndTextList.linesCount() =
toList()
.filterIsInstance<PsiElement>()
.sumBy { StringUtil.getLineBreakCount(it.text) }
fun runPostProcessing(project: Project, file: KtFile, bounds: TextRange?, converterContext: ConverterContext?) { fun runPostProcessing(project: Project, file: KtFile, bounds: TextRange?, converterContext: ConverterContext?) {
val postProcessor = JavaToKotlinConverterFactory.createPostProcessor(formatCode = true) val postProcessor = JavaToKotlinConverterFactory.createPostProcessor(formatCode = true)
if (JavaToKotlinConverterFactory.isNewJ2k) { if (JavaToKotlinConverterFactory.isNewJ2k) {
@@ -28,17 +28,17 @@ import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Ref import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.*
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiFileFactory
import com.intellij.util.LocalTimeCounter import com.intellij.util.LocalTimeCounter
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.editor.KotlinEditorOptions import org.jetbrains.kotlin.idea.editor.KotlinEditorOptions
import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory
import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.util.projectStructure.module import org.jetbrains.kotlin.idea.util.projectStructure.module
import org.jetbrains.kotlin.j2k.ConversionType
import org.jetbrains.kotlin.j2k.logJ2kConversionStatistics
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.Transferable import java.awt.datatransfer.Transferable
import kotlin.system.measureTimeMillis
class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferableData>() { class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferableData>() {
private val LOG = Logger.getInstance(ConvertTextJavaCopyPasteProcessor::class.java) private val LOG = Logger.getInstance(ConvertTextJavaCopyPasteProcessor::class.java)
@@ -107,33 +108,45 @@ class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransf
val copiedJavaCode = prepareCopiedJavaCodeByContext(text, conversionContext, pasteTarget) val copiedJavaCode = prepareCopiedJavaCodeByContext(text, conversionContext, pasteTarget)
val dataForConversion = DataForConversion.prepare(copiedJavaCode, project) val dataForConversion = DataForConversion.prepare(copiedJavaCode, project)
val additionalImports = dataForConversion.tryResolveImports(targetFile) fun convert() {
var convertedImportsText = additionalImports.convertCodeToKotlin(project, targetModule).text val additionalImports = dataForConversion.tryResolveImports(targetFile)
var convertedImportsText = additionalImports.convertCodeToKotlin(project, targetModule).text
val convertedResult = dataForConversion.convertCodeToKotlin(project, targetModule) val convertedResult = dataForConversion.convertCodeToKotlin(project, targetModule)
val convertedText = convertedResult.text val convertedText = convertedResult.text
val newBounds = runWriteAction { val newBounds = runWriteAction {
val importsInsertOffset = targetFile.importList?.endOffset ?: 0
if (targetFile.importDirectives.isEmpty() && importsInsertOffset > 0)
convertedImportsText = "\n" + convertedImportsText
if (convertedImportsText.isNotBlank())
editor.document.insertString(importsInsertOffset, convertedImportsText)
val importsInsertOffset = targetFile.importList?.endOffset ?: 0 val startOffset = bounds.startOffset
if (targetFile.importDirectives.isEmpty() && importsInsertOffset > 0) editor.document.replaceString(startOffset, bounds.endOffset, convertedText)
convertedImportsText = "\n" + convertedImportsText
if (convertedImportsText.isNotBlank())
editor.document.insertString(importsInsertOffset, convertedImportsText)
val startOffset = bounds.startOffset val endOffsetAfterCopy = startOffset + convertedText.length
editor.document.replaceString(startOffset, bounds.endOffset, convertedText) editor.caretModel.moveToOffset(endOffsetAfterCopy)
val endOffsetAfterCopy = startOffset + convertedText.length TextRange(startOffset, startOffset + convertedText.length)
editor.caretModel.moveToOffset(endOffsetAfterCopy) }
TextRange(startOffset, startOffset + convertedText.length) psiDocumentManager.commitAllDocuments()
runPostProcessing(project, targetFile, newBounds, convertedResult.converterContext)
conversionPerformed = true
} }
psiDocumentManager.commitAllDocuments() val conversionTime = measureTimeMillis {
runPostProcessing(project, targetFile, newBounds, convertedResult.converterContext) convert()
}
conversionPerformed = true logJ2kConversionStatistics(
ConversionType.TEXT_EXPRESSION,
JavaToKotlinConverterFactory.isNewJ2k,
conversionTime,
dataForConversion.elementsAndTexts.linesCount(),
filesCount = 1
)
} }
private fun DataForConversion.convertCodeToKotlin(project: Project, targetModule: Module?): ConversionResult { private fun DataForConversion.convertCodeToKotlin(project: Project, targetModule: Module?): ConversionResult {
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.j2k
import org.jetbrains.kotlin.idea.statistics.FUSEventGroups
import org.jetbrains.kotlin.idea.statistics.KotlinFUSLogger
enum class ConversionType(val text: String) {
FILES("Files"), PSI_EXPRESSION("PSI expression"), TEXT_EXPRESSION("Text expression");
}
fun logJ2kConversionStatistics(
type: ConversionType,
isNewJ2k: Boolean,
conversionTime: Long,
linesCount: Int,
filesCount: Int
) {
val data = mapOf(
"Lines count" to linesCount,
"Files count" to filesCount,
"Is new J2K" to isNewJ2k,
"Time" to conversionTime
).map { (key, value) ->
key to value.toString()
}.toMap()
KotlinFUSLogger.log(FUSEventGroups.J2K, type.text, data)
}