startup classage expr81 { main(String[] args) { create TX(); } } classage TX = T + X with E >> F as K { TX() { :X(); } } classage T { mixer E { export void c() { return; } } plugger A { import void t0() import void t1() export void e(int x) {return; } } } classage X { X() { ::t(); } mixer F { export void b() { return; } } plugger A { import void t0() import void t1() export void t1() { print("OK from export t1 of A"); print("now passive call for t0 from inside t1 of A"); t0(); print("passive call ends"); } export void t2() { print("OK from export t2 of A"); print("now passive call for t0 and t1 from inside t2 of A"); t0(); t1(); print("passive call ends"); } } void t() { A x1, x2; print("[1]"); // the following line should have no effect, since currently // A is not satisfied by any plugins forall(h::A) {print("now inside forall before plugin:"); h..t1();} print("[2]"); //plugin happens here x1 = plugin Y with A >> B; print("[3]"); // now the t0 defined by Y's B should be invoked, pure import case x1..t0(); print("[4]"); // now the t1 defined by Y's B should be invoked, overriding case x1..t1(); print("[5]"); // now the t2 defined by X's A should be invoked, pure export case x1..t2(); print("[6]"); // the following line should now invoke t1 defined by Y's B, since // currently A is satisfied by one plugin, that is Y forall(h::A) {print("now inside forall after plugin:"); h..t1(); } print("[7]"); // another plugin happens here x2 = plugin Z with A >> B; print("[8]"); // now the t0 defined by Z's B should be invoked, pure import case x2..t0(); print("[9]"); // now the t1 defined by Z's B should be invoked, overriding case x2..t1(); print("[10]"); // now the t2 defined by X's A should be invoked, pure export case x2..t2(); print("[11]"); // the following line should now invoke t1 defined by Y's B, and // invoke t1 defined by Z's B, since currently A is satisfied by two // plugins forall(h::A) {print("now inside forall after plugin:"); h..t1(); } print("[12]"); //unplug unplug x1; print("[13]"); // the following line should now invoke t1 defined by Z's B, // since currently A is satisfied by one plugin, that is Z. forall(h::A) {print("now inside forall after unplug:"); h..t1();} print("[14]"); // if the following line are not commented out, runtime exception // will be thrown because x1 is currently stale. // x1..t0(); // x1..t1(); // x1..t2(); print("[15]"); //cascaded plugin/unplug unplug (plugin Y with A >> B); return; } } classage Y { mixer B { export void t0() { print("OK from export t0 of Y"); return; } export void t1() { print("OK from export t1 of Y"); return; } } } classage Z { mixer B { export void t0() { print("OK from export t0 of Z"); return; } export void t1() { print("OK from export t1 of Z"); return; } } }