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:
parent
2363e9da5e
commit
d4c5b20e97
98
CS2JLibrary/NetFramework/System/EnumAsNumber.xml
Normal file
98
CS2JLibrary/NetFramework/System/EnumAsNumber.xml
Normal 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>
|
@ -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)
|
||||
;
|
||||
|
@ -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;
|
||||
|
@ -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"])
|
||||
->
|
||||
;
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user