mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
before invoking delegates in a Multi instance make a copy of the invocation list and invoke from that in case they manipulate the original delegate
This commit is contained in:
parent
1b2222254a
commit
d928e3c7bf
@ -21,6 +21,7 @@
|
|||||||
package CS2JNet.System;
|
package CS2JNet.System;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import CS2JNet.JavaSupport.util.ListSupport;
|
import CS2JNet.JavaSupport.util.ListSupport;
|
||||||
@ -32,7 +33,12 @@ import CS2JNet.JavaSupport.util.ListSupport;
|
|||||||
public class __MultiEventHandler<TEventArgs> implements EventHandler<TEventArgs> {
|
public class __MultiEventHandler<TEventArgs> implements EventHandler<TEventArgs> {
|
||||||
|
|
||||||
public void Invoke(Object other, TEventArgs e) throws Exception {
|
public void Invoke(Object other, TEventArgs e) throws Exception {
|
||||||
for (EventHandler<TEventArgs> d : this.GetInvocationList())
|
List<EventHandler<TEventArgs>> copy, members = this.GetInvocationList();
|
||||||
|
synchronized (members)
|
||||||
|
{
|
||||||
|
copy = new LinkedList<EventHandler<TEventArgs>>(members);
|
||||||
|
}
|
||||||
|
for (EventHandler<TEventArgs> d : copy)
|
||||||
{
|
{
|
||||||
d.Invoke(other, e);
|
d.Invoke(other, e);
|
||||||
}
|
}
|
||||||
|
@ -250,6 +250,14 @@ lock(<exp>)
|
|||||||
<block(statements = block, indent = indent)>
|
<block(statements = block, indent = indent)>
|
||||||
>>
|
>>
|
||||||
|
|
||||||
|
synchstat(comments,exp,stats) ::= <<
|
||||||
|
<comments; separator=""\n"">
|
||||||
|
synchronized (<exp>)
|
||||||
|
{
|
||||||
|
<stats>
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
yield(comments,exp) ::= <<
|
yield(comments,exp) ::= <<
|
||||||
<comments; separator=""\n"">
|
<comments; separator=""\n"">
|
||||||
yield <if(exp)>return <exp><else>break<endif>;
|
yield <if(exp)>return <exp><else>break<endif>;
|
||||||
|
@ -1556,8 +1556,10 @@ scope TypeContext;
|
|||||||
multiDelName = "__Multi" + delName;
|
multiDelName = "__Multi" + delName;
|
||||||
delClassMemberNodes = this.parseString("class_member_declarations", Fragments.MultiDelegateMethods(mkTypeString(delName, $variant_generic_parameter_list.tyargs), mkTypeString(multiDelName, $variant_generic_parameter_list.tyargs),mkTypeArgString($variant_generic_parameter_list.tyargs)));
|
delClassMemberNodes = this.parseString("class_member_declarations", Fragments.MultiDelegateMethods(mkTypeString(delName, $variant_generic_parameter_list.tyargs), mkTypeString(multiDelName, $variant_generic_parameter_list.tyargs),mkTypeArgString($variant_generic_parameter_list.tyargs)));
|
||||||
AddToImports("java.util.List");
|
AddToImports("java.util.List");
|
||||||
|
AddToImports("java.util.LinkedList");
|
||||||
AddToImports("java.util.ArrayList");
|
AddToImports("java.util.ArrayList");
|
||||||
AddToImports("CS2JNet.JavaSupport.util.ListSupport");
|
AddToImports("CS2JNet.JavaSupport.util.ListSupport");
|
||||||
|
$NSContext::namespaces.Add("System.Collection"); // System.Collection.Ilist used in multi invoke method
|
||||||
}
|
}
|
||||||
magicMultiDelClass[$d.token, $atts, toplevel ? dupTree($mods) : addModifier($mods, (CommonTree)adaptor.Create(STATIC, $d.token, "static")), multiDelName, ifTree, $type_parameter_constraints_clauses.tree, $variant_generic_parameter_list.tree, $magicMultiInvokerMethod.tree, delClassMemberNodes]
|
magicMultiDelClass[$d.token, $atts, toplevel ? dupTree($mods) : addModifier($mods, (CommonTree)adaptor.Create(STATIC, $d.token, "static")), multiDelName, ifTree, $type_parameter_constraints_clauses.tree, $variant_generic_parameter_list.tree, $magicMultiInvokerMethod.tree, delClassMemberNodes]
|
||||||
{
|
{
|
||||||
@ -2259,14 +2261,28 @@ magicDelegateInterface[IToken tok, CommonTree return_type, CommonTree identifier
|
|||||||
;
|
;
|
||||||
|
|
||||||
// First execute all but the last one, then execute the last one and (if non-void) return its result.
|
// First execute all but the last one, then execute the last one and (if non-void) return its result.
|
||||||
|
// List<CompleteCallback> copy, members = this.GetInvocationList();
|
||||||
|
// synchronized (members) {
|
||||||
|
// copy = new LinkedList<CompleteCallback>(members);
|
||||||
|
// }
|
||||||
|
// for (CompleteCallback d : copy)
|
||||||
|
// {
|
||||||
|
// d.Invoke(name, result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
magicMultiInvokerMethod[IToken tok, CommonTree return_type, bool retIsVoid, CommonTree type, CommonTree formal_parameter_list, CommonTree argument_list, List<String> tyArgs]
|
magicMultiInvokerMethod[IToken tok, CommonTree return_type, bool retIsVoid, CommonTree type, CommonTree formal_parameter_list, CommonTree argument_list, List<String> tyArgs]
|
||||||
:
|
:
|
||||||
e1=magicThrowsException[Cfg.TranslatorBlanketThrow, tok]
|
e1=magicThrowsException[Cfg.TranslatorBlanketThrow, tok]
|
||||||
-> {retIsVoid}?
|
-> {retIsVoid}?
|
||||||
^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
||||||
OPEN_BRACE[tok, "{"]
|
OPEN_BRACE[tok, "{"]
|
||||||
|
^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "IList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) IDENTIFIER[tok, "copy"] COMMA[tok, ","] IDENTIFIER[tok, "members"] ASSIGN[tok, "="] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"])) SEMI[tok, ";"]
|
||||||
|
^(SYNCHRONIZED[tok, "synchronized"] IDENTIFIER[tok, "members"] OPEN_BRACE[tok, "{"]
|
||||||
|
IDENTIFIER[tok, "copy"] ASSIGN[tok, "="] ^(NEW[tok, "new"] ^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "LinkedList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) ^(ARGS[tok, "ARGS"] IDENTIFIER[tok, "members"])) SEMI[tok, ";"]
|
||||||
|
CLOSE_BRACE[tok, "}"]
|
||||||
|
)
|
||||||
^(FOREACH[tok, "foreach"]
|
^(FOREACH[tok, "foreach"]
|
||||||
{ $type } IDENTIFIER[tok, "d"] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"]))
|
{ $type } IDENTIFIER[tok, "d"] IDENTIFIER[tok, "copy"]
|
||||||
SEP[tok, "SEP"]
|
SEP[tok, "SEP"]
|
||||||
OPEN_BRACE[tok, "{"]
|
OPEN_BRACE[tok, "{"]
|
||||||
^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"d"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"]
|
^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"d"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"]
|
||||||
@ -2277,9 +2293,14 @@ magicMultiInvokerMethod[IToken tok, CommonTree return_type, bool retIsVoid, Comm
|
|||||||
)
|
)
|
||||||
-> ^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
-> ^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
||||||
OPEN_BRACE[tok, "{"]
|
OPEN_BRACE[tok, "{"]
|
||||||
|
^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "IList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) IDENTIFIER[tok, "copy"] COMMA[tok, ","] IDENTIFIER[tok, "members"] ASSIGN[tok, "="] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"])) SEMI[tok, ";"]
|
||||||
|
^(SYNCHRONIZED[tok, "synchronized"] IDENTIFIER[tok, "members"] OPEN_BRACE[tok, "{"]
|
||||||
|
IDENTIFIER[tok, "copy"] ASSIGN[tok, "="] ^(NEW[tok, "new"] ^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "LinkedList"] LTHAN[tok, "<"] { dupTree($type) } GT[tok, ">"]) ^(ARGS[tok, "ARGS"] IDENTIFIER[tok, "members"])) SEMI[tok, ";"]
|
||||||
|
CLOSE_BRACE[tok, "}"]
|
||||||
|
)
|
||||||
{ $type } IDENTIFIER[tok, "prev"] ASSIGN[tok, "="] NULL[tok, "null"] SEMI[tok,";"]
|
{ $type } IDENTIFIER[tok, "prev"] ASSIGN[tok, "="] NULL[tok, "null"] SEMI[tok,";"]
|
||||||
^(FOREACH[tok, "foreach"]
|
^(FOREACH[tok, "foreach"]
|
||||||
{ $type } IDENTIFIER[tok, "d"] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"]))
|
{ $type } IDENTIFIER[tok, "d"] IDENTIFIER[tok, "copy"]
|
||||||
SEP[tok, "SEP"]
|
SEP[tok, "SEP"]
|
||||||
OPEN_BRACE[tok, "{"]
|
OPEN_BRACE[tok, "{"]
|
||||||
^(IF[tok, "if"] ^(NOT_EQUAL[tok, "!="] IDENTIFIER[tok,"prev"] NULL[tok, "null"]) SEP ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"prev"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"])
|
^(IF[tok, "if"] ^(NOT_EQUAL[tok, "!="] IDENTIFIER[tok,"prev"] NULL[tok, "null"]) SEP ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"prev"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"])
|
||||||
|
@ -1465,6 +1465,7 @@ embedded_statement returns [bool isSemi, bool isIf, bool indent]
|
|||||||
catches = { $catch_clauses.st }, fin = { $finally_clause.st } )
|
catches = { $catch_clauses.st }, fin = { $finally_clause.st } )
|
||||||
| checked_statement -> { $checked_statement.st }
|
| checked_statement -> { $checked_statement.st }
|
||||||
| unchecked_statement -> { $unchecked_statement.st }
|
| unchecked_statement -> { $unchecked_statement.st }
|
||||||
|
| synchronized_statement -> { $synchronized_statement.st }
|
||||||
| lock_statement -> { $lock_statement.st }
|
| lock_statement -> { $lock_statement.st }
|
||||||
| yield_statement -> { $yield_statement.st }
|
| yield_statement -> { $yield_statement.st }
|
||||||
| ^('unsafe' { preComments = CollectedComments; } block { someText = %op(); %{someText}.op="unsafe"; %{someText}.post = $block.st; })
|
| ^('unsafe' { preComments = CollectedComments; } block { someText = %op(); %{someText}.op="unsafe"; %{someText}.post = $block.st; })
|
||||||
@ -1564,6 +1565,10 @@ catch_clause:
|
|||||||
^('catch' type identifier block) -> catch_template(type = { $type.st }, id = { $identifier.st }, block = {$block.st}, blockindent = { $block.isSemi } );
|
^('catch' type identifier block) -> catch_template(type = { $type.st }, id = { $identifier.st }, block = {$block.st}, blockindent = { $block.isSemi } );
|
||||||
finally_clause:
|
finally_clause:
|
||||||
^('finally' block) -> fin(block = {$block.st}, blockindent = { $block.isSemi });
|
^('finally' block) -> fin(block = {$block.st}, blockindent = { $block.isSemi });
|
||||||
|
|
||||||
|
synchronized_statement:
|
||||||
|
^(SYNCHRONIZED expression '{' s+=statement* '}') -> synchstat(exp={ $expression.st }, stats = { $s });
|
||||||
|
|
||||||
checked_statement
|
checked_statement
|
||||||
@init {
|
@init {
|
||||||
StringTemplate someText = null;
|
StringTemplate someText = null;
|
||||||
|
@ -519,7 +519,7 @@ scope MkNonGeneric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected CommonTree mkJavaRep(IToken tok, TypeRepTemplate ty) {
|
protected CommonTree mkJavaRep(IToken tok, TypeRepTemplate ty) {
|
||||||
if (ty.InstantiatedTypes.Length == 0) {
|
if (ty.InstantiatedTypes == null || ty.InstantiatedTypes.Length == 0) {
|
||||||
return (CommonTree)adaptor.Create(IDENTIFIER, tok, ty.Java);
|
return (CommonTree)adaptor.Create(IDENTIFIER, tok, ty.Java);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2634,6 +2634,7 @@ embedded_statement[bool isStatementListCtxt]
|
|||||||
| ^('try' block catch_clauses? finally_clause?)
|
| ^('try' block catch_clauses? finally_clause?)
|
||||||
| checked_statement
|
| checked_statement
|
||||||
| unchecked_statement
|
| unchecked_statement
|
||||||
|
| synchronized_statement // Java: synchronized(obj) {}
|
||||||
| lock_statement
|
| lock_statement
|
||||||
| yield_statement
|
| yield_statement
|
||||||
| ^('unsafe' block)
|
| ^('unsafe' block)
|
||||||
@ -2932,6 +2933,10 @@ checked_statement:
|
|||||||
'checked' block ;
|
'checked' block ;
|
||||||
unchecked_statement:
|
unchecked_statement:
|
||||||
^(UNCHECKED block) ;
|
^(UNCHECKED block) ;
|
||||||
|
|
||||||
|
synchronized_statement:
|
||||||
|
^(SYNCHRONIZED expression[ObjectType] '{' statement_list '}') ;
|
||||||
|
|
||||||
lock_statement:
|
lock_statement:
|
||||||
'lock' '(' expression[ObjectType] ')' embedded_statement[/* isStatementListCtxt */ false] ;
|
'lock' '(' expression[ObjectType] ')' embedded_statement[/* isStatementListCtxt */ false] ;
|
||||||
|
|
||||||
|
@ -148,6 +148,8 @@ tokens {
|
|||||||
|
|
||||||
EXCEPTION;
|
EXCEPTION;
|
||||||
|
|
||||||
|
SYNCHRONIZED;
|
||||||
|
|
||||||
PAYLOAD; // carries arbitrary text for the output file
|
PAYLOAD; // carries arbitrary text for the output file
|
||||||
PAYLOAD_LIST;
|
PAYLOAD_LIST;
|
||||||
JAVAWRAPPER;
|
JAVAWRAPPER;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user