Additional Plural Information

Installation

The official installation instructions for Plural are available here.  Below is the (slightly more explicit) list of steps that I used.  If you have trouble, follow this exactly with a fresh version of Eclipse, and if it still doesn't work contact me with the exact problem symptoms you are seeing (including any error messages).

Running the Tool

Before running Plural, check the boxes on the Crystal menu as follows:
If you only have one project open and want to check all of it, use Crystal | Run Crystal to run the Plural tool.  If you only want to analyze one file, not all the files in all open projects, right-click on the file in the Eclipse Package Explorer and choose Crystal | Run Analyses.  If you get a bunch of warnings and want to clear them off, use Crystal | Clear Warnings.

Specifying a Framework in Plural

To see an example of specifying a framework in Plural, download the MiniEcipse example from Blackboard.  It's probably best to focus on MiniEclipseSimple.zip, which just specifies the framework interfaces and verifies a simple client.  The framework is supposed to be something like Eclipse, though it is vastly simplified.  The client, SimplePlugin.java, creates an instance of itself in main() and passes the instance to the run method of the Main class in the framework.  Plugin.java is an interface defining the Plugin lifecycle: Plugins start in the created state, in which start() is called, transitioning the plugin into the started state.  Finally stop() is called, transitioning the plugin into the stopped state.

The plugin must be able to interact with the framework, and so a FrameworkFacade interface is passed to each of the Plugin lifecycle callbacks.  The FrameworkFacade can itself be in one of three states: setup (which is when Plugin.start() is called), running, and teardown (which is when Plugin.stop() is called).  The Plugin methods are specified to take a FrameworkFacade interface in one of these states.  Our SimplePlugin registers a menu and associates it with an Action.  Note that it must do this in start() because the registerMenu() method in FrameworkFacade requires the FrameworkFacade to be in the "setup" state.  This shows how typestates can constrain the plugin to only call methods that are appropriate in a particular lifecycle callback.

FieldAccess specifications

One technical side note: any method implementation that, like SimplePlugin.start(), changes the state of the object (in this case from created to started) must be declared with a permission where fieldAccess=true.  The idea is that you transition from one state to another by making some changes to the object's fields.  Of course occasionally you don't actually have to change the fields, but Plural still requires this annotation, so put it in.  It is NOT necessary in interfaces, because they do not contain method implementations.  If you are using @Perm instead of @Full or similar, you must specify a permission on this with "this!fr", where the !fr is the string-based syntax for fieldAccess=true.  Note that this will NOT affect you if all you are doing is specifying interfaces; however, as soon as you check real code (even blank method bodies) with Plural, you'll have to pay attention to this.

Null checking

If you want to specify in a precondition or postcondition that an argument or result is not null, use the @Perm permission and say #0 != null.  Here #0 refers to the first argument; you can use #1 for the second method argument, etc., or this for the receiver or result for the result.  Here's an example:

@Perm(requires = "#0 != null", ensures = "result != null")
public Object identity(Object o) {
    return o;
}