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

resolve method names

This commit is contained in:
Kevin Glynn 2011-01-16 23:44:14 +01:00
parent 59a578f82f
commit a879b884fd
3 changed files with 76 additions and 38 deletions

View File

@ -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<TypeRepTemplate> 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<TypeRepTemplate> 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 {

View File

@ -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<TypeRepTemplate>(), AppEnv);
if (methodResult != null) {
Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'");
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
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<TypeRepTemplate>(), AppEnv);
if (methodResult != null) {
Debug($i2.tree.Token.Line + ": Found '" + $i2.thetext + "'");
MethodRepTemplate methodRep = methodResult.Result as MethodRepTemplate;
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
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<TypeRepTemplate>(), AppEnv);
if (methodResult != null) {
Debug($identifier.tree.Token.Line + ": Found '" + $identifier.thetext + "'");
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
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<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
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);
}
}
}

View File

@ -176,13 +176,16 @@ namespace RusticiSoftware.Translator.Utils
public TValue Search(IList<string> 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