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

some method resolution

This commit is contained in:
Kevin Glynn 2011-01-14 19:36:09 +01:00
parent 891b83b894
commit 59a578f82f
2 changed files with 120 additions and 18 deletions

View File

@ -1374,6 +1374,65 @@ namespace RusticiSoftware.Translator.CLR
return null; return null;
} }
public virtual ResolveResult Resolve(String name, List<TypeRepTemplate> args, DirectoryHT<TypeRepTemplate> AppEnv)
{
if (Methods != null)
{
foreach (MethodRepTemplate m in Methods)
{
if (m.Name == name)
{
// same number of arguments?
bool matchingArgs = true;
if (m.Params == null || args == null)
{
// Are they both zero length?
matchingArgs = (m.Params == null || m.Params.Count == 0) && (args == null || args.Count == 0);
}
else
{
if (m.Params.Count != args.Count)
{
matchingArgs = false;
}
else
{
for (int idx = 0; idx < m.Params.Count; idx++) {
if (args[idx] == null || m.Params[idx].Type != args[idx].TypeName)
{
matchingArgs = false;
break;
}
}
}
}
if (matchingArgs)
{
ResolveResult res = new ResolveResult();
res.Result = m;
res.ResultType = AppEnv.Search(Uses, m.Return);
return res;
}
}
}
}
if (Inherits != null)
{
foreach (String b in Inherits)
{
InterfaceRepTemplate baseType = AppEnv.Search(Uses, b) as InterfaceRepTemplate;
if (baseType != null)
{
ResolveResult ret = baseType.Resolve(name,args,AppEnv);
if (ret != null)
return ret;
}
}
}
return null;
}
#region Equality #region Equality
public bool Equals (InterfaceRepTemplate other) public bool Equals (InterfaceRepTemplate other)

View File

@ -209,13 +209,46 @@ scope {
$primary_expression.tree = ret; $primary_expression.tree = ret;
}: }:
^(INDEX expression expression_list?) ^(INDEX expression expression_list?)
// | ^(APPLY identifier argument_list?) | (^(APPLY identifier argument_list?)) => ^(APPLY identifier argument_list?)
// | ^(APPLY ^('.' expression 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];
}
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?) | ^(APPLY {$primary_expression::parentIsApply = true; } expression {$primary_expression::parentIsApply = false; } argument_list?)
| ^(POSTINC expression) | ^(POSTINC expression)
| ^(POSTDEC expression) | ^(POSTDEC expression)
| ^(d1='.' e1=expression i1=identifier generic_argument_list?) | ^(d1='.' e1=expression i1=identifier generic_argument_list?)
{ {
// Possibilities:
// - accessing a property/field of some object
// - a qualified type name
// - part of a qualified type name
InterfaceRepTemplate expType = $e1.dotNetType as InterfaceRepTemplate; InterfaceRepTemplate expType = $e1.dotNetType as InterfaceRepTemplate;
// Is it a property read? Ensure we are not being applied to arguments or about to be assigned // Is it a property read? Ensure we are not being applied to arguments or about to be assigned
@ -250,8 +283,14 @@ scope {
| 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"); }
| (identifier generic_argument_list) => identifier generic_argument_list
| i=identifier | i=identifier
{ {
// Possibilities:
// - a variable in scope.
// - a property/field of current object
// - a type name
// - part of a type name
bool found = false; bool found = false;
TypeRepTemplate idType = SymTabLookup($identifier.thetext); TypeRepTemplate idType = SymTabLookup($identifier.thetext);
if (idType != null) { if (idType != null) {
@ -311,8 +350,7 @@ scope {
; ;
primary_expression_start returns [TypeRepTemplate dotNetType]: primary_expression_start returns [TypeRepTemplate dotNetType]:
(identifier generic_argument_list) => identifier generic_argument_list ^('::' identifier identifier)
| ^('::' identifier identifier)
| literal | literal
; ;
@ -333,26 +371,31 @@ paren_expression:
'(' expression ')' ; '(' expression ')' ;
arguments: arguments:
'(' argument_list? ')' ; '(' argument_list? ')' ;
argument_list: argument_list returns [List<TypeRepTemplate> argTypes, List<CommonTree> argTrees]
^(ARGS argument+); @init {
$argTypes = new List<TypeRepTemplate>();
$argTrees = new List<CommonTree>();
}:
^(ARGS (argument { $argTypes.Add($argument.dotNetType); $argTrees.Add($argument.tree); })+);
// 4.0 // 4.0
argument: argument returns [TypeRepTemplate dotNetType]:
argument_name argument_value argument_name argument_value { $dotNetType = $argument_value.dotNetType; }
| argument_value; | argument_value { $dotNetType = $argument_value.dotNetType; }
;
argument_name: argument_name:
identifier ':'; identifier ':';
argument_value: argument_value returns [TypeRepTemplate dotNetType]:
expression expression { $dotNetType = $expression.dotNetType; }
| ref_variable_reference | ref_variable_reference { $dotNetType = $ref_variable_reference.dotNetType; }
| 'out' variable_reference ; | 'out' variable_reference { $dotNetType = $variable_reference.dotNetType; } ;
ref_variable_reference: ref_variable_reference returns [TypeRepTemplate dotNetType]:
'ref' 'ref'
(('(' type ')') => '(' type ')' (ref_variable_reference | variable_reference) // SomeFunc(ref (int) ref foo) (('(' type ')') => '(' type ')' (ref_variable_reference | variable_reference) { $dotNetType = $type.dotNetType; } // SomeFunc(ref (int) ref foo)
// SomeFunc(ref (int) foo) // SomeFunc(ref (int) foo)
| variable_reference); // SomeFunc(ref foo) | v1=variable_reference { $dotNetType = $v1.dotNetType; }); // SomeFunc(ref foo)
// lvalue // lvalue
variable_reference: variable_reference returns [TypeRepTemplate dotNetType]:
expression; expression { $dotNetType = $expression.dotNetType; };
rank_specifiers: rank_specifiers:
rank_specifier+ ; rank_specifier+ ;
rank_specifier: rank_specifier: