uber / motif

A simple DI API for Android / Java
Apache License 2.0
534 stars 43 forks source link

Fix StackOverflowError on types with self-references #261

Open psteiger opened 9 months ago

psteiger commented 9 months ago

Description:

When we have self types (implemented by recursive generics), Motif fails with StackOverflowError:

    at com.uber.xprocessing.ext.XTypeKt.hasCollectionType(XType.kt:316)
    at com.uber.xprocessing.ext.XTypeKt.hasCollectionType(XType.kt:316)
    at com.uber.xprocessing.ext.XTypeKt.hasCollectionType(XType.kt:316)
        ...

The following code seems to trigger that condition:

open class BaseRouter<out R : BaseRouter<R, *>, I : BaseInteractor<*, *, *>>(
    interactor: I,
) : Router<I>(interactor)

abstract class BaseInteractor<P : Any, I : BaseInteractor<*, I, *>, R : BaseRouter<R, I>>(
    presenter: P,
) : Interactor<P, R>(presenter) 
public class ConcreteInteractor extends 
    BaseInteractor<EmptyPresenter, ConcreteInteractor, ConcreteRouter>

public class ConcreteRouter extends
    BaseRouter<ConcreteRouter, ConcreteInteractor>
   ...

This PR changes XType.hasCollectionType() implementation to:

  1. Not re-process types that were already processed
  2. Use a queue instead of recursion (to avoid StackOverflowError for big enough type trees).

Test

Created a local build, built and ran one of our apps with the local build.

davissuber commented 9 months ago

Code looks great; could we add a test?

davissuber commented 9 months ago

Some extra investigation notes regarding the room-compiler-processing library: