Ticket #178 (closed enhancement: fixed)

Opened 4 years ago

Last modified 4 years ago

Support role migration

Reported by: stephan Owned by: stephan
Priority: major Milestone: OTDT_1.2.5
Component: language Version: 1.2.4
Keywords: Cc:

Description

Currently, roles are immutably connected to their enclosing team, and bound roles are furthermore immutably connected to their base object.

In some situations it is desirable to change this link during a role's lifetime.

Yet, in normal situations the existing behavior should be kept, and in any case care should be taken to maintain consistency.

Change History

Changed 4 years ago by stephan

r19340 introduces a new marker interface ITeamMigratable to the effect that for all roles implementing this interface the compiler will generate the following method:

public final team class MyTeam {
    public class MyRole {
        MyRole<@otherTeam> migrateToTeam(final MyTeam otherTeam);
    }
}

After executing this method, a role will belong to the new team otherTeam. This implies, that MyTeam.this now refers to otherTeam and also the type of the role has changed to MyRole<@otherTeam> as indicated by the above signature.

In order to safely use this method, the following preconditions must be met:

  • The enclosing team must be final.
  • The role must not be bound (playedBy).
  • The role must be public (otherwise the return type would be illegal).

Note, that the signature in ITeamMigratable cannot exactly specify the desired return type (would require a type parameter that (a) is bound to the current type (a THIS type) and (b) has a value parameter -- neither is supported in Java 5 -- OT/J 1.2). Yet, the compiler performs type checking as if the desired signature were given.

One caveat remains: If the role has references to sibling roles (i.e., roles of the same team instance) these reference will become inter-team references after migration. Requiring the enclosing team to be final avoids any method not found errors, but the family guarantee as ensured by the use of dependent types no longer holds. This could introduce inconsistent object graphs that cannot be detected by the compiler.

Disciplined use of this feature should ensure that a role also migrates all referenced sibling roles (simply dropping a reference might also be an option).

For all roles that do not implement ITeamMigratable the old semantics is maintained.

Changed 4 years ago by stephan

The above change together with the option to override even final roles (since r19330) allows to implement "tournament polymorphism". See 1.3.20-otjld-tournament-polymorphism-3, where within a group of families of the same type family members can migrate from one family to another. At the same time a subtype hierarchy of families can be reflected by a hierarchy of groups of same families.

To map this description to the given test case use this mapping:

family Team1320tp3_1 members are of type R
sub-family Team1320tp3_2 changes wrt super are not shown
group Team1320tp3_3 family is "imported" as final class Nested
sub-group Team1320tp3_4 overrides Nested with the more specific import of sub-family

By default, overriding final roles is an error. For the batch compiler this can be changed by passing -warn:+overridefinalrole which lessens the problem to a warning. Within the IDE you would have to add the following line to the project preferences in .settings/org.eclipse.jdt.core.prefs:

org.objectteams.otdt.compiler.problem.override_final_role=warning

Note, that in no case a final role can be subclassed using extends.

Changed 4 years ago by stephan

  • status changed from new to closed
  • resolution set to fixed

r19346 adds the second kind of role migration: changing the attached base object of a role. This is achieved using a second marker interface: IBaseMigratable and the method defined therein:

        void migrateToBase(Object otherBase);

Again, despite the very general signature the compiler will ensure that only base objects of a suitable base type of the current role are passed. The generated method will also ensure that indeed a valid object argument is passed. I.e., passing null will cause a NullPointerException to be thrown (this also applies to team migration, above).

Other than that the role implementing IBaseMigratable must be a bound role, no special constraints must be met.

Base migration not only updates the role-base linkage but also the team's role cache, so lifting will respect the changes and also the team's reflective methods consistently operate on the new state.

See 2.1.13-otjld-base-migration-1 f.

While all changes in this ticket are still considered experimental I'm releasing this into 1.2.5. May need to re-open later, if evaluation of these features calls for changes.

Note: See TracTickets for help on using tickets.