From a879b884fd397894762a8daad123137e35ef87c6 Mon Sep 17 00:00:00 2001 From: Kevin Glynn Date: Sun, 16 Jan 2011 23:44:14 +0100 Subject: [PATCH] resolve method names --- .../src/cs2j/CLR/TranslationTemplate.cs | 46 +++++++++++++++-- .../antlr3/src/cs2j/CSharp/NetMaker.g | 51 +++++++++---------- .../antlr3/src/cs2j/Utils/DirectoryHT.cs | 17 ++++--- 3 files changed, 76 insertions(+), 38 deletions(-) diff --git a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs index b831a23..95b1a27 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs +++ b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs @@ -929,6 +929,11 @@ namespace RusticiSoftware.Translator.CLR } } + // Returns true if other is a subclass, or implements our interface + public virtual bool IsA (TypeRepTemplate other, DirectoryHT AppEnv) { + return false; + } + #region deserialization private static object Deserialize (Stream fs, System.Type t) @@ -1264,7 +1269,13 @@ namespace RusticiSoftware.Translator.CLR private string[] _inherits; [XmlArrayItem("Type")] public string[] Inherits { - get { return _inherits; } + get { + if (_inherits == null) + { + _inherits = new string[] { "System.Object" }; + } + return _inherits; + } set { if (value != null) { _inherits= new string[value.Length]; @@ -1337,6 +1348,32 @@ namespace RusticiSoftware.Translator.CLR _indexers = ixs; } + + // Returns true if we are a subclass of other, or implements its interface + public override bool IsA (TypeRepTemplate other, DirectoryHT AppEnv) { + InterfaceRepTemplate i = other as InterfaceRepTemplate; + if (i == null) + { + return false; + } + if (i.TypeName == this.TypeName) + { + return true; + } + if (Inherits != null) + { + foreach (String ibase in Inherits) + { + TypeRepTemplate tbase = AppEnv.Search(ibase, new UnknownRepTemplate(ibase)); + if (tbase.IsA(other,AppEnv)) + { + return true; + } + } + } + return false; + } + public override TypeRep mkEmptyRep () { return new InterfaceRep (); @@ -1383,8 +1420,8 @@ namespace RusticiSoftware.Translator.CLR { if (m.Name == name) { - // same number of arguments? bool matchingArgs = true; + // If either params are null then make sure both represent zero length args if (m.Params == null || args == null) { // Are they both zero length? @@ -1392,14 +1429,16 @@ namespace RusticiSoftware.Translator.CLR } else { + // Are num args the same? if (m.Params.Count != args.Count) { matchingArgs = false; } else { + // check that for each argument in the caller its type 'IsA' the type of the formal argument for (int idx = 0; idx < m.Params.Count; idx++) { - if (args[idx] == null || m.Params[idx].Type != args[idx].TypeName) + if (args[idx] == null || !args[idx].IsA(AppEnv.Search(Uses, m.Params[idx].Type, new UnknownRepTemplate(m.Params[idx].Type)),AppEnv)) { matchingArgs = false; break; @@ -1830,6 +1869,7 @@ namespace RusticiSoftware.Translator.CLR public UnknownRepTemplate (string typeName) : base(typeName) { + Inherits = new String[] { "System.Object" }; } public override string[] Imports { diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g index 1b36e95..63f4bbd 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g @@ -203,41 +203,33 @@ scope { @init { $primary_expression::parentIsApply = false; CommonTree ret = null; + InterfaceRepTemplate expType = SymTabLookup("this") as InterfaceRepTemplate; + bool implicitThis = true; } @after { if (ret != null) $primary_expression.tree = ret; }: ^(INDEX expression expression_list?) - | (^(APPLY identifier argument_list?)) => ^(APPLY identifier argument_list?) + | (^(APPLY (^('.' expression identifier)|identifier) argument_list?)) => + ^(APPLY (^('.' e2=expression {expType = $e2.dotNetType as InterfaceRepTemplate; implicitThis = false;} i2=identifier)|i2=identifier) argument_list?) { - InterfaceRepTemplate thisType = SymTabLookup("this") as InterfaceRepTemplate; - ResolveResult methodResult = thisType.Resolve($identifier.thetext, $argument_list.argTypes ?? new List(), AppEnv); - if (methodResult != null) { - Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'"); - Dictionary myMap = new Dictionary(); - MethodRepTemplate methodRep = methodResult.Result as MethodRepTemplate; - for (int idx = 0; idx < methodRep.Params.Count; idx++) { - myMap[methodRep.Params[idx].Name] = $argument_list.argTrees[idx]; + if (expType != null) { + ResolveResult methodResult = expType.Resolve($i2.thetext, $argument_list.argTypes ?? new List(), AppEnv); + if (methodResult != null) { + Debug($i2.tree.Token.Line + ": Found '" + $i2.thetext + "'"); + MethodRepTemplate methodRep = methodResult.Result as MethodRepTemplate; + Dictionary myMap = new Dictionary(); + if (!implicitThis) { + myMap["this"] = $e2.tree; + } + for (int idx = 0; idx < methodRep.Params.Count; idx++) { + myMap[methodRep.Params[idx].Name] = $argument_list.argTrees[idx]; + } + ret = mkJavaWrapper(methodResult.Result.Java, myMap, $i2.tree.Token); + Imports.Add(methodResult.Result.Imports); + $dotNetType = methodResult.ResultType; } - ret = mkJavaWrapper(methodResult.Result.Java, myMap, $identifier.tree.Token); - $dotNetType = methodResult.ResultType; - } - } - | (^(APPLY ^('.' expression identifier) argument_list?)) => ^(APPLY ^('.' e2=expression identifier) argument_list?) - { - InterfaceRepTemplate expType = $e2.dotNetType as InterfaceRepTemplate; - ResolveResult methodResult = expType.Resolve($identifier.thetext, $argument_list.argTypes ?? new List(), AppEnv); - if (methodResult != null) { - Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'"); - Dictionary myMap = new Dictionary(); - MethodRepTemplate methodRep = methodResult.Result as MethodRepTemplate; - myMap["this"] = $e2.tree; - for (int idx = 0; idx < methodRep.Params.Count; idx++) { - myMap[methodRep.Params[idx].Name] = $argument_list.argTrees[idx]; - } - ret = mkJavaWrapper(methodResult.Result.Java, myMap, $identifier.tree.Token); - $dotNetType = methodResult.ResultType; } } | ^(APPLY {$primary_expression::parentIsApply = true; } expression {$primary_expression::parentIsApply = false; } argument_list?) @@ -249,7 +241,7 @@ scope { // - accessing a property/field of some object // - a qualified type name // - part of a qualified type name - InterfaceRepTemplate expType = $e1.dotNetType as 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 && @@ -264,6 +256,7 @@ scope { Dictionary myMap = new Dictionary(); myMap["this"] = $e1.tree; ret = mkJavaWrapper(fieldResult.Result.Java, myMap, $i1.tree.Token); + Imports.Add(fieldResult.Result.Imports); $dotNetType = fieldResult.ResultType; } else if ($e1.dotNetType is UnknownRepTemplate) { @@ -311,6 +304,7 @@ scope { if (fieldResult != null) { Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'"); ret = mkJavaWrapper(fieldResult.Result.Java, null, $i.tree.Token); + Imports.Add(fieldResult.Result.Imports); $dotNetType = fieldResult.ResultType; found = true; } @@ -641,6 +635,7 @@ scope { valMap["this"] = $se.tree; valMap["value"] = $rhs.tree; ret = mkJavaWrapper(((PropRepTemplate)fieldResult.Result).JavaSet, valMap, $a.token); + Imports.Add(fieldResult.Result.Imports); } } } diff --git a/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs b/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs index d4df034..e6fae14 100644 --- a/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs +++ b/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs @@ -176,13 +176,16 @@ namespace RusticiSoftware.Translator.Utils public TValue Search(IList searchPath, string name, TValue def) { TValue ret = def; bool found = false; - for (int i = searchPath.Count-1; i >= 0; i--) { - String ns = searchPath[i]; - String fullName = (ns ?? "") + (String.IsNullOrEmpty(ns) ? "" : ".") + name; - if (this.ContainsKey(fullName)) { - ret = this[fullName]; - found = true; - break; + if (searchPath != null) + { + for (int i = searchPath.Count-1; i >= 0; i--) { + String ns = searchPath[i]; + String fullName = (ns ?? "") + (String.IsNullOrEmpty(ns) ? "" : ".") + name; + if (this.ContainsKey(fullName)) { + ret = this[fullName]; + found = true; + break; + } } } // Check if name is fully qualified