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

resolve property reads within dotted expressions

This commit is contained in:
Kevin Glynn 2011-01-13 13:09:05 +01:00
parent d4d24341ac
commit 892d1c17e2
2 changed files with 82 additions and 26 deletions

View File

@ -173,7 +173,7 @@ namespace RusticiSoftware.Translator.CLR
// The Java translation for this C# entity // The Java translation for this C# entity
protected string _java = null; protected string _java = null;
public string Java { public virtual string Java {
get { get {
if (_java == null) { if (_java == null) {
return mkJava(); return mkJava();
@ -640,7 +640,7 @@ namespace RusticiSoftware.Translator.CLR
public override string mkJava() { public override string mkJava() {
return Name; return "${this}." + Name;
} }
#region Equality #region Equality
@ -707,6 +707,14 @@ namespace RusticiSoftware.Translator.CLR
set { _javaGet = value; } set { _javaGet = value; }
} }
public override string Java
{
get
{
return JavaGet;
}
}
private string _javaSet = null; private string _javaSet = null;
[XmlElementAttribute("Set")] [XmlElementAttribute("Set")]
public string JavaSet { public string JavaSet {
@ -1334,7 +1342,7 @@ namespace RusticiSoftware.Translator.CLR
return new InterfaceRep (); return new InterfaceRep ();
} }
public virtual TranslationBase Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv) public virtual ResolveResult Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv)
{ {
if (Properties != null) if (Properties != null)
@ -1342,16 +1350,25 @@ namespace RusticiSoftware.Translator.CLR
foreach (PropRepTemplate p in Properties) foreach (PropRepTemplate p in Properties)
{ {
if (p.Name == name) if (p.Name == name)
return p; {
ResolveResult res = new ResolveResult();
res.Result = p;
res.ResultType = AppEnv.Search(Uses, p.Type);
return res;
}
} }
} }
if (Inherits != null) if (Inherits != null)
{ {
foreach (String b in Inherits) foreach (String b in Inherits)
{ {
TranslationBase ret = ((InterfaceRepTemplate)AppEnv.Search(Uses, b)).Resolve(name,AppEnv); InterfaceRepTemplate baseType = AppEnv.Search(Uses, b) as InterfaceRepTemplate;
if (ret != null) if (baseType != null)
return ret; {
ResolveResult ret = baseType.Resolve(name,AppEnv);
if (ret != null)
return ret;
}
} }
} }
return null; return null;
@ -1550,7 +1567,7 @@ namespace RusticiSoftware.Translator.CLR
return new ClassRep (); return new ClassRep ();
} }
public override TranslationBase Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv) public override ResolveResult Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv)
{ {
if (Fields != null) if (Fields != null)
@ -1558,7 +1575,12 @@ namespace RusticiSoftware.Translator.CLR
foreach (FieldRepTemplate f in Fields) foreach (FieldRepTemplate f in Fields)
{ {
if (f.Name == name) if (f.Name == name)
return f; {
ResolveResult res = new ResolveResult();
res.Result = f;
res.ResultType = AppEnv.Search(Uses, f.Type);
return res;
}
} }
} }
return base.Resolve(name, AppEnv); return base.Resolve(name, AppEnv);
@ -1697,7 +1719,7 @@ namespace RusticiSoftware.Translator.CLR
return new StructRep (); return new StructRep ();
} }
public override TranslationBase Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv) public override ResolveResult Resolve(String name, DirectoryHT<TypeRepTemplate> AppEnv)
{ {
return base.Resolve(name, AppEnv); return base.Resolve(name, AppEnv);
} }
@ -1793,7 +1815,19 @@ namespace RusticiSoftware.Translator.CLR
} }
public class ResolveResult
{
public TranslationBase Result
{
get; set;
}
public TypeRepTemplate ResultType
{
get; set;
}
}

View File

