Miha-x64 / Mikes_IDEA_extensions

IntelliJ IDEA: missing parts.
Apache License 2.0
34 stars 7 forks source link

Request: add inspection of having @UiThread (or similar annotations) to the overridden functions #24

Open AndroidDeveloperLB opened 2 years ago

AndroidDeveloperLB commented 2 years ago

Suppose you have a class :

open class Foo{

    @UiThread
    open fun onBindView(view: View) {
    }
}

Each class that extends it, the annotation should be added to this function, and we should have an inspection for it.

And same thing for abstract/interface, of course, and for similar annotations.

Miha-x64 commented 2 years ago

Hmm, this sounds questionable to me. @UiThread fun means “call this method from UI thread only”, @UiThread abstract fun means “this method is guaranteed to be called from UI thread”. But overridden method could be unconstrained, this is up to implementer. And the implementer themself may call it from any thread knowing that the method is pure or concurrent. The example is ProgressBar class which extends @UiThread View but has some synchronized methods.

AndroidDeveloperLB commented 2 years ago

But if I call the function (either inside the abstract class or from another class), I assume it should be on the UI thread, based on the parent. It can't be a background thread (you will get a warning when you change it to @WorkerThread) , and it's rare to make it @AnyThread too, because of possible breaking of what's in the parent class.

The IDE knows you should run it on the UI thread even if you didn't put the annotation, because the parent has it. See here:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val textView = TextView(this)
        thread {
            test(textView)
        }
    }

    @WorkerThread
    fun test(textView: TextView) {
        //you will get an IDE error/warning here:
        FooEx().onBindView(textView)
    }

    open class Foo {
        @UiThread
        open fun onBindView(view: View) {
        }
    }

    class FooEx : Foo() {
        override fun onBindView(view: View) {
        }
    }
}

The new inspection could say "missing annotation based on parent", and the first quick-fix (which is the correct one in 99% of the times) would be to add what's on the parent. This annotation can help finding bugs later, as the annotation should match what's on the parent.