Open stackotter opened 1 year ago
I'm trying to implement this, with good results already, however I am not sure what classRestriction
, metatype
and missing
cases of Type
should be mapped to in NormalizedType
.
Awesome! I reckon classRestriction should map to the nominal type AnyObject
(iirc it’s equivalent to that but I may be mistaken), metatype should be mapped to the member type X.Type
(where X
is the type that the metatype is of), and missing is a bit annoying. For missing it may turn out that macros are never invoked on malformed syntax (the only way that missing can appear in the AST afaik), in which case we could potentially fatalError on missing
earlier on (when initialising a Type
) since it’s meant to be unreachable; but for now maybe just add a missing case to NormalizedType and I’ll deal with that issue later.
A major pain point for many Macro developers is handling all of the different ways that users can write types. For example,
Void?
is equivalent toOptional<Void>
which is equivalent to(((((()))?)))
; what a nightmare!If you're going to complete this issue you may need a good understanding of Swift itself, but the issue should still be relatively approachable for anyone new to Swift Macros.
This task contains four main steps; I've tried to give enough detail for someone to jump in and complete this without looking around the codebase for too long (specifically for Hacktoberfest!)
NormalizedType
enum with the smallest possible number of cases to describe all types in Swift. See below for a rough idea of what this might look like.NormalizedType
enum: e.g.NormalizedTupleType
should be a copy ofTupleType
except with the element types beingNormalizedType
instead ofType
. This will create some duplication, but I think it's probably the best solution in the long run (as it provides a compile-time guarantee that a type and all subtypes within it have been normalized).func normalized() -> NormalizedType
method toType
(and implement accordingly)Type
'snormalizedDescription
computed property to useType
'snormalized
method under the hood instead of the hacky normalization it currently performs.The following steps would likely improve Quality of Life (but could be completed separately);
func normalized() -> NormalizedType
method in an extension ofTypeProtocol
which first converts the specific type to aType
and then normalizes it using the previously implementedType.normalized
method.NormalizedTypeProtocol
(by copyingTypeProtocol
and modifying where applicable) with an additional method or computed property to convert a normalized type back to an instance of theType
enum.NormalizedType
(a rough plan)Converting
Type
toNormalizedType
as simply as possible will tackle most forms of normalization. However, there are another two normalization patterns that need to be considered and aren't encoded in this new type:()
gets replaced byVoid
(aNormalizedSimpleType
), and(_)
gets replaced by_
(where_
is some arbitrary type).