LWO #002: Annotations are just modifiers, array access curiosity, faux code generators and more
Tags: java, devjournal
Published: 2022-11-24 10:23:08

Hi, welcome to the second edition of Last Week in Objectos (LWO).

In this edition I will discuss:

- a few of my findings about the Java language while working on Objectos Code; and
- the last week's work on Objectos Code itself.

Let's begin.

## Annotations are just modifiers (grammatically speaking)

I didn't know that, grammatically (syntactically?) speaking, annotations are just modifiers to the [Java language](https://docs.oracle.com/javase/specs/jls/se19/html/index.html). In other words, I have always thought that the only way to annotate, say a method, would be:

```java
@Override
public final String toString() {
  return "Annotations are just modifiers";
}
```

But, in fact, you can write:

```java
public @Override final String toString() ...
```

Or, if you prefer:

```java
public final @Override String toString() ...
```

I always thought that the last two examples would fail to compile. But they do not; all of the three declarations are syntactically correct.

Additionally, all of the three declarations are equivalent. Well, there is a small caveat in the last example regarding type annotations, which we'll look into at another time.

I found out about it when reading the grammar [production](https://en.wikipedia.org/wiki/Production_(computer_science)) of method declarations:

```
MethodDeclaration:
  {MethodModifier} MethodHeader MethodBody
```

It means that a method declaration can contain zero or more `MethodModifier`. The `MethodModifier` production is defined as:

```
MethodModifier:
  (one of)
  Annotation public protected private
  abstract static final synchronized native strictfp
```

So any of the _modifiers_ can appear in any order. Cool!

## An Array Access Expression curiosity

[Array access expressions](https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.10.3) are expressions to, well, access a component of an array.

A simple example can be:

```java
String[] a = { "array", "access" };
System.out.println(a[1]);
```

The argument to the `println` method, i.e. the `a[1]`, is an array access expression.

The following is wrong and does not compile:

```java
System.out.println(this[1]);
```

But why does it not compile? Well, that's what is curious to me. I thought it failed to compile simply because the "syntax is invalid". But that is not exactly what happens in this case.

Let's try to compile and run the following program:

```java
public class Test {
  public static void main(String[] args) {
    new Test().execute();
  }
  
  public void execute() {
    System.out.println(this[1]);
  }
}
```

When I try to run it:

```
$ java Test.java
Test.java:7: error: array required, but Test found
  System.out.println(this[1]);
                         ^
1 error
error: compilation failed
```

It fails to compile because `this` does not evaluate to an array type. So, in some ways, the syntax itself is valid. But, as `this` resolves to a non-array type, it fails to compile.

This is expected as it is defined in the language specification. The `ArrayAccess` production is given by the following:

```
ArrayAccess:
  ExpressionName [ Expression ]
  PrimaryNoNewArray [ Expression ]
  ArrayCreationExpressionWithInitializer [ Expression ]
```

We are interested in the second form, the one with `PrimaryNoNewArray`. `PrimaryNoNewArray` is defined as:

```
Literal
ClassLiteral
this
TypeName . this
( Expression )
ClassInstanceCreationExpression
FieldAccess
ArrayAccess
MethodInvocation
MethodReference
``` 

So the following (wrong) examples:

```java
1234[0];
Object.class[1];
this[2];
Outer.this[3];
```

All fail to compile. But not because the "syntax is invalid". Instead, they fail to compile because the part to left of the brackets do not evaluate to an array type.

## Faux code generators

I am creating Objectos Code because I write a lot of code generators. But parts of Objectos Code itself might benefit of having them being generated. What to do in this case?

Well, I write a plain "faux" (ad-hoc?) code generator. It looks a bit like this:

```java
import static java.lang.System.out;

public class ByteCodeFauxGenerator {
  private int value = -1;
  
  public static void main(String[] args) {
    var gen = new ByteCodeFauxGenerator();

    gen.execute();
  }

  public final void execute() {
    comment("class");

    value("CLASS");
    value("MODIFIER");
    value("IDENTIFIER");

    comment("statements");

    value("LOCAL_VARIABLE");
    value("RETURN_STATEMENT");
  }  

  private void comment(String string) {
    out.println();
    out.println("// " + string);
    out.println();
  }

  private void value(String string) {
    out.println("static final int " + string + " = " + value-- + ";");
  }  
}
```

This code resides in the `src/test/java` directory of the project. It has a `main` method, so I can just run it. It prints:

```
// class

static final int CLASS = -1;
static final int MODIFIER = -2;
static final int IDENTIFIER = -3;

// statements

static final int LOCAL_VARIABLE = -4;
static final int RETURN_STATEMENT = -5;
```

Then I copy this output and paste it into the actual class, located in `src/main/java`:

```java
final class ByteCode {
  // class

  static final int CLASS = -1;
  static final int MODIFIER = -2;
  static final int IDENTIFIER = -3;

  // statements

  static final int LOCAL_VARIABLE = -4;
  static final int RETURN_STATEMENT = -5;

  private ByteCode() {}
}
```

I call it a "faux" code generator because the process is manual. Even though it is manual, it is still effective.

## Last week in Objectos Code

And here is a summary of the work I have done in Objectos Code.

### Lambda inclusion support

To generate a class with a single field you write the following in Objectos Code:

```java
_class(
  id("Example"),
  field(_int(), id("a"))
);
```

It generates the following:

```java
class Example {
  int a;
}
```

What if you don't know beforehand the number and names of the fields to be generated?

To this use-case, Objectos Code offers the `include` directive:

```java
public class IncludeExample extends JavaTemplate {
  private final List<String> fieldNames = List.of("a", "b", "c");

  @Override
  protected final void definition() {
    _class(
      id("Example"),
      include(this::generateFields)
    );
  }

  private void generateFields() {
    for (var fieldName : fieldNames) {
      field(_int(), id(fieldName));
    }
  }
}
```

Which should generate:

```java
class Example {
  int a;
  
  int b;
  
  int c;
}
```

[Remember](/blog/last-week-in-objectos-001.html) that Objectos Code is a pure Java template. So the previous example is equivalent to the following string-based template:

```
class Example {
  {{#fieldNames}
  int {{.}};
  {{/fieldNames}
}
```

### Constructor declarations, assignment expressions, and field access expressions

I have started the implementation of constructor declarations. The following Objectos Code:

```java
_class(
  id("Foo"),
  field(_final(), _int(), id("a")),
  constructor(
    param(_int(), id("a"),
    assign(n(_this(), "a"), n("a"))
  )
);
```

Generates the following Java code:

```java
class Foo {
  final int a;
  
  Foo(int a) {
    this.a = a;
  }
}
```

### More enum declarations

I have also continued the work on enum declarations. Enum class declarations are currently required in Objectos HTML.

The following Objectos Code: 

```java
var test = PackageName.of("test");
var iface = ClassName.of(test, "Iface");

_enum(
  _public(), id("Test"), _implements(iface),
  enumConstant(id("A"), s("a")),
  enumConstant(id("B"), s("b")),
  field(_private(), _final(), t(String.class), id("value")),
  constructor(
    _private(),
    param(t(String.class), id("value")),
    assign(n(_this(), "value"), n("value"))
  ),
  method(
    annotation(Override.class),
    _public(), _final(), t(String.class), id("toString"),
    _return(n("value"))
  )
);
```

Generates:

```java
public enum Test implements test.Iface {
  A("a"),

  B("b");

  private final java.lang.String value;

  private Test(java.lang.String value) {
    this.value = value;
  }

  @java.lang.Override
  public final java.lang.String toString() {
    return value;
  }
}
```

## Until the next edition

So that's it for today. I hope you've enjoyed reading.

You can find the source code in this [GitHub repository](https://github.com/objectos/blog-examples/tree/master/p022-lwo-002/src/test/java/post). 

Please [send me an e-mail](mailto:marcio@objectos.com.br) if you have comments, questions or corrections regarding this post.

If you liked this content you can follow me on [Twitter](https://twitter.com/marcioendo).