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

support for -experimental-enums-numericconsts and -experimental-unsigned-translatesigned

This commit is contained in:
Kevin Glynn 2011-06-14 09:38:13 +02:00
parent 2363e9da5e
commit d4c5b20e97
7 changed files with 211 additions and 19 deletions

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is
Copyright 2010,2011 Kevin Glynn (kevin.glynn@twigletsoftware.com)
-->
<Class xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:www.twigletsoftware.com:schemas:txtemplate:1:0">
<Imports />
<Java>Enum</Java>
<Name>System.EnumAsNumber</Name>
<Uses />
<Inherits>
<Type>System.Int32</Type>
</Inherits>
<Methods>
<Method>
<Imports>
<Import>CS2JNet.System.EnumSupport</Import>
</Imports>
<Java>EnumSupport.isDefined(${enumType}, ${value})</Java>
<Params>
<Param>
<Type>System.Object</Type>
<Name>enumType</Name>
</Param>
<Param>
<Type>System.Object</Type>
<Name>value</Name>
</Param>
</Params>
<Name>IsDefined</Name>
<Return>System.Boolean</Return>
</Method>
<Method>
<Imports>
<Import>CS2JNet.System.EnumSupport</Import>
</Imports>
<Java>EnumSupport.toString(${this}, ${modifier})</Java>
<Params>
<Param>
<Type>System.String</Type>
<Name>modifier</Name>
</Param>
</Params>
<Name>ToString</Name>
<Return>System.String</Return>
</Method>
<Method>
<Imports />
<Java>Enum.valueOf((Class*[? extends Enum]*)${enumType:15}, ${value})</Java>
<Params>
<Param>
<Type>System.Type</Type>
<Name>enumType</Name>
</Param>
<Param>
<Type>System.String</Type>
<Name>value</Name>
</Param>
</Params>
<Name>Parse</Name>
<Return>System.Object</Return>
</Method>
</Methods>
<Properties />
<Events />
<Indexers />
<Constructors />
<Fields />
<Casts>
<Cast>
<Imports />
<Java>${to_type}.values()[${expr}]</Java>
<From>System.Byte</From>
</Cast>
<Cast>
<Imports />
<Java>(byte)(((Enum)${expr}).ordinal())</Java>
<From>System.Enum</From>
<To>System.Byte</To>
</Cast>
<Cast>
<Imports />
<Java>${to_type}.values()[${expr}]</Java>
<From>System.Int32</From>
</Cast>
<Cast>
<Imports />
<Java>((Enum)${expr}).ordinal()</Java>
<From>System.Enum</From>
<To>System.Int32</To>
</Cast>
</Casts>
<UnaryOps />
<BinaryOps />
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>IJMEeLm8aEBz8xz+22PUOm4mKmY=</DigestValue></Reference></SignedInfo><SignatureValue>GBzy7yxUC2deFlJLdqC849pFbVEg5Zv+sB5LLtV4mnAixFeiQ5PlOHal7FqDSoqMtMpjMYpc9rjRvkWrQSWWWMJ5IAOI4HZBcTy1CYAWXnBXMjoUscMdyFIgzQF7ExrANCDt0LUn7xWCAb2S57bcj7yIREPjDonAM6YPOWi9Xa4=</SignatureValue></Signature></Class>

View File

@ -130,6 +130,8 @@ namespace Twiglet.CS2J.Translator
.Add ("translator-keep-parens=", v => cfg.TranslatorKeepParens = Boolean.Parse(v))
.Add ("translator-timestamp-files=", v => cfg.TranslatorAddTimeStamp = Boolean.Parse(v))
.Add ("translator-exception-is-throwable=", v => cfg.TranslatorExceptionIsThrowable = Boolean.Parse(v))
.Add ("experimental-enums-numericconsts", v => cfg.EnumsAsNumericConsts = true)
.Add ("experimental-unsigned-translatesigned", v => cfg.UnsignedNumbersToSigned = true)
.Add ("experimental-transforms=", v => cfg.ExperimentalTransforms = Boolean.Parse(v))
.Add ("internal-isjavaish", v => cfg.InternalIsJavaish = true)
;

View File

