Draft idea about user defined annotation and processor


(Steve K. Chiu) #1

Hi,

This is yet another idea had been discussed but had no real conclusion. I
find this could be very useful for the framework developers, here is my
draft proposal.

First I should explain why this is useful for framework developers, let's
take some example:

1. add annotation to class to generate extension for JSON parsing and
serialization.
2. add annotation to property or function to generate glue code for
exporting to Lua script.
3. add annotation to function or class to generate c/objective-c and java
source for bridge JNI call.
4. add annotation to function or class to generate objective-c++ glue for
bridge c++ call.
5. add annotation to function or class to dynamically bind shared library
6. add annotation to class to generate stub/skeleton call for your favorite
RPC framework
7. add annotation to class to generate stub call for your favorite database
framework
8. etc... anything that can be systematically generated

Some of the problem can be solved with generic function, but many are not,
especially swift generic is a bit limited compared to C++ template.

Traditionally user defined annotation are for declaration only, and
basically a runtime feature that paired with reflection.
I did not find this arrangement particularly useful, and actually have some
shortcoming:

1. you need to actually store the annotation in final binary
2. it would help reverse engineering/hacking
3. runtime reflection is slow

So, why not just make the annotation and processing a compile time feature?

Application developer (user of framework) can annotation the source, the
annotation processor (written by framework developer) can read the
annotation and generate source code for further compile (not necessary
limited to generate swift only)

Of course, there are many difficulty with this approach, you have to revise
the compile processing pipe-line, build/make tool need to be revised too,
etc... But I think it did bring a lot of value to swift, especially when
you need to integrate swift with external framework or service.

There are many things need to be done to implement this feature:

1. Syntax for annotation, I would suggest:

@[ MyAnnotation1(), MyAnnotation2(option: "xxx", force: false) ]

It looks like old-time objective-c array, each element is an instance of
sub-class of Swift.Annotation, you can attach it alongside with built-in
annotation.

2. The processor should implement protocol Swift.AnnotationProcessor<T:
Swift.Annotation> , the protocol contract need to be determined later.

3. Need a way to forward declare function, so the annotation processor can
emit function implementation later.

4. Need a way to represent the class/method/etc code model for annotation
processor, much like reflection interface, but for compile time and with
declaration only.

5. And we need to divide compile pipeline into at least two phase, etc..

Anyway, we can always discuss the implementation later, giving all these
difficulties, I want to know your opinion about this arrangement and is it
worth the trouble? What do you think?


(Brent Royal-Gordon) #2

So, why not just make the annotation and processing a compile time feature?

Because what you are describing is a macro system, which would be out of scope for Swift 3. <https://github.com/apple/swift-evolution#out-of-scope>

ยทยทยท

--
Brent Royal-Gordon
Architechies