mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
generate java main method to wrap a C# Main method
This commit is contained in:
parent
71512e308f
commit
65508713f0
@ -21,6 +21,11 @@ scope NSContext {
|
|||||||
string currentNS;
|
string currentNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A scope to keep track of the current type context
|
||||||
|
scope TypeContext {
|
||||||
|
string typeName;
|
||||||
|
}
|
||||||
|
|
||||||
@namespace { RusticiSoftware.Translator.CSharp }
|
@namespace { RusticiSoftware.Translator.CSharp }
|
||||||
|
|
||||||
@header
|
@header
|
||||||
@ -69,11 +74,11 @@ scope NSContext {
|
|||||||
protected CommonTree addConstModifiers(IToken tok, List<string> filter) {
|
protected CommonTree addConstModifiers(IToken tok, List<string> filter) {
|
||||||
CommonTree root = (CommonTree)adaptor.Nil;
|
CommonTree root = (CommonTree)adaptor.Nil;
|
||||||
|
|
||||||
if (!filter.Contains("static") )
|
if (filter == null || !filter.Contains("static") )
|
||||||
{
|
{
|
||||||
adaptor.AddChild(root, (CommonTree)adaptor.Create(STATIC, tok, "static"));
|
adaptor.AddChild(root, (CommonTree)adaptor.Create(STATIC, tok, "static"));
|
||||||
}
|
}
|
||||||
if (!filter.Contains("final"))
|
if (filter == null || !filter.Contains("final"))
|
||||||
{
|
{
|
||||||
adaptor.AddChild(root, (CommonTree)adaptor.Create(FINAL, tok, "final"));
|
adaptor.AddChild(root, (CommonTree)adaptor.Create(FINAL, tok, "final"));
|
||||||
}
|
}
|
||||||
@ -207,15 +212,15 @@ modifier:
|
|||||||
class_member_declaration:
|
class_member_declaration:
|
||||||
a=attributes?
|
a=attributes?
|
||||||
m=modifiers?
|
m=modifiers?
|
||||||
( c='const' ct=type constant_declarators ';' -> ^(FIELD[$c.token, "FIELD"] $a? $m { addConstModifiers($c.token, $modifiers.modList) } $ct constant_declarators)
|
( c='const' ct=type constant_declarators ';' -> ^(FIELD[$c.token, "FIELD"] $a? $m? { addConstModifiers($c.token, $m.modList) } $ct constant_declarators)
|
||||||
| ed=event_declaration -> ^(EVENT[$ed.start.Token, "EVENT"] $a? $m? $ed)
|
| ed=event_declaration -> ^(EVENT[$ed.start.Token, "EVENT"] $a? $m? $ed)
|
||||||
| p='partial' { Warning($p.line, "[UNSUPPORTED] 'partial' definition"); } (v1=void_type m3=method_declaration[$a.tree, $m.tree, $v1.tree] -> $m3 //-> ^(METHOD[$v1.token, "METHOD"] $a? $m? ^(TYPE $v1) $m3)
|
| p='partial' { Warning($p.line, "[UNSUPPORTED] 'partial' definition"); } (v1=void_type m3=method_declaration[$a.tree, $m.tree, $m.modList, $v1.tree, $v1.text] -> $m3 //-> ^(METHOD[$v1.token, "METHOD"] $a? $m? ^(TYPE $v1) $m3)
|
||||||
| i1=interface_declaration -> ^(INTERFACE[$i1.start.Token, "INTERFACE"] $a? $m? $i1)
|
| i1=interface_declaration -> ^(INTERFACE[$i1.start.Token, "INTERFACE"] $a? $m? $i1)
|
||||||
| c1=class_declaration -> ^(CLASS[$c1.start.Token, "CLASS"] $a? $m? $c1)
|
| c1=class_declaration -> ^(CLASS[$c1.start.Token, "CLASS"] $a? $m? $c1)
|
||||||
| s1=struct_declaration) -> ^(CLASS[$s1.start.Token, "CLASS"] $a? $m? $s1)
|
| s1=struct_declaration) -> ^(CLASS[$s1.start.Token, "CLASS"] $a? $m? $s1)
|
||||||
| i2=interface_declaration -> ^(INTERFACE[$i2.start.Token, "INTERFACE"] $a? $m? $i2) // 'interface'
|
| i2=interface_declaration -> ^(INTERFACE[$i2.start.Token, "INTERFACE"] $a? $m? $i2) // 'interface'
|
||||||
| v2=void_type m1=method_declaration[$a.tree, $m.tree, $v2.tree] -> $m1 //-> ^(METHOD[$v.token, "METHOD"] $a? $m? ^(TYPE[$v.token, "TYPE"] $v) $m1)
|
| v2=void_type m1=method_declaration[$a.tree, $m.tree, $m.modList, $v2.tree, $v2.text] -> $m1 //-> ^(METHOD[$v.token, "METHOD"] $a? $m? ^(TYPE[$v.token, "TYPE"] $v) $m1)
|
||||||
| t=type ( (member_name type_parameter_list? '(') => m2=method_declaration[$a.tree, $m.tree, $t.tree] -> $m2
|
| t=type ( (member_name type_parameter_list? '(') => m2=method_declaration[$a.tree, $m.tree, $m.modList, $t.tree, $t.text] -> $m2
|
||||||
| (member_name '{') => pd=property_declaration[$a.tree, $m.tree, $t.tree] -> $pd
|
| (member_name '{') => pd=property_declaration[$a.tree, $m.tree, $t.tree] -> $pd
|
||||||
| (member_name '.' 'this') => type_name '.' ix1=indexer_declaration[$a.tree, $m.tree, $t.tree] -> $ix1
|
| (member_name '.' 'this') => type_name '.' ix1=indexer_declaration[$a.tree, $m.tree, $t.tree] -> $ix1
|
||||||
| ix2=indexer_declaration[$a.tree, $m.tree, $t.tree] -> $ix2 //this
|
| ix2=indexer_declaration[$a.tree, $m.tree, $t.tree] -> $ix2 //this
|
||||||
@ -712,8 +717,10 @@ attribute_argument_expression:
|
|||||||
// Class Section
|
// Class Section
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
|
||||||
class_declaration returns [string name]:
|
class_declaration returns [string name]
|
||||||
c='class' identifier type_parameter_list? { $name = mkTypeName($identifier.text, $type_parameter_list.names); } class_base? type_parameter_constraints_clauses? class_body ';'?
|
scope TypeContext;
|
||||||
|
:
|
||||||
|
c='class' identifier { $TypeContext::typeName = $identifier.text; } type_parameter_list? { $name = mkTypeName($identifier.text, $type_parameter_list.names); } class_base? type_parameter_constraints_clauses? class_body ';'?
|
||||||
-> ^(CLASS[$c.Token] identifier type_parameter_constraints_clauses? type_parameter_list? class_base? class_body );
|
-> ^(CLASS[$c.Token] identifier type_parameter_constraints_clauses? type_parameter_list? class_base? class_body );
|
||||||
|
|
||||||
type_parameter_list returns [List<string> names]
|
type_parameter_list returns [List<string> names]
|
||||||
@ -756,20 +763,62 @@ variable_declarator:
|
|||||||
type_name ('=' variable_initializer)? ; // eg. event EventHandler IInterface.VariableName = Foo;
|
type_name ('=' variable_initializer)? ; // eg. event EventHandler IInterface.VariableName = Foo;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
method_declaration [CommonTree atts, CommonTree mods, CommonTree type]
|
method_declaration [CommonTree atts, CommonTree mods, List<string> modList, CommonTree type, String typeText]
|
||||||
@init {
|
@init {
|
||||||
bool isToString = false;
|
bool isToString = false;
|
||||||
CommonTree exceptions = null;
|
CommonTree exceptions = null;
|
||||||
|
CommonTree optMain = null;
|
||||||
|
bool isVoid = $typeText == "void";
|
||||||
|
bool isInt = $typeText == "int" || $typeText == "System.Int32" || $typeText == "Int32";
|
||||||
|
bool isMain = isVoid || isInt;
|
||||||
|
bool isMainHasArg = false;
|
||||||
}:
|
}:
|
||||||
member_name { isToString = $member_name.text == "ToString"; } (type_parameter_list { isToString = false; })? '(' (formal_parameter_list { isToString = false; })? ')' ( type_parameter_constraints_clauses { isToString = false; })? b=method_body[isToString]
|
// TODO: According to the spec the C# Main() method should be static and not public. We aren't checking for lack of public
|
||||||
{ if (isToString) {
|
// we can check the modifiers in modList if we want to enforce that.
|
||||||
$member_name.tree.Token.Text = "toString";
|
member_name { isToString = $member_name.text == "ToString"; isMain &= $member_name.text == "Main"; }
|
||||||
}
|
(type_parameter_list { isToString = false; isMain = false; })?
|
||||||
else {
|
'('
|
||||||
|
// We are looking for ToString(), and Main(String[] args), where arg is optional.
|
||||||
|
(formal_parameter_list
|
||||||
|
{ isToString = false;
|
||||||
|
if (isMain) {
|
||||||
|
isMain = false;
|
||||||
|
// since we have an argument, must check its an array of String
|
||||||
|
if ($formal_parameter_list.tree != null && $formal_parameter_list.tree.Children != null && $formal_parameter_list.tree.Children.Count == 2) {
|
||||||
|
// parameter list children size is 2 (type arg)
|
||||||
|
CommonTree argTy = (CommonTree)$formal_parameter_list.tree.Children[0];
|
||||||
|
if (argTy != null && argTy.Children != null && argTy.Children.Count == 3) {
|
||||||
|
// Looking for Children of "String" "[" "]"
|
||||||
|
if (argTy.Children[0].Text.ToLower() == "string" &&
|
||||||
|
argTy.Children[1].Text == "[" &&
|
||||||
|
argTy.Children[2].Text == "]") {
|
||||||
|
// Bingo!
|
||||||
|
isMain = true;
|
||||||
|
isMainHasArg = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)?
|
||||||
|
')'
|
||||||
|
( type_parameter_constraints_clauses { isToString = false; isMain = false; })?
|
||||||
|
b=method_body[isToString]
|
||||||
|
|
||||||
|
// build main method if required
|
||||||
|
argParam=magicMainArgs[isMain && isMainHasArg, $member_name.tree.Token]
|
||||||
|
mainApply=magicMainApply[isMain, $member_name.tree.Token, $TypeContext::typeName, $argParam.tree]
|
||||||
|
mainCall=magicMainExit[isMain, isInt, $member_name.tree.Token, $mainApply.tree]
|
||||||
|
mainMethod=magicMainWrapper[isMain, $member_name.tree.Token, $mainCall.tree]
|
||||||
|
|
||||||
|
|
||||||
|
{ if (isToString) {
|
||||||
|
$member_name.tree.Token.Text = "toString";
|
||||||
|
}
|
||||||
exceptions = $b.exceptionList;
|
exceptions = $b.exceptionList;
|
||||||
}
|
}
|
||||||
}
|
-> $mainMethod?
|
||||||
-> ^(METHOD { dupTree($atts) } { dupTree($mods) } { dupTree($type) }
|
^(METHOD { dupTree($atts) } { dupTree($mods) } { dupTree($type) }
|
||||||
member_name type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list? $b { exceptions });
|
member_name type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list? $b { exceptions });
|
||||||
|
|
||||||
method_body [bool smotherExceptions] returns [CommonTree exceptionList]:
|
method_body [bool smotherExceptions] returns [CommonTree exceptionList]:
|
||||||
@ -832,8 +881,10 @@ remove_accessor_declaration:
|
|||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// enum declaration
|
// enum declaration
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
enum_declaration returns [string name]:
|
enum_declaration returns [string name]
|
||||||
'enum' identifier { $name = $identifier.text; } enum_base? enum_body ';'? ;
|
scope TypeContext;
|
||||||
|
:
|
||||||
|
'enum' identifier { $name = $identifier.text; $TypeContext::typeName = $identifier.text; } enum_base? enum_body ';'? ;
|
||||||
enum_base:
|
enum_base:
|
||||||
':' integral_type ;
|
':' integral_type ;
|
||||||
enum_body:
|
enum_body:
|
||||||
@ -887,8 +938,10 @@ integral_type:
|
|||||||
'sbyte' | 'byte' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' | 'char' ;
|
'sbyte' | 'byte' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' | 'char' ;
|
||||||
|
|
||||||
// B.2.12 Delegates
|
// B.2.12 Delegates
|
||||||
delegate_declaration returns [string name]:
|
delegate_declaration returns [string name]
|
||||||
'delegate' return_type identifier { $name = $identifier.text; } variant_generic_parameter_list?
|
scope TypeContext;
|
||||||
|
:
|
||||||
|
'delegate' return_type identifier { $name = $identifier.text; $TypeContext::typeName = $identifier.text; } variant_generic_parameter_list?
|
||||||
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' ->
|
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' ->
|
||||||
'delegate' return_type identifier type_parameter_constraints_clauses? variant_generic_parameter_list?
|
'delegate' return_type identifier type_parameter_constraints_clauses? variant_generic_parameter_list?
|
||||||
'(' formal_parameter_list? ')' ';';
|
'(' formal_parameter_list? ')' ';';
|
||||||
@ -951,8 +1004,10 @@ parameter_array:
|
|||||||
'params' type identifier ;
|
'params' type identifier ;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
interface_declaration returns [string name]:
|
interface_declaration returns [string name]
|
||||||
c='interface' identifier { $name = $identifier.text; } variant_generic_parameter_list?
|
scope TypeContext;
|
||||||
|
:
|
||||||
|
c='interface' identifier { $name = $identifier.text; $TypeContext::typeName = $identifier.text; } variant_generic_parameter_list?
|
||||||
interface_base? type_parameter_constraints_clauses? interface_body ';'?
|
interface_base? type_parameter_constraints_clauses? interface_body ';'?
|
||||||
-> ^(INTERFACE[$c.Token] identifier type_parameter_constraints_clauses? variant_generic_parameter_list? interface_base? interface_body );
|
-> ^(INTERFACE[$c.Token] identifier type_parameter_constraints_clauses? variant_generic_parameter_list? interface_base? interface_body );
|
||||||
|
|
||||||
@ -997,8 +1052,10 @@ interface_accessor_declaration [CommonTree atts, CommonTree mods, CommonTree typ
|
|||||||
;
|
;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
struct_declaration returns [string name]:
|
struct_declaration returns [string name]
|
||||||
c='struct' identifier type_parameter_list? { $name = mkTypeName($identifier.text, $type_parameter_list.names); } class_base? type_parameter_constraints_clauses? class_body ';'?
|
scope TypeContext;
|
||||||
|
:
|
||||||
|
c='struct' identifier { $TypeContext::typeName = $identifier.text; } type_parameter_list? { $name = mkTypeName($identifier.text, $type_parameter_list.names); } class_base? type_parameter_constraints_clauses? class_body ';'?
|
||||||
-> ^(CLASS[$c.Token, "class"] identifier type_parameter_constraints_clauses? type_parameter_list? class_base? class_body );
|
-> ^(CLASS[$c.Token, "class"] identifier type_parameter_constraints_clauses? type_parameter_list? class_base? class_body );
|
||||||
|
|
||||||
// UNUSED, HOPEFULLY
|
// UNUSED, HOPEFULLY
|
||||||
@ -1395,3 +1452,37 @@ magicSmotherExceptions[CommonTree body]:
|
|||||||
magicThrowable:
|
magicThrowable:
|
||||||
-> EXCEPTION["Throwable"]
|
-> EXCEPTION["Throwable"]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// METHOD{ public static TYPE{ void } main PARAMS{ TYPE{ String [ ] } args } { APPLY{ .{ System exit } ARGS{ APPLY{ .{ Program Main } } } } ;
|
||||||
|
|
||||||
|
magicMainArgs[bool isOn, IToken tok]:
|
||||||
|
-> { isOn }?
|
||||||
|
^(ARGS[tok, "ARGS"] IDENTIFIER[tok, "args"])
|
||||||
|
->
|
||||||
|
;
|
||||||
|
|
||||||
|
magicMainApply[bool isOn, IToken tok, String klass, CommonTree args]:
|
||||||
|
-> { isOn }?
|
||||||
|
^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,klass] IDENTIFIER[tok,"Main"]) { dupTree(args) } )
|
||||||
|
->
|
||||||
|
;
|
||||||
|
|
||||||
|
magicMainExit[bool isOn, bool retInt, IToken tok, CommonTree body]:
|
||||||
|
-> { isOn && retInt }?
|
||||||
|
^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"System"] IDENTIFIER[tok,"exit"]) ^(ARGS[tok, "ARGS"] { dupTree(body) } ) )
|
||||||
|
-> { isOn }?
|
||||||
|
{ dupTree(body) }
|
||||||
|
->
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
magicMainWrapper[bool isOn, IToken tok, CommonTree body]:
|
||||||
|
-> { isOn }?
|
||||||
|
^(METHOD[tok, "METHOD"]
|
||||||
|
PUBLIC[tok, "public"] STATIC[tok,"static"]
|
||||||
|
^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "void"])
|
||||||
|
IDENTIFIER[tok, "main"] ^(PARAMS[tok, "PARAMS"] ^(TYPE[tok, "TYPE"] IDENTIFIER[tok,"String"] OPEN_BRACKET[tok, "["] CLOSE_BRACKET[tok, "]"]) IDENTIFIER[tok, "args"])
|
||||||
|
OPEN_BRACE[tok, "{"] { dupTree(body) } SEMI[tok, ";"] CLOSE_BRACE[tok, "}"]
|
||||||
|
EXCEPTION[tok, "Throwable"])
|
||||||
|
->
|
||||||
|
;
|
||||||
|
@ -49,6 +49,8 @@ tokens {
|
|||||||
|
|
||||||
RETURN = 'return';
|
RETURN = 'return';
|
||||||
PRIVATE = 'private';
|
PRIVATE = 'private';
|
||||||
|
PUBLIC = 'public';
|
||||||
|
PROTECTED = 'protected';
|
||||||
STATIC = 'static';
|
STATIC = 'static';
|
||||||
PRIVATE = 'private';
|
PRIVATE = 'private';
|
||||||
TRY = 'try';
|
TRY = 'try';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user