While internally enums are mostly the same as classes, their output in
`ReflectionClass::__toString()` should show the enum as the developer wrote it,
rather than as the engine stored it. Accordingly
- Say that the enum is an enum, not a final class
- Include the backing type, if any, in the declaration line
- List enum cases separately from constants, and show the underlying values, if
any
GH-15766
Instead mark name/value as readonly and the class as
NO_DYNAMIC_PROPERTIES. This gives us the desired limitations
using native features.
In fact, this also fixes a bug where opcache cache slot merging
might result in a write to the name/value properties being
allowed. The readonly implementation handles this case correctly.