StubUserLang has two problems:
- it's incompatible with type hints against the Language type, see e.g. T244300, T278429
- and it binds to global variables, which we want to remove, see T159283: Deprecate non-configuration globals.
When thinking about solutions for this, we have to keep in mind that the information for instantiating the user language object comes from the current web request (or alternative invocation context, when running maintenance scripts or background jobs). The necessary context information needs to be passed from the top level code in the entry point, probably the MediaWiki class. It's not known to service wiring code, and may not be obtained via a service. Also, we don't want to fully initialize the user or user language on all requests, or right away. This initialization should be deferred as long as possible.
Here are two possible approaches:
- Make a LazyLanguage class that is an actual Language implementation, but lazy-loads its state from a WebRequest or other context when needed. Initially, wouldn't even know its own language code. Once loaded, it would delegate all calls to the "real" Language instance internally.
- Instead of a Language object, we pass a context object somewhat similar to RequestContext, except that it doesn't use global state, and returns classes that are more narrow than what is currently exposed. It would have methods like getUser() and getRequest() and getUserLanguage().