Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.intellij.psi.PsiCodeBlock
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpressionStatement
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiWhiteSpace
Expand All @@ -28,7 +29,7 @@ class LogInserterService(private val project: Project) {
logTag: String,
framework: LoggingSettings.LoggingFramework = LoggingSettings.LoggingFramework.PRINTLN,
) {
val strategy = LogStrategyFactory.getStrategy(framework)
val strategy = LogStrategyFactory.getStrategy(framework, LoggingSettings.getInstance(project).state)
val factory = KtPsiFactory(project)
val assignments =
PsiTreeUtil.findChildrenOfType(
Expand Down Expand Up @@ -72,7 +73,7 @@ class LogInserterService(private val project: Project) {
logTag: String,
framework: LoggingSettings.LoggingFramework = LoggingSettings.LoggingFramework.PRINTLN,
) {
val strategy = LogStrategyFactory.getStrategy(framework)
val strategy = LogStrategyFactory.getStrategy(framework, LoggingSettings.getInstance(project).state)
val factory = KtPsiFactory(project)
val functions =
PsiTreeUtil.findChildrenOfType(
Expand Down Expand Up @@ -114,7 +115,7 @@ class LogInserterService(private val project: Project) {
logTag: String,
framework: LoggingSettings.LoggingFramework = LoggingSettings.LoggingFramework.PRINTLN,
) {
val strategy = LogStrategyFactory.getStrategy(framework)
val strategy = LogStrategyFactory.getStrategy(framework, LoggingSettings.getInstance(project).state)
val factory = JavaPsiFacade.getElementFactory(project)
val methods =
PsiTreeUtil.findChildrenOfType(searchScope, PsiMethod::class.java)
Expand Down Expand Up @@ -146,7 +147,7 @@ class LogInserterService(private val project: Project) {
logTag: String,
framework: LoggingSettings.LoggingFramework = LoggingSettings.LoggingFramework.PRINTLN,
) {
val strategy = LogStrategyFactory.getStrategy(framework)
val strategy = LogStrategyFactory.getStrategy(framework, LoggingSettings.getInstance(project).state)
val factory = JavaPsiFacade.getElementFactory(project)
val assignments =
PsiTreeUtil.findChildrenOfType(
Expand Down Expand Up @@ -205,17 +206,28 @@ class LogInserterService(private val project: Project) {

val psiClass =
JavaPsiFacade.getInstance(project)
.findClass(importPath, file.resolveScope) ?: return
val importStatement = factory.createImportStatement(psiClass)
importList.add(importStatement)
.findClass(importPath, file.resolveScope)
if (psiClass != null) {
val importStatement = factory.createImportStatement(psiClass)
importList.add(importStatement)
} else {
val tempFile =
PsiFileFactory.getInstance(project).createFileFromText(
"Dummy.java",
com.intellij.lang.java.JavaLanguage.INSTANCE,
"import $importPath;\nclass Dummy {}",
) as PsiJavaFile
val importStatement = tempFile.importList?.allImportStatements?.firstOrNull() ?: return
importList.add(importStatement)
}
}

fun removeLogs(
searchScope: PsiElement,
logTag: String,
framework: LoggingSettings.LoggingFramework = LoggingSettings.LoggingFramework.PRINTLN,
) {
val strategy = LogStrategyFactory.getStrategy(framework)
val strategy = LogStrategyFactory.getStrategy(framework, LoggingSettings.getInstance(project).state)
val patterns = strategy.getRemovalPatterns(logTag)

if (searchScope.containingFile is PsiJavaFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,54 @@ class NapierStrategy : LogStrategy {
override fun getJavaImport(): String? = null
}

class CustomLogStrategy(
private val kotlinTemplate: String,
private val javaTemplate: String,
private val importPath: String?,
) : LogStrategy {
override fun createKotlinLog(
factory: KtPsiFactory,
tag: String,
message: String,
): String = kotlinTemplate.replace("{tag}", tag).replace("{message}", message)

override fun createJavaLog(
factory: PsiElementFactory,
tag: String,
message: String,
): String {
val tagReplaced = javaTemplate.replace("{tag}", tag)
return if (message.endsWith(")")) {
// Method-style: message ends with ")", the template's closing " is needed to form the ")" string literal
tagReplaced.replace("{message}", message)
} else {
// Assignment-style: message ends with a variable (e.g. " + x"), no closing " from template needed
tagReplaced.replace("\"{message}\"", "\"$message").replace("{message}", message)
}
}

override fun getRemovalPatterns(tag: String): List<String> = listOf(tag)

override fun getKotlinImport(): String? = importPath?.takeIf { it.isNotBlank() }

override fun getJavaImport(): String? = importPath?.takeIf { it.isNotBlank() }
}

object LogStrategyFactory {
fun getStrategy(framework: LoggingSettings.LoggingFramework): LogStrategy {
fun getStrategy(
framework: LoggingSettings.LoggingFramework,
state: LoggingSettings.State? = null,
): LogStrategy {
return when (framework) {
LoggingSettings.LoggingFramework.PRINTLN -> PrintlnStrategy()
LoggingSettings.LoggingFramework.TIMBER -> TimberStrategy()
LoggingSettings.LoggingFramework.NAPIER -> NapierStrategy()
LoggingSettings.LoggingFramework.CUSTOM ->
CustomLogStrategy(
state?.customKotlinTemplate ?: "Log.d(\"{tag}\", \"{message}\")",
state?.customJavaTemplate ?: "Log.d(\"{tag}\", \"{message}\");",
state?.customImport,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ class LoggingSettings : PersistentStateComponent<LoggingSettings.State> {
PRINTLN("System Println"),
TIMBER("Timber"),
NAPIER("Napier"),
CUSTOM("Custom"),
}

data class State(
var trackMethodExecution: Boolean = true,
var trackAssignments: Boolean = true,
var logTag: String = "Myfancy log",
var loggingFramework: LoggingFramework = LoggingFramework.PRINTLN,
var customKotlinTemplate: String = "Log.d(\"{tag}\", \"{message}\")",
var customJavaTemplate: String = "Log.d(\"{tag}\", \"{message}\");",
var customImport: String = "",
)

private var myState = State()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class LoggingToolWindowFactory : ToolWindowFactory {
fun updatePreview() {
val state = settings.state
val logTag = state.logTag
val strategy = LogStrategyFactory.getStrategy(state.loggingFramework)
val strategy = LogStrategyFactory.getStrategy(state.loggingFramework, state)
val preview = StringBuilder()

val ktFactory = org.jetbrains.kotlin.psi.KtPsiFactory(project)
Expand Down Expand Up @@ -92,13 +92,94 @@ class LoggingToolWindowFactory : ToolWindowFactory {
previewArea.text = preview.toString()
}

val customKotlinTemplateLabel = JBLabel("Kotlin Template ({tag}, {message}):")
val customKotlinTemplateField =
JBTextField(settings.state.customKotlinTemplate).apply {
document.addDocumentListener(
object : DocumentListener {
override fun insertUpdate(e: DocumentEvent) {
settings.state.customKotlinTemplate = text
updatePreview()
}

override fun removeUpdate(e: DocumentEvent) {
settings.state.customKotlinTemplate = text
updatePreview()
}

override fun changedUpdate(e: DocumentEvent) {
settings.state.customKotlinTemplate = text
updatePreview()
}
},
)
}

val customJavaTemplateLabel = JBLabel("Java Template ({tag}, {message}):")
val customJavaTemplateField =
JBTextField(settings.state.customJavaTemplate).apply {
document.addDocumentListener(
object : DocumentListener {
override fun insertUpdate(e: DocumentEvent) {
settings.state.customJavaTemplate = text
updatePreview()
}

override fun removeUpdate(e: DocumentEvent) {
settings.state.customJavaTemplate = text
updatePreview()
}

override fun changedUpdate(e: DocumentEvent) {
settings.state.customJavaTemplate = text
updatePreview()
}
},
)
}

val customImportLabel = JBLabel("Import (optional):")
val customImportField =
JBTextField(settings.state.customImport).apply {
document.addDocumentListener(
object : DocumentListener {
override fun insertUpdate(e: DocumentEvent) {
settings.state.customImport = text
updatePreview()
}

override fun removeUpdate(e: DocumentEvent) {
settings.state.customImport = text
updatePreview()
}

override fun changedUpdate(e: DocumentEvent) {
settings.state.customImport = text
updatePreview()
}
},
)
}

fun updateCustomFieldsVisibility(framework: LoggingSettings.LoggingFramework) {
val isCustom = framework == LoggingSettings.LoggingFramework.CUSTOM
customKotlinTemplateLabel.isVisible = isCustom
customKotlinTemplateField.isVisible = isCustom
customJavaTemplateLabel.isVisible = isCustom
customJavaTemplateField.isVisible = isCustom
customImportLabel.isVisible = isCustom
customImportField.isVisible = isCustom
}

val frameworkModel = CollectionComboBoxModel(LoggingSettings.LoggingFramework.entries)
val frameworkCombo =
ComboBox(frameworkModel).apply {
renderer = SimpleListCellRenderer.create("") { it.displayName }
selectedItem = settings.state.loggingFramework
addActionListener {
settings.state.loggingFramework = selectedItem as LoggingSettings.LoggingFramework
val selected = selectedItem as LoggingSettings.LoggingFramework
settings.state.loggingFramework = selected
updateCustomFieldsVisibility(selected)
updatePreview()
}
}
Expand Down Expand Up @@ -144,6 +225,18 @@ class LoggingToolWindowFactory : ToolWindowFactory {
constraints.gridy++
settingsPanel.add(frameworkCombo, constraints)
constraints.gridy++
settingsPanel.add(customKotlinTemplateLabel, constraints)
constraints.gridy++
settingsPanel.add(customKotlinTemplateField, constraints)
constraints.gridy++
settingsPanel.add(customJavaTemplateLabel, constraints)
constraints.gridy++
settingsPanel.add(customJavaTemplateField, constraints)
constraints.gridy++
settingsPanel.add(customImportLabel, constraints)
constraints.gridy++
settingsPanel.add(customImportField, constraints)
constraints.gridy++
settingsPanel.add(JBLabel("Log Tag:"), constraints)
constraints.gridy++
settingsPanel.add(tagField, constraints)
Expand All @@ -155,6 +248,7 @@ class LoggingToolWindowFactory : ToolWindowFactory {
mainPanel.add(settingsPanel, BorderLayout.NORTH)
mainPanel.add(previewArea, BorderLayout.CENTER)

updateCustomFieldsVisibility(settings.state.loggingFramework)
updatePreview()

val content = ContentFactory.getInstance().createContent(mainPanel, "", false)
Expand Down
Loading
Loading