Kotlin / anko

Pleasant Android application development
Apache License 2.0
15.89k stars 1.29k forks source link

Alertdialog can't find referenced class #400

Open IonAalbers opened 7 years ago

IonAalbers commented 7 years ago

If you are showing a alert dialog within a forEach loop, I get the following warning when compiling on the command line.

Warning: com.testapp.MainActivity$showDialog$1$1$2: can't find referenced class com.testapp.MainActivity$showDialog$1$1
Warning: com.testapp.MainActivity$showDialog$1$1$2: can't find referenced class com.testapp.MainActivity$showDialog$1$1

I used the following code to reproduce it:

    val list = ArrayList<String>();
    list.forEach {
        alert {
            message = "This message"
            positiveButton("Action", {
                doSomething()
            })
            negativeButton("Cancel", {})
        }.show()
    }

And this is caused by the empty lambda in the negativeButton, removing that solves the gradle warning.

This only happens when proguard is enabled (with the default rules file) Kotlin version: 1.1.2-4 anko commons: 0.10.0

Ornolfr commented 7 years ago

I have the same issue too. Removing anko's alert {...} fixes this issue, and I can't seem to find which proguard rule helps in this situation

huycn commented 7 years ago

I have a similar issue for a different piece of code:

class DepotActivity {
    var allCategories: SparseArray<Category>?
    ...
    fun showMenuFragment(fragmentTag: String, fragmentCreator: () -> DialogFragment) {...}
    ...
    private fun showCategoryChoice() {
        allCategories?.let { allCats ->
            showMenuFragment("categories") {
                val count = allCats.size()
                val categories = ArrayList<Category>(count)
                (0 until count).mapTo(categories) { allCats.valueAt(it) }
                categories.sortBy { it.name.toLowerCase(Locale.getDefault()) }
                CategoryViewFragment.newInstance(categories)
            }
        }
    }
}

It will raise a warning like: ...DepotActivity$showHideCategoryChoice$1$1$2: can't find referenced class ...DepotActivity$showHideCategoryChoice$1$1 When look at the generated code, it will create a class like ...DepotActivity$showHideCategoryChoice$$inlined$let$lambda$1 extends Lambda implements Function0 and the function showCategoryChoice is like:

private final void showCategoryChoice() {
  SparseArray var10000 = this.allCategories;
  if(this.allCategories != null) {
     SparseArray var1 = var10000;
     this.showMenuFragment("categories", (Function0)(new DepotActivity$showCategoryChoice$$inlined$let$lambda$1(var1, this)));
  }
}

Now if I change a little bit the function into:

private fun showCategoryChoice() {
    val allCats = allCategories
    if (allCats != null) {
        showHideMenuFragment("categories") {
        ...
        }
    }
}

Then there will be no Proguard warnings and if we look at the generated code, everything is inlined as expected, no extra class generated.

That being said, I don't thing this is related to anko but rather a bug in kotlin compiler