1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00

implement using statements and fix indentation

This commit is contained in:
Kevin Glynn 2010-12-20 22:05:25 +01:00
parent f1c9c5e6aa
commit 0940c53833
5 changed files with 189 additions and 88 deletions

View File

@ -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<string> 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<String> 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<String> variableNames]
@init {
$variableNames = new List<String>();
}:
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<String> resourceNames]
@init {
$resourceNames = new List<String>();
}:
(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, "}"])
;

View File

@ -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<String> 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' ';') ;

View File

@ -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' ';') ;

View File

@ -55,6 +55,7 @@ tokens {
PRIVATE = 'private';
TRY = 'try';
CATCH = 'catch';
FINALLY = 'finally';
THROW = 'throw';
OPEN_BRACKET='[';

View File

@ -53,18 +53,20 @@ class_member(comments, member) ::= <<
<member>
>>
constructor(modifiers, name, params, exception="Throwable", bodyIsSemi, body) ::= <<
<modifiers(modifiers)><name>(<params; separator=", ">) throws <exception><if(!bodyIsSemi)> {<else>;<endif>
<body>
<if(!bodyIsSemi)>}<endif>
constructor(modifiers, name, params, exception="Throwable", body, bodyIsSemi) ::= <<
<modifiers(modifiers)><name>(<params; separator=", ">) throws <exception> <if(bodyIsSemi)>;
<else>
<body>
<endif>
<\n>
>>
method(modifiers, typeparams, type, name, params, exceptions, bodyIsSemi, body) ::= <<
<modifiers(modifiers)><typeparams> <type> <name>(<params; separator=", ">)<if(exceptions)> throws <exceptions; separator=", "><endif><if(!bodyIsSemi)> {<else>;<endif>
<body>
<if(!bodyIsSemi)>}<endif>
method(modifiers, typeparams, type, name, params, exceptions, body, bodyIsSemi) ::= <<
<modifiers(modifiers)><typeparams> <type> <name>(<params; separator=", ">)<if(exceptions)> throws <exceptions; separator=", "><endif> <if(bodyIsSemi)>;
<else>
<body>
<endif>
<\n>
>>
field(modifiers, type, field, comments, init) ::= "<comments><modifiers(modifiers)><type> <field>;"
@ -133,52 +135,52 @@ extends(types) ::= "<if(types)>extends <types; separator=\",\"><endif>"
imps(types) ::= "<if(types)>implements <types; separator=\",\"><endif>"
// ******* STATEMENTS *******
if_template(comments, cond,then,thensemi, thenbraces,else, elseisif, elsesemi,elsebraces) ::= <<
if_template(comments, cond, then, thenindent, else, elseindent, elseisif) ::= <<
<comments; separator="\n">
if (<cond>)
<block(statements = then, issemi = thensemi, isbraces = thenbraces)>
<block(statements = then, indent = thenindent)>
<if(else)>
else<if(elseisif)> <block(statements = else, issemi = elsesemi, isbraces = elsebraces)><else>
else<if(elseisif)> <block(statements = else)><else>
<block(statements = else, issemi = elsesemi, isbraces = elsebraces)>
<block(statements = else, indent = elseindent)>
<endif>
<endif>
>>
while(comments,cond,block,blocksemi, blockbraces) ::= <<
while(comments,cond,block) ::= <<
<comments; separator="\n">
while (<cond>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block)>
>>
for(comments,init,cond,iter,block,blocksemi, blockbraces) ::= <<
for(comments,init,cond,iter,block,blockindent) ::= <<
<comments; separator="\n">
for (<init>;<cond>;<iter>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block, indent=blockindent)>
>>
foreach(comments,type,loopid,fromexp,block,blocksemi, blockbraces) ::= <<
foreach(comments,type,loopid,fromexp,block,blockindent) ::= <<
<comments; separator="\n">
for (<type> <loopid> : <fromexp>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block,indent=blockindent)>
>>
try(comments,block,blocksemi, blockbraces, catches, fin) ::= <<
try(comments,block, blockindent, catches, fin) ::= <<
<comments; separator="\n">
try
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block, indent=blockindent)>
<catches>
<fin>
>>
catch_template(type, id, block,blocksemi, blockbraces) ::= <<
catch_template(type, id, block, blockindent) ::= <<
catch (<type> <id>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block, indent = blockindent)>
>>
fin(block,blocksemi, blockbraces) ::= <<
fin(block, blockindent) ::= <<
finally
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block, indent = blockindent)>
>>
@ -204,31 +206,30 @@ default_template() ::= <<
default:
>>
lock(comments,exp,block,blocksemi, blockbraces) ::= <<
lock(comments,exp,block, indent) ::= <<
<comments; separator="\n">
lock(<exp>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block, indent = indent)>
>>
keyword_block(comments,keyword,block,blocksemi, blockbraces) ::= <<
keyword_block(comments,keyword,block, indent) ::= <<
<comments; separator="\n">
<keyword>
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)>
<block(statements = block, indent = indent)>
>>
block(statements,issemi,isbraces) ::= <<
<if(issemi)>
;
<else>
<if(isbraces)>
{
<endif>
block(statements, indent) ::= <<
<if(indent)>
<statements>
<if(isbraces)>
<else>
<statements>
<endif>
>>
braceblock(statements) ::= <<
{
<statements; separator="\n">
}
<endif>
<endif>
>>
// ******* EXPRESSIONS *******