Currently, handle_dynamic_class_or_module() in the indexer detects Class.new and Module.new calls by checking if the receiver name is Class or Module. However, this check happens before name resolution, so it can't distinguish between top-level ::Class/::Module and redefined constants with the same name.
Consider this example:
module Foo
class Module; end
class Class; end
Module.new # This is Foo::Module.new, NOT anonymous module creation
Class.new # This is Foo::Class.new, NOT anonymous class creation
end
Here, Foo::Module and Foo::Class are regular classes that shadow the top-level Module and Class. Calling .new on them should be treated as ordinary method calls, not as anonymous class/module definitions. But because the indexer only sees the unresolved name Module/Class, it incorrectly treats these as anonymous class/module creation.
The fix would be to move the anonymous class/module detection logic to the resolver pass, where constant resolution is available and we can determine whether Class/Module actually refers to ::Class/::Module.
Currently,
handle_dynamic_class_or_module()in the indexer detectsClass.newandModule.newcalls by checking if the receiver name isClassorModule. However, this check happens before name resolution, so it can't distinguish between top-level::Class/::Moduleand redefined constants with the same name.Consider this example:
Here,
Foo::ModuleandFoo::Classare regular classes that shadow the top-levelModuleandClass. Calling.newon them should be treated as ordinary method calls, not as anonymous class/module definitions. But because the indexer only sees the unresolved nameModule/Class, it incorrectly treats these as anonymous class/module creation.The fix would be to move the anonymous class/module detection logic to the resolver pass, where constant resolution is available and we can determine whether
Class/Moduleactually refers to::Class/::Module.