Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnusedPrivateClass check led to an exception #1345

Closed
zayo opened this issue Nov 16, 2018 · 2 comments
Closed

UnusedPrivateClass check led to an exception #1345

zayo opened this issue Nov 16, 2018 · 2 comments
Assignees
Milestone

Comments

@zayo
Copy link

zayo commented Nov 16, 2018

I'm getting following error after update to 1.0.0-RC11
Most likely caused with #1309
I'm able to suppress "UnusedPrivateClass" and then it's not failing, but there is some issue with those change.

Analyzing '/Users/.../settings2/SettingsMigrations.kt' led to an exception.
Running detekt 'unknown' on Java '1.8.0_144-b01' on OS 'Mac OS X'.
Please create an issue and report this exception.
java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1592)
java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
io.gitlab.arturbosch.detekt.rules.style.UnusedPrivateClass$UnusedClassVisitor.registerAccess(UnusedPrivateClass.kt:83)
io.gitlab.arturbosch.detekt.rules.style.UnusedPrivateClass$UnusedClassVisitor.visitParameter(UnusedPrivateClass.kt:92)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitParameter(KtVisitorVoid.java:591)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitParameter(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtParameter.accept(KtParameter.java:50)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.PsiElementBase.acceptChildren(PsiElementBase.java:69)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitor.visitKtElement(KtVisitor.java:24)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:447)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitParameterList(KtVisitor.java:134)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitParameterList(KtVisitorVoid.java:121)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitParameterList(KtVisitorVoid.java:585)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitParameterList(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtParameterList.accept(KtParameterList.java:40)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.PsiElementBase.acceptChildren(PsiElementBase.java:69)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitor.visitKtElement(KtVisitor.java:24)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:447)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitExpression(KtVisitor.java:182)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:169)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:659)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitDeclaration(KtVisitor.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:453)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitNamedDeclaration(KtVisitor.java:398)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:381)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:959)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitPrimaryConstructor(KtVisitor.java:49)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitPrimaryConstructor(KtVisitorVoid.java:45)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitPrimaryConstructor(KtVisitorVoid.java:477)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitPrimaryConstructor(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtPrimaryConstructor.accept(KtPrimaryConstructor.kt:31)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.PsiElementBase.acceptChildren(PsiElementBase.java:69)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitor.visitKtElement(KtVisitor.java:24)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:447)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitExpression(KtVisitor.java:182)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:169)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:659)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitDeclaration(KtVisitor.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:453)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitNamedDeclaration(KtVisitor.java:398)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:381)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:959)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClassOrObject(KtVisitor.java:41)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:37)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:465)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClass(KtVisitor.java:33)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:33)
io.gitlab.arturbosch.detekt.rules.style.UnusedPrivateClass$UnusedClassVisitor.visitClass(UnusedPrivateClass.kt:69)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:459)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtClass.accept(KtClass.kt:34)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.PsiElementBase.acceptChildren(PsiElementBase.java:69)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitor.visitKtElement(KtVisitor.java:24)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:447)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClassBody(KtVisitor.java:98)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassBody(KtVisitorVoid.java:89)
.org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassBody(KtVisitorVoid.java:537)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassBody(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtClassBody.accept(KtClassBody.kt:38)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.PsiElementBase.acceptChildren(PsiElementBase.java:69)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitor.visitKtElement(KtVisitor.java:24)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:25)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:447)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtElement(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitExpression(KtVisitor.java:182)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:169)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:659)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitExpression(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitDeclaration(KtVisitor.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:29)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:453)
.org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitNamedDeclaration(KtVisitor.java:398)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:381)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:959)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitNamedDeclaration(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClassOrObject(KtVisitor.java:41)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:37)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:465)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClassOrObject(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtVisitor.visitClass(KtVisitor.java:33)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:33)
io.gitlab.arturbosch.detekt.rules.style.UnusedPrivateClass$UnusedClassVisitor.visitClass(UnusedPrivateClass.kt:69)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:459)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitClass(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtClass.accept(KtClass.kt:34)
org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.SharedImplUtil.acceptChildren(SharedImplUtil.java:200)
org.jetbrains.kotlin.com.intellij.psi.impl.source.PsiFileImpl.acceptChildren(PsiFileImpl.java:728)
org.jetbrains.kotlin.psi.KtTreeVisitorVoid.visitElement(KtTreeVisitorVoid.java:25)
org.jetbrains.kotlin.com.intellij.psi.PsiElementVisitor.visitFile(PsiElementVisitor.java:34)
org.jetbrains.kotlin.psi.KtVisitor.visitKtFile(KtVisitor.java:73)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:69)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:513)
org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:21)
org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:221)
org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:208)
io.gitlab.arturbosch.detekt.rules.style.UnusedPrivateClass.visit(UnusedPrivateClass.kt:46)
io.gitlab.arturbosch.detekt.api.BaseRule.visitFile(BaseRule.kt:20)
io.gitlab.arturbosch.detekt.api.RuleSet.accept(RuleSet.kt:22)
io.gitlab.arturbosch.detekt.core.Detektor.analyze(Detektor.kt:60)
io.gitlab.arturbosch.detekt.core.Detektor.access$analyze(Detektor.kt:15)
io.gitlab.arturbosch.detekt.core.Detektor$run$1$$special$$inlined$map$lambda$1.invoke(Detektor.kt:29)
io.gitlab.arturbosch.detekt.core.Detektor$run$1$$special$$inlined$map$lambda$1.invoke(Detektor.kt:15)
io.gitlab.arturbosch.detekt.core.TasksKt$runAsync$1.invoke(Tasks.kt:23)
io.gitlab.arturbosch.detekt.core.TasksKt$task$1.get(Tasks.kt:27)
java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

