mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
support explicit casts
This commit is contained in:
parent
d27c25c2c8
commit
c536686bf6
@ -579,7 +579,17 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
else {
|
||||
if (!String.IsNullOrEmpty(SurroundingTypeName)) {
|
||||
return SurroundingTypeName.Substring(SurroundingTypeName.LastIndexOf('.') + 1) + ".__castto_" + To.Replace('.','_') + "(${expr})";
|
||||
String myType = SurroundingTypeName.Substring(SurroundingTypeName.LastIndexOf('.') + 1);
|
||||
String toType = To.Substring(To.LastIndexOf('.') + 1);
|
||||
if (myType == toType)
|
||||
{
|
||||
// just overload various casts to my type
|
||||
return myType + ".__cast(${expr})";
|
||||
}
|
||||
else
|
||||
{
|
||||
return myType + ".__cast${TYPEOF_totype}(${expr})";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -906,6 +916,16 @@ namespace RusticiSoftware.Translator.CLR
|
||||
[XmlArrayItem("Alias")]
|
||||
public AliasRepTemplate[] Aliases { get; set; }
|
||||
|
||||
protected List<CastRepTemplate> _casts = null;
|
||||
[XmlArrayItem("Cast")]
|
||||
public virtual List<CastRepTemplate> Casts {
|
||||
get {
|
||||
if (_casts == null)
|
||||
_casts = new List<CastRepTemplate> ();
|
||||
return _casts;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeRepTemplate () : base()
|
||||
{
|
||||
TypeName = null;
|
||||
@ -966,6 +986,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve a method call (name and arg types)
|
||||
public virtual ResolveResult Resolve(String name, List<TypeRepTemplate> args, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
if (Inherits != null)
|
||||
@ -984,6 +1005,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve a field or property access
|
||||
public virtual ResolveResult Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
if (Inherits != null)
|
||||
@ -1002,6 +1024,85 @@ namespace RusticiSoftware.Translator.CLR
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve a cast from this type to castTo
|
||||
public virtual ResolveResult ResolveCastTo(TypeRepTemplate castTo, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
if (Casts != null)
|
||||
{
|
||||
foreach (CastRepTemplate c in Casts)
|
||||
{
|
||||
if (c.To != null)
|
||||
{
|
||||
// Is this a cast from us?
|
||||
TypeRepTemplate fromTy = null;
|
||||
if (c.From != null)
|
||||
{
|
||||
fromTy = AppEnv.Search(Uses, c.From);
|
||||
}
|
||||
if (c.From == null || (fromTy != null && fromTy.TypeName == TypeName))
|
||||
{
|
||||
// cast from us
|
||||
TypeRepTemplate toTy = AppEnv.Search(Uses, c.To);
|
||||
if (toTy.IsA(castTo, AppEnv))
|
||||
{
|
||||
ResolveResult res = new ResolveResult();
|
||||
res.Result = c;
|
||||
res.ResultType = toTy;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Inherits != null)
|
||||
{
|
||||
foreach (String b in Inherits)
|
||||
{
|
||||
TypeRepTemplate baseType = AppEnv.Search(Uses, b);
|
||||
if (baseType != null)
|
||||
{
|
||||
ResolveResult ret = baseType.ResolveCastTo(castTo,AppEnv);
|
||||
if (ret != null)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve a cast to this type from castFrom
|
||||
public virtual ResolveResult ResolveCastFrom(TypeRepTemplate castFrom, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
if (Casts != null)
|
||||
{
|
||||
foreach (CastRepTemplate c in Casts)
|
||||
{
|
||||
if (c.From != null)
|
||||
{
|
||||
// Is this a cast to us?
|
||||
TypeRepTemplate toTy = null;
|
||||
if (c.To != null)
|
||||
{
|
||||
toTy = AppEnv.Search(Uses, c.To);
|
||||
}
|
||||
if (c.To == null || (toTy != null && toTy.TypeName == TypeName))
|
||||
{
|
||||
// cast to us
|
||||
TypeRepTemplate fromTy = AppEnv.Search(Uses, c.From);
|
||||
if (castFrom.IsA(fromTy, AppEnv))
|
||||
{
|
||||
ResolveResult res = new ResolveResult();
|
||||
res.Result = c;
|
||||
res.ResultType = toTy;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns true if other is a subclass, or implements our interface
|
||||
public virtual bool IsA (TypeRepTemplate other, DirectoryHT<TypeRepTemplate> AppEnv) {
|
||||
if (other.TypeName == this.TypeName)
|
||||
@ -1122,6 +1223,15 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
|
||||
if (Casts != other.Casts) {
|
||||
if (Casts == null || other.Casts == null || Casts.Count != other.Casts.Count)
|
||||
return false;
|
||||
for (int i = 0; i < Casts.Count; i++) {
|
||||
if (Casts[i] != other.Casts[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return TypeName == other.TypeName && base.Equals(other);
|
||||
}
|
||||
|
||||
@ -1163,6 +1273,12 @@ namespace RusticiSoftware.Translator.CLR
|
||||
hashCode ^= e.GetHashCode();
|
||||
}
|
||||
}
|
||||
if (Casts != null) {
|
||||
foreach (CastRepTemplate e in Casts) {
|
||||
hashCode ^= e.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
return (Java ?? String.Empty).GetHashCode () ^ hashCode;
|
||||
}
|
||||
#endregion
|
||||
@ -1186,6 +1302,38 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
|
||||
private List<CastRepTemplate> _enumCasts = null;
|
||||
private List<CastRepTemplate> EnumCasts {
|
||||
get {
|
||||
if (_enumCasts == null)
|
||||
{
|
||||
_enumCasts = new List<CastRepTemplate> ();
|
||||
CastRepTemplate kast = new CastRepTemplate();
|
||||
kast.From = "System.Int32";
|
||||
kast.Java = "${TYPEOF_totype}.values()[${expr}]";
|
||||
_enumCasts.Add(kast);
|
||||
kast = new CastRepTemplate();
|
||||
kast.To = "System.Int32";
|
||||
kast.Java = "((Enum)${expr}).ordinal()";
|
||||
_enumCasts.Add(kast);
|
||||
}
|
||||
return _enumCasts;
|
||||
}
|
||||
}
|
||||
|
||||
public override List<CastRepTemplate> Casts {
|
||||
get {
|
||||
if (_casts == null)
|
||||
{
|
||||
return EnumCasts;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _casts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public EnumRepTemplate () : base()
|
||||
{
|
||||
Inherits = new string[] { "System.Enum" };
|
||||
@ -1632,16 +1780,6 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
|
||||
private List<CastRepTemplate> _casts = null;
|
||||
[XmlArrayItem("Cast")]
|
||||
public List<CastRepTemplate> Casts {
|
||||
get {
|
||||
if (_casts == null)
|
||||
_casts = new List<CastRepTemplate> ();
|
||||
return _casts;
|
||||
}
|
||||
}
|
||||
|
||||
private List<MethodRepTemplate> _unaryOps = null;
|
||||
[XmlArrayItem("UnaryOp")]
|
||||
public List<MethodRepTemplate> UnaryOps {
|
||||
@ -1752,7 +1890,6 @@ namespace RusticiSoftware.Translator.CLR
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
#region Equality
|
||||
public bool Equals (ClassRepTemplate other)
|
||||
{
|
||||
@ -1777,15 +1914,6 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
|
||||
if (Casts != other.Casts) {
|
||||
if (Casts == null || other.Casts == null || Casts.Count != other.Casts.Count)
|
||||
return false;
|
||||
for (int i = 0; i < Casts.Count; i++) {
|
||||
if (Casts[i] != other.Casts[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnaryOps != other.UnaryOps) {
|
||||
if (UnaryOps == null || other.UnaryOps == null || UnaryOps.Count != other.UnaryOps.Count)
|
||||
return false;
|
||||
@ -1841,11 +1969,6 @@ namespace RusticiSoftware.Translator.CLR
|
||||
hashCode ^= e.GetHashCode();
|
||||
}
|
||||
}
|
||||
if (Casts != null) {
|
||||
foreach (CastRepTemplate e in Casts) {
|
||||
hashCode ^= e.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
@ -751,8 +751,7 @@ assignment
|
||||
unary_expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTemplate typeofType]:
|
||||
//('(' arguments ')' ('[' | '.' | '(')) => primary_or_array_creation_expression
|
||||
|
||||
//(cast_expression) => cast_expression
|
||||
^(CAST_EXPR type unary_expression) { $dotNetType = $type.dotNetType; }
|
||||
cast_expression { $dotNetType = $cast_expression.dotNetType; }
|
||||
| primary_or_array_creation_expression { $dotNetType = $primary_or_array_creation_expression.dotNetType; $rmId = $primary_or_array_creation_expression.rmId; $typeofType = $primary_or_array_creation_expression.typeofType; }
|
||||
| ^(MONOPLUS u1=unary_expression) { $dotNetType = $u1.dotNetType; }
|
||||
| ^(MONOMINUS u2=unary_expression) { $dotNetType = $u2.dotNetType; }
|
||||
@ -764,8 +763,36 @@ unary_expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTempla
|
||||
| ^(ADDRESSOF unary_expression) { $dotNetType = ObjectType; }
|
||||
| ^(PARENS expression) { $dotNetType = $expression.dotNetType; $rmId = $expression.rmId; $typeofType = $expression.typeofType; }
|
||||
;
|
||||
//cast_expression:
|
||||
// '(' type ')' non_assignment_expression ;
|
||||
|
||||
cast_expression returns [TypeRepTemplate dotNetType]
|
||||
@init {
|
||||
CommonTree ret = null;
|
||||
}
|
||||
@after {
|
||||
if (ret != null)
|
||||
$cast_expression.tree = ret;
|
||||
}:
|
||||
^(c=CAST_EXPR type unary_expression)
|
||||
{
|
||||
$dotNetType = $type.dotNetType;
|
||||
if ($type.dotNetType != null && $unary_expression.dotNetType != null) {
|
||||
// see if expression's type has a cast to type
|
||||
ResolveResult kaster = $unary_expression.dotNetType.ResolveCastTo($type.dotNetType, AppEnv);
|
||||
if (kaster == null) {
|
||||
// see if type has a cast from expression's type
|
||||
kaster = $type.dotNetType.ResolveCastFrom($unary_expression.dotNetType, AppEnv);
|
||||
}
|
||||
if (kaster != null) {
|
||||
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
||||
myMap["expr"] = wrapExpression($unary_expression.tree, $c.token);
|
||||
myMap["TYPEOF_totype"] = wrapTypeOfType($type.dotNetType, $c.token);
|
||||
myMap["TYPEOF_expr"] = wrapTypeOfType($unary_expression.dotNetType, $c.token);
|
||||
ret = mkJavaWrapper(kaster.Result.Java, myMap, $c.token);
|
||||
Imports.Add(kaster.Result.Imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
assignment_operator:
|
||||
'=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>' '>=' ;
|
||||
//pre_increment_expression:
|
||||
@ -1195,10 +1222,22 @@ conversion_operator_declaration[CommonTree atts, CommonTree mods]
|
||||
scope SymTab;
|
||||
@init {
|
||||
$SymTab::symtab = new Dictionary<string,TypeRepTemplate>();
|
||||
String methodName = "__cast";
|
||||
}:
|
||||
h=conversion_operator_declarator { $SymTab::symtab[$h.var] = $h.varTy; } b=operator_body meth=magicCastOperator[$mods, $h.tree, $b.tree] -> $meth;
|
||||
conversion_operator_declarator returns [ String var, TypeRepTemplate varTy ] :
|
||||
('implicit' | 'explicit') o='operator' t=type '(' f=type n=identifier ')' { $var = $n.thetext; $varTy = $f.dotNetType; } -> $o $t $f $n;
|
||||
h=conversion_operator_declarator
|
||||
{
|
||||
$SymTab::symtab[$h.var] = $h.varTy;
|
||||
// if varTy is same as this class then need to include toType in methodname
|
||||
if ($NSContext::currentNS == $h.varTy.TypeName)
|
||||
{
|
||||
methodName += $h.toTy.Java;
|
||||
}
|
||||
}
|
||||
b=operator_body meth=magicCastOperator[$mods, methodName, $h.tree, $b.tree] -> $meth;
|
||||
conversion_operator_declarator returns [ String var, TypeRepTemplate varTy, TypeRepTemplate toTy ] :
|
||||
('implicit' | 'explicit') o='operator' t=type '(' f=type n=identifier ')'
|
||||
{ $var = $n.thetext; $varTy = $f.dotNetType; $toTy = $t.dotNetType; }
|
||||
-> $o $t $f $n;
|
||||
operator_body:
|
||||
block ;
|
||||
|
||||
@ -1479,7 +1518,7 @@ magicScrutineeVar [IToken tok] returns [String thetext]
|
||||
}:
|
||||
-> IDENTIFIER[tok,$thetext];
|
||||
|
||||
magicCastOperator[CommonTree mods, CommonTree header, CommonTree body]
|
||||
magicCastOperator[CommonTree mods, String methodName, CommonTree header, CommonTree body]
|
||||
@init {
|
||||
IToken tok = ((CommonTree)$header.Children[0]).Token;
|
||||
CommonTree toType = dupTree((CommonTree)$header.Children[1]);
|
||||
@ -1488,7 +1527,7 @@ magicCastOperator[CommonTree mods, CommonTree header, CommonTree body]
|
||||
}:
|
||||
-> ^(METHOD[tok, "METHOD"]
|
||||
{ dupTree($mods) }
|
||||
{ toType } IDENTIFIER[tok, "__cast"] ^(PARAMS[tok, "PARAMS"] { fromType } { paramName})
|
||||
{ toType } IDENTIFIER[tok, $methodName] ^(PARAMS[tok, "PARAMS"] { fromType } { paramName})
|
||||
{ dupTree(body) }
|
||||
EXCEPTION[tok, "Throwable"])
|
||||
;
|
||||
|
Loading…
x
Reference in New Issue
Block a user