Skip to content

Commit a7b27d8

Browse files
committed
RoleDeclarations now being added to FunctionDeclaration object
1 parent 34bf783 commit a7b27d8

File tree

9 files changed

+369
-62
lines changed

9 files changed

+369
-62
lines changed

samples/dci/_goal.html

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,97 @@
44
var isNodeJs = (typeof window == 'undefined' && typeof global != 'undefined');
55
if (!isNodeJs) var global = window;
66

7-
//Calls a method on a role player - could be either a role method or a method on the data object
8-
function callRolePlayerMethod(context, player, playerName, roleName, methodName, args) {
9-
if (player != context.__rolePlayers[playerName]) {
10-
//support constructor functions within role methods - make sure we don't wrongly
11-
//assume `this` refers to the current role
7+
//This function is for handling calls beginning with `this`; it calls a method on the current role player,
8+
//which could be either a role method or a method on the data object.
9+
//
10+
// TODO test data object methods that aren't overridden by the role
11+
//
12+
function callMethodOnCurrentRolePlayer(context, player, roleName, methodName, args) {
13+
//if `this` is not equal to the current role player
14+
if (player != context[roleName]) {
15+
//support functions within role methods for which `this` is unbound - but make sure we
16+
//don't wrongly assume `this` refers to the current role
1217
if (player != undefined && player != global) {
18+
//not a role method; call normally
1319
return player[methodName].apply(player, args);
1420
}
1521
//if we're here, then `this` probably *should* refer to the current role and the only
1622
//reason it's undefined is most likely a nested function
1723
//(e.g. a callback function passed to forEach() to loop over an array)
1824
else {
19-
player = context.__rolePlayers[playerName];
25+
player = context[roleName];
2026
}
2127
}
2228

2329
var roleMethod = context['__$'+roleName][methodName];
24-
//if the method exists on the role, we always call it (role methods can override data object methods)
30+
//if the method exists on the role, we always call it (role methods override data object methods)
2531
if (typeof roleMethod == 'function') {
2632
return (args ? roleMethod.apply(player, args): roleMethod.call(player));
2733
}
34+
//otherwise, call the data object method
35+
//(if the method is not found on the data object, this will throw Javascript's usual
36+
//'[function name] is not defined' error)
2837
return player[methodName].apply(player, args);
2938
}
3039

40+
41+
//for class version
42+
43+
function TransferMoney(sourceAcct, destinationAcct) {
44+
var __context = this;
45+
this.bindRoles(sourceAcct, destinationAcct);
46+
47+
//roles need to be inside constructor so that __context variable can be accessed
48+
this.__$SourceAccount = {
49+
transferOut: function () {
50+
//this.withdraw();
51+
__context.__$DestinationAccount.deposit.call(__context.__rolePlayers['DestinationAccount']);
52+
},
53+
withdraw: function () {
54+
}
55+
}
56+
}
57+
58+
TransferMoney.prototype.bindRoles = function(sourceAcct, destinationAcct) {
59+
__context.SourceAccount = sourceAcct;
60+
__context.DestinationAccount = destinationAcct;
61+
}
62+
63+
TransferMoney.prototype.execute = function() {
64+
var __context = this;
65+
__context.__$SourceAccount.transferOut.call(__context.SourceAccount);
66+
};
67+
68+
//for JS version
69+
70+
function TransferMoney(sourceAcct, destinationAcct) {
71+
var __context = this;
72+
__context.__rolePlayers = {};
73+
this.bindRoles = function () {
74+
__context.__rolePlayers['SourceAccount'] = sourceAcct;
75+
__context.__rolePlayers['DestinationAccount'] = destinationAcct;
76+
};
77+
this.bindRoles();
78+
this.execute = function () {
79+
__context.__$SourceAccount.transferOut.call(__context.__rolePlayers['SourceAccount']);
80+
};
81+
this.__$SourceAccount = { transferOut: function () {
82+
//this.withdraw();
83+
__context.__$DestinationAccount.deposit.call(__context.__rolePlayers['DestinationAccount']);
84+
}
85+
,withdraw: function () {
86+
}
87+
}
88+
this.__$DestinationAccount = { deposit: function () {
89+
console.log('deposit');
90+
}
91+
}
92+
}
93+
var ctx = new TransferMoney({}, {});
94+
ctx.execute();
95+
96+
97+
/*
3198
function TransferMoney(sourceAcct) {
3299
var __context = this;
33100
@@ -44,7 +111,7 @@
44111
, foo: function () {
45112
console.log('foo');
46113
//this.greet();
47-
callRolePlayerMethod(__context, this, 'SourceAccount', 'SourceAccount', 'greet');
114+
callRolePlayerMethod(__context, this, 'SourceAccount', 'greet');
48115
49116
// [1,2,3].forEach(function() {
50117
// callRolePlayerMethod(__context, this, 'SourceAccount', 'SourceAccount', 'greet');
@@ -64,5 +131,7 @@
64131
};
65132
var transferMoneyCtx = new TransferMoney(sourceAcct);
66133
transferMoneyCtx.execute();
134+
*/
135+
67136

68137
</script>

samples/dci/test.js

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
1-
function TransferMoney(sourceAcct2) {
1+
var DCI = {
2+
Context: function Context(callback) {
3+
return function () {
4+
var args = [];
5+
for (var _i = 0; _i < (arguments.length - 0); _i++) {
6+
args[_i] = arguments[_i + 0];
7+
}
8+
var context = new callback();
9+
context.bindRoles.apply(callback, arguments);
10+
return context;
11+
};
12+
}
13+
};
14+
15+
//TODO DCI.Context.extend() -- DCI.Context should be a Typescript class
16+
var TransferMoney = DCI.Context(function () {
217
var __context = this;
3-
4-
var test = '123';
5-
this.__$SourceAccount = { test: function () {
6-
__context.__$DestinationAccount.deposit.call(rolePlayer);
18+
this.bindRoles = function (sourceAcct, destinationAcct) {
19+
__context.SourceAccount = undefined;
20+
__context.DestinationAccount = undefined;
21+
};
22+
this.execute = function () {
23+
SourceAccount.transferOut();
24+
};
25+
this.__$SourceAccount = { transferOut: function () {
26+
//TODO test calling role methods this way:
27+
//this['withdraw']();
28+
DCI.callRolePlayerMethod(__context, this, 'SourceAccount', 'withdraw');
29+
__context.__$DestinationAccount.deposit.call(__context.DestinationAccount);
730
}
8-
,foo: function () {
9-
DCI.callRolePlayerMethod(__context, this, TODO-playerName, 'SourceAccount', 'greet');
31+
,withdraw: function () {
1032
}
1133
}
34+
this.__$DestinationAccount = { deposit: function () {
35+
__context.__$console.log.call(__context.console, 'deposit');
36+
}
1237
}
38+
});
39+
var ctx = TransferMoney({}, {});
40+
ctx.execute();

samples/dci/test.ts

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,98 @@
1-
function TransferMoney(sourceAcct2) {
1+
var DCI = {
2+
Context: function Context(callback) {
3+
return function(...args : any[]) {
4+
var context = new callback();
5+
context.bindRoles.apply(callback, arguments);
6+
return context;
7+
}
8+
}
9+
};
10+
11+
//TODO DCI.Context.extend() -- DCI.Context should be a Typescript class
12+
var TransferMoney = DCI.Context(function() {
13+
14+
this.bindRoles = function(sourceAcct, destinationAcct) {
15+
SourceAccount <- sourceAcct;
16+
DestinationAccount <- destinationAcct;
17+
}
218

3-
SourceAccount <- sourceAcct2;
4-
var test = '123';
19+
this.execute = function() {
20+
SourceAccount.transferOut();
21+
}
522

623
role SourceAccount {
7-
test() {
24+
transferOut() {
25+
//TODO test calling role methods this way:
26+
//this['withdraw']();
27+
28+
this.withdraw();
829
DestinationAccount.deposit();
930
}
1031

11-
foo() {
12-
this.greet();
32+
withdraw() {
33+
34+
}
35+
}
36+
37+
role DestinationAccount {
38+
deposit() {
39+
console.log('deposit');
1340
}
1441
}
15-
}
42+
});
43+
44+
45+
var ctx = TransferMoney({}, {});
46+
ctx.execute();
47+
48+
/*
49+
function TransferMoney(sourceAcct, destinationAcct) {
50+
51+
this.bindRoles = function(a1, a2) {
52+
SourceAccount <- a1;
53+
DestinationAccount <- a2;
54+
}
55+
this.bindRoles(sourceAcct, destinationAcct);
56+
57+
this.execute = function() {
58+
SourceAccount.transferOut();
59+
}
60+
61+
role SourceAccount {
62+
transferOut() {
63+
this.withdraw();
64+
DestinationAccount.deposit();
65+
}
66+
67+
withdraw() {
68+
69+
}
70+
}
71+
72+
role DestinationAccount {
73+
deposit() {
74+
console.log('deposit');
75+
}
76+
}
77+
}
78+
79+
var ctx = new TransferMoney({}, {});
80+
ctx.execute();
81+
*/
82+
83+
/*
84+
85+
var TransferMoney = DCI.Context(function() {
86+
this.bindRoles = function(sourceAcct, destinationAcct) {
87+
SourceAccount <- sourceAcct;
88+
DestinationAccount <- destinationAcct;
89+
}
90+
91+
this.execute = function() {
92+
console.log('executing');
93+
}
94+
});
95+
96+
var ctx = TransferMoney({}, {});
97+
ctx.execute();
98+
*/

src/compiler/ast.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,14 @@ module TypeScript {
248248
public isMissing() { return false; }
249249

250250
public emit(emitter: Emitter) {
251+
//DCI
252+
if (emitter.thisFunctionDeclaration && emitter.thisFunctionDeclaration.isDCIContext) {
253+
//DCI TODO
254+
//if (emitter.thisFunctionDeclaration.roleDeclarations[this.actualText]) {
255+
if (true) {
256+
emitter.writeToOutput("__context.");
257+
}
258+
}
251259
emitter.emitName(this, true);
252260
}
253261

@@ -610,6 +618,14 @@ module TypeScript {
610618
structuralEquals(this.operand2, ast.operand2, includingPosition);
611619
}
612620
}
621+
622+
//DCI
623+
export class RoleAssignmentExpression extends AST {
624+
constructor(public roleName: AST,
625+
public rolePlayerName: AST) {
626+
super();
627+
}
628+
}
613629

614630
export class ConditionalExpression extends AST {
615631
constructor(public operand1: AST,
@@ -869,7 +885,7 @@ module TypeScript {
869885
public classDecl: ClassDeclaration = null;
870886
//DCI
871887
public isDCIContext = false;
872-
public roleMap = {};
888+
public roleDeclarations = {};
873889

874890
public returnStatementsWithExpressions: ReturnStatement[];
875891

@@ -1211,7 +1227,13 @@ module TypeScript {
12111227
//Is this the right place to add the role to the collection?
12121228
//Maybe do this in parser and simply do nothing here
12131229
var operand1 = (<BinaryExpression>this.expression).operand1;
1214-
console.log('adding role ' + (<Identifier>operand1).actualText);
1230+
var operand2 = (<BinaryExpression>this.expression).operand2;
1231+
var roleName = (<Identifier>operand1).actualText;
1232+
var rolePlayerName = (<Identifier>operand2).actualText;
1233+
console.log('adding role ' + roleName);
1234+
1235+
emitter.writeToOutput("__context."+roleName+" = " + rolePlayerName + ";");
1236+
12151237
return;
12161238
}
12171239

src/compiler/astWalker.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ module TypeScript {
126126
this.childrenWalkers[NodeType.ObjectCreationExpression] = ChildrenWalkers.walkObjectCreationExpressionChildren;
127127
this.childrenWalkers[NodeType.AssignmentExpression] = ChildrenWalkers.walkBinaryExpressionChildren;
128128
//DCI
129-
this.childrenWalkers[NodeType.RoleAssignmentExpression] = ChildrenWalkers.walkBinaryExpressionChildren;
129+
this.childrenWalkers[NodeType.RoleAssignmentExpression] = ChildrenWalkers.walkRoleAssignmentExpressionChildren;
130130
this.childrenWalkers[NodeType.AddAssignmentExpression] = ChildrenWalkers.walkBinaryExpressionChildren;
131131
this.childrenWalkers[NodeType.SubtractAssignmentExpression] = ChildrenWalkers.walkBinaryExpressionChildren;
132132
this.childrenWalkers[NodeType.DivideAssignmentExpression] = ChildrenWalkers.walkBinaryExpressionChildren;
@@ -265,6 +265,19 @@ module TypeScript {
265265
preAst.operand2 = walker.walk(preAst.operand2, preAst);
266266
}
267267
}
268+
269+
//DCI
270+
export function walkRoleAssignmentExpressionChildren(preAst: RoleAssignmentExpression, parent: AST, walker: IAstWalker): void {
271+
//DCI TODO remove this
272+
console.log('walkRoleAssignmentExpressionChildren');
273+
274+
if (preAst.roleName) {
275+
preAst.roleName = walker.walk(preAst.roleName, preAst);
276+
}
277+
if (preAst.rolePlayerName) {
278+
preAst.rolePlayerName = walker.walk(preAst.rolePlayerName, preAst);
279+
}
280+
}
268281

269282
export function walkTypeParameterChildren(preAst: TypeParameter, parent: AST, walker: IAstWalker): void {
270283
if (preAst.name) {

0 commit comments

Comments
 (0)