jythontools/clamp — pull request #14 by cpburnz (2014-11-20 13:27:08+00:00)
Title: Support class and method annotations.

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 is constructed (e.g., before any methods with potential signatures and annotations are created). Instead of using a meta-class:

```python
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 the whole class has been constructed (instead of before):

```python
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()`:

```python
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:

- NOTE: Methods decorated with `@classmethod` or `@staticmethod` are not supported yet.

```
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:

```python
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:

```python
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:

```python
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
```