[Java. Logging] Move checking of possibility to place the logger to the JvmLogger

IDEA-331693

GitOrigin-RevId: a86f29e4024188587da80651724e4a302fdb48d9
This commit is contained in:
Georgii Ustinov
2024-01-31 11:11:12 +02:00
committed by intellij-monorepo-bot
parent 7ef6316e14
commit d4d41665c2
6 changed files with 35 additions and 31 deletions

View File

@@ -22,13 +22,15 @@ class GenerateLoggerHandler : CodeInsightActionHandler {
override fun invoke(project: Project, editor: Editor, file: PsiFile) { override fun invoke(project: Project, editor: Editor, file: PsiFile) {
val currentElement = file.findElementAt(editor.caretModel.offset) ?: return val currentElement = file.findElementAt(editor.caretModel.offset) ?: return
val places = getPossiblePlacesForLogger(currentElement)
val lastClass = places.lastOrNull() ?: return
val module = ModuleUtil.findModuleForFile(file) val module = ModuleUtil.findModuleForFile(file)
val availableLoggers = findSuitableLoggers(module) val availableLoggers = findSuitableLoggers(module)
val places = getPossiblePlacesForLogger(currentElement, availableLoggers)
val lastClass = places.lastOrNull() ?: return
val chosenLogger = getSelectedLogger(project, availableLoggers) ?: return val chosenLogger = getSelectedLogger(project, availableLoggers) ?: return
CommandProcessor.getInstance().executeCommand(project, { CommandProcessor.getInstance().executeCommand(project, {
@@ -86,22 +88,13 @@ class GenerateLoggerHandler : CodeInsightActionHandler {
companion object { companion object {
fun findSuitableLoggers(module: Module?): List<JvmLogger> = JvmLogger.getAllLoggers(false).filter { it.isAvailable(module) } fun findSuitableLoggers(module: Module?): List<JvmLogger> = JvmLogger.getAllLoggers(false).filter { it.isAvailable(module) }
fun getPossiblePlacesForLogger(element: PsiElement): List<PsiClass> = element.parentsOfType(PsiClass::class.java, false) fun getPossiblePlacesForLogger(element: PsiElement, loggerList: List<JvmLogger>): List<PsiClass> = element.parentsOfType(
.filter { clazz -> clazz !is PsiAnonymousClass && isPossibleToPlaceLogger(clazz) } PsiClass::class.java, false)
.filter { clazz -> clazz !is PsiAnonymousClass && isPossibleToPlaceLogger(clazz, loggerList) }
.toList() .toList()
private fun isPossibleToPlaceLogger(psiClass: PsiClass, loggerList: List<JvmLogger>): Boolean = loggerList.all {
private fun isPossibleToPlaceLogger(psiClass: PsiClass): Boolean { it.isPossibleToPlaceLoggerAtClass(psiClass)
for (psiField in psiClass.fields) {
val typeName = psiField.type.canonicalText
if (psiField.name == JvmLogger.LOGGER_IDENTIFIER) return false
for (logger in JvmLogger.getAllLoggers(false)) {
if (logger.loggerTypeName == typeName) return false
}
}
return true
} }
} }
} }

View File

@@ -12,7 +12,7 @@ class GenerateLoggerAction : BaseGenerateAction(GenerateLoggerHandler()) {
override fun isValidForFile(project: Project, editor: Editor, file: PsiFile): Boolean { override fun isValidForFile(project: Project, editor: Editor, file: PsiFile): Boolean {
val element = file.findElementAt(editor.caretModel.offset) ?: return false val element = file.findElementAt(editor.caretModel.offset) ?: return false
val module = ModuleUtil.findModuleForFile(file) val module = ModuleUtil.findModuleForFile(file)
return GenerateLoggerHandler.findSuitableLoggers(module).isNotEmpty() && GenerateLoggerHandler.getPossiblePlacesForLogger( val availableLoggers = GenerateLoggerHandler.findSuitableLoggers(module)
element).isNotEmpty() return availableLoggers.isNotEmpty() && GenerateLoggerHandler.getPossiblePlacesForLogger(element, availableLoggers).isNotEmpty()
} }
} }

View File

@@ -23,17 +23,17 @@ interface JvmLogger {
} }
} }
fun insertLoggerAtClass(project: Project, clazz: PsiClass, logger: PsiElement): PsiElement?
fun isAvailable(project: Project?) : Boolean fun isAvailable(project: Project?) : Boolean
fun isAvailable(module: Module?) : Boolean fun isAvailable(module: Module?) : Boolean
fun insertLoggerAtClass(project: Project, clazz: PsiClass, logger: PsiElement): PsiElement? fun isPossibleToPlaceLoggerAtClass(clazz: PsiClass) : Boolean
fun createLoggerElementText(project: Project, clazz: PsiClass): PsiElement? fun createLoggerElementText(project: Project, clazz: PsiClass): PsiElement?
companion object { companion object {
const val LOGGER_IDENTIFIER = "LOGGER"
private val EP_NAME = ExtensionPointName<JvmLogger>("com.intellij.jvm.logging") private val EP_NAME = ExtensionPointName<JvmLogger>("com.intellij.jvm.logging")
fun getAllLoggersNames(isOnlyOnStartup: Boolean): List<String> { fun getAllLoggersNames(isOnlyOnStartup: Boolean): List<String> {

View File

@@ -15,10 +15,22 @@ class JvmLoggerFieldDelegate(
override val loggerTypeName: String, override val loggerTypeName: String,
override val priority: Int, override val priority: Int,
) : JvmLogger { ) : JvmLogger {
override fun insertLoggerAtClass(project: Project, clazz: PsiClass, logger: PsiElement): PsiElement? {
JavaCodeStyleManager.getInstance(project).shortenClassReferences(logger)
return clazz.add(logger)
}
override fun isAvailable(project: Project?): Boolean = JavaLibraryUtil.hasLibraryClass(project, loggerTypeName)
override fun isAvailable(module: Module?): Boolean = JavaLibraryUtil.hasLibraryClass(module, loggerTypeName)
override fun isPossibleToPlaceLoggerAtClass(clazz: PsiClass): Boolean = clazz
.fields.any { it.name == LOGGER_IDENTIFIER || it.type.canonicalText == loggerTypeName }.not()
override fun createLoggerElementText(project: Project, clazz: PsiClass): PsiField? { override fun createLoggerElementText(project: Project, clazz: PsiClass): PsiField? {
val factory = JavaPsiFacade.getElementFactory(project) val factory = JavaPsiFacade.getElementFactory(project)
val className = clazz.name ?: return null val className = clazz.name ?: return null
val fieldText = "$loggerTypeName ${JvmLogger.LOGGER_IDENTIFIER} = ${factoryName}.$methodName(${ val fieldText = "$loggerTypeName $LOGGER_IDENTIFIER = ${factoryName}.$methodName(${
String.format(classNamePattern, className) String.format(classNamePattern, className)
});" });"
return factory.createFieldFromText(fieldText, clazz).apply { return factory.createFieldFromText(fieldText, clazz).apply {
@@ -28,12 +40,7 @@ class JvmLoggerFieldDelegate(
} }
} }
override fun insertLoggerAtClass(project: Project, clazz: PsiClass, logger: PsiElement): PsiElement? { companion object {
JavaCodeStyleManager.getInstance(project).shortenClassReferences(logger) private const val LOGGER_IDENTIFIER = "LOGGER"
return clazz.add(logger)
} }
override fun isAvailable(project: Project?): Boolean = JavaLibraryUtil.hasLibraryClass(project, loggerTypeName)
override fun isAvailable(module: Module?): Boolean = JavaLibraryUtil.hasLibraryClass(module, loggerTypeName)
} }

View File

@@ -15,9 +15,11 @@ class UnspecifiedLogger : JvmLogger {
clazz: PsiClass, clazz: PsiClass,
logger: PsiElement): PsiElement = throw UnsupportedOperationException() logger: PsiElement): PsiElement = throw UnsupportedOperationException()
override fun isAvailable(project: Project?): Boolean = throw UnsupportedOperationException() override fun isAvailable(project: Project?): Boolean = false
override fun isAvailable(module: Module?): Boolean = throw UnsupportedOperationException() override fun isAvailable(module: Module?): Boolean = false
override fun isPossibleToPlaceLoggerAtClass(clazz: PsiClass): Boolean = false
override fun createLoggerElementText(project: Project, clazz: PsiClass): PsiElement = throw UnsupportedOperationException() override fun createLoggerElementText(project: Project, clazz: PsiClass): PsiElement = throw UnsupportedOperationException()

View File

@@ -30,6 +30,8 @@ class JvmLoggerAnnotationDelegate(
return module != null && JavaLibraryUtil.hasLibraryClass(module, fieldLoggerName) && LombokLibraryUtil.hasLombokClasses(module) return module != null && JavaLibraryUtil.hasLibraryClass(module, fieldLoggerName) && LombokLibraryUtil.hasLombokClasses(module)
} }
override fun isPossibleToPlaceLoggerAtClass(clazz: PsiClass): Boolean = clazz.hasAnnotation(loggerTypeName).not()
override fun createLoggerElementText(project: Project, clazz: PsiClass): PsiAnnotation { override fun createLoggerElementText(project: Project, clazz: PsiClass): PsiAnnotation {
val factory = JavaPsiFacade.getElementFactory(project) val factory = JavaPsiFacade.getElementFactory(project)
return factory.createAnnotationFromText("@$loggerTypeName", clazz) return factory.createAnnotationFromText("@$loggerTypeName", clazz)