-
Notifications
You must be signed in to change notification settings - Fork 56
IntelliJ Leonidas
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.
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
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.
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.