Skip to content

IntelliJ Leonidas

Amir Sagiv edited this page Jul 1, 2017 · 1 revision

The Language definition

The Leonidas Language defines a way of representing tippers. Each tipper is created by specifying a legal Java 8 compilable Class: class TipperName extends LeonidasTipperDefinition In this class resides two methods:

  • matcher() - representing a general structure of a code that should be replaced.
  • replacer() - representing a general structure of a code that should be replaced to. Each of the two should always have \** start **\ and \** end **\ comments, to represent which sections of the replacer and the matcher are active. This is essential as sometimes, we want to capture a structure that its definition requires some extra not-interesting code. For example, if we wish to capture an access to an array as the root element of the tipper, we need to define it first, but the definition itself is irrelevant to the tipper.

Building Blocks

Most of the tippers defines a generic way of dealing with any instance of a certain language element. For example, if we wish to eliminate the redundant braces { } from a single-then statemented if statement, we would like a way to represent a statement, regardless of its content. We use an hierarchy of stub language elements (including Stub Method Based Architecture) to represent such generic elements. For Example: statement(1) for a statement, method0 for a method and so on. Each generic element representation holds an Integer which is the ID of the generic element. Thus ID is used to match correctly between an element in the matcher tree and an element in the replacer tree.

The Matcher

The Matcher class has the match method. It gets PsiElement that represent the partial tree that we want to match from the user. The matcher uses the pattern matching algorithm of SNOBOL4 to find if the tree of the user matcher the tree in the tipper. In addition, there is a mechanism of additional constraints that enables you to define every constriant you wish on a generic type.

If match returns true for those trees it means we can apply the tip on this partial tree in the user's source.

The Replacer

After the user presses "tip", the repalcer replaces the partial tree from the user's source with a new partial tree as defined in the tip, this is done with the Replacer class.

The main method in this class is replace which gets the user's partial tree that matched the matcher of the current tip. The matcher traverse the the matcher code and the user's tree and creates a mapping from the id's of the generic element in the template tree to the corresponding element in the user's tree. Afterwards Replacer traverse the replacer` tree and change it so that instead of having generic elements it will have the user's corresponding elements. When we finish creating a new partial tree that represents the user's part of source after we applied the tip, we replace the user's tree with the new tree we created.

Clone this wiki locally