diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml index 5715e17b8c8..86d79ebcc36 100644 --- a/idea/resources/META-INF/plugin-common.xml +++ b/idea/resources/META-INF/plugin-common.xml @@ -3316,6 +3316,14 @@ language="kotlin" key="inspection.redundant.elvis.return.null.display.name" bundle="messages.KotlinBundle"/> + + diff --git a/idea/resources/inspectionDescriptions/KotlinLoggerInitializedWithForeignClass.html b/idea/resources/inspectionDescriptions/KotlinLoggerInitializedWithForeignClass.html new file mode 100644 index 00000000000..81806f14b95 --- /dev/null +++ b/idea/resources/inspectionDescriptions/KotlinLoggerInitializedWithForeignClass.html @@ -0,0 +1,7 @@ + + +This inspection reports any Loggers which are initialized with a class literal from a different class than the Logger is contained in. +

+Use the table below to specify the logger factory classes and logger factory methods recognized by this inspection. + + \ No newline at end of file diff --git a/idea/resources/messages/KotlinBundle.properties b/idea/resources/messages/KotlinBundle.properties index 0beb48597a8..11d6bf8474c 100644 --- a/idea/resources/messages/KotlinBundle.properties +++ b/idea/resources/messages/KotlinBundle.properties @@ -2206,4 +2206,9 @@ kotlin.script.definitions.model.name.name=Name codestyle.name.kotlin=Kotlin add.missing.class.keyword=Add missing 'class' keyword fix.move.typealias.to.top.level=Move typealias to top level -fix.change.jvm.name=Change JVM name \ No newline at end of file +fix.change.jvm.name=Change JVM name +inspection.logger.initialized.with.foreign.class.display.name=Logger initialized with foreign class +logger.initialized.with.foreign.class=Logger initialized with foreign class ''{0}'' +logger.factory.method.name=Logger factory method name +logger.factory.class.name=Logger factory class name +choose.logger.factory.class=Choose logger factory class \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/logging/KotlinLoggerInitializedWithForeignClassInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/logging/KotlinLoggerInitializedWithForeignClassInspection.kt new file mode 100644 index 00000000000..b3483ceefd8 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/logging/KotlinLoggerInitializedWithForeignClassInspection.kt @@ -0,0 +1,155 @@ +/* + * Copyright 2010-2020 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.idea.inspections.logging + +import com.intellij.codeInspection.LocalQuickFix +import com.intellij.codeInspection.ProblemDescriptor +import com.intellij.codeInspection.ProblemsHolder +import com.intellij.codeInspection.ui.ListTable +import com.intellij.codeInspection.ui.ListWrappingTableModel +import com.intellij.openapi.project.Project +import com.intellij.util.xmlb.Accessor +import com.intellij.util.xmlb.SerializationFilterBase +import com.intellij.util.xmlb.XmlSerializer +import com.siyeh.ig.BaseInspection +import com.siyeh.ig.ui.UiUtils +import org.jdom.Element +import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall +import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection +import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.containingClass +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull +import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import javax.swing.JComponent + +class KotlinLoggerInitializedWithForeignClassInspection : AbstractKotlinInspection() { + companion object { + private val DEFAULT_LOGGER_FACTORIES = listOf( + "java.util.logging.Logger" to "getLogger", + "org.slf4j.LoggerFactory" to "getLogger", + "org.apache.commons.logging.LogFactory" to "getLog", + "org.apache.log4j.Logger" to "getLogger", + "org.apache.logging.log4j.LogManager" to "getLogger", + ) + private val DEFAULT_LOGGER_FACTORY_CLASS_NAMES = DEFAULT_LOGGER_FACTORIES.map { it.first } + private val DEFAULT_LOGGER_FACTORY_METHOD_NAMES = DEFAULT_LOGGER_FACTORIES.map { it.second } + private val DEFAULT_LOGGER_FACTORY_CLASS_NAME = BaseInspection.formatString(DEFAULT_LOGGER_FACTORY_CLASS_NAMES) + private val DEFAULT_LOGGER_FACTORY_METHOD_NAME = BaseInspection.formatString(DEFAULT_LOGGER_FACTORY_METHOD_NAMES) + } + + @Suppress("MemberVisibilityCanBePrivate") + var loggerFactoryClassName: String = DEFAULT_LOGGER_FACTORY_CLASS_NAME + + @Suppress("MemberVisibilityCanBePrivate") + var loggerFactoryMethodName: String = DEFAULT_LOGGER_FACTORY_METHOD_NAME + + private val loggerFactoryClassNames = DEFAULT_LOGGER_FACTORY_CLASS_NAMES.toMutableList() + private val loggerFactoryMethodNames = DEFAULT_LOGGER_FACTORY_METHOD_NAMES.toMutableList() + private val loggerFactoryFqNames + get() = loggerFactoryClassNames.zip(loggerFactoryMethodNames).groupBy( + { (_, methodName) -> methodName }, + { (className, methodName) -> FqName("${className}.${methodName}") } + ) + + override fun createOptionsPanel(): JComponent? { + val table = ListTable( + ListWrappingTableModel( + listOf(loggerFactoryClassNames, loggerFactoryMethodNames), + KotlinBundle.message("logger.factory.class.name"), + KotlinBundle.message("logger.factory.method.name") + ) + ) + return UiUtils.createAddRemoveTreeClassChooserPanel(table, KotlinBundle.message("choose.logger.factory.class")) + } + + override fun readSettings(element: Element) { + super.readSettings(element) + BaseInspection.parseString(loggerFactoryClassName, loggerFactoryClassNames) + BaseInspection.parseString(loggerFactoryMethodName, loggerFactoryMethodNames) + if (loggerFactoryClassNames.isEmpty() || loggerFactoryClassNames.size != loggerFactoryMethodNames.size) { + BaseInspection.parseString(DEFAULT_LOGGER_FACTORY_CLASS_NAME, loggerFactoryClassNames) + BaseInspection.parseString(DEFAULT_LOGGER_FACTORY_METHOD_NAME, loggerFactoryMethodNames) + } + } + + override fun writeSettings(element: Element) { + loggerFactoryClassName = BaseInspection.formatString(loggerFactoryClassNames) + loggerFactoryMethodName = BaseInspection.formatString(loggerFactoryMethodNames) + XmlSerializer.serializeInto(this, element, object : SerializationFilterBase() { + override fun accepts(accessor: Accessor, bean: Any, beanValue: Any?): Boolean { + if (accessor.name == "loggerFactoryClassName" && beanValue == DEFAULT_LOGGER_FACTORY_CLASS_NAME) return false + if (accessor.name == "loggerFactoryMethodName" && beanValue == DEFAULT_LOGGER_FACTORY_METHOD_NAME) return false + return true + } + }) + } + + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = callExpressionVisitor(fun(call) { + val containingClassName = call.containingClass()?.name ?: return + + val callee = call.calleeExpression ?: return + val loggerMethodFqNames = loggerFactoryFqNames[callee.text] ?: return + + val argument = call.valueArguments.singleOrNull()?.getArgumentExpression() as? KtDotQualifiedExpression ?: return + val argumentSelector = argument.selectorExpression ?: return + val classLiteral = when (val argumentReceiver = argument.receiverExpression) { + // Foo::class.java, Foo::class.qualifiedName, Foo::class.simpleName + is KtClassLiteralExpression -> { + val selectorText = argumentSelector.safeAs()?.text + if (selectorText !in listOf("java", "qualifiedName", "simpleName")) return + argumentReceiver + } + // Foo::class.java.name, Foo::class.java.simpleName, Foo::class.java.canonicalName + is KtDotQualifiedExpression -> { + val classLiteral = argumentReceiver.receiverExpression as? KtClassLiteralExpression ?: return + if (argumentReceiver.selectorExpression.safeAs()?.text != "java") return + val selectorText = argumentSelector.safeAs()?.text + ?: argumentSelector.safeAs()?.calleeExpression?.text + if (selectorText !in listOf("name", "simpleName", "canonicalName", "getName", "getSimpleName", "getCanonicalName")) return + classLiteral + } + else -> return + } + val classLiteralName = classLiteral.receiverExpression?.text ?: return + if (containingClassName == classLiteralName) return + + if (call.resolveToCall()?.resultingDescriptor?.fqNameOrNull() !in loggerMethodFqNames) return + + holder.registerProblem( + classLiteral, + KotlinBundle.message("logger.initialized.with.foreign.class", "$classLiteralName::class"), + ReplaceForeignFix(containingClassName) + ) + }) + + private class ReplaceForeignFix(private val containingClassName: String) : LocalQuickFix { + override fun getName() = KotlinBundle.message("replace.with.0", "$containingClassName::class") + + override fun getFamilyName() = name + + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val argument = descriptor.psiElement.getStrictParentOfType()?.getArgumentExpression() + as? KtDotQualifiedExpression ?: return + val receiver = argument.receiverExpression + val selector = argument.selectorExpression ?: return + val psiFactory = KtPsiFactory(argument) + val newArgument = when (receiver) { + is KtClassLiteralExpression -> { + psiFactory.createExpressionByPattern("${containingClassName}::class.$0", selector) + } + is KtDotQualifiedExpression -> { + psiFactory.createExpressionByPattern("${containingClassName}::class.java.$0", selector) + } + else -> return + } + argument.replace(newArgument) + } + } +} diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/.inspection b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/.inspection new file mode 100644 index 00000000000..7389a382020 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.logging.KotlinLoggerInitializedWithForeignClassInspection diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/canonicalName.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/canonicalName.kt new file mode 100644 index 00000000000..dce99776846 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/canonicalName.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.java.canonicalName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/canonicalName.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/canonicalName.kt.after new file mode 100644 index 00000000000..8d43ac171fb --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/canonicalName.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java.canonicalName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getCanonicalName.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getCanonicalName.kt new file mode 100644 index 00000000000..5c4025d77b3 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getCanonicalName.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.java.getCanonicalName()) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getCanonicalName.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getCanonicalName.kt.after new file mode 100644 index 00000000000..e0e690fec0e --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getCanonicalName.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java.getCanonicalName()) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getName.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getName.kt new file mode 100644 index 00000000000..a387163f7c0 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getName.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.java.getName()) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getName.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getName.kt.after new file mode 100644 index 00000000000..54428f78963 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getName.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java.getName()) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getSimpleName.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getSimpleName.kt new file mode 100644 index 00000000000..47d03dbeadf --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getSimpleName.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.java.getSimpleName()) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getSimpleName.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getSimpleName.kt.after new file mode 100644 index 00000000000..0342a840aaa --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getSimpleName.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java.getSimpleName()) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassQualiiedName.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassQualiiedName.kt new file mode 100644 index 00000000000..94174db7ece --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassQualiiedName.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.qualifiedName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassQualiiedName.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassQualiiedName.kt.after new file mode 100644 index 00000000000..2709c95edb5 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassQualiiedName.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.qualifiedName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassSimpleName.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassSimpleName.kt new file mode 100644 index 00000000000..d03958e9078 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassSimpleName.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.simpleName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassSimpleName.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassSimpleName.kt.after new file mode 100644 index 00000000000..786cb32733b --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassSimpleName.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.simpleName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/name.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/name.kt new file mode 100644 index 00000000000..731f1e4afd7 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/name.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.java.name) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/name.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/name.kt.after new file mode 100644 index 00000000000..a0ac4d28196 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/name.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java.name) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/nonForeignClass.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/nonForeignClass.kt new file mode 100644 index 00000000000..2abd3fdd66d --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/nonForeignClass.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// PROBLEM: none +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simple.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simple.kt new file mode 100644 index 00000000000..8c14b89ea28 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simple.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME +// PROBLEM: Logger initialized with foreign class 'Bar::class' +// FIX: Replace with 'Foo::class' +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.java) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simple.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simple.kt.after new file mode 100644 index 00000000000..2e772e7152c --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simple.kt.after @@ -0,0 +1,15 @@ +// WITH_RUNTIME +// PROBLEM: Logger initialized with foreign class 'Bar::class' +// FIX: Replace with 'Foo::class' +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simpleName.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simpleName.kt new file mode 100644 index 00000000000..15d948d5f41 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simpleName.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Bar::class.java.simpleName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simpleName.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simpleName.kt.after new file mode 100644 index 00000000000..b297ab038b5 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simpleName.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +package org.apache.commons.logging + +class Foo { + private val logger = LogFactory.getLog(Foo::class.java.simpleName) +} + +class Bar + +object LogFactory { + fun getLog(clazz: Class<*>) {} + fun getLog(name: String?) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j/simple.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j/simple.kt new file mode 100644 index 00000000000..b9abf548416 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j/simple.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +package org.apache.log4j + +class Foo { + private val logger = Logger.getLogger(Bar::class.java) +} + +class Bar + +object Logger { + fun getLogger(clazz: Class<*>) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j/simple.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j/simple.kt.after new file mode 100644 index 00000000000..53f264f5516 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j/simple.kt.after @@ -0,0 +1,12 @@ +// WITH_RUNTIME +package org.apache.log4j + +class Foo { + private val logger = Logger.getLogger(Foo::class.java) +} + +class Bar + +object Logger { + fun getLogger(clazz: Class<*>) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2/simple.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2/simple.kt new file mode 100644 index 00000000000..b36f4c5b81c --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2/simple.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +package org.apache.logging.log4j + +class Foo { + private val logger = LogManager.getLogger(Bar::class.java) +} + +class Bar + +object LogManager { + fun getLogger(clazz: Class<*>) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2/simple.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2/simple.kt.after new file mode 100644 index 00000000000..aa243b6f0c6 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2/simple.kt.after @@ -0,0 +1,12 @@ +// WITH_RUNTIME +package org.apache.logging.log4j + +class Foo { + private val logger = LogManager.getLogger(Foo::class.java) +} + +class Bar + +object LogManager { + fun getLogger(clazz: Class<*>) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j/simple.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j/simple.kt new file mode 100644 index 00000000000..3ad07c3cfea --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j/simple.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +package org.slf4j + +class Foo { + private val logger = LoggerFactory.getLogger(Bar::class.java) +} + +class Bar + +object LoggerFactory { + fun getLogger(clazz: Class<*>) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j/simple.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j/simple.kt.after new file mode 100644 index 00000000000..1f4f88714a0 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j/simple.kt.after @@ -0,0 +1,12 @@ +// WITH_RUNTIME +package org.slf4j + +class Foo { + private val logger = LoggerFactory.getLogger(Foo::class.java) +} + +class Bar + +object LoggerFactory { + fun getLogger(clazz: Class<*>) {} +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple.kt new file mode 100644 index 00000000000..d9896d32ca0 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple.kt @@ -0,0 +1,10 @@ +// RUNTIME_WITH_FULL_JDK +package util + +import java.util.logging.Logger + +class Foo { + private val logger = Logger.getLogger(Bar::class.qualifiedName) +} + +class Bar \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple.kt.after new file mode 100644 index 00000000000..ae26de5e81a --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple.kt.after @@ -0,0 +1,10 @@ +// RUNTIME_WITH_FULL_JDK +package util + +import java.util.logging.Logger + +class Foo { + private val logger = Logger.getLogger(Foo::class.qualifiedName) +} + +class Bar \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple2.kt b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple2.kt new file mode 100644 index 00000000000..c901c1c6d13 --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple2.kt @@ -0,0 +1,10 @@ +// RUNTIME_WITH_FULL_JDK +package util + +import java.util.logging.Logger.getLogger + +class Foo { + private val logger = getLogger(Bar::class.qualifiedName) +} + +class Bar \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple2.kt.after b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple2.kt.after new file mode 100644 index 00000000000..f9a5d7d396d --- /dev/null +++ b/idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple2.kt.after @@ -0,0 +1,10 @@ +// RUNTIME_WITH_FULL_JDK +package util + +import java.util.logging.Logger.getLogger + +class Foo { + private val logger = getLogger(Foo::class.qualifiedName) +} + +class Bar \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 2c28d84d923..bd627cb7f46 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -5797,6 +5797,172 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { } } + @TestMetadata("idea/testData/inspectionsLocal/logging") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Logging extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInLogging() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/logging"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class LoggerInitializedWithForeignClass extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInLoggerInitializedWithForeignClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Commons extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInCommons() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("canonicalName.kt") + public void testCanonicalName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/canonicalName.kt"); + } + + @TestMetadata("getCanonicalName.kt") + public void testGetCanonicalName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getCanonicalName.kt"); + } + + @TestMetadata("getName.kt") + public void testGetName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getName.kt"); + } + + @TestMetadata("getSimpleName.kt") + public void testGetSimpleName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/getSimpleName.kt"); + } + + @TestMetadata("kclassQualiiedName.kt") + public void testKclassQualiiedName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassQualiiedName.kt"); + } + + @TestMetadata("kclassSimpleName.kt") + public void testKclassSimpleName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/kclassSimpleName.kt"); + } + + @TestMetadata("name.kt") + public void testName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/name.kt"); + } + + @TestMetadata("nonForeignClass.kt") + public void testNonForeignClass() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/nonForeignClass.kt"); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simple.kt"); + } + + @TestMetadata("simpleName.kt") + public void testSimpleName() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/commons/simpleName.kt"); + } + } + + @TestMetadata("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Log4j extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInLog4j() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j/simple.kt"); + } + } + + @TestMetadata("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Log4j2 extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInLog4j2() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/log4j2/simple.kt"); + } + } + + @TestMetadata("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Slf4j extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInSlf4j() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/slf4j/simple.kt"); + } + } + + @TestMetadata("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Util extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInUtil() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple.kt"); + } + + @TestMetadata("simple2.kt") + public void testSimple2() throws Exception { + runTest("idea/testData/inspectionsLocal/logging/loggerInitializedWithForeignClass/util/simple2.kt"); + } + } + } + } + @TestMetadata("idea/testData/inspectionsLocal/mainFunctionReturnUnit") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)