Add checks that Enum subclasses are being used properly

Summary: Do a bunch of checks on classes extending Enums to make sure they are being used at least somewhat reasonably. This means checking that all constants are actually compatible with the declared type, enforcing that only int, string, and mixed can be used, and only allowing int and string constants when the type is mixed.

We also make the declared Enum type the type for each of the constants.

We also want to allow abstract types to be used if the actual underlying type is int or string, which requires some pretty tasteless abstraction breaking.

Reviewed By: @elgenie

Differential Revision: D1388879