HexUML - Development of a code-generation tool for simulations

Transform your code into visual models with ease using HexUML

June 1st, 2021

Back

Outline

HexUML is my bachelor thesis, which was created collaboratively with a class-mate.

The SDU Center for Energy Informatics creates ecosystem maps, UML-like representations of agents, roles, value-chains, and interactions in an ecosystem, for the energy sector. They currently create simulations manually, which is tedious and error-prone. They aim to generate simulation-ready code from ecosystem maps to streamline the process and prevent misinterpretations. They aim of this project is to create a multi-purpose code generator that supports visual representations that can be translated to code.

Challenges

One of the primary challenges is designing the input data for the code generator. There are different ways to build a code generator, including those that rely on an API, a structured model, or parsing data from supported files. Each approach has its benefits and limitations.

Another challenge is targeting the output source, such as generating code for a specific programming language that adheres to its syntax, best practices, and formatting. This requires extensive knowledge of the output and can limit code generation to certain file formats. In addition, creating an efficient code generator requires managing memory and selecting the right generation approach while maintaining good performance.

An intermediate model (meta-model) is necessary to hold the data and ensure it is flexible enough to allow for slight differences in syntaxes or concepts while being founded in theoretics. The current availability of service-oriented code generators is not user-friendly or interesting enough for widespread adoption.

Methodology

To create a viable product, various methodologies have been implemented. Specifically, scrum and its ceremonies have been heavily used to ensure plans are being kept and the project is iteratively improved to meet the aim. Pair programming and black-box programming have also been utilized to provide a high code cohesion while having a low coupling and maintaining an understanding between the two group members.

Lastly, the project is developed using test-driven development, which in theory, makes the delivered product more stable and protects the codebase against errors that can cascade through a project. Continuous integration ensured that only code passing the tests could be merged with the main branch.

Code conversion

The process of generating code is complex and there are many different approaches that can be used. HexUML uses a combination of text-to-model and model-to-text conversion to translate input from one language into another. This process consists of two steps: first, a parser converts the input into a unified intermediate model, and second, a generator combines template files with the intermediate model to create the desired output. This process is depicted in a simplified overview in Figure 5.4, and more detailed information is provided in Chapter 6.

The template engine

The Template Engine is a core component of HexUML that combines a template file with variables to create an output code file or a section of another template file. It was influenced by Laravel's Blade template engine and .NET's Razor template engine but was found to be insufficient for code generation as it was primarily designed for outputting HTML. As a result, a code-optimized template engine was developed instead.

Transpiling templates

A template file is instantiated with the name of the template to process and the base directory to look for the template. Variables are assigned within the template using the data class, which contains a key-value dictionary allowing the user to set variables. The template class accepts a wide range of data types, such as primitives, arrays, and complex objects like Plain Old CLR Objects.

Template template = new Template("Interface", "assets/csharp-9.0");
template.Data.Add("interfaceName", "IHelloWorld");
template.Data.Add("visibility", "public");
string output = new TemplateEngine.Engine().Transpile(template);

Using HexUML

HexUML can be utilized in four different ways:

  • CLI - Allows users to make a conversion from the terminal - the application serves as a developer-friendly UI in this case.
  • GrapGQL API - Made it easy to use the application without downloading and installing. GraphQL has the benefit that it's to some degree self-explanatory as it "documents itself."
  • WebInterface - Allows the user to access a web interface where files can be uploaded and processed.
  • GitHub Actions - Allows developers to have their code automatically converted on push. This is useful if you want to create PlantUML diagrams based on your codebase each time it changes.¨

Testing the solution

Testing is an essential aspect of software development and helps ensure that the code written lives up to expectations. Testing also facilitates agile development. Four types of testing have been practiced throughout the development of HexUML. Unit testing is done to validate the functionality of a single piece of code, while integration testing is done to test multiple components when put together. System testing ensures that the entirety of the project is working as anticipated, and acceptance testing covers the project's scope to ensure that every requirement is realized. HexUML has been thoroughly tested to ensure that every part of the project works as intended and meets client expectations, even though there is no specific business owner.

Stack

.NET
AnyLogic
ASP:NET
GitHub Actions
GraphQL