Tags for Software Engineering Activities in Eclipse
TagSEA was not implemented merely as a tool to support source code tagging in Java. It was designed as an extensible framework for creating tags within your working environment. Exemplary extensions have been created for tagging Java source, web pages, resources, and tasks.
Still, TagSEA was created for software developers concerned with being able to find source code. So, new with version 0.6.6, there are some features that make it easy for you to extend TagSEA to support the reading of standard-formatted waypoints from almost any source language.
From the early days of TagSEA, when only Java was supported, a standard syntax was defined as:
//@tag tag-names meta-data : message
Where tag-names
is a white-space-separated
list of tag names to be applied in the code, meta-data
is a white-space-separated list of meta data to be applied in the code,
and message
is a display message for the waypoint in
the code.
Tag names can be single words, or they can be part of a hierarchy. Hierarchies are defined by dot-separation between the tag words. For example:
//@tag hack bug.1234
Will create a waypoint that has the tags hack
and bug.1234
where 1234
is considered a sub-tag of bug
.
There are two types of meta-data that can be applied: names
and dates. Where a name can be specified by -name="name"
and a date can be specified by -date="date-code"
.
The date-code is a locale-specific date of the format languageCOUNTRY:date
.
For example, we can add an author and a date to the previous waypoint:
//@tag hack bug.1234 -author="Joe Shmidt" -date="enCA:01/01/01"
This would create a waypoint with an author of Joe Shmidt, and a date of January first, 2001 in English speaking Canada.
This standard format for parsed waypoints makes it easy to imagine the usage of parsed waypoints in many other languages besides Java. Since programming languages are just in plain text, and the text that we are considering is standard, the same parsers can be used to discover waypoints for all different languages. The only missing part of the puzzle is how to discover the areas of text that contain valid waypoints. Since waypoints can't be a part of the proper program, the natural place to put them is in comments. So, an extension point has been defined to allow extenders to contribute their own standard parsed waypoints.
Let's consider the Perl programming language. There are really only two pieces of information that we need to know about Perl: the standard file names that are used to define a Perl program; and the way that comments are defined in Perl.
In Eclipse, there is a way to define content types associated
with files. For example, the JDT defines a content type for files that
represent java programs. For this example, though, we don't want to
depend on any third-party Perl IDE plugins, so we will just use the file
extensions for Perl programs. These file extensions are .pl
and .pm
.
As for defining how the parser finds comments, there are two
steps. First, we must tell the plugin what characters to look for. For
Perl, this is straight-forward because Perl only has single-line
comments. The begin with a hash (#
) symbol. But we have to
be careful. There are certain cases when we don't want the hash-symbol
to be considered as a comment. For example, within strings or regex's.
Otherwise, a piece of code such as:
print "#1 : the first number\n";
would be considered a comment. In order to deal with these
situations, TagSEA provides an "exclusion" mechanism. We will define
areas within quote-like characters ('
and "
)
as areas to be excluded. We also want to ignore regex areas. Perl
complicates this by allowing the regex syntax to be changed dynamically.
Since we can't anticipate all possible scenarios, we will simplify the
problem by just excluding areas between the standard '/' characters. The
final plugin XML code looks like this:
<extension point="net.sourceforge.tagsea.parsed.standardComment"> <definition fileAssociations="*.pl,*.pm" kind="net.sourceforge.tagse.parsed.perl.waypoint" name="Parsed Per Waypoints"> <singleline open="#"> </singleline> <exclusion close="'" open="'"> </exclusion> <exclusion close=""" open="""> </exclusion> <exclusion close="/" open="/"> </exclusion> </definition> </extension>
And that's it. That is all you have to do. The TagSEA platform will automatically create the parsers, the markers, the icons, and the refactoring support for you. Now, you are ready to start using waypoints inside your Perl code.
Though everything you need is now available, and you are ready to
start using waypoints in your Perl code, it might be nice to tweek it a
little. For example, it would be nice to have a way of making sure that
Perl waypoints are distinguishable in the TagSEA ui. There is a simple
interface for this called IParsedWaypointPresentation
. It
offers a number of methods which provide images and labels for your
parsed waypoint.
For now, we are only interested in decorating an image to
indicate that the waypoint is in a Perl file. The standard image for
Perl is a camel . So we'll use that. TagSEA
also offers some decorations for images to indicate that an image is a
waypoint, and that it is parsed. We'll use those as well to decorate our
image. The methods of interest in our implementation are getImage(IWaypoint)
and getImage()
. They look like this:
public Image getImage(IWaypoint waypoint) { return getImage(); } public Image getImage() { ImageRegistry registry = PerlWaypointPlugin.getDefault().getImageRegistry(); Image image = registry.get("PERL_WAYPOINT_IMAGE"); if (image == null) { //construct the image from various adornments. Image base = registry.get("PERL_ICON"); ImageDescriptor overlay = TagSEAPlugin. getDefault(). getImageRegistry(). getDescriptor(ITagSEAImageConstants.IMG_WAYPOINT_OVERLAY); ImageDescriptor overlay2 = ParsedWaypointPlugin. getDefault(). getImageRegistry(). getDescriptor(IParsedWaypointImageConstants.PARSE_OVERLAY); DecorationOverlayIcon icon = new DecorationOverlayIcon( base, new ImageDescriptor[] { overlay, null, null, overlay2, null } ); registry.put("PERL_WAYPOINT_IMAGE", icon); image = registry.get("PERL_WAYPOINT_IMAGE"); } return image; }
This assumes that our plugin object has an icon called "PERL_ICON" in its image registry. That icon is the camel image.
Finally, we have to tell the plugin that the new waypoint kind has a presentation associated with it. This is done through the "presentation" attribute in the plugin xml. The final XML looks like this:
<extension point="net.sourceforge.tagsea.parsed.standardComment"> <definition fileAssociations="*.pl,*.pm" kind="net.sourceforge.tagse.parsed.perl.waypoint" name="Parsed Per Waypoints", presentation="net.sourceforge.tagsea.parsed.perl.PerlWaypointPresentation"> <singleline open="#"> </singleline> <exclusion close="'" open="'"> </exclusion> <exclusion close=""" open="""> </exclusion> <exclusion close="/" open="/"> </exclusion> </definition> </extension>
It is possible to create all kinds of different waypoints that don't necessarily follow the standard syntax, though
it is normally better to follow a standard way of writing waypoints. Nonetheless, another extension point--
net.sourceforge.tagsea.parsed.parsedWaypoint
exists for this purpose. It allows you to define your own
parsers and refactoring support. See the extension point documentation, and the example project
net.sourceforge.tagsea.parsed.javabang
for an example. The "javabang" plugin allows you to add tags in a
much more light-weight manner: by simply placing a back-tick (`) character in front of the word that you want
to be a tag. For example:
//this code is a `hack
The above will create a waypoint with the tag hack applied to it, and a message of this code is a hack. Other metadata is not supported by this kind of waypoint.
Note also that parsed waypoint kinds are not allowed to overlap in a file. If you have both Java waypoints and "Simple Java" waypoints installed, the following code will cause a conflict:
//@tag `hack : this code is a hack
Because the word `hack is recognized by both parsers.
It is possible to create waypoints for more than just source code, as well. TagSEA comes with several different
types of waypoints for waypointing on arbitrary resources, Java Task Tags, breakpoints, and URLs. These all use the
net.sourceforge.tagsea.waypoint
extension point. Using this extension point, you can create a new
Waypoint Delegate. Waypoint delegates are responsible for the full lifecycle of waypoints, from their creation
to their death. They are also responsible for reacting to changes to waypoints, and allowing/dissallowing those changes.
The following plugins make use of the net.sourceforge.tagsea.waypoint
extension point:
net.sourceforge.tagsea.url
net.sourceforge.tagsea.parsed
net.sourceforge.tagsea.tasks
net.sourceforge.tagsea.resources
net.sourceforge.tagsea.breakpoint