Repository: square/anvil
Issue: Factory generation: overloaded Provides functions

If a module has multiple overloaded `@Provides` functions with the same, only one Factory gets generated. 
Dagger gives an error `Cannot have more than one binding method with the same name in a single module` for such modules.

```
@Module
object MyModule {
    @Provides fun s(): String = ""
    @Provides fun s(s: String): Int = 1
}
```

Changed files:
compiler/src/test/java/com/squareup/anvil/compiler/dagger/ProvidesMethodFactoryGeneratorTest.kt
compiler/src/main/java/com/squareup/anvil/compiler/codegen/dagger/ProvidesMethodFactoryGenerator.kt

diff --git a/compiler/src/main/java/com/squareup/anvil/compiler/codegen/dagger/ProvidesMethodFactoryGenerator.kt b/compiler/src/main/java/com/squareup/anvil/compiler/codegen/dagger/ProvidesMethodFactoryGenerator.kt
index 47e4c69..3269652 100644
--- a/compiler/src/main/java/com/squareup/anvil/compiler/codegen/dagger/ProvidesMethodFactoryGenerator.kt
+++ b/compiler/src/main/java/com/squareup/anvil/compiler/codegen/dagger/ProvidesMethodFactoryGenerator.kt
@@ -1,5 +1,6 @@
 package com.squareup.anvil.compiler.codegen.dagger
 
+import com.squareup.anvil.compiler.AnvilCompilationException
 import com.squareup.anvil.compiler.codegen.CodeGenerator.GeneratedFile
 import com.squareup.anvil.compiler.codegen.PrivateCodeGenerator
 import com.squareup.anvil.compiler.codegen.addGeneratedByComment
@@ -55,6 +56,20 @@ internal class ProvidesMethodFactoryGenerator : PrivateCodeGenerator() {
               .functions(includeCompanionObjects = true)
               .asSequence()
               .filter { it.hasAnnotation(daggerProvidesFqName) }
+              .also { functions ->
+                // Check for duplicate function names.
+                val duplicateFunctions = functions
+                    .groupBy { it.requireFqName() }
+                    .filterValues { it.size > 1 }
+
+                if (duplicateFunctions.isNotEmpty()) {
+                  throw AnvilCompilationException(
+                      element = clazz,
+                      message = "Cannot have more than one binding method with the same name in " +
+                          "a single module: ${duplicateFunctions.keys.joinToString()}"
+                  )
+                }
+              }
               .forEach { function ->
                 generateFactoryClass(codeGenDir, module, clazz, function)
               }
diff --git a/compiler/src/test/java/com/squareup/anvil/compiler/dagger/ProvidesMethodFactoryGeneratorTest.kt b/compiler/src/test/java/com/squareup/anvil/compiler/dagger/ProvidesMethodFactoryGeneratorTest.kt
index a1c29b1..9943c7c 100644
--- a/compiler/src/test/java/com/squareup/anvil/compiler/dagger/ProvidesMethodFactoryGeneratorTest.kt
+++ b/compiler/src/test/java/com/squareup/anvil/compiler/dagger/ProvidesMethodFactoryGeneratorTest.kt
@@ -6,6 +6,7 @@ import com.squareup.anvil.compiler.daggerModule1
 import com.squareup.anvil.compiler.innerModule
 import com.squareup.anvil.compiler.isStatic
 import com.squareup.anvil.compiler.moduleFactoryClass
+import com.tschuchort.compiletesting.KotlinCompilation.ExitCode.COMPILATION_ERROR
 import com.tschuchort.compiletesting.KotlinCompilation.Result
 import dagger.Lazy
 import dagger.internal.Factory
@@ -2156,6 +2157,31 @@ public final class DaggerComponentInterface implements ComponentInterface {
     }
   }
 
+  @Test fun `an error is thrown for overloaded provider methods`() {
+    compile(
+        """
+        package com.squareup.test
+        
+        import dagger.Module
+        import dagger.Provides
+        import dagger.multibindings.ElementsIntoSet
+        
+        typealias StringList = List<String>
+        
+        @Module
+        object DaggerModule1 {
+            @Provides fun provideString(): String = ""
+            @Provides fun provideString(s: String): Int = 1
+        }
+        """
+    ) {
+      assertThat(exitCode).isEqualTo(COMPILATION_ERROR)
+      assertThat(messages).contains(
+          "Cannot have more than one binding method with the same name in a single module"
+      )
+    }
+  }
+
   private fun compile(
     source: String,
     block: Result.() -> Unit = { }