From 892d1c17e2672e216d09102794b8dca7fc0881cd Mon Sep 17 00:00:00 2001 From: Kevin Glynn Date: Thu, 13 Jan 2011 13:09:05 +0100 Subject: [PATCH] resolve property reads within dotted expressions --- .../src/cs2j/CLR/TranslationTemplate.cs | 54 +++++++++++++++---- .../antlr3/src/cs2j/CSharp/NetMaker.g | 54 +++++++++++++------ 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs index 2c07539..02c2168 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs +++ b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs @@ -173,7 +173,7 @@ namespace RusticiSoftware.Translator.CLR // The Java translation for this C# entity protected string _java = null; - public string Java { + public virtual string Java { get { if (_java == null) { return mkJava(); @@ -640,7 +640,7 @@ namespace RusticiSoftware.Translator.CLR public override string mkJava() { - return Name; + return "${this}." + Name; } #region Equality @@ -707,6 +707,14 @@ namespace RusticiSoftware.Translator.CLR set { _javaGet = value; } } + public override string Java + { + get + { + return JavaGet; + } + } + private string _javaSet = null; [XmlElementAttribute("Set")] public string JavaSet { @@ -1334,7 +1342,7 @@ namespace RusticiSoftware.Translator.CLR return new InterfaceRep (); } - public virtual TranslationBase Resolve(String name, DirectoryHT AppEnv) + public virtual ResolveResult Resolve(String name, DirectoryHT AppEnv) { if (Properties != null) @@ -1342,16 +1350,25 @@ namespace RusticiSoftware.Translator.CLR foreach (PropRepTemplate p in Properties) { 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) { foreach (String b in Inherits) { - TranslationBase ret = ((InterfaceRepTemplate)AppEnv.Search(Uses, b)).Resolve(name,AppEnv); - if (ret != null) - return ret; + InterfaceRepTemplate baseType = AppEnv.Search(Uses, b) as InterfaceRepTemplate; + if (baseType != null) + { + ResolveResult ret = baseType.Resolve(name,AppEnv); + if (ret != null) + return ret; + } } } return null; @@ -1550,7 +1567,7 @@ namespace RusticiSoftware.Translator.CLR return new ClassRep (); } - public override TranslationBase Resolve(String name, DirectoryHT AppEnv) + public override ResolveResult Resolve(String name, DirectoryHT AppEnv) { if (Fields != null) @@ -1558,7 +1575,12 @@ namespace RusticiSoftware.Translator.CLR foreach (FieldRepTemplate f in Fields) { 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); @@ -1697,7 +1719,7 @@ namespace RusticiSoftware.Translator.CLR return new StructRep (); } - public override TranslationBase Resolve(String name, DirectoryHT AppEnv) + public override ResolveResult Resolve(String name, DirectoryHT 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; + } + } diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g index cf9f8f4..c736181 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g @@ -132,14 +132,14 @@ scope SymTab { } // Resolve Routines - protected String ResolveGetter(InterfaceRepTemplate thisType, CommonTree thisExp, String name) { - String ret = null; - PropRepTemplate entity = thisType.Resolve(name, AppEnv) as PropRepTemplate; - if (entity != null) { - ret = entity.JavaGet; - } - return ret; - } +// protected ResolveResult ResolveGetter(InterfaceRepTemplate thisType, String name) { +// ResolveResult ret = null; +// PropRepTemplate entity = thisType.Resolve(name, AppEnv) as PropRepTemplate; +// if (entity != null) { +// ret = entity.JavaGet; +// } +// return ret; +// } protected CommonTree dupTree(CommonTree t) { return (CommonTree)adaptor.DupTree(t); @@ -214,7 +214,27 @@ scope { | ^(APPLY {$primary_expression::parentIsApply = true; } expression {$primary_expression::parentIsApply = false; } argument_list?) | ^(POSTINC 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 myMap = new Dictionary(); + 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; } | 'this' { $dotNetType = SymTabLookup("this"); } | SUPER { $dotNetType = SymTabLookup("super"); } @@ -223,23 +243,25 @@ scope { TypeRepTemplate idType = SymTabLookup($identifier.thetext); if (idType == null) { // 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; + + // Is it a property read? Ensure we are not being applied to arguments or about to be assigned if (thisType != null && ($primary_expression.Count == 1 || !((primary_expression_scope)($primary_expression.ToArray()[1])).parentIsApply) && ($assignment.Count == 0 || !$assignment::parentIsSetter)) { Debug($identifier.tree.Token.Line + ": '" + $identifier.thetext + "' might be a property"); - String template = ResolveGetter(thisType, null, $identifier.thetext); - if (template != null) { + ResolveResult fieldResult = thisType.Resolve($identifier.thetext, AppEnv); + if (fieldResult != null) { Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'"); - // Dictionary myMap = new Dictionary(); - // myMap["this"] = null; - ret = mkJavaWrapper(template, null, $i.tree.Token); + ret = mkJavaWrapper(fieldResult.Result.Java, null, $i.tree.Token); + $dotNetType = fieldResult.ResultType; } } } - $dotNetType = idType; + else { + $dotNetType = idType; + } } | primary_expression_start // ('this' brackets) => 'this' brackets primary_expression_part*