How to force a concrete class inheriting some superclass/trait to be a case object?

Say you have this class-hierarchy:

trait Super

abstract class Middle extends Super

case object Concrete extends Middle

object OtherConcrete extends Middle // want this to compile-error
class SomeClass extends Middle // want this to compile-error
class OtherClass extends Super // want this to compile-error

Is it possible to write a macro, or some other mechanism, to enforce the concrete classes (which all inherit from Super) to be case object?

I’m not interested in solutions involving sealed trait/classes.

Is it possible?

Thanks.


Andreas

No, but why do you want to do this? There may be a better approach.

I have a very specific need to implement a generic trait and being able to reference them “statically” (as in MyObject.caseObject and have a method getName in the super-trait which returns the String "caseObject" (in this case) which would simply be calling toString in that case. Current solution calls getClass.getSimpleName (and removed the trailing $), but that returns “” (empty-string) when classes are reloaded using JRebel, which makes development a pain.

I suspect a typeclass would solve your problem, but it’s hard to know without more information about what you’re trying to do.

Based on my example above:

trait Super {
    def getName: String = {
      getClass.getSimpleName // Fails after JRebel reloads class as getSimpleName returns ""
    }
}

abstract class Middle extends Super

object MyStuff {
    case object ConcreteStuff extends Middle

    object OtherConcrete extends Middle // want this to compile-error
    class SomeClass extends Middle // want this to compile-error
    class OtherClass extends Super // want this to compile-error
}

I have a use-case where some code operates on the trait Super and getName should always yield the object's name “as in code”, and case objects do just that. So when passed MyStuff.ConcreteStuff (which is an impl. of Super), getName should return "ConcreteStuff".

The reason I don’t use TypeClasses here is that then I have to write boilerplate for each inherited sub-class (I think), and I want to be able to write as little code as possible, but ensure that getName returns the object’s “code-name”.