OTDT 1.3 - New and Noteworthy

Views

Colored labels since 1.2.1
#118

Colored labels are now supported for method mappings, too:

  • Search view and Call hierarchy can now display method mappings (callin/callout) with colored labels. By default this capability is used for displaying the declaring class in a shaded font color.

    CallHierachyColoredLabels

    Previously, earnCredit <- book would be displayed without the grey suffix.

Displaying guard predicates since 1.2.5
#179#181

Search view and Call hierarchy can now display guard predicates using the new icons (regular guard) and (base guard).

  • A guard is shown in the search view, if it contains references to the searched element:

    GuardpredicateSearch

  • As a node in the call hierarchy (caller mode), a guard lists all callin bindings which it controls as its children:

    GuardCallHierarchy

Improved callin markers since 1.2.5
#172, #185

In addition to method-level callin markers, corresponding markers for playedBy bindings are now supported, too.

  • When looking at the header of a base class it is immediately visible, if any roles are bound to this class.
    Callin markers

  • The marker's context menu supports easy navigation to the bound role class.
    Callin marker menu

Furthermore, callin markers are now represented by a green mark on the right overview ruler, and configurability using standard preferences has been stream-lined (Window->Preferences->General->Editors->Text Editors->Annotations).

As of #185 callin markers are now properly updated when a role has been modified in the editor (previously, updating was only implemented for changes in base classes).

since 1.2.6
#186

Additionally, callout bindings (to method / to field) which apply decapsulation are annotated with markers in both rulers of the editor:

Marker in overview ruler with tooltip:
Callout markers

Marker in left hand side ruler with context menu:
Callout markers

Decorations for roles since 1.2.8
#216, #220

