§4.8 Callin precedence

If multiple callins from the same team refer to the same base method and also have the same callin modifier (before, after or replace), the order in which the callin bindings shall be triggered has to be declared using a precedence declaration.

(a) Precedence declaration

A precedence declaration consists of the keyword precedence followed by a list of names referring to callin bindings (see §4.1.(e) for named callin bindings).
A precedence declaration is only legal within a role or team class.

(b) Qualified and unqualified names

Within a role class a callin binding may be referenced by its unqualified name. A precedence declaration in a team class must qualify the callin name with the name of the declaring role class. A team with nested teams may concat role class names. Elements of a qualified callin name are separated by ".".
The callin binding must be found in the role specified by the qualifying prefix or in the enclosing role for unqualified names, or any super class of this role (including implicit super classes §1.3.1).

(c) Class based precedence

At the team level a precedence declaration may contain role class names without explicitly mentioning callin bindings in order to refer to all callin bindings of the role.

(d) Multiple precedence statements

All precedence statements are collected at the outer-most team. At that level all precedence declarations involving the same base method are merged using the C3 algorithm [3]. It is an error to declare incompatible precedence lists that cannot be merged by the C3 algorithm.

(e) Binding overriding

Precedence declarations may conflict with overriding of callin bindings (see §4.1.(e)): For each pair of callin bindings of which one callin binding overrides the other one, precedence declarations are not applicable, since dynamic binding will already select exactly one callin binding.
It is an error to explicitly mention such a pair of overriding callin bindings in a precedence declaration.
When a class-based precedence declaration implicitly refers to a callin binding that is overridden by, or overrides any other callin binding within the same precedence declaration, this does not affect the fact, that the most specific callin binding overrides less specific ones.

Callin binding example
1
public class LogLogin playedBy Database {
2
  callin void log (String what) {
3
    System.out.println("enter " + what);
4
    base.log(what.toLowerCase());
5
    System.out.println("leave " + what);
6
  }
7
  void log(String what) <- replace void login(String uid, String passwd) 
8
    with { what <- uid }
9
}
10
(new Database()).login("Admin", "Passwd");
Effects:

Provided the callin bindings are active (cf. §5) then:

  • the call in line 10 is intercepted by method log of role LogLogin.
  • the call target of log is a role of type LogLogin which is created by lifting the original call target (of type Database) to LogLogin.
  • only parameter uid is passed to log (bound to formal parameter what).
  • within method log the base call (line 4) invokes the original method passing a modified uid (converted to lower case, cf. line 4) and the unmodified password, which is hidden from the callin method due to the parameter mapping in line 8.