This is my class where this issue happened:

@Suppress("UseDataClass", "UnusedPrivateMember")
internal class SettingsMigrations(val context: Context, val settings: AppSettingsImpl) {

    /******************************************** Migration Definitions ********************************************/

    /**
     * Migration definitions.
     *
     * Usage:
     *    boolean|long|string|int {
     *       from { X : AbstractSettings }.key { String }
     *       to { Y : AbstractSettings }.key { String }
     *       condition { Boolean } // optional.
     *    }
     */
    private val migrations: Sequence<Migration> = sequenceOf(
        boolean {
            from { clazz = InitSettingsSyncedImpl::class; key = InitSettingsSyncedImpl.EULA_ACCEPTED }
            to { clazz = InitSettingsImpl::class ; key = InitSettingsImpl.EULA_ACCEPTED }
            condition { settings.init.getFirstVersionCode() < BuildUtils.getAppVersionCode(context) }
            // We cannot depend on settings getAppLastVersionCode as it might not be set yet, thus we obtain fresh val.
        },
        int {
            from { clazz = InitSettingsSyncedImpl::class; key = InitSettingsSyncedImpl.EULA_VIEWED_COUNT }
            to { clazz = InitSettingsImpl::class; key = InitSettingsImpl.EULA_VIEWED_COUNT }
            condition { settings.init.getFirstVersionCode() < BuildUtils.getAppVersionCode(context) }
        }
    )

    /**
     * Migrates all [Migration] specified in the [migrations] sequence.
     */
    internal fun migrate() = migrations.forEach { migration -> migration.migrate() }

    /******************************************** Core ********************************************/

    /**
     * Starts migration.
     */
    private fun Migration.migrate() {
        val shouldMigrate = condition?.invoke() ?: true

        if (!shouldMigrate) {
            return
        }

        val sourceSettingsImpl = settings.getSettings(source.clazz)
        val destinationSettingsImpl = settings.getSettings(destination.clazz)

        if (!sourceSettingsImpl.prefs.contains(source.key)) {
            return // Value for migration not set, we don't know the default, exit.
        }

        when (type) {
            Long::class -> {
                val value = sourceSettingsImpl.prefs.getLong(source.key, 0)
                destinationSettingsImpl.prefs.edit { putLong(destination.key, value) }
            }

            Int::class -> {
                val value = sourceSettingsImpl.prefs.getInt(source.key, 0)
                destinationSettingsImpl.prefs.edit { putInt(destination.key, value) }
            }

            String::class -> {
                val value = sourceSettingsImpl.prefs.getString(source.key, null)
                destinationSettingsImpl.prefs.edit { putString(destination.key, value) }
            }

            Boolean::class -> {
                val value = sourceSettingsImpl.prefs.getBoolean(source.key, false)
                destinationSettingsImpl.prefs.edit { putBoolean(destination.key, value) }
            }
        }

        // Clear the 'old' to prevent copying again.
        sourceSettingsImpl.prefs.remove(source.key)
    }

    /******************************************** DSL ********************************************/

    /**
     * Creates [Migration] for [Long] value.
     *
     * @param block Extension function of migration. Either [from], [to] or [condition].
     */
    private fun long(block: Migration.() -> Unit): Migration = Migration(Long::class).apply(block)

    /**
     * Creates [Migration] for [Int] value.
     *
     * @param block Extension function of migration. Either [from], [to] or [condition].
     */
    private fun int(block: Migration.() -> Unit): Migration = Migration(Int::class).apply(block)

    /**
     * Creates [Migration] for [String] value.
     *
     * @param block Extension function of migration. Either [from], [to] or [condition].
     */
    private fun string(block: Migration.() -> Unit): Migration = Migration(String::class).apply(block)

    /**
     * Creates [Migration] for [Boolean] value.
     *
     * @param block Extension function of migration. Either [from], [to] or [condition].
     */
    private fun boolean(block: Migration.() -> Unit): Migration = Migration(Boolean::class).apply(block)

    /**
     * Creates the [Migration] source.
     */
    private fun Migration.from(block: Location.() -> Unit) { source = Location().apply(block) }

    /**
     * Creates the [Migration] destination.
     */
    private fun Migration.to(block: Location.() -> Unit) { destination = Location().apply(block) }

    /**
     * Allows to restrict applying [Migration] only if [predicate] is true. Optional.
     */
    private fun Migration.condition(predicate: () -> Boolean) { this.condition = predicate }

    /******************************************** Model ********************************************/

    /**
     * Represents the Migration for the value.
     */
    private class Migration(val type: KClass<*>) {
        lateinit var source: Location
        lateinit var destination: Location
        var condition: (() -> Boolean)? = null
    }

    /**
     * Represents the [AbstractSettings] implementation and [String] key inside [AbstractSettings.prefs].
     * Source or destination.
     */
    private class Location {
        lateinit var clazz: KClass<out AbstractSettings>
        lateinit var key: String
    }
}
@arturbosch
Copy link
Member

Thanks for reporting, will be fixed in next release.

@lock
Copy link

lock bot commented Jun 20, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related topics.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants