mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Java. Logging] Add tests for anonymous and implicitly declared classes + review refactor
IDEA-331693 GitOrigin-RevId: 2ca3503bfbf7d37602ad698f071292a8773c6e29
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7019bbd5df
commit
baf6a46750
@@ -21,7 +21,8 @@ import com.intellij.psi.util.parentsOfType
|
||||
import com.intellij.refactoring.IntroduceTargetChooser
|
||||
import com.intellij.refactoring.introduce.PsiIntroduceTarget
|
||||
import com.intellij.refactoring.suggested.endOffset
|
||||
import com.intellij.ui.logging.JavaSettingsStorage
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||
import com.intellij.ui.logging.JvmLoggingSettingsStorage
|
||||
import org.jetbrains.java.generate.GenerationUtil
|
||||
|
||||
class GenerateLoggerHandler : CodeInsightActionHandler {
|
||||
@@ -35,7 +36,16 @@ class GenerateLoggerHandler : CodeInsightActionHandler {
|
||||
val chosenLogger = getSelectedLogger(project, availableLoggers) ?: return
|
||||
|
||||
when (places.size) {
|
||||
0 -> return
|
||||
0 -> {
|
||||
CommonRefactoringUtil.showErrorHint(
|
||||
project,
|
||||
editor,
|
||||
JavaBundle.message("generate.logger.no.place.found.dialog.message"),
|
||||
JavaBundle.message("generate.logger.no.place.found.dialog.title"),
|
||||
null
|
||||
)
|
||||
return
|
||||
}
|
||||
1 -> execute(places.first(), chosenLogger, project, editor)
|
||||
else -> {
|
||||
val targetInfo = places.map { PsiTargetClassInfo(it) }
|
||||
@@ -85,7 +95,7 @@ class GenerateLoggerHandler : CodeInsightActionHandler {
|
||||
0 -> null
|
||||
1 -> availableLoggers.first()
|
||||
else -> {
|
||||
val preferredLogger = JvmLogger.getLoggerByName(project.service<JavaSettingsStorage>().state.loggerName)
|
||||
val preferredLogger = JvmLogger.getLoggerByName(project.service<JvmLoggingSettingsStorage>().state.loggerName)
|
||||
|
||||
val chooseLoggerDialog = ChooseLoggerDialogWrapper(
|
||||
project,
|
||||
@@ -110,7 +120,7 @@ class GenerateLoggerHandler : CodeInsightActionHandler {
|
||||
|
||||
private fun saveLoggerAfterFirstTime(project: Project, logger: JvmLogger?) {
|
||||
if (logger == null) return
|
||||
val settings = project.service<JavaSettingsStorage>().state
|
||||
val settings = project.service<JvmLoggingSettingsStorage>().state
|
||||
if (settings.loggerName == UnspecifiedLogger.UNSPECIFIED_LOGGER_NAME) {
|
||||
settings.loggerName = logger.toString()
|
||||
}
|
||||
@@ -123,7 +133,7 @@ class GenerateLoggerHandler : CodeInsightActionHandler {
|
||||
|
||||
fun getPossiblePlacesForLogger(element: PsiElement, loggerList: List<JvmLogger>): List<PsiClass> = element.parentsOfType(
|
||||
PsiClass::class.java, true)
|
||||
.filter { clazz -> clazz !is PsiAnonymousClass && isPossibleToPlaceLogger(clazz, loggerList) }
|
||||
.filter { clazz -> clazz !is PsiAnonymousClass && clazz !is PsiImplicitClass && isPossibleToPlaceLogger(clazz, loggerList) }
|
||||
.toList()
|
||||
.reversed()
|
||||
|
||||
@@ -134,7 +144,7 @@ class GenerateLoggerHandler : CodeInsightActionHandler {
|
||||
}
|
||||
|
||||
private class PsiTargetClassInfo(clazz: PsiClass) : PsiIntroduceTarget<PsiClass>(clazz) {
|
||||
private val className : String = clazz.name ?: throw IllegalStateException("Unable to fetch class name")
|
||||
private val className: String = clazz.name ?: throw IllegalStateException("Unable to fetch class name")
|
||||
|
||||
override fun render(): String = "class $className"
|
||||
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.ui.logging.JavaLoggerModel
|
||||
import com.intellij.ui.logging.JavaSettingsStorage
|
||||
import com.intellij.ui.logging.JvmLoggingSettingsStorage
|
||||
import com.intellij.ui.logging.JvmLoggingConfigurable
|
||||
import com.intellij.ui.dsl.builder.Cell
|
||||
import com.intellij.ui.dsl.builder.panel
|
||||
@@ -25,7 +25,7 @@ class ChooseLoggerDialogWrapper(
|
||||
private set
|
||||
|
||||
private lateinit var comboBox: Cell<ComboBox<String>>
|
||||
private val settings = project.service<JavaSettingsStorage>().state
|
||||
private val settings = project.service<JvmLoggingSettingsStorage>().state
|
||||
|
||||
init {
|
||||
title = JavaBundle.message("dialog.title.choose.logger")
|
||||
|
||||
@@ -7,11 +7,13 @@ import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Extension point representing a JVM logger. Extensions of this EP are used to store information about concrete logger and provide
|
||||
* the way to generate a logger at the class.
|
||||
* the way to generate a logger at the class. Please, don't use it now, this API will be rewritten in the future.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
interface JvmLogger {
|
||||
/**
|
||||
* This field represents fully qualified name of the logger's type
|
||||
@@ -20,7 +22,7 @@ interface JvmLogger {
|
||||
|
||||
/**
|
||||
* This field is used to determine the order of loggers in the settings
|
||||
* @see com.intellij.settings.JvmLoggingConfigurable
|
||||
* @see com.intellij.ui.logging.JvmLoggingConfigurable
|
||||
*/
|
||||
val priority: Int
|
||||
|
||||
@@ -29,7 +31,7 @@ interface JvmLogger {
|
||||
* For example, it happens after creation of the new project.
|
||||
*
|
||||
* @return true if the logger should only be used during startup, false otherwise
|
||||
* @see com.intellij.logging.UnspecifiedLogger
|
||||
* @see com.intellij.lang.logging.UnspecifiedLogger
|
||||
*/
|
||||
fun isOnlyOnStartup() = false
|
||||
|
||||
@@ -42,7 +44,7 @@ interface JvmLogger {
|
||||
fun insertLoggerAtClass(project: Project, clazz: PsiClass, logger: PsiElement): PsiElement?
|
||||
|
||||
/**
|
||||
* Determines if the logger is available for the given project.
|
||||
* Determines if the logger is available for the given project. Should only be invoked inside ReadAction.
|
||||
*
|
||||
* @param project the project context
|
||||
* @return true if the logger is available, false otherwise
|
||||
@@ -50,7 +52,7 @@ interface JvmLogger {
|
||||
fun isAvailable(project: Project?) : Boolean
|
||||
|
||||
/**
|
||||
* Determines if the logger is available for the given module.
|
||||
* Determines if the logger is available for the given module. Should only be invoked inside ReadAction.
|
||||
*
|
||||
* @param module the module context
|
||||
* @return true if the logger is available, false otherwise
|
||||
|
||||
@@ -20,8 +20,7 @@ import javax.swing.JComponent
|
||||
class JvmLoggingConfigurable(private val project: Project) : SearchableConfigurable, NoScroll {
|
||||
private lateinit var warningRow: Row
|
||||
private lateinit var panel: DialogPanel
|
||||
private val boundedExecutor = AppExecutorUtil.getAppExecutorService()
|
||||
private val settings = project.service<JavaSettingsStorage>().state
|
||||
private val settings = project.service<JvmLoggingSettingsStorage>().state
|
||||
|
||||
override fun getDisplayName(): String = JavaBundle.message("jvm.logging.configurable.display.name")
|
||||
|
||||
@@ -53,7 +52,7 @@ class JvmLoggingConfigurable(private val project: Project) : SearchableConfigura
|
||||
JvmLogger.getLoggerByName(loggerDisplayName)?.isAvailable(project) == false
|
||||
}.finishOnUiThread(ModalityState.any()) { isVisible ->
|
||||
warningRow.visible(isVisible)
|
||||
}.submit(boundedExecutor)
|
||||
}.submit(AppExecutorUtil.getAppExecutorService())
|
||||
}
|
||||
|
||||
override fun isModified(): Boolean = panel.isModified()
|
||||
|
||||
+2
-2
@@ -5,9 +5,9 @@ import com.intellij.lang.logging.UnspecifiedLogger
|
||||
import com.intellij.openapi.components.*
|
||||
|
||||
@Service(Service.Level.PROJECT)
|
||||
@State(name = "JavaSettingsStorage",
|
||||
@State(name = "JvmLoggingSettingsStorage",
|
||||
storages = [Storage(StoragePathMacros.WORKSPACE_FILE)])
|
||||
class JavaSettingsStorage : SimplePersistentStateComponent<JavaSettingsStorage.State>(State()) {
|
||||
class JvmLoggingSettingsStorage : SimplePersistentStateComponent<JvmLoggingSettingsStorage.State>(State()) {
|
||||
class State : BaseState() {
|
||||
var loggerName: String? by string(UnspecifiedLogger.UNSPECIFIED_LOGGER_NAME)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
class A {
|
||||
private static final Logger log<caret> = Logger.getLogger(A.class);
|
||||
|
||||
public void foo() {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
void main() {<caret>
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
public void foo() {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
void main() {<caret>
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.intellij.ui.UiInterceptors
|
||||
import com.intellij.ui.UiInterceptors.UiInterceptor
|
||||
import com.intellij.ui.components.JBList
|
||||
import com.intellij.ui.logging.JavaSettingsStorage
|
||||
import com.intellij.ui.logging.JvmLoggingSettingsStorage
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import junit.framework.TestCase
|
||||
import javax.swing.ListModel
|
||||
@@ -82,6 +82,39 @@ class GenerateLoggerTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testAnonymousClass() {
|
||||
myFixture.addClass("""
|
||||
package org.apache.log4j;
|
||||
|
||||
interface Logger {
|
||||
static <T> Logger getLogger(Class<T> clazz) {}
|
||||
}
|
||||
""".trimIndent())
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testImplicitlyDeclaredClass() {
|
||||
myFixture.addClass("""
|
||||
package org.apache.log4j;
|
||||
|
||||
interface Logger {
|
||||
static <T> Logger getLogger(Class<T> clazz) {}
|
||||
}
|
||||
""".trimIndent())
|
||||
myFixture.configureByText("implicitlyDeclaredClass.java",
|
||||
"""
|
||||
void main() {<caret>
|
||||
}
|
||||
""".trimIndent())
|
||||
|
||||
val loggers = GenerateLoggerHandler.findSuitableLoggers(module)
|
||||
TestCase.assertTrue(loggers.isNotEmpty())
|
||||
val element = file.findElementAt(editor.caretModel.offset)!!
|
||||
val places = GenerateLoggerHandler.getPossiblePlacesForLogger(element, loggers)
|
||||
|
||||
TestCase.assertTrue(places.isEmpty())
|
||||
}
|
||||
|
||||
fun testNestedClassesOuterClass() {
|
||||
myFixture.addClass("""
|
||||
package org.slf4j;
|
||||
@@ -156,12 +189,12 @@ class GenerateLoggerTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
static <T> Logger getLogger(Class<T> clazz) {}
|
||||
}
|
||||
""".trimIndent())
|
||||
assertEquals(project.service<JavaSettingsStorage>().state.loggerName, UnspecifiedLogger.UNSPECIFIED_LOGGER_NAME)
|
||||
assertEquals(project.service<JvmLoggingSettingsStorage>().state.loggerName, UnspecifiedLogger.UNSPECIFIED_LOGGER_NAME)
|
||||
doTest()
|
||||
assertEquals(project.service<JavaSettingsStorage>().state.loggerName, "Log4j")
|
||||
assertEquals(project.service<JvmLoggingSettingsStorage>().state.loggerName, "Log4j")
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = JAVA_LATEST_WITH_LATEST_JDK
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = JAVA_21
|
||||
|
||||
private fun doTestWithMultiplePlaces(expectedClassNameList: List<String>, selectedClass: String) {
|
||||
val name = getTestName(false)
|
||||
|
||||
@@ -300,6 +300,8 @@ generate.getter.fields.chooser.title=Select Fields to Generate Getters
|
||||
generate.getter.setter.title=Select Fields to Generate Getters and Setters
|
||||
generate.getter.template=&Getter template:
|
||||
generate.hashcode.template.title=HashCode Template:
|
||||
generate.logger.no.place.found.dialog.title = No Places Found
|
||||
generate.logger.no.place.found.dialog.message = Could not find places to insert logger
|
||||
generate.logger.specify.place.popup.title=Choose Place
|
||||
generate.record.constructor.title=Generate Records Constructor
|
||||
generate.setter.fields.chooser.title=Select Fields to Generate Setters
|
||||
|
||||
Reference in New Issue
Block a user