mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
resolve indexers
This commit is contained in:
parent
27e774356d
commit
43323f46ea
@ -822,10 +822,9 @@ namespace RusticiSoftware.Translator.CLR
|
||||
// guessing that normally imports will be the same for both)
|
||||
public class PropRepTemplate : FieldRepTemplate, IEquatable<PropRepTemplate>
|
||||
{
|
||||
|
||||
private string _javaGet = null;
|
||||
protected string _javaGet = null;
|
||||
[XmlElementAttribute("Get")]
|
||||
public string JavaGet {
|
||||
public virtual string JavaGet {
|
||||
get {
|
||||
if (!CanRead) return null;
|
||||
if (_javaGet == null) {
|
||||
@ -842,7 +841,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
set { _javaGet = value; }
|
||||
}
|
||||
|
||||
|
||||
public override string Java
|
||||
{
|
||||
get
|
||||
@ -851,9 +850,9 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
|
||||
private string _javaSet = null;
|
||||
protected string _javaSet = null;
|
||||
[XmlElementAttribute("Set")]
|
||||
public string JavaSet {
|
||||
public virtual string JavaSet {
|
||||
get {
|
||||
if (_javaSet == null) {
|
||||
return (CanWrite ? "${this}.set" + Name + "(${value})" : null);
|
||||
@ -939,6 +938,152 @@ namespace RusticiSoftware.Translator.CLR
|
||||
#endregion
|
||||
}
|
||||
|
||||
// An indexer is like a unnamed property that has params
|
||||
public class IndexerRepTemplate : PropRepTemplate, IEquatable<IndexerRepTemplate>
|
||||
{
|
||||
private List<ParamRepTemplate> _params = null;
|
||||
[XmlArrayItem("Param")]
|
||||
public List<ParamRepTemplate> Params {
|
||||
get {
|
||||
if (_params == null)
|
||||
_params = new List<ParamRepTemplate> ();
|
||||
return _params;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ParamRepTemplate> _setParams = null;
|
||||
private List<ParamRepTemplate> SetParams {
|
||||
get {
|
||||
if (_setParams == null)
|
||||
{
|
||||
_setParams = new List<ParamRepTemplate> ();
|
||||
foreach (ParamRepTemplate p in Params)
|
||||
{
|
||||
_setParams.Add(p);
|
||||
}
|
||||
_setParams.Add(new ParamRepTemplate(Type,"value"));
|
||||
}
|
||||
return _setParams;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElementAttribute("Get")]
|
||||
public override string JavaGet {
|
||||
get {
|
||||
if (!CanRead) return null;
|
||||
if (_javaGet == null) {
|
||||
if (_java == null) {
|
||||
return (CanRead ? "${this}.get___idx" + mkJavaParams(Params) : null);
|
||||
}
|
||||
else {
|
||||
return _java;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return _javaGet;
|
||||
}
|
||||
}
|
||||
set { _javaGet = value; }
|
||||
}
|
||||
|
||||
[XmlElementAttribute("Set")]
|
||||
public override string JavaSet {
|
||||
get {
|
||||
if (_javaSet == null) {
|
||||
return (CanWrite ? "${this}.set___idx" + mkJavaParams(SetParams): null);
|
||||
}
|
||||
else {
|
||||
return _javaSet;
|
||||
}
|
||||
}
|
||||
set { _javaSet = value; }
|
||||
}
|
||||
|
||||
public IndexerRepTemplate () : base()
|
||||
{
|
||||
}
|
||||
|
||||
public IndexerRepTemplate (string fType, List<ParamRepTemplate> pars) : base(fType, "this")
|
||||
{
|
||||
_params = pars;
|
||||
}
|
||||
|
||||
public IndexerRepTemplate (string fType, List<ParamRepTemplate> pars, string[] imps, string javaGet, string javaSet) : base(fType, "this",imps,javaGet,javaSet)
|
||||
{
|
||||
_params = pars;
|
||||
}
|
||||
|
||||
|
||||
public override void Apply(Dictionary<string,TypeRepTemplate> args)
|
||||
{
|
||||
if (Params != null)
|
||||
{
|
||||
foreach(ParamRepTemplate p in Params)
|
||||
{
|
||||
p.Apply(args);
|
||||
}
|
||||
}
|
||||
if (_setParams != null)
|
||||
{
|
||||
foreach(ParamRepTemplate p in _setParams)
|
||||
{
|
||||
p.Apply(args);
|
||||
}
|
||||
}
|
||||
base.Apply(args);
|
||||
}
|
||||
|
||||
#region Equality
|
||||
|
||||
public bool Equals (IndexerRepTemplate other)
|
||||
{
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
if (Params != other.Params) {
|
||||
if (Params == null || other.Params == null || Params.Count != other.Params.Count)
|
||||
return false;
|
||||
for (int i = 0; i < Params.Count; i++) {
|
||||
if (Params[i] != other.Params[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.Equals(other);
|
||||
}
|
||||
|
||||
public override bool Equals (object obj)
|
||||
{
|
||||
|
||||
IndexerRepTemplate temp = obj as IndexerRepTemplate;
|
||||
|
||||
if (!Object.ReferenceEquals (temp, null))
|
||||
return this.Equals (temp);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator == (IndexerRepTemplate a1, IndexerRepTemplate a2)
|
||||
{
|
||||
return Object.Equals (a1, a2);
|
||||
}
|
||||
|
||||
public static bool operator != (IndexerRepTemplate a1, IndexerRepTemplate a2)
|
||||
{
|
||||
return !(a1 == a2);
|
||||
}
|
||||
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
int hashCode = 0;
|
||||
foreach (ParamRepTemplate o in Params) {
|
||||
hashCode = hashCode ^ o.GetHashCode() ;
|
||||
}
|
||||
|
||||
return base.GetHashCode () ^ hashCode;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
// A member of an enum, may also have a numeric value
|
||||
public class EnumMemberRepTemplate : TranslationBase, IEquatable<EnumMemberRepTemplate>
|
||||
{
|
||||
@ -1169,6 +1314,25 @@ namespace RusticiSoftware.Translator.CLR
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve a indexer call (arg types)
|
||||
public virtual ResolveResult ResolveIndexer(List<TypeRepTemplate> args, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
if (Inherits != null)
|
||||
{
|
||||
foreach (String b in Inherits)
|
||||
{
|
||||
TypeRepTemplate baseType = BuildType(b, AppEnv);
|
||||
if (baseType != null)
|
||||
{
|
||||
ResolveResult ret = baseType.ResolveIndexer(args,AppEnv);
|
||||
if (ret != null)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve a cast from this type to castTo
|
||||
public virtual ResolveResult ResolveCastTo(TypeRepTemplate castTo, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
@ -1734,12 +1898,13 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
|
||||
private List<MethodRepTemplate> _indexers = null;
|
||||
[XmlIgnore]
|
||||
private List<IndexerRepTemplate> _indexers = null;
|
||||
[XmlArrayItem("Indexer")]
|
||||
public List<MethodRepTemplate> Indexers {
|
||||
public List<IndexerRepTemplate> Indexers {
|
||||
get {
|
||||
if (_indexers == null)
|
||||
_indexers = new List<MethodRepTemplate> ();
|
||||
_indexers = new List<IndexerRepTemplate> ();
|
||||
return _indexers;
|
||||
}
|
||||
}
|
||||
@ -1753,7 +1918,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
{
|
||||
}
|
||||
|
||||
protected InterfaceRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, string[] imps, string javaTemplate)
|
||||
protected InterfaceRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> es, List<IndexerRepTemplate> ixs, string[] imps, string javaTemplate)
|
||||
: base(tName, tParams, usePath, aliases, imps, javaTemplate)
|
||||
{
|
||||
Inherits = inherits;
|
||||
@ -1789,7 +1954,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
if (Indexers != null)
|
||||
{
|
||||
foreach(MethodRepTemplate i in Indexers)
|
||||
foreach(IndexerRepTemplate i in Indexers)
|
||||
{
|
||||
i.Apply(args);
|
||||
}
|
||||
@ -1878,6 +2043,50 @@ namespace RusticiSoftware.Translator.CLR
|
||||
return base.Resolve(name, args, AppEnv);
|
||||
}
|
||||
|
||||
public override ResolveResult ResolveIndexer(List<TypeRepTemplate> args, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
|
||||
if (Indexers != null)
|
||||
{
|
||||
foreach (IndexerRepTemplate i in Indexers)
|
||||
{
|
||||
bool matchingArgs = true;
|
||||
// If either params are null then make sure both represent zero length args
|
||||
if (i.Params == null || args == null)
|
||||
{
|
||||
// Are they both zero length?
|
||||
matchingArgs = (i.Params == null || i.Params.Count == 0) && (args == null || args.Count == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Are num args the same?
|
||||
if (i.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 < i.Params.Count; idx++) {
|
||||
if (args[idx] == null || !args[idx].IsA(BuildType(i.Params[idx].Type, AppEnv, new UnknownRepTemplate(i.Params[idx].Type)),AppEnv))
|
||||
{
|
||||
matchingArgs = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchingArgs)
|
||||
{
|
||||
ResolveResult res = new ResolveResult();
|
||||
res.Result = i;
|
||||
res.ResultType = BuildType(i.Type, AppEnv);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return base.ResolveIndexer(args, AppEnv);
|
||||
}
|
||||
|
||||
#region Equality
|
||||
public bool Equals (InterfaceRepTemplate other)
|
||||
@ -1977,7 +2186,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
}
|
||||
}
|
||||
if (Indexers != null) {
|
||||
foreach (MethodRepTemplate e in Indexers) {
|
||||
foreach (IndexerRepTemplate e in Indexers) {
|
||||
hashCode ^= e.GetHashCode();
|
||||
}
|
||||
}
|
||||
@ -2039,7 +2248,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
{
|
||||
}
|
||||
|
||||
public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts,
|
||||
public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<IndexerRepTemplate> ixs, List<CastRepTemplate> cts,
|
||||
string[] imports, string javaTemplate)
|
||||
: base(tName, tParams, usePath, aliases, inherits, ms, ps, es, ixs, imports, javaTemplate)
|
||||
{
|
||||
@ -2048,7 +2257,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
_casts = cts;
|
||||
}
|
||||
|
||||
public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts)
|
||||
public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<IndexerRepTemplate> ixs, List<CastRepTemplate> cts)
|
||||
: base(tName, tParams, usePath, aliases, inherits, ms, ps, es, ixs, null, null)
|
||||
{
|
||||
_constructors = cs;
|
||||
@ -2111,7 +2320,7 @@ namespace RusticiSoftware.Translator.CLR
|
||||
return base.Resolve(name, AppEnv);
|
||||
}
|
||||
|
||||
public virtual ResolveResult Resolve(List<TypeRepTemplate> args, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
public ResolveResult Resolve(List<TypeRepTemplate> args, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
|
||||
if (Constructors != null)
|
||||
@ -2259,13 +2468,13 @@ namespace RusticiSoftware.Translator.CLR
|
||||
{
|
||||
}
|
||||
|
||||
public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts,
|
||||
public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<IndexerRepTemplate> ixs, List<CastRepTemplate> cts,
|
||||
string[] imports, string javaTemplate) : base(tName, tParams, usePath, aliases, inherits, cs, ms, ps, fs, es, ixs, cts,
|
||||
imports, javaTemplate)
|
||||
{
|
||||
}
|
||||
|
||||
public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts)
|
||||
public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<IndexerRepTemplate> ixs, List<CastRepTemplate> cts)
|
||||
: base(tName, tParams, usePath, aliases, inherits, cs, ms, ps, fs, es, ixs, cts, null, null)
|
||||
{
|
||||
}
|
||||
|
@ -322,7 +322,29 @@ scope {
|
||||
if (ret != null)
|
||||
$primary_expression.tree = ret;
|
||||
}:
|
||||
^(INDEX expression expression_list?)
|
||||
^(INDEX ie=expression expression_list?)
|
||||
{
|
||||
if ($ie.dotNetType != null) {
|
||||
ResolveResult indexerResult = $ie.dotNetType.ResolveIndexer($expression_list.expTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
||||
if (indexerResult != null) {
|
||||
IndexerRepTemplate indexerRep = indexerResult.Result as IndexerRepTemplate;
|
||||
if (!String.IsNullOrEmpty(indexerRep.JavaGet)) {
|
||||
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
||||
myMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
||||
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
||||
myMap[indexerRep.Params[idx].Name] = wrapArgument($expression_list.expTrees[idx], $ie.tree.Token);
|
||||
if (indexerRep.Params[idx].Name.StartsWith("TYPEOF") && $expression_list.expTreeTypeofTypes[idx] != null) {
|
||||
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
|
||||
myMap[indexerRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($expression_list.expTreeTypeofTypes[idx], $ie.tree.Token);
|
||||
}
|
||||
}
|
||||
ret = mkJavaWrapper(indexerResult.Result.Java, myMap, $ie.tree.Token);
|
||||
Imports.Add(indexerResult.Result.Imports);
|
||||
$dotNetType = indexerResult.ResultType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
| (^(APPLY (^('.' expression identifier)|identifier) argument_list?)) =>
|
||||
^(APPLY (^('.' e2=expression {expType = $e2.dotNetType; implicitThis = false;} i2=identifier)|i2=identifier) argument_list?)
|
||||
{
|
||||
@ -745,8 +767,14 @@ expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTemplate typ
|
||||
(unary_expression assignment_operator) => assignment { $dotNetType = VoidType; }
|
||||
| non_assignment_expression { $dotNetType = $non_assignment_expression.dotNetType; $rmId = $non_assignment_expression.rmId; $typeofType = $non_assignment_expression.typeofType; }
|
||||
;
|
||||
expression_list:
|
||||
expression (',' expression)* ;
|
||||
expression_list returns [List<TypeRepTemplate> expTypes, List<CommonTree> expTrees, List<TypeRepTemplate> expTreeTypeofTypes]
|
||||
@init {
|
||||
$expTypes = new List<TypeRepTemplate>();
|
||||
$expTrees = new List<CommonTree>();
|
||||
$expTreeTypeofTypes = new List<TypeRepTemplate>();
|
||||
}:
|
||||
e1=expression { $expTypes.Add($e1.dotNetType); $expTrees.Add(dupTree($e1.tree)); $expTreeTypeofTypes.Add($e1.typeofType); }
|
||||
(',' en=expression { $expTypes.Add($en.dotNetType); $expTrees.Add(dupTree($en.tree)); $expTreeTypeofTypes.Add($en.typeofType); })* ;
|
||||
|
||||
assignment
|
||||
@init {
|
||||
@ -774,6 +802,30 @@ assignment
|
||||
}
|
||||
}
|
||||
}
|
||||
| (^(INDEX expression expression_list?) '=') =>
|
||||
^(INDEX ie=expression expression_list?) ia='=' irhs=expression
|
||||
{
|
||||
if ($ie.dotNetType != null) {
|
||||
ResolveResult indexerResult = $ie.dotNetType.ResolveIndexer($expression_list.expTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
||||
if (indexerResult != null) {
|
||||
IndexerRepTemplate indexerRep = indexerResult.Result as IndexerRepTemplate;
|
||||
if (!String.IsNullOrEmpty(indexerRep.JavaSet)) {
|
||||
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
||||
myMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
||||
myMap["value"] = wrapExpression($irhs.tree, $irhs.tree.Token);
|
||||
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
||||
myMap[indexerRep.Params[idx].Name] = wrapArgument($expression_list.expTrees[idx], $ie.tree.Token);
|
||||
if (indexerRep.Params[idx].Name.StartsWith("TYPEOF") && $expression_list.expTreeTypeofTypes[idx] != null) {
|
||||
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
|
||||
myMap[indexerRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($expression_list.expTreeTypeofTypes[idx], $ie.tree.Token);
|
||||
}
|
||||
}
|
||||
ret = mkJavaWrapper(indexerRep.JavaSet, myMap, $ie.tree.Token);
|
||||
Imports.Add(indexerRep.Imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
| unary_expression assignment_operator expression ;
|
||||
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ interface_event_declaration:
|
||||
interface_indexer_declaration [string returnType]:
|
||||
// attributes? 'new'? type
|
||||
'this' '[' fpl=formal_parameter_list ']' '{' interface_accessor_declarations '}'
|
||||
{ ((InterfaceRepTemplate)$NSContext::currentTypeRep).Indexers.Add(new MethodRepTemplate($returnType, "this", null, $fpl.paramlist)); }
|
||||
{ ((InterfaceRepTemplate)$NSContext::currentTypeRep).Indexers.Add(new IndexerRepTemplate($returnType, $fpl.paramlist)); }
|
||||
{ Debug("Processing interface indexer declaration"); }
|
||||
;
|
||||
interface_accessor_declarations returns [bool hasGetter, bool hasSetter]
|
||||
@ -1104,7 +1104,7 @@ indexer_declaration [string returnType, string prefix]:
|
||||
indexer_declarator [string returnType, string prefix]:
|
||||
//(type_name '.')?
|
||||
'this' '[' fpl=formal_parameter_list ']'
|
||||
{ ((InterfaceRepTemplate)$NSContext::currentTypeRep).Indexers.Add(new MethodRepTemplate($returnType, $prefix+"this", null, $fpl.paramlist)); }
|
||||
{ ((InterfaceRepTemplate)$NSContext::currentTypeRep).Indexers.Add(new IndexerRepTemplate($returnType, $fpl.paramlist)); }
|
||||
{ Debug("Processing indexer declaration"); }
|
||||
;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user