diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g index 5a261c6..5511ab0 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g @@ -86,6 +86,72 @@ scope TypeContext { return root; } +// for ["conn", "conn1", "conn2"] generate: +// +// if (conn != null) +// ((IDisposable)conn).Dispose(); +// +// +// if (conn2 != null) +// ((IDisposable)conn2).Dispose(); +// +// +// if (conn3 != null) +// ((IDisposable)conn3).Dispose(); +// used in the finally block of the using translation + protected CommonTree addDisposeVars(IToken tok, List vars) { + + CommonTree root = (CommonTree)adaptor.Nil; + + foreach (String var in vars) { + + CommonTree root_1 = (CommonTree)adaptor.Nil; + root_1 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(IF, tok, "if"), root_1); + + CommonTree root_2 = (CommonTree)adaptor.Nil; + root_2 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(NOT_EQUAL, tok, "!="), root_2); + + adaptor.AddChild(root_2, (CommonTree)adaptor.Create(IDENTIFIER, tok, var)); + adaptor.AddChild(root_2, (CommonTree)adaptor.Create(NULL, tok, "null")); + + adaptor.AddChild(root_1, root_2); + + adaptor.AddChild(root_1, (CommonTree)adaptor.Create(SEP, "SEP")); + + root_2 = (CommonTree)adaptor.Nil; + root_2 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(APPLY, tok, "APPLY"), root_2); + + CommonTree root_3 = (CommonTree)adaptor.Nil; + root_3 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(DOT, tok, "."), root_3); + + CommonTree root_4 = (CommonTree)adaptor.Nil; + root_4 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(CAST_EXPR, tok, "CAST"), root_4); + + CommonTree root_5 = (CommonTree)adaptor.Nil; + root_5 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(TYPE, tok, "TYPE"), root_5); + + adaptor.AddChild(root_5, (CommonTree)adaptor.Create(IDENTIFIER, tok, "IDisposable")); + + adaptor.AddChild(root_4, root_5); + + adaptor.AddChild(root_4, (CommonTree)adaptor.Create(IDENTIFIER, tok, var)); + + adaptor.AddChild(root_3, root_4); + + adaptor.AddChild(root_3, (CommonTree)adaptor.Create(IDENTIFIER, tok, "Dispose")); + + adaptor.AddChild(root_2, root_3); + + adaptor.AddChild(root_1, root_2); + + adaptor.AddChild(root_1, (CommonTree)adaptor.Create(SEMI, tok, ";")); + + adaptor.AddChild(root, root_1); + } + + return (CommonTree)adaptor.RulePostProcessing(root); + } + // TODO: Read reserved words from a file so that they can be extended by customer private readonly static string[] javaReserved = new string[] { "int", "protected", "package" }; @@ -121,6 +187,8 @@ scope TypeContext { // counter to ensure that the catch vars we introduce are unique protected int dummyCatchVarCtr = 0; + protected int newVarCtr = 0; + protected CommonTree dupTree(CommonTree t) { return (CommonTree)adaptor.DupTree(t); } @@ -1255,16 +1323,19 @@ labeled_statement: declaration_statement: (local_variable_declaration | local_constant_declaration) ';' ; -local_variable_declaration: - local_variable_type local_variable_declarators ; +local_variable_declaration returns [List variableNames]: + local_variable_type local_variable_declarators { $variableNames = $local_variable_declarators.variableNames; }; local_variable_type: ('var') => 'var' | ('dynamic') => 'dynamic' | type ; -local_variable_declarators: - local_variable_declarator (',' local_variable_declarator)* ; -local_variable_declarator: - identifier ('=' local_variable_initializer)? ; +local_variable_declarators returns [List variableNames] +@init { + $variableNames = new List(); +}: + i1=local_variable_declarator { $variableNames.Add($i1.variableName); } (',' ip=local_variable_declarator { $variableNames.Add($ip.variableName); })* ; +local_variable_declarator returns [String variableName]: + identifier { $variableName = $identifier.text; } ('=' local_variable_initializer)? ; local_variable_initializer: expression | array_initializer @@ -1375,11 +1446,28 @@ unchecked_statement: 'unchecked' block ; lock_statement: 'lock' '(' expression ')' embedded_statement ; -using_statement: - 'using' '(' resource_acquisition ')' embedded_statement ; -resource_acquisition: - (local_variable_declaration) => local_variable_declaration - | expression ; +using_statement +@init { + CommonTree disposers = null; +}: +// see http://msdn.microsoft.com/en-us/library/yh598w02.aspx for translation + u='using' '(' resource_acquisition c=')' embedded_statement + { disposers = addDisposeVars($c.token, $resource_acquisition.resourceNames); } + f=magicFinally[$c.token, disposers] + magicTry[$u.token, $embedded_statement.tree, null, $f.tree] + -> OPEN_BRACE[$u.token, "{"] + resource_acquisition SEMI[$c.token, ";"] + magicTry + CLOSE_BRACE[$u.token, "}"] + ; +resource_acquisition returns [List resourceNames] +@init { + $resourceNames = new List(); +}: + (local_variable_declaration) => local_variable_declaration { $resourceNames = $local_variable_declaration.variableNames; } + | expression { $resourceNames.Add("__newVar"+newVarCtr); } -> ^(TYPE[$expression.tree.Token, "TYPE"] IDENTIFIER[$expression.tree.Token, "IDisposable"]) + IDENTIFIER[$expression.tree.Token, "__newVar"+newVarCtr++] ASSIGN[$expression.tree.Token, "="] expression //SEMI[$expression.tree.Token, ";"] + ; yield_statement: 'yield' ('return' expression ';' | 'break' ';') ; @@ -1534,3 +1622,19 @@ magicMainWrapper[bool isOn, IToken tok, CommonTree body]: EXCEPTION[tok, "Throwable"]) -> ; + +magicTry[IToken tok, CommonTree body, CommonTree catches, CommonTree fin]: +-> + ^(TRY[tok, "try"] { dupTree(body) } { dupTree(catches) } { dupTree(fin) }) +; + +magicDispose[IToken tok, String var]: +-> ^(IF[tok, "if"] ^(NOT_EQUAL[tok, "!="] IDENTIFIER[tok, var] NULL[tok, "null"]) SEP + ^(APPLY[tok, "APPLY"] ^(DOT[tok, "."] ^(CAST_EXPR[tok, "CAST"] ^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "IDisposable"]) IDENTIFIER[tok, var]) IDENTIFIER[tok, "Dispose"])) SEMI[tok, ";"]) +; + +magicFinally[IToken tok, CommonTree statement_list]: +-> + ^(FINALLY[tok, "finally"] OPEN_BRACE[tok, "{"] { dupTree(statement_list) } CLOSE_BRACE[tok, "}"]) +; + diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g index 393f171..b920d45 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g @@ -400,10 +400,19 @@ argument_name: argument_name_unsupported -> unsupported(reason={ "named parameters are not yet supported"}, text = { $argument_name_unsupported.st } ); argument_name_unsupported: identifier ':' -> op(pre={$identifier.st}, op={":"}); -argument_value: +argument_value +@init { + StringTemplate someText = null; +}: expression -> { $expression.st } | ref_variable_reference - | 'out' variable_reference ; + | 'out' variable_reference + { someText = %op(); + %{someText}.op = "out"; + %{someText}.post = $variable_reference.st; + %{someText}.space = " "; + } -> unsupported(reason = {"out arguments are not yet supported"}, text = { someText } ) + ; ref_variable_reference: 'ref' (('(' type ')') => '(' type ')' (ref_variable_reference | variable_reference) // SomeFunc(ref (int) ref foo) @@ -411,7 +420,7 @@ ref_variable_reference: | variable_reference); // SomeFunc(ref foo) // lvalue variable_reference: - expression; + expression -> { $expression.st }; rank_specifiers: rs+=rank_specifier+ -> rank_specifiers(rs={$rs}); rank_specifier: @@ -630,8 +639,8 @@ block returns [bool isSemi] @init { $isSemi = false; }: - ';' { $isSemi = true; } -> - | '{' s+=statement* '}' -> statement_list(statements = { $s }); + ';' { $isSemi = true; } -> string(payload = { " ;" }) + | '{' s+=statement* '}' -> braceblock(statements = { $s }); /////////////////////////////////////////////////////// // Expression Section @@ -1169,28 +1178,28 @@ statement_plus: (identifier ':') => labeled_statement -> statement(statement = { $labeled_statement.st }) | embedded_statement -> statement(statement = { $embedded_statement.st }) ; -embedded_statement returns [bool isSemi, bool isBraces, bool isIf] +embedded_statement returns [bool isSemi, bool isIf, bool indent] @init { StringTemplate someText = null; - $isBraces = false; + $isSemi = false; $isIf = false; + $indent = true; List preComments = null; }: - block { $isSemi = $block.isSemi; $isBraces = !$block.isSemi;} -> { $block.st } + block { $isSemi = $block.isSemi; $indent = false; } -> { $block.st } | ^(IF boolean_expression { preComments = CollectedComments; } SEP t=embedded_statement e=else_statement?) { $isIf = true; } -> if_template(comments = { preComments }, cond= { $boolean_expression.st }, - then = { $t.st }, thensemi = { $t.isSemi }, thenbraces = { $t.isBraces }, - else = { $e.st }, elsesemi = { $e.isSemi }, elsebraces = { $e.isBraces }, elseisif = { $e.isIf }) + then = { $t.st }, thenindent = { $t.indent }, + else = { $e.st }, elseisif = { $e.isIf }, elseindent = { $e.indent}) | ^('switch' expression { preComments = CollectedComments; } s+=switch_section*) -> switch(comments = { preComments }, scrutinee = { $expression.st }, sections = { $s }) | iteration_statement -> { $iteration_statement.st } // while, do, for, foreach | jump_statement -> { $jump_statement.st } // break, continue, goto, return, throw | ^('try' { preComments = CollectedComments; } b=block catch_clauses? finally_clause?) - -> try(comments = { preComments }, block = {$b.st}, blocksemi = {$b.isSemi}, blockbraces = { !$b.isSemi }, + -> try(comments = { preComments }, block = {$b.st}, blockindent = { $b.isSemi }, catches = { $catch_clauses.st }, fin = { $finally_clause.st } ) | checked_statement -> { $checked_statement.st } | unchecked_statement -> { $unchecked_statement.st } | lock_statement -> { $lock_statement.st } - | using_statement | yield_statement | ^('unsafe' { preComments = CollectedComments; } block { someText = %op(); %{someText}.op="unsafe"; %{someText}.post = $block.st; }) -> unsupported(comments = { preComments }, reason = {"unsafe blocks are not supported"}, text = { someText } ) @@ -1246,8 +1255,8 @@ if_statement: // else goes with closest if ; -else_statement returns [bool isSemi, bool isBraces, bool isIf]: - 'else' s=embedded_statement { $isSemi = $s.isSemi; $isBraces = $s.isBraces; $isIf = $s.isIf; } -> { $embedded_statement.st } ; +else_statement returns [bool isSemi, bool isIf, bool indent]: + 'else' s=embedded_statement { $isSemi = $s.isSemi; $isIf = $s.isIf; $indent = $s.indent; } -> { $embedded_statement.st } ; switch_section: ^(SWITCH_SECTION lab+=switch_label+ stat+=statement+) -> switch_section(labels = { $lab }, statements = { $stat }); switch_label: @@ -1255,14 +1264,14 @@ switch_label: | 'default' -> default_template() ; iteration_statement: ^('while' boolean_expression SEP embedded_statement) - -> while(cond = { $boolean_expression.st }, block = { $embedded_statement.st }, blocksemi = { $embedded_statement.isSemi }, blockbraces = { $embedded_statement.isBraces }) + -> while(cond = { $boolean_expression.st }, block = { $embedded_statement.st }, blockindent = { $embedded_statement.indent }) | do_statement -> { $do_statement.st } | ^('for' for_initializer? SEP expression? SEP for_iterator? SEP embedded_statement) -> for(init = { $for_initializer.st }, cond = { $expression.st }, iter = { $for_iterator.st }, - block = { $embedded_statement.st }, blocksemi = { $embedded_statement.isSemi }, blockbraces = { $embedded_statement.isBraces }) + block = { $embedded_statement.st }, blockindent = { $embedded_statement.indent }) | ^('foreach' local_variable_type identifier expression SEP embedded_statement) -> foreach(type = { $local_variable_type.st }, loopid = { $identifier.st }, fromexp = { $expression.st }, - block = { $embedded_statement.st }, blocksemi = { $embedded_statement.isSemi }, blockbraces = { $embedded_statement.isBraces }); + block = { $embedded_statement.st }, blockindent = { $embedded_statement.indent }); do_statement: 'do' embedded_statement 'while' '(' boolean_expression ')' ';' ; for_initializer: @@ -1286,9 +1295,9 @@ goto_statement: catch_clauses: c+=catch_clause+ -> seplist(items={ $c }, sep = { "\n" }) ; catch_clause: - ^('catch' type identifier block) -> catch_template(type = { $type.st }, id = { $identifier.st }, block = {$block.st}, blocksemi = { $block.isSemi }, blockbraces = { !$block.isSemi } ); + ^('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}, blocksemi = { $block.isSemi }, blockbraces = { !$block.isSemi }); + ^('finally' block) -> fin(block = {$block.st}, blockindent = { $block.isSemi }); checked_statement @init { StringTemplate someText = null; @@ -1297,8 +1306,7 @@ checked_statement { someText = %keyword_block(); %{someText}.keyword = "checked"; %{someText}.block = $block.st; - %{someText}.blocksemi = $block.isSemi; - %{someText}.blockbraces = !$block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } ) + %{someText}.indent = $block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } ) ; unchecked_statement @init { @@ -1308,8 +1316,7 @@ unchecked_statement { someText = %keyword_block(); %{someText}.keyword = "unchecked"; %{someText}.block = $block.st; - %{someText}.blocksemi = $block.isSemi; - %{someText}.blockbraces = !$block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } ) + %{someText}.indent = $block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } ) ; lock_statement @init { @@ -1319,14 +1326,8 @@ lock_statement { someText = %lock(); %{someText}.exp = $expression.st; %{someText}.block = $embedded_statement.st; - %{someText}.blocksemi = $embedded_statement.isSemi; - %{someText}.blockbraces = $embedded_statement.isBraces; } -> unsupported(reason = {"lock() statements are not supported"}, text = { someText } ) + %{someText}.indent = $embedded_statement.indent; } -> unsupported(reason = {"lock() statements are not supported"}, text = { someText } ) ; -using_statement: - 'using' '(' resource_acquisition ')' embedded_statement ; -resource_acquisition: - (local_variable_declaration) => local_variable_declaration - | expression ; yield_statement: 'yield' ('return' expression ';' | 'break' ';') ; diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g index 663ecfa..936d860 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g @@ -847,7 +847,6 @@ block | checked_statement | unchecked_statement | lock_statement - | using_statement | yield_statement | ^('unsafe' block) | fixed_statement @@ -942,11 +941,6 @@ unchecked_statement: 'unchecked' block ; lock_statement: 'lock' '(' expression ')' embedded_statement ; -using_statement: - 'using' '(' resource_acquisition ')' embedded_statement ; -resource_acquisition: - (local_variable_declaration) => local_variable_declaration - | expression ; yield_statement: 'yield' ('return' expression ';' | 'break' ';') ; diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g index 92f33f5..91dda58 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g @@ -55,6 +55,7 @@ tokens { PRIVATE = 'private'; TRY = 'try'; CATCH = 'catch'; + FINALLY = 'finally'; THROW = 'throw'; OPEN_BRACKET='['; diff --git a/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg b/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg index 297dd49..5d75984 100644 --- a/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg +++ b/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg @@ -53,18 +53,20 @@ class_member(comments, member) ::= << >> -constructor(modifiers, name, params, exception="Throwable", bodyIsSemi, body) ::= << -() throws {; - -} - +constructor(modifiers, name, params, exception="Throwable", body, bodyIsSemi) ::= << +() throws ; + + + +<\n> >> -method(modifiers, typeparams, type, name, params, exceptions, bodyIsSemi, body) ::= << - () throws {; - -} - +method(modifiers, typeparams, type, name, params, exceptions, body, bodyIsSemi) ::= << + () throws ; + + + +<\n> >> field(modifiers, type, field, comments, init) ::= " ;" @@ -133,52 +135,52 @@ extends(types) ::= "extends " imps(types) ::= "implements " // ******* STATEMENTS ******* -if_template(comments, cond,then,thensemi, thenbraces,else, elseisif, elsesemi,elsebraces) ::= << +if_template(comments, cond, then, thenindent, else, elseindent, elseisif) ::= << if () - + -else +else - + >> -while(comments,cond,block,blocksemi, blockbraces) ::= << +while(comments,cond,block) ::= << while () - + >> -for(comments,init,cond,iter,block,blocksemi, blockbraces) ::= << +for(comments,init,cond,iter,block,blockindent) ::= << for (;;) - + >> -foreach(comments,type,loopid,fromexp,block,blocksemi, blockbraces) ::= << +foreach(comments,type,loopid,fromexp,block,blockindent) ::= << for ( : ) - + >> -try(comments,block,blocksemi, blockbraces, catches, fin) ::= << +try(comments,block, blockindent, catches, fin) ::= << try - + >> -catch_template(type, id, block,blocksemi, blockbraces) ::= << +catch_template(type, id, block, blockindent) ::= << catch ( ) - + >> -fin(block,blocksemi, blockbraces) ::= << +fin(block, blockindent) ::= << finally - + >> @@ -204,31 +206,30 @@ default_template() ::= << default: >> -lock(comments,exp,block,blocksemi, blockbraces) ::= << +lock(comments,exp,block, indent) ::= << lock() - + >> -keyword_block(comments,keyword,block,blocksemi, blockbraces) ::= << +keyword_block(comments,keyword,block, indent) ::= << - + >> -block(statements,issemi,isbraces) ::= << - - ; - - -{ - - +block(statements, indent) ::= << + - + + + +>> + +braceblock(statements) ::= << +{ + } - - >> // ******* EXPRESSIONS *******