Throughout all views, role icons may now have two additional decorations:

  • An override decoration for a role which overrides a role from the super-team (#220) (see also here).
  • A playedBy decoration for a role which is bound to a base class using playedBy (#216).

Additionally, the OT/J editor presents an override indicator in the ruler, which supports navigating to the overridden implicit super role (#220).

Role decorations

  • roles Subscriber and Item have both an override and a bound-role decoration
  • role FlightItem only has the bound-role decoration
  • decorations are shown in the outline and also in the breadcrumbs
  • the vertical ruler shows override annotations for Subscriber and Item
  • hover on such annotations says: "overrides bonussystem.Bonus.Item"
Not shown in the screenshot: the context menu on the vertical ruler offers the "Open super implementation" action, which in this case takes you directly to the overridden role "bonussystem.Bonus.Item".

These decorations/indicators can be configured in the preferences at ->General->Appearance->Label Decorations, respectively ->General->Editors->Text Editors->Annotations

Syntax highlighting
since 1.3.0M4
#271

Editors now automatically detect whether the current file is a team or role class or whether it contains plain Java code and adjusts syntax hightlighting accordingly. This consistently works for source and .class files.

Content Assist

Improved completion
since 1.2.1, since 1.2.2, since 1.2.5, since 1.2.6, since 1.3.0M2
several

Improvements regarding code completion:

  • Base-call completion is more robust now, see#134
  • Method bindings to invisible base features (private features of super-classes) are no longer proposed, see#138.
  • Internal variables (starting with _OT$) are no longer proposed as arguments to a method call, see#126.
  • since 1.2.2 Completion after tsuper. now only proposes the correct overridden method from the implicit super role, see#45.
  • since 1.2.5 Completion now works within guard predicates, too, see #180.
  • since 1.2.6 Completion can now be used to create a guard predicate, including the necessary pair of parantheses, see #191.
  • since 1.2.6 Completion now proposes base features which are available via inferred callout, see #129.
  • since 1.3.0M2 When overriding an implicitly inherited method the default method body now contains a tsuper call, see #234.
  • since 1.3.0M2 When creating a callout binding that overrides an inherited method the callout override token => is correctly used, see #170.

Improved and new quickfixes
since 1.2.1, since 1.2.6, since 1.2.7, since 1.2.8, since 1.3.0M3
several tickets

The following quickfixes have been added or improved:

  • Cross-file corrections since 1.2.1
    Previously, in OT/J code some quickfixes worked only within the current source file. This limitation has been removed in #12, #120, #238
  • Role constructor visibility: since 1.2.1
    Previously, the visibility of a role constructor could not be changed using a quickfix (this happened, because role constructors are internally translated to team-level methods). This limitation has been removed in #120
  • Callout method visibility: since 1.2.6
    To support the newly introduced modifiers of callout bindings, quickfixes regarding method visibility are now applicable to shorthand callout bindings, too #196
  • Add unimplemented methods: since 1.2.1
    Implicitly inherited abstract methods can now be added using a quickfix just like explicitly inherited ones. #143
    AddUnimplementedMethods
  • Add bundle activation policy: since 1.2.7
    Aspect bundles need a lazy activation policy in order for team activation to work. A new quickfix for this issue has been added (see #197).
  • Add @Override annotation for roles: since 1.2.8
    If a role overrides a role from its super-team, a missing @Override annotation can be added via quickfix (see #221).
  • Change qualified baseclass reference to using base import instead: since 1.3.0M3
    If a base class refers to its base class using the fully qualified name this is now signaled by the compiler (see below). A new quickfix is offered to change that reference to a simple name and use a base import instead (see #240).

Content assist for @role tags
since 1.2.5
#167

The OTJLD OTJLD 1.2.5(d) mentions a @role tag which should be used in the javadoc comment of a team class, for documenting role files that belong to the given team. This tag is now supported in compiler, search, UI and content assist.

Hovering over the name after a @role tag shows the javadoc of the referenced role file (of course, F3-navigation is supported, too):

If compiler warnings regarding missing and malformed javadoc are enabled, also missing or incorrect @role tags will be marked with a warning and a quickfix is provided:

Launching

Unified Launch Configuration Types
since 1.2.1,since 1.2.2
#137

Standard launches now support OT/J(for migrating old launches see below)

The OT/J specific launch types ( Object Teams Application, Object Teams Eclipse Application OT/Equinox Framework) are no longer needed and are gradually being faded out. Instead simply select one of these standard launch types

  • Java Application
  • JUnit
  • JUnit Plug-in Test
  • Eclipse Application
  • OSGi Framework
All these launches now consistently provide one additional checkbox, which is shown next to where the Runtime JRE is configured.

since 1.2.1

For Java Applications (, ) this checkbox is found on the JRE tab:

  • If the new option is checked the application will be launched with the Object Teams Runtime Environment (OTRE) enabled which is needed to weave callin bindings into base classes. Conversely, disabling the OTRE lets you run an OT/J application with all callin-bindings disabled. But note that a few more OT/J mechanisms will not work either (like decapsulation).
  • For OT/J projects this option is enabled by default.
  • If Enable OTRE is checked the known Team Activation tab will be shown, too.
    (If a launch configuration was opened while the OTRE was disabled, you need to re-open this configuration (e.g., unselect and select) in order for the new tab to show.)

since 1.2.2

For launching a Runtime Workbench (, ) the new checkbox is right on the main page:

since 1.2.2

For OSGi Framework launches () the runtime environment is configured on the Settings tab:

since 1.2.2

Migration Assistant

A migration assistant is provided for converting existing OT launch configurations to the new style. The assistent is invoked via Preferences > Run/Debug > Launching > Launch Configurations:

Debugging

Stepping options
since 1.3.0M4
#258

Step through / filter callin dispatch
Preference options have been added which select whether or not the internal dispatch for callin bindings is shown in the debugger when stepping through code.
If enabled the corresponding stack frames will be shown with a label Dispatch callins for yourBaseMethod.
Detailed description of stepping behavior is given in the OTDT help.

If this option is disabled, the debugger will skip such steps and directly enter the target of dispatch, either a callin binding or the base method.
The option is split into three sub-options available via Preferences -> Object Teams -> Debug

Language

Baseclass generalization
since 1.2.1

Base bounded type parameters
A new kind of bound for type parameters has been introduced in order to express that a team method expects as an argument any value that can be lifted to a given role type. This allows to generalize over otherwise unrelated base classes.
The new syntax is:

<B base Role0> void workWithRole(B as Role0 arg) { ... }

This method can be invoked with an argument of any type that can be lifted to Role0 which means the provided value must be conform to a base class Base1 that is bound to a given role Role1 (Role1 playedBy Base1) where Role1 is a subtype or equal Role0.

See BaseclassGeneralization in the wiki for application and further explanation.

since 1.2.8
#237

Since 1.2.8 baseclass generalization is fully integrated with team inheritance, which means that a method with declared lifting with a base-bounded type parameter will be re-interpreted for each sub-team. As a result it is even possible to use an unbound role with no bound sub-roles in the current team in a declared lifting signature, and leave the definition of bound sub-roles to a sub-team, without needing to redefine the team method that uses declared lifting (#237).

Generic bound roles
since 1.3.0M4
#192

While unbound role classes can use type parameters without further restrictions, this was not possible for bound roles. Since 1.3.0M4 it is now possible to bind a generic role class to a generic base class constrained by a new rule in OTJLD 2.1.2(e) — this paragraph also introduces and discusses the following example:

public class ValueTrafo<T> {
    public T transform(T val) throws Exception { /* ... */ }
}
public team class TransformTeam {
    protected class SafeTrafo<U> playedBy ValueTrafo<U> {
        U transform(U v) -> U transform(U val); 
        protected U safeTransform(U v) {
            try {
            	return transform(v);
            } catch (Exception e) {
            	return v;
            }
        }
    }
    <V> V perform(ValueTrafo<V> as SafeTrafo<V> trafo, V value) {
        return trafo.safeTransform(value);
    }
}
...
ValueTrafo<String> trafo = new ValueTrafo<String>();
TransformTeam safeTrafo = new TransformTeam();
String s = safeTrafo.perform(trafo, "Testing");

Incompatible covariance
since 1.2.1

The compiler now detects and correctly reports a situation where different incompatible versions of the same method are inherited along different paths. This can happen by an unfortunate combination of implicit inheritance and a covariantly redefined return type.
See this example (visibility modifiers omitted):

team class T1 {
  class R1 {
    A m() { return new A(); }
  }
  class R2 extends R1 {
    A m() { return new A(); }
  }
}
team class T2 extends T1 {
  class R1 { // overrides T1.R1
    B m() { return new B(); } // given B subtype of A, thus: covariant return type
  }
  // implicit role R2 inherits conflicting methods m() from T1.R2 and T2.R1.
}

In this example, role T2.R2 implicitly inherits m() from T1.R2 (returning A), which, however, is not compatible to the super version from T2.R1 (returning B). This is thus a violation against the new OTJLD 1.3.1(k).

Import in role files
since 1.2.2
#60

A small new paragraph in the OTJLD, OTJLD 1.2.5(f) defines how imports for role files are evaluated.

Role inheriting from regular class
since 1.2.3
#121

A small new paragraph in the OTJLD, OTJLD 1.3.2(e) clarifies the visibility of non-public methods which a role inherits from a non-role superclass. The essence of this rule is that such methods are accessible within the role but not exposed to clients of the role.

Base super call
since 1.2.4
#158

This new feature has been introduced as OTJLD 4.3(f). It solves a problem which typically arises, if a callin method replaces a base method containing a super-call, where this super-call should then be issued from the callin method instead. To support this situation the following syntax is introduced:

rm <- replace bm;
callin void rm() {
base.super.rm(); // behaves exactly as super.bm() would do within bm().
}

Warning for dangerous callin
since 1.2.5
#165

The compiler issues a new warning when one of the methods boolean equals(Object other) or int hashCode() is bound by callin. Such bindings are dangerous because the lifting infrastructure itself uses these methods during lifting, which can easily result in infinite recursions. However, test 9.2.4-otjld-is-executing-callin-called-5 demonstrates how such callin binding can be made safe by using isExecutingCallin() in a base guard. The warning can be silences by a @SuppressWarnings("dangerouscallin") annotation.

Java 6 compliance
since 1.2.5
#177

The compiler is now fully capable to produce valid byte code for compliance level 1.6.

Experimental: Role migration
since 1.2.5
#178

Normally, roles are immutably linked to their enclosing team and base instances. New capabilities have been added in OTJLD 6.2(e), by which a role may migrate to a new team or base instance. In order to enable this feature a role has to declare the new interface ITeamMigratable or IBaseMigratable as its superinterface. These interfaces tell the compiler to generate one or both of these methods:

MyRole<@otherTeam> migrateToTeam(final MyTeam otherTeam)
<B> void migrateToBase(B otherBase)
  • The first method migrates the current role (call target) to the team passed as argument, and returns the same role re-typed as a role of that new team (note, that the method signature in ITeamMigratable is actually less specific, but the compiler performs all desired checking as if the signature would specify the return type MyRole<@otherTeam>).
  • The second method migrates the current role (which must be a bound role) to a new base instance passed as argument.
Caveat: Team migration intentionally violates the rules of family polymorphism, which normally ensures that roles of different teams cannot be mixed. Using ITeamMigratable it is the responsibility of the programmer, to ensure that after migration no references across the team boundary will cause any harm. Traditional type-checking, which ensures that "NoSuchMethod" cannot occur at runtime is not affected by team migration, only the additional guarantees provided by dependent types can be compromised with team migration.
By contrast, base migration does not conflict with any type guarantees.

Modifiers of callout bindings
since 1.2.6
#195

A shorthand callout binding (OTJLD 3.1(i)) now by default inherits the visibility and static modifiers from its bound base feature. If the role method introduced by a shorthand callout binding should have different visility than its bound base feature, the callout binding may optionally specify a visibility modifier, like this:

protected void rm() -> void bm();

@Override annotation for roles
since 1.2.8
#176

It is now recommended that a role which overrides a role from the super-team is annotated with @Override. If checking of override annotations is enabled any missing or wrongly placed @Override annotation for a role class will be flagged, too.

public team class SubTeam extends SuperTeam { // assume SuperTeam has a role Role
@Override
protected class Role { ... }
}

Exceptions in guards
since 1.2.8
#214

When a guard throws an exception this is now caught by the generated dispatch code to the effect that a thrown exception is interpreted just like an evaluation to false. Additionally, if a guard possibly throws a declared exception this is signaled by a configurable warning of token "exceptioninguard".

Qualified baseclass reference
since 1.3.0M3
#240

A new diagnostic in category "bindingconventions" has been added if a role refers to its baseclass using a fully qualified name, because a base import should preferrably be used.

By default diagnostics of category "bindingconventions" are treated as warnings in OT/J projects and as errors in OT plug-in projects.

Decapsulation via base import
since 1.3.0M4
#250

When importing an inaccessible base class using an import base declaration a decapsulation warning is reported against that import. If this warning should be suppressed (using a @SuppressWarnings annotation) this had to happen at the toplevel class of the current file because Java doesn't support annotations for import declarations. However, declaration at the toplevel class (the team) may be more coarse grained than desired (disabling all decapsulation warnings for the entire team). Since 1.3.0M4 it is now possible to place this annotation at the corrsponding role rather then the enclosing team.

Decapsulation of final class
since 1.3.0M4
#242

Binding a role to a base class didn't pay attention to whether the base class is declared final or not. Yet, considering the similarity between inheritance and role playing, the intention behind marking a class as final might be to disallow any adaptation including role playing. For that reason, binding a role to a final base class is now reported as decapsulation, too.

Runtime

Weaving into system classes
since 1.2.3
#149

It is now possible to bind a role to a system class as its base class. Here "system class" means any class that is loaded via the bootstrap classpath, i.e., normally all classes from rt.jar. To leverage this feature, applications must be launched using the JPLIS mode, which otherwise has graduated from experimental status to being fully equivalent to the old JMangler based mode.

Still not all classes can be bound, simply because the runtime environment cannot intercept classes that were loaded before it could start its work. For that sake the compiler issues a warning when binding into classes from any java... or javax... packages (see #64)

OT/Equinox

Aspect binding negotiation
since 1.2.6
#199

OT/Equinox now offers an extension point for negotiation about aspect bindings and forced exports.
Extensions to org.objectteams.otequinox.aspectBindingNegotiators are consulted whenever the OT/Equinox runtime encounters an aspect binding or a request for a forced export. The intention is to give the user full control over which aspect bindings and forced exports (s)he likes to accept or not.

An example implementation is given by the optional feature org.objectteams.otequinox.aspectasker (in category "Object Teams Contributions"):
Negotation re Forced Export

Using a negotiator it is no longer necessary to specify all forced exports in configuration/config.ini.
See the extension point documentation.
since 1.2.8

Several inevitable threading issues in the first implementation forced us to re-implement the dialogs of the org.objectteams.otequinox.aspectasker using Swing instead of SWT. Since then, no further problems (like deadlocks) have been observed any more (#236).

OT/Equinox dependencies
since 1.2.1
#128

OT/Equinox has now even fewer dependencies.
Previously, OT/Equinox had a dependency on org.eclipse.core.runtime thus constraining the use of OT/Equinox in "pure" OSGi applications. As of 1.2.1 these dependencies have been reduced to:

  • org.eclipse.equinox.common
  • org.eclipse.equinox.registry
  • org.eclipse.osgi

Improved validation
since 1.2.7
#197, #203

The following validations have been added to make OT/Equinox safer:

Activation policy
Aspect bundles need a lazy activation policy in order for team activation to work. Checking for this condition has been added in #197 (see also the corresponding quickfix).
Adapting bundle fragments
When an aspect adapts classes from a bundle fragment, the aspect binding needs to be declared against the fragment's host bundle. A new element requiredFragment has been added to the schema of org.objectteams.otequinox.aspectBindings, whereby an aspect binding can declare that it requires a given fragment. Runtime validation for this specification has been added as per #203.

Multiplicities in aspect bindings
since 1.2.7
#206

A team can now officially be bound to multiple base plugins.
To secure this situation against multiple or inconsistent instantiation of a team class additional runtime validation has been added (#206).