diff --git a/CS2JLibrary/src/CS2JNet/System/__MultiEventHandler.java b/CS2JLibrary/src/CS2JNet/System/__MultiEventHandler.java index ca77ff6..06240ce 100644 --- a/CS2JLibrary/src/CS2JNet/System/__MultiEventHandler.java +++ b/CS2JLibrary/src/CS2JNet/System/__MultiEventHandler.java @@ -21,6 +21,7 @@ package CS2JNet.System; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import CS2JNet.JavaSupport.util.ListSupport; @@ -32,7 +33,12 @@ import CS2JNet.JavaSupport.util.ListSupport; public class __MultiEventHandler implements EventHandler { public void Invoke(Object other, TEventArgs e) throws Exception { - for (EventHandler d : this.GetInvocationList()) + List> copy, members = this.GetInvocationList(); + synchronized (members) + { + copy = new LinkedList>(members); + } + for (EventHandler d : copy) { d.Invoke(other, e); } diff --git a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JMain/Templates.cs b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JMain/Templates.cs index ac33952..2fdba2c 100644 --- a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JMain/Templates.cs +++ b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JMain/Templates.cs @@ -250,6 +250,14 @@ lock() >> +synchstat(comments,exp,stats) ::= << + +synchronized () +{ + +} +>> + yield(comments,exp) ::= << yield return break; diff --git a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaMaker.g b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaMaker.g index 87d9b55..a51a82b 100644 --- a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaMaker.g +++ b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaMaker.g @@ -1556,8 +1556,10 @@ scope TypeContext; 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))); AddToImports("java.util.List"); + AddToImports("java.util.LinkedList"); AddToImports("java.util.ArrayList"); 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] { @@ -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. +// List copy, members = this.GetInvocationList(); +// synchronized (members) { +// copy = new LinkedList(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 tyArgs] : e1=magicThrowsException[Cfg.TranslatorBlanketThrow, tok] -> {retIsVoid}? ^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) } 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"] - { $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"] OPEN_BRACE[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) } 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,";"] ^(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"] 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, ";"]) diff --git a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g index 5e008e1..fbfaf61 100644 --- a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g +++ b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g @@ -1465,6 +1465,7 @@ embedded_statement returns [bool isSemi, bool isIf, bool indent] catches = { $catch_clauses.st }, fin = { $finally_clause.st } ) | checked_statement -> { $checked_statement.st } | unchecked_statement -> { $unchecked_statement.st } + | synchronized_statement -> { $synchronized_statement.st } | lock_statement -> { $lock_statement.st } | yield_statement -> { $yield_statement.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 } ); finally_clause: ^('finally' block) -> fin(block = {$block.st}, blockindent = { $block.isSemi }); + +synchronized_statement: + ^(SYNCHRONIZED expression '{' s+=statement* '}') -> synchstat(exp={ $expression.st }, stats = { $s }); + checked_statement @init { StringTemplate someText = null; diff --git a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/NetMaker.g b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/NetMaker.g index 9c029a0..9d9a659 100644 --- a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/NetMaker.g +++ b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/NetMaker.g @@ -519,7 +519,7 @@ scope MkNonGeneric { } 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); } else { @@ -2634,6 +2634,7 @@ embedded_statement[bool isStatementListCtxt] | ^('try' block catch_clauses? finally_clause?) | checked_statement | unchecked_statement + | synchronized_statement // Java: synchronized(obj) {} | lock_statement | yield_statement | ^('unsafe' block) @@ -2932,6 +2933,10 @@ checked_statement: 'checked' block ; unchecked_statement: ^(UNCHECKED block) ; + +synchronized_statement: + ^(SYNCHRONIZED expression[ObjectType] '{' statement_list '}') ; + lock_statement: 'lock' '(' expression[ObjectType] ')' embedded_statement[/* isStatementListCtxt */ false] ; diff --git a/CSharpTranslator/antlr3/src/CSharpParser/cs.g b/CSharpTranslator/antlr3/src/CSharpParser/cs.g index 7a0113e..ed423f6 100644 --- a/CSharpTranslator/antlr3/src/CSharpParser/cs.g +++ b/CSharpTranslator/antlr3/src/CSharpParser/cs.g @@ -148,6 +148,8 @@ tokens { EXCEPTION; + SYNCHRONIZED; + PAYLOAD; // carries arbitrary text for the output file PAYLOAD_LIST; JAVAWRAPPER;