Integrated: 7903590: Refactor jextract source code generation

Jorn Vernee jvernee at openjdk.org
Mon Nov 27 14:12:43 UTC 2023


On Wed, 22 Nov 2023 07:38:29 GMT, Jorn Vernee <jvernee at openjdk.org> wrote:

> We currently use `ClassSourceBuilder` both for top level classes and nested classes. That means for instance that we need to check whether to generate package declarations and import statements, and for nested classes we also emit code into a separate intermediate buffer that is copied into the enclosing buffer when we end the nested class. This PR proposes splitting part of the logic in `ClassSourceBuilder` into a separate `SourceFileBuilder`, which handles package decl/imports, and holds the underling `StringBuilder` which allows a nested class to share the `StringBuilder` with its enclosing class. Each `SourceFileBuilder` produces exactly one `JavaFileObject`. `TopLevelBuilder` and `Constants` now aggregate over `SourceFileBuilder`s instead of `JavaSourceBuilder`s. This also allows reducing the number of classes that implement `JavaSourceBuilder` to just `TopLevelBuilder` and `StructBuilder`, and allows dropping several methods from the interface. Other builders now wrap `Source
 FileBuilder`, and emit code into its buffer.
> 
> Jextract source code generation related code currently relies on method overriding to allow sub classes to inject behavior into the generation code in a super class. This, however, makes it hard to follow what method implementation is actually being called when reading code. And, any method call may become 'suspicious' because it might do something non-obvious. For example, `emitConstructor` is overridden to do nothing in several sub-classes. But, this is not obvious when seeing the `emitConstructor()` call in `ClassSourceBuilder::classBegin`.
> 
> Furthermore, we use method overriding for instance to specify the class modifiers for a `ClassSourceBuilder` subclass, which means that control flow will flow through several class levels when generating code. This, and other cases, could be replaced by a simple (`String`) value passed to `ClassSourceBuilder` constructor. Using a direct field value in the generation code makes it clear that there is nothing special going on (as the method call might imply).
> 
> This PR proposes to remove most uses of method overriding, to make it easier to follow control flow when reading the code. This has a few implications:
> -  Direct field access is used where possible, and data is passed to *Builder constructors instead of through a virtual method call to a sub class implementation
> - `emitConstructor` was not needed in all cases. So, I've moved it from `ClassSourceBuilder::classBegin` to callers of that method...

This pull request has now been integrated.

Changeset: 42076349
Author:    Jorn Vernee <jvernee at openjdk.org>
URL:       https://git.openjdk.org/jextract/commit/420763490986d25c741a4368147ccea2f31cfd9a
Stats:     751 lines in 10 files changed: 255 ins; 327 del; 169 mod

7903590: Refactor jextract source code generation

Reviewed-by: mcimadamore

-------------

PR: https://git.openjdk.org/jextract/pull/141


More information about the jextract-dev mailing list