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

Multiple extensions with the same name produces fully-qualified references #1604

Closed
damianw opened this issue Jun 27, 2023 · 1 comment
Closed
Labels

Comments

@damianw
Copy link
Contributor

damianw commented Jun 27, 2023

Describe the bug
Referencing multiple extension MemberNames with the same simple name leads to only one of them being imported, even though they have isExtension = true.

To Reproduce
Here is a unit test that exposes the problem:

/**
 * Referenced code:
 *
 * ```Kotlin
 * package pkg1
 *
 * class Foo
 *
 * fun Foo.doSomething() {}
 * ```
 *
 * ```Kotlin
 * package pkg2
 *
 * class Bar
 *
 * fun Bar.doSomething() {}
 * ```
 */
@Test
fun test() {
    val fooClassName = ClassName("pkg1", "Foo")
    val fooExtensionName = MemberName("pkg1", "doSomething", isExtension = true)
    val barClassName = ClassName("pkg2", "Bar")
    val barExtensionName = MemberName("pkg2", "doSomething", isExtension = true)
    val fileSpec = FileSpec
        .builder("app", "MyFile")
        .addFunction(
            FunSpec
                .builder("doSomethingWith")
                .addParameter("foo", fooClassName)
                .addStatement("foo.%M()", fooExtensionName)
                .build()
        )
        .addFunction(
            FunSpec
                .builder("doSomethingWith")
                .addParameter("bar", barClassName)
                .addStatement("bar.%M()", barExtensionName)
                .build()
        )
        .build()
    val expected = """
        package app

        import kotlin.Unit
        import pkg1.Foo
        import pkg1.doSomething
        import pkg2.Bar
        import pkg2.doSomething

        public fun doSomethingWith(foo: Foo): Unit {
          foo.doSomething()
        }

        public fun doSomethingWith(bar: Bar): Unit {
          bar.doSomething()
        }
    """.trimIndent()
    assertEquals(expected, fileSpec.toString())
}

Expected behavior

The result of generating the above code should be:

package app

import kotlin.Unit
import pkg1.Foo
import pkg1.doSomething
import pkg2.Bar
import pkg2.doSomething

public fun doSomethingWith(foo: Foo): Unit {
  foo.doSomething()
}

public fun doSomethingWith(bar: Bar): Unit {
  bar.doSomething()
}

Actual behavior

The generated code fully-qualifies one of the two extensions, which cannot be compiled:

package app

import kotlin.Unit
import pkg1.Foo
import pkg1.doSomething
import pkg2.Bar

public fun doSomethingWith(foo: Foo): Unit {
  foo.doSomething()
}

public fun doSomethingWith(bar: Bar): Unit {
  bar.pkg2.doSomething()
}

Additional context
Using version 1.12.0

@damianw damianw added the bug label Jun 27, 2023
@Egorand
Copy link
Collaborator

Egorand commented Jun 28, 2023

1.13.0 shipped with auto-generated import aliases for conflicting imports, on 1.14.2 your test case produces the following output, which compiles:

package app
    
import pkg1.Foo
import pkg2.Bar
import pkg1.doSomething as pkg1DoSomething
import pkg2.doSomething as pkg2DoSomething
    
public fun doSomethingWith(foo: Foo) {
  foo.pkg1DoSomething()
}
    
public fun doSomethingWith(bar: Bar) {
  bar.pkg2DoSomething()
}

That said, we should probably allow duplicate member imports as long as the package name is different - I'll open a different ticket for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants