Kotlin / dukat

Converter of <any kind of declarations> to Kotlin external declarations
552 stars 42 forks source link

Type references are not generated properly for namespaces with dots #304

Open Kiryushin-Andrey opened 4 years ago

Kiryushin-Andrey commented 4 years ago

Consider the following TypeScript declarations:

declare namespace A.B {
    interface Bar {}
    namespace C {
        function foo(bar: Bar): void;
    }
}

Here we have a root namespace A.B with a dot in its name, and a nested namespace C with a declaration that references some type Bar from the containing A.B namespace.

Dukat generates two files with the following contents (omitting imports and file annotations for brevity):

// sample.A.B.kt
package A.B
external interface Bar

// sample.A.B.C.kt
package A.B.C
external fun foo(bar: B.Bar)

This code does not compile due to an invalid reference to the Bar type in the A.B.C package. I expect the foo declaration in A.B.C package to fully qualify the type of the bar parameter like this:

external fun foo(bar: A.B.Bar)

I found this issue when converting TypeScript declarations for Google Maps JS API (https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/googlemaps/reference). These declarations declare the root google.maps namespace and a bunch of nested namespaces like google.maps.data, google.maps.events and so forth. The generated Kotlin declarations then qualify any type from the root google.maps namespace with just maps each time such type is referenced in a nested namespace declaration:

package google.maps.event
...
// MapsEventListener declared in google.maps namespace
external fun removeListener(listener: maps.MapsEventListener)

So I had to manually clean up all these maps namespaces from type references and introduce an explicit import for a google.maps package instead.

I've seen a couple of exceptions from this behavior though - a type from the root namespace is fully qualified when referenced from a nested namespace if it serves as a base type or is an option of a discriminated union.