PIL/G

PIL/G adds a number of code generation-specific features to PIL.

Partial classes

Within one PIL artifact (e.g. a file) you can define multiple fragments of the same class by use of the @partial annotation. For instance:

    @partial
    class User {
       String name;
    }
    ...
    @partial
    class User {
       Int age;
    }

Will result in a single User class with both these properties. Partial classes can be convenient to formulate code generation rules that only generate code for a certain aspect of the application.

Partial methods

Similar to partial classes, partial methods are fragments of method that are automatically merged at compile-time. The order in which methods are merged is undefined and partial methods must have return type void.

    @partial
    class User {
      @partial
      void init() {
        name = "pete";
      }
    }
    ...
    @partial
    class User {
      @partial
      void init() {
        age = 40;
      }
    }

Expression blocks

Let's say we have the following (Web)DSL code fragment:

    var be : BlogEntry := BlogEntry { blog := b };

which we have to translate to PIL. Now, the constructors at the right-side of the assignment cannot be implemented in one expression, in fact, two statements are required to implement it. Expression blocks help with this type of problem. They allow a number of statements to be used to implement one expression. The translation could look as follows:

    BlogEntry be = {| BlogEntry e0 = new BlogEntry(); e0.setBlog(b); | e0 |};

where first a new BlogEntry object is instantiated and put in temporary variable e0. Subsequently the setBlog method is invoked on this temporary variable. The result of the expression is the value of e0.