jythontools / clamp

Implements clamp in Python. Pre-alpha version - API subject to change.
Apache License 2.0
38 stars 10 forks source link

Support class and method annotations. #14

Open cpburnz opened 9 years ago

cpburnz commented 9 years ago

I have implemented Java annotations for both Python classes and methods, as well as method signatures. I added jUnit tests to support that the implementation works as expected. Support for field signatures and annotations is being worked on, but is not included in this pull request. I would like my work reviewed. Please let me know If you have any questions, critiques, or objections.

The method to clamp a class has changed because the clamp meta-class is called and compiles the class before any class decorators are applied. Instead of using a meta-class:

from java.lang import Object
from clamp import clamp_base

BarBase = clamp_base("bar")

class BarClamp(BarBase, Object):
    ...

The @clamp_class() decorator is used to clamp the class. This compiles the class once it is decorated which happens after any other decorators on the class have been applied:

from java.lang import Object, String, Void
from clamp.declarative import clamp_class

@clamp_class("bar")
class BarClamp(Object):
    ...

A class can be annotated using @annotate() but it must be applied before (i.e., below) @clamp_class():

from java.lang import Object
from clamp.declarative import annotate, clamp_class
from ... import AnnotationClass

@clamp_class("bar")
@annotate(AnnotationClass, field1=value1, ...)
class BarClamp(Object):
    ...

A method signature can be specified using @method() which must be the first (i.e., bottom most decorator). A method decorated with @method() will be exported to the Java class file and directly accessible from Java:

from java.lang import Object, String
from clamp.declarative import annotate, clamp_class, method

@clamp_class("bar")
class BarClamp(Object):

    @method(String, (String, String))
    def concat(self, string1, string2):
        return string1 + string2

Exception information can be added to the method signature using @throws() after (i.e., above) the @method() decorator:

from java.io import FileNotFoundException
from java.lang import Object, String, Void
from clamp.declarative import annotate, clamp_class, method, throws

@clamp_class("bar")
class BarClamp(Object):

    @throws(FileNotFoundException)
    @method(Void.TYPE, (String,))
    def findFile(self, filename):
        raise FileNotFoundException()

A method can be annotated using the @annotate() decorator after (i.e., above) the @method() decorator as well:

from java.lang import Object, Void
from clamp.declarative import annotate, clamp_class
from ... import AnnotationClass

@clamp_class("bar")
class BarClamp(Object):

    @annotate(AnnotationClass, field1=value1, ...)
    @method(Void.TYPE)
    def foo(self):
        pass

A method's arguments can also be annotated by name using @annotate() after (i.e., above) the @method() decorator:

from java.lang import Object, Void
from clamp.declarative import annotate, clamp_class
from ... import AnnotationClass

@clamp_class("bar")
class BarClamp(Object):

    @annotate('one', AnnotationClass, field1=value1, ...)
    @annotate('two', AnnotationClass, field1=value1, ...)
    @annotate('three', AnnotationClass, field1=value1, ...)
    @method(Void.TYPE, (Object, Object, Object))
    def foo(self, one, two, three):
        pass