@ -56,6 +56,16 @@ namespace Twiglet.CS2J.Translator
get; set;
}
public bool EnumsAsNumericConsts
{
get; set;
}
public bool UnsignedNumbersToSigned
{
get; set;
}
public bool ExperimentalTransforms
{
get; set;
@ -99,6 +109,9 @@ namespace Twiglet.CS2J.Translator
TranslatorAddTimeStamp = true;
TranslatorExceptionIsThrowable = false;
EnumsAsNumericConsts = false;
UnsignedNumbersToSigned = false;
ExperimentalTransforms = false;
InternalIsJavaish = false;

View File

@ -467,6 +467,13 @@ scope TypeContext {
{"string", "String"}
};
Dictionary<string, string> predefined_unsigned_type_map = new Dictionary<string, string>()
{
{"uint", "int"},
{"ulong", "long"},
{"ushort", "short"}
};
protected CommonTree mkHole() {
return mkHole(null);
}
@ -1439,13 +1446,20 @@ remove_accessor_declaration:
///////////////////////////////////////////////////////
enum_declaration[CommonTree atts, CommonTree mods] returns [string name]
scope TypeContext;
@init {
CommonTree constType = null;
}
:
e='enum' identifier { $name = $identifier.thetext; $TypeContext::typeName = $identifier.thetext; } enum_base? enum_body ';'?
-> ^(ENUM[$e.token, "ENUM"] { dupTree($atts) } { dupTree($mods) } identifier enum_base? enum_body);
{ Cfg.EnumsAsNumericConsts }? =>
e1='enum' identifier { $name = $identifier.thetext; $TypeContext::typeName = $identifier.thetext; } magicBoxedType[true,$e1.token,"System.Int32"] { constType = $magicBoxedType.tree; } (enum_base {constType = $enum_base.tree; } )? enum_body_asnumber[constType] ';'?
-> ^(CLASS[$e1.token, "class"] { dupTree($atts) } { dupTree($mods) } identifier enum_body_asnumber)
| e2='enum' identifier { $name = $identifier.thetext; $TypeContext::typeName = $identifier.thetext; } enum_base? enum_body ';'?
-> ^(ENUM[$e2.token, "ENUM"] { dupTree($atts) } { dupTree($mods) } identifier enum_base? enum_body);
enum_base:
':' integral_type ;
enum_body:
'{' (enum_member_declarations ','?)? '}' -> ^(ENUM_BODY enum_member_declarations? ) ;
c=':' integral_type -> ^(TYPE[$c.token, "TYPE"] integral_type) ;
enum_body:
'{' (enum_member_declarations ','?)? '}' -> ^(ENUM_BODY enum_member_declarations? ) ;
enum_member_declarations
@init {
SortedList<int,CommonTree> members = new SortedList<int,CommonTree>();
@ -1502,6 +1516,25 @@ enum_member_declaration[ SortedList<int,CommonTree> members, ref int next]
integral_type:
'sbyte' | 'byte' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' | 'char' ;
// this escheme translates enums to a class containing numeric constants
enum_body_asnumber [ CommonTree typeTree ]:
'{' (enum_member_declarations_asnumber[typeTree] (','!)?)? '}' ;
enum_member_declarations_asnumber [ CommonTree typeTree ]
@init {
CommonTree prevTree = null;
}:
e1=enum_member_declaration_asnumber[typeTree, prevTree] { prevTree = $e1.thisTree; }
(','! en=enum_member_declaration_asnumber[typeTree, prevTree] { prevTree = $en.thisTree; })*
;
enum_member_declaration_asnumber [ CommonTree typeTree, CommonTree prevTree ] returns [ CommonTree thisTree ]
@init {
CommonTree prev = $prevTree;
}:
attributes? identifier { $thisTree = $identifier.tree; }
(eq='=' expression -> ^(FIELD[$eq.token, "FIELD"] attributes? PUBLIC[$eq.token, "public"] STATIC[$eq.token, "static"] FINAL[$eq.token, "final"] { dupTree(typeTree) } identifier $eq expression)
| magicNumber[$prevTree == null, $identifier.tree.Token, "0"] magicIncrement[$prevTree != null, $identifier.tree.token, $prevTree]
{ prev = $prevTree == null ? $magicNumber.tree : $magicIncrement.tree; } -> ^(FIELD[$identifier.tree.Token, "FIELD"] attributes? PUBLIC[$identifier.tree.Token, "public"] STATIC[$identifier.tree.Token, "static"] FINAL[$identifier.tree.Token, "final"] { dupTree(typeTree) } identifier ASSIGN[$identifier.tree.Token, "="] { dupTree(prev) })) ;
// B.2.12 Delegates
delegate_declaration[CommonTree atts, CommonTree mods, bool toplevel] returns [Dictionary<String, CommonTree> compUnits]
scope TypeContext;
@ -1962,6 +1995,9 @@ predefined_type returns [string thetext]
if (predefined_type_map.TryGetValue($predefined_type.tree.Token.Text, out newText)) {
$predefined_type.tree.Token.Text = newText;
}
if (Cfg.UnsignedNumbersToSigned && predefined_unsigned_type_map.TryGetValue($predefined_type.tree.Token.Text, out newText)) {
$predefined_type.tree.Token.Text = newText;
}
}:
'bool' { $thetext = "System.Boolean"; }
| 'byte' { $thetext = "System.Byte"; }
@ -1975,9 +2011,9 @@ predefined_type returns [string thetext]
| 'sbyte' { $thetext = "System.SByte"; }
| 'short' { $thetext = "System.Int16"; }
| 'string' { $thetext = "System.String"; }
| 'uint' { $thetext = "System.UInt32"; }
| 'ulong' { $thetext = "System.UInt64"; }
| 'ushort' { $thetext = "System.UInt16"; }
| 'uint' { $thetext = Cfg.UnsignedNumbersToSigned ? "System.Int32" : "System.UInt32"; }
| 'ulong' { $thetext = Cfg.UnsignedNumbersToSigned ? "System.Int64" : "System.UInt64"; }
| 'ushort' { $thetext = Cfg.UnsignedNumbersToSigned ? "System.Int16" : "System.UInt16"; }
;
identifier returns [string thetext]
@ -2271,3 +2307,18 @@ magicMultiDelClass[IToken tok, CommonTree atts, CommonTree mods, string classNam
//magicClassFromDescriptor[IToken tok, ClassDescriptor klass]:
//-> ^(CLASS[tok] PAYLOAD[tok, klass.Comments] { dupTree(klass.Atts) } { dupTree(klass.Mods) } { dupTree(klass.Identifier) } { dupTree(klass.TypeParameterConstraintsClauses) } { dupTree(klass.TypeParameterList) } { dupTree(klass.ClassBase) } OPEN_BRACE[tok, "{"] { dupTree(klass.ClassBody) } { emitPartialTypes(klass.PartialTypes) } CLOSE_BRACE[tok, "}"] );
magicBoxedType[bool isOn, IToken tok, String boxedName]:
-> { isOn }? ^(TYPE[tok, "TYPE"] IDENTIFIER[tok, boxedName])
->
;
magicNumber[bool isOn, IToken tok, string number]:
-> { isOn }? NUMBER[tok, number]
->
;
magicIncrement[bool isOn, IToken tok, CommonTree prevExpr]:
-> { isOn }? ^(PLUS[tok, "+"] { dupTree(prevExpr) } NUMBER[tok, "1"])
->
;

View File

@ -1268,7 +1268,7 @@ enum_declaration
^(ENUM { preComments = CollectedComments; } attributes? modifiers? identifier enum_base? enum_body )
-> enum(comments = { preComments}, modifiers = { $modifiers.st }, name={$identifier.text}, body={$enum_body.st}) ;
enum_base:
':' integral_type ;
type ;
enum_body:
^(ENUM_BODY es+=enum_member_declaration*) -> enum_body(values={$es});
enum_member_declaration:

View File

@ -2397,7 +2397,7 @@ remove_accessor_declaration:
enum_declaration:
^(ENUM attributes? modifiers? identifier enum_base? enum_body );
enum_base:
':' integral_type ;
type ;
enum_body:
^(ENUM_BODY enum_member_declarations?) ;
enum_member_declarations:
@ -2949,9 +2949,9 @@ predefined_type returns [TypeRepTemplate dotNetType]
| 'sbyte' { ns = "System.SByte"; }
| 'short' { ns = "System.Int16"; }
| 'string' { ns = "System.String"; }
| 'uint' { ns = "System.UInt32"; }
| 'ulong' { ns = "System.UInt64"; }
| 'ushort' { ns = "System.UInt16"; }
| 'uint' { ns = Cfg.UnsignedNumbersToSigned ? "System.Int32" : "System.UInt32"; }
| 'ulong' { ns = Cfg.UnsignedNumbersToSigned ? "System.Int64" : "System.UInt64"; }
| 'ushort' { ns = Cfg.UnsignedNumbersToSigned ? "System.Int16" : "System.UInt16"; }
;
// Don't trust identifier.text in tree grammars: Doesn't work for our magic additions because the text function goes back to the

View File

@ -924,11 +924,16 @@ remove_accessor_declaration:
// enum declaration
///////////////////////////////////////////////////////
enum_declaration
scope {
String baseType;
}
scope NSContext;
@init {
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
EnumRepTemplate eenum = new EnumRepTemplate();
TypeRepTemplate eenum = Cfg.EnumsAsNumericConsts ? (TypeRepTemplate)new ClassRepTemplate() : (TypeRepTemplate)new EnumRepTemplate();
$enum_declaration::baseType = "System.Int32";
string javatype = "int";
}
:
'enum' identifier enum_base?
@ -943,25 +948,48 @@ scope NSContext;
eenum.Uses = this.CollectUses;
eenum.Aliases = this.CollectAliases;
eenum.Imports = new string[] {NSPrefix(ParentNameSpace) + $identifier.text};
if (Cfg.EnumsAsNumericConsts) {
if (!String.IsNullOrEmpty($enum_base.thetext)) {
$enum_declaration::baseType = $enum_base.thetext;
javatype = $enum_base.javatype;
}
eenum.Java = javatype;
eenum.Inherits = new String[] { "System.EnumAsNumber" };
}
}
enum_body ';'? ;
enum_base:
':' integral_type ;
enum_base returns [string thetext, string javatype]:
':' integral_type { $thetext = $integral_type.thetext; $javatype = $integral_type.javatype; } ;
enum_body:
'{' (enum_member_declarations ','?)? '}' ;
enum_member_declarations:
enum_member_declaration (',' enum_member_declaration)* ;
enum_member_declaration:
attributes? identifier ('=' expression)?
{ ((EnumRepTemplate)$NSContext::currentTypeRep).Members.Add(new EnumMemberRepTemplate($identifier.text, $expression.text)); } // todo: are arbitrary expressions really allowed
{ if (Cfg.EnumsAsNumericConsts) {
((ClassRepTemplate)$NSContext::currentTypeRep).Fields.Add(new FieldRepTemplate($enum_declaration::baseType, $identifier.text));
}
else {
((EnumRepTemplate)$NSContext::currentTypeRep).Members.Add(new EnumMemberRepTemplate($identifier.text, $expression.text));
}
}
{ DebugDetail("Processing enum member: " + $identifier.text); }
;
//enum_modifiers:
// enum_modifier+ ;
//enum_modifier:
// 'new' | 'public' | 'protected' | 'internal' | 'private' ;
integral_type:
'sbyte' | 'byte' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' | 'char' ;
integral_type returns [string thetext, string javatype]:
'byte' { $thetext = "System.Byte"; $javatype = "byte"; }
| 'char' { $thetext = "System.Char"; $javatype = "char"; }
| 'int' { $thetext = "System.Int32"; $javatype = "int"; }
| 'long' { $thetext = "System.Int64"; $javatype = "long"; }
| 'sbyte' { $thetext = "System.SByte"; $javatype = "byte"; }
| 'short' { $thetext = "System.Int16"; $javatype = "short"; }
| 'uint' { $thetext = "System.UInt32"; $javatype = "int"; }
| 'ulong' { $thetext = "System.UInt64"; $javatype = "long"; }
| 'ushort' { $thetext = "System.UInt16"; $javatype = "short"; }
;
// B.2.12 Delegates
delegate_declaration