@ -132,14 +132,14 @@ scope SymTab {
} }
// Resolve Routines // Resolve Routines
protected String ResolveGetter(InterfaceRepTemplate thisType, CommonTree thisExp, String name) { // protected ResolveResult ResolveGetter(InterfaceRepTemplate thisType, String name) {
String ret = null; // ResolveResult ret = null;
PropRepTemplate entity = thisType.Resolve(name, AppEnv) as PropRepTemplate; // PropRepTemplate entity = thisType.Resolve(name, AppEnv) as PropRepTemplate;
if (entity != null) { // if (entity != null) {
ret = entity.JavaGet; // ret = entity.JavaGet;
} // }
return ret; // return ret;
} // }
protected CommonTree dupTree(CommonTree t) { protected CommonTree dupTree(CommonTree t) {
return (CommonTree)adaptor.DupTree(t); return (CommonTree)adaptor.DupTree(t);
@ -214,7 +214,27 @@ scope {
| ^(APPLY {$primary_expression::parentIsApply = true; } expression {$primary_expression::parentIsApply = false; } argument_list?) | ^(APPLY {$primary_expression::parentIsApply = true; } expression {$primary_expression::parentIsApply = false; } argument_list?)
| ^(POSTINC expression) | ^(POSTINC expression)
| ^(POSTDEC expression) | ^(POSTDEC expression)
| ^(access_operator expression identifier generic_argument_list?) | ^(d1='.' e1=expression i1=identifier generic_argument_list?)
{
InterfaceRepTemplate expType = $e1.dotNetType as InterfaceRepTemplate;
// Is it a property read? Ensure we are not being applied to arguments or about to be assigned
if (expType != null &&
($primary_expression.Count == 1 || !((primary_expression_scope)($primary_expression.ToArray()[1])).parentIsApply) &&
($assignment.Count == 0 || !$assignment::parentIsSetter)) {
Debug($d1.token.Line + ": '" + $i1.thetext + "' might be a property");
ResolveResult fieldResult = expType.Resolve($i1.thetext, AppEnv);
if (fieldResult != null) {
Debug($d1.token.Line + ": Found '" + $i1.thetext + "'");
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
myMap["this"] = $e1.tree;
ret = mkJavaWrapper(fieldResult.Result.Java, myMap, $i1.tree.Token);
$dotNetType = fieldResult.ResultType;
}
}
}
| ^('->' expression identifier generic_argument_list?)
| predefined_type { $dotNetType = $predefined_type.dotNetType; } | predefined_type { $dotNetType = $predefined_type.dotNetType; }
| 'this' { $dotNetType = SymTabLookup("this"); } | 'this' { $dotNetType = SymTabLookup("this"); }
| SUPER { $dotNetType = SymTabLookup("super"); } | SUPER { $dotNetType = SymTabLookup("super"); }
@ -223,23 +243,25 @@ scope {
TypeRepTemplate idType = SymTabLookup($identifier.thetext); TypeRepTemplate idType = SymTabLookup($identifier.thetext);
if (idType == null) { if (idType == null) {
// Not a variable // Not a variable
// Is it a property? Ensure we are not being applied to arguments or about to be assigned
InterfaceRepTemplate thisType = SymTabLookup("this") as InterfaceRepTemplate; InterfaceRepTemplate thisType = SymTabLookup("this") as InterfaceRepTemplate;
// Is it a property read? Ensure we are not being applied to arguments or about to be assigned
if (thisType != null && if (thisType != null &&
($primary_expression.Count == 1 || !((primary_expression_scope)($primary_expression.ToArray()[1])).parentIsApply) && ($primary_expression.Count == 1 || !((primary_expression_scope)($primary_expression.ToArray()[1])).parentIsApply) &&
($assignment.Count == 0 || !$assignment::parentIsSetter)) { ($assignment.Count == 0 || !$assignment::parentIsSetter)) {
Debug($identifier.tree.Token.Line + ": '" + $identifier.thetext + "' might be a property"); Debug($identifier.tree.Token.Line + ": '" + $identifier.thetext + "' might be a property");
String template = ResolveGetter(thisType, null, $identifier.thetext); ResolveResult fieldResult = thisType.Resolve($identifier.thetext, AppEnv);
if (template != null) { if (fieldResult != null) {
Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'"); Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'");
// Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>(); ret = mkJavaWrapper(fieldResult.Result.Java, null, $i.tree.Token);
// myMap["this"] = null; $dotNetType = fieldResult.ResultType;
ret = mkJavaWrapper(template, null, $i.tree.Token);
} }
} }
} }
$dotNetType = idType; else {
$dotNetType = idType;
}
} }
| primary_expression_start | primary_expression_start
// ('this' brackets) => 'this' brackets primary_expression_part* // ('this' brackets) => 'this' brackets primary_expression_part*