mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
Support for Generic Types (to be continued ....).
This commit is contained in:
parent
c0cfaf00c0
commit
e4600b7885
205
CS2JLibrary/NetFramework/System/Collections/Generic/List'1.xml
Normal file
205
CS2JLibrary/NetFramework/System/Collections/Generic/List'1.xml
Normal file
@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
|
||||
This file is
|
||||
|
||||
Copyright 2007,2008,2009,2010 Rustici Software, LLC
|
||||
Copyright 2010,2011 Kevin Glynn (kevin.glynn.com)
|
||||
|
||||
-->
|
||||
<Class xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:www.twigletsoftware.com:schemas:txtemplate:1:0">
|
||||
<Imports>
|
||||
<Import>java.util.ArrayList</Import>
|
||||
</Imports>
|
||||
<Java>ArrayList*[${T}]*</Java>
|
||||
<Name>System.Collections.Generic.List</Name>
|
||||
<TypeParams>
|
||||
<Name>T</Name>
|
||||
</TypeParams>
|
||||
<Uses />
|
||||
<Inherits>
|
||||
<!-- <Type>IList<T>, ICollection<T>,
|
||||
IEnumerable<T>, IList, ICollection, IEnumerable</Type> -->
|
||||
</Inherits>
|
||||
<Methods>
|
||||
<Method>
|
||||
<Imports />
|
||||
<Java>${this:16}.add(${arg})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>T</Type>
|
||||
<Name>arg</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Name>Add</Name>
|
||||
<!-- TODO: this.add(e) actually always returns true -->
|
||||
<Return>System.Int32</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports>
|
||||
<Import>java.util.Arrays</Import>
|
||||
</Imports>
|
||||
<Java>${this:16}.addAll(Arrays.asList(${arg}))</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>T[]</Type>
|
||||
<Name>arg</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Name>AddRange</Name>
|
||||
<Return>System.Void</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports />
|
||||
<Java>${this:16}.addAll(${arg})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>System.Collections.Generic.IEnumerable*[T]*</Type>
|
||||
<Name>arg</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Name>AddRange</Name>
|
||||
<Return>System.Void</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports />
|
||||
<Java>${this:16}.clear()</Java>
|
||||
<Params />
|
||||
<Name>Clear</Name>
|
||||
<Return>System.Void</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports />
|
||||
<Java>${this:16}.contains(${key})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>T</Type>
|
||||
<Name>key</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Name>Contains</Name>
|
||||
<Return>System.Boolean</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports />
|
||||
<Java>${this:16}.add(${index}, ${value})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>System.Int32</Type>
|
||||
<Name>index</Name>
|
||||
</Param>
|
||||
<Param>
|
||||
<Type>T</Type>
|
||||
<Name>value</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Name>Insert</Name>
|
||||
<Return>System.Void</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports />
|
||||
<Java>${this:16}.remove(${value})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>T</Type>
|
||||
<Name>value</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Name>Remove</Name>
|
||||
<Return>System.Boolean</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports />
|
||||
<Java>${this:16}.remove((int)${value})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>System.Int32</Type>
|
||||
<Name>index</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Name>RemoveAt</Name>
|
||||
<Return>System.Void</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Java>${this:16}.toArray(new ${T}[${this}.size()])</Java>
|
||||
<Params>
|
||||
</Params>
|
||||
<Name>ToArray</Name>
|
||||
<Return>T[]</Return>
|
||||
</Method>
|
||||
<Method>
|
||||
<Imports>
|
||||
<Import>java.util.Collections</Import>
|
||||
</Imports>
|
||||
<Java>Collections.sort(${this})</Java>
|
||||
<Params />
|
||||
<Name>Sort</Name>
|
||||
<Return>System.Void</Return>
|
||||
</Method>
|
||||
</Methods>
|
||||
<Properties>
|
||||
<Property>
|
||||
<Imports />
|
||||
<Java>${this:16}.size()</Java>
|
||||
<Type>System.Int32</Type>
|
||||
<Name>Count</Name>
|
||||
<Get>${this:16}.size()</Get>
|
||||
<Set>${this:16}.setCount(${value})</Set>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events />
|
||||
<Indexers>
|
||||
<Indexer>
|
||||
<Imports />
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>System.Int32</Type>
|
||||
<Name>i</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
<Type>T</Type>
|
||||
<Get>${this:16}.get(${i})</Get>
|
||||
<Set>${this:16}.add(${i}, ${value})</Set>
|
||||
</Indexer>
|
||||
</Indexers>
|
||||
<Constructors>
|
||||
<Constructor>
|
||||
<Imports />
|
||||
<Java>new ArrayList*[${T}]*()</Java>
|
||||
<Params />
|
||||
</Constructor>
|
||||
<Constructor>
|
||||
<Imports />
|
||||
<Java>new ArrayList*[${T}]*(${length})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>System.Int32</Type>
|
||||
<Name>length</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
</Constructor>
|
||||
<Constructor>
|
||||
<Java>new ArrayList*[${T}]*(Arrays.asList(${collection}))</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>T[]</Type>
|
||||
<Name>collection</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
</Constructor>
|
||||
<Constructor>
|
||||
<Imports />
|
||||
<Java>new ArrayList*[${T}]*(${collection})</Java>
|
||||
<Params>
|
||||
<Param>
|
||||
<Type>System.IEnumerable[T]</Type>
|
||||
<Name>collection</Name>
|
||||
</Param>
|
||||
</Params>
|
||||
</Constructor>
|
||||
</Constructors>
|
||||
<Fields />
|
||||
<Casts />
|
||||
<UnaryOps />
|
||||
<BinaryOps />
|
||||
</Class>
|
@ -35,7 +35,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static string SubstituteInType(String type, Dictionary<string,TypeRepTemplate> argMap)
|
||||
{
|
||||
if (String.IsNullOrEmpty(type))
|
||||
@ -88,7 +88,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public string Type {
|
||||
get { return _type; }
|
||||
set {
|
||||
_type=value.Replace('<','[').Replace('>',']');
|
||||
_type=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
public string Name { get; set; }
|
||||
@ -281,7 +281,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public string SurroundingTypeName {
|
||||
get { return _surroundingTypeName; }
|
||||
set {
|
||||
_surroundingTypeName=value.Replace('<','[').Replace('>',']');
|
||||
_surroundingTypeName=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
public virtual string[] mkImports() {
|
||||
@ -632,15 +632,41 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
// Method name
|
||||
public string Name { get; set; }
|
||||
|
||||
private string[] _typeParams = null;
|
||||
[XmlArrayItem("Name")]
|
||||
public string[] TypeParams { get; set; }
|
||||
public string[] TypeParams {
|
||||
get
|
||||
{
|
||||
if (_typeParams == null)
|
||||
{
|
||||
TypeParams = new string[0];
|
||||
}
|
||||
return _typeParams;
|
||||
}
|
||||
set
|
||||
{
|
||||
// First time that TypeParams is set then create InstantiatedTypes as corresponding list of TypeVars
|
||||
if (value != null && InstantiatedTypes == null)
|
||||
{
|
||||
InstantiatedTypes = new TypeRepTemplate[value.Length];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
InstantiatedTypes[i] = new TypeVarRepTemplate(value[i]);
|
||||
}
|
||||
}
|
||||
_typeParams = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public TypeRepTemplate[] InstantiatedTypes { get; set; }
|
||||
|
||||
// Return type
|
||||
private string _return;
|
||||
public string Return {
|
||||
get { return _return; }
|
||||
set {
|
||||
_return=value.Replace('<','[').Replace('>',']');
|
||||
_return=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,6 +696,15 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
TypeParams[i] = copyFrom.TypeParams[i];
|
||||
}
|
||||
}
|
||||
if (copyFrom.InstantiatedTypes != null)
|
||||
{
|
||||
len = copyFrom.InstantiatedTypes.Length;
|
||||
InstantiatedTypes = new TypeRepTemplate[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
InstantiatedTypes[i] = copyFrom.InstantiatedTypes[i].Instantiate(null);
|
||||
}
|
||||
}
|
||||
if (!String.IsNullOrEmpty(copyFrom.Return))
|
||||
{
|
||||
Return = copyFrom.Return;
|
||||
@ -749,6 +784,14 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (InstantiatedTypes != other.InstantiatedTypes) {
|
||||
if (InstantiatedTypes == null || other.InstantiatedTypes == null || InstantiatedTypes.Length != other.InstantiatedTypes.Length)
|
||||
return false;
|
||||
for (int i = 0; i < InstantiatedTypes.Length; i++) {
|
||||
if (InstantiatedTypes[i] != other.InstantiatedTypes[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Return == other.Return && Name == other.Name && IsStatic == other.IsStatic && base.Equals(other);
|
||||
}
|
||||
@ -781,6 +824,11 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
hashCode = hashCode ^ o.GetHashCode() ;
|
||||
}
|
||||
}
|
||||
if (InstantiatedTypes != null) {
|
||||
foreach (TypeRepTemplate o in InstantiatedTypes) {
|
||||
hashCode = hashCode ^ o.GetHashCode() ;
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode ^ (Return ?? String.Empty).GetHashCode () ^ (Name ?? String.Empty).GetHashCode () ^ IsStatic.GetHashCode() ^ base.GetHashCode();
|
||||
}
|
||||
@ -796,7 +844,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public string From {
|
||||
get { return _from; }
|
||||
set {
|
||||
_from=value.Replace('<','[').Replace('>',']');
|
||||
_from=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
|
||||
@ -804,7 +852,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public string To {
|
||||
get { return _to; }
|
||||
set {
|
||||
_to=value.Replace('<','[').Replace('>',']');
|
||||
_to=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
|
||||
@ -930,7 +978,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public string Type {
|
||||
get { return _type; }
|
||||
set {
|
||||
_type=value.Replace('<','[').Replace('>',']');
|
||||
_type=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
public string Name { get; set; }
|
||||
@ -1414,8 +1462,48 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
[XmlElementAttribute("Name")]
|
||||
public string TypeName { get; set; }
|
||||
|
||||
private string[] _typeParams = null;
|
||||
[XmlArrayItem("Name")]
|
||||
public string[] TypeParams { get; set; }
|
||||
public string[] TypeParams {
|
||||
get
|
||||
{
|
||||
if (_typeParams == null)
|
||||
{
|
||||
TypeParams = new string[0];
|
||||
}
|
||||
return _typeParams;
|
||||
}
|
||||
set
|
||||
{
|
||||
// First time that TypeParams is set then create InstantiatedTypes as corresponding list of TypeVars
|
||||
if (value != null && InstantiatedTypes == null)
|
||||
{
|
||||
InstantiatedTypes = new TypeRepTemplate[value.Length];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
InstantiatedTypes[i] = new TypeVarRepTemplate(value[i]);
|
||||
}
|
||||
}
|
||||
_typeParams = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public TypeRepTemplate[] InstantiatedTypes { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Dictionary<string,TypeRepTemplate> TyVarMap
|
||||
{ get
|
||||
{
|
||||
Dictionary<string,TypeRepTemplate> ret = new Dictionary<string,TypeRepTemplate>(TypeParams.Length);
|
||||
for (int i = 0; i < TypeParams.Length; i++)
|
||||
{
|
||||
ret[TypeParams[i]] = InstantiatedTypes[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Path to use when resolving types
|
||||
[XmlArrayItem("Use")]
|
||||
@ -1449,7 +1537,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
if (value != null) {
|
||||
_inherits= new string[value.Length];
|
||||
for (int i = 0; i < value.Length; i++) {
|
||||
_inherits[i] = (value[i] != null ? value[i].Replace('<','[').Replace('>',']') : null);
|
||||
_inherits[i] = (value[i] != null ? value[i].Replace("<","*[").Replace(">","]*") : null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1490,36 +1578,20 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
|
||||
// Equivalent to "this is TypeVarRepTemplate"
|
||||
[XmlIgnore]
|
||||
public bool IsTypeVar
|
||||
public virtual bool IsTypeVar
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this is TypeVarRepTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
// Type Arguments that this (generic) type has been instantiated with
|
||||
private TypeRepTemplate[] _instantiatedTypes = null;
|
||||
// Equivalent to "this is UnknownRepTemplate"
|
||||
[XmlIgnore]
|
||||
public TypeRepTemplate[] InstantiatedTypes
|
||||
public virtual bool IsUnknownType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instantiatedTypes == null)
|
||||
{
|
||||
// Create from the TypeParams
|
||||
int numParams = TypeParams == null ? 0 : TypeParams.Length;
|
||||
_instantiatedTypes = new TypeRepTemplate[numParams];
|
||||
for (int i = 0; i < numParams; i++)
|
||||
{
|
||||
_instantiatedTypes[i] = new TypeVarRepTemplate(TypeParams[i]);
|
||||
}
|
||||
}
|
||||
return _instantiatedTypes;
|
||||
}
|
||||
set
|
||||
{
|
||||
_instantiatedTypes = value;
|
||||
return (this is UnknownRepTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1556,6 +1628,16 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
}
|
||||
}
|
||||
|
||||
if (copyFrom.InstantiatedTypes != null)
|
||||
{
|
||||
len = copyFrom.InstantiatedTypes.Length;
|
||||
InstantiatedTypes = new TypeRepTemplate[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
InstantiatedTypes[i] = copyFrom.InstantiatedTypes[i].Instantiate(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (copyFrom.Uses != null)
|
||||
{
|
||||
len = copyFrom.Uses.Length;
|
||||
@ -1623,20 +1705,16 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
// IMPORTANT: Call this on the fresh copy because it has the side effect of updating this type's TypeParams.
|
||||
protected Dictionary<string,TypeRepTemplate> mkTypeMap(ICollection<TypeRepTemplate> args) {
|
||||
Dictionary<string,TypeRepTemplate> ret = new Dictionary<string,TypeRepTemplate>();
|
||||
if (args.Count == TypeParams.Length)
|
||||
if (args != null && args.Count == TypeParams.Length)
|
||||
{
|
||||
List<string> remTypeParams = new List<string>();
|
||||
InstantiatedTypes = new TypeRepTemplate[args.Count];
|
||||
int i = 0;
|
||||
foreach (TypeRepTemplate sub in args)
|
||||
{
|
||||
if (sub.IsTypeVar)
|
||||
{
|
||||
remTypeParams.Add(sub.TypeName);
|
||||
}
|
||||
ret[TypeParams[i]] = sub;
|
||||
InstantiatedTypes[i] = sub;
|
||||
i++;
|
||||
}
|
||||
TypeParams = remTypeParams.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1666,16 +1744,6 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
Inherits[i] = TemplateUtilities.SubstituteInType(Inherits[i],args);
|
||||
}
|
||||
}
|
||||
if (InstantiatedTypes != null)
|
||||
{
|
||||
for(int i = 0; i < InstantiatedTypes.Length; i++)
|
||||
{
|
||||
if (InstantiatedTypes[i].IsTypeVar && args.ContainsKey(InstantiatedTypes[i].TypeName))
|
||||
{
|
||||
InstantiatedTypes[i] = args[InstantiatedTypes[i].TypeName];
|
||||
}
|
||||
}
|
||||
}
|
||||
base.Apply(args);
|
||||
}
|
||||
|
||||
@ -2077,9 +2145,9 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
}
|
||||
if (InstantiatedTypes != null)
|
||||
{
|
||||
foreach (TypeRepTemplate t in InstantiatedTypes)
|
||||
foreach (TypeRepTemplate ty in InstantiatedTypes)
|
||||
{
|
||||
hashCode ^= t.GetHashCode();
|
||||
hashCode ^= ty.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2102,7 +2170,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
else
|
||||
{
|
||||
fmt.Append(TypeName.Substring(incNameSpace ? 0 : TypeName.LastIndexOf('.')+1));
|
||||
if (InstantiatedTypes.Length > 0)
|
||||
if (InstantiatedTypes != null && InstantiatedTypes.Length > 0)
|
||||
{
|
||||
bool isFirst = true;
|
||||
fmt.Append("<");
|
||||
@ -2291,7 +2359,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public string Return {
|
||||
get { return _return; }
|
||||
set {
|
||||
_return=value.Replace('<','[').Replace('>',']');
|
||||
_return=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2974,7 +3042,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
{
|
||||
ResolveResult res = new ResolveResult();
|
||||
res.Result = c;
|
||||
res.ResultType = BuildType(TypeName, AppEnv);
|
||||
res.ResultType = this;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +273,8 @@ options {
|
||||
|
||||
public string fillTemplate(string template, Dictionary<string,ReplacementDescriptor> templateMap) {
|
||||
string ret = template;
|
||||
// *[ -> < and ]* -> >
|
||||
ret = ret.Replace("*[","<").Replace("]*",">");
|
||||
foreach (string v in templateMap.Keys) {
|
||||
MatchEvaluator myEvaluator = new MatchEvaluator(templateMap[v].replace);
|
||||
ret = Regex.Replace(ret, Regex.Escape("${" + v) + "(?::(?<prec>\\d+))?}", myEvaluator);
|
||||
@ -481,6 +483,7 @@ rank_specifier:
|
||||
wrapped returns [int precedence]:
|
||||
^(JAVAWRAPPEREXPRESSION expression) { $precedence = $expression.precedence; } -> { $expression.st }
|
||||
| ^(JAVAWRAPPERARGUMENT argument_value) { $precedence = $argument_value.precedence; } -> { $argument_value.st }
|
||||
| ^(JAVAWRAPPERTYPE type) { $precedence = int.MaxValue; } -> { $type.st }
|
||||
;
|
||||
|
||||
delegate_creation_expression:
|
||||
@ -627,8 +630,18 @@ commas:
|
||||
// Type Section
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
type_name:
|
||||
namespace_or_type_name -> { $namespace_or_type_name.st };
|
||||
type_name
|
||||
@init {
|
||||
Dictionary<string,ReplacementDescriptor> templateMap = new Dictionary<string,ReplacementDescriptor>();
|
||||
}:
|
||||
namespace_or_type_name -> { $namespace_or_type_name.st }
|
||||
| ^(JAVAWRAPPER t=identifier
|
||||
(k=identifier v=wrapped
|
||||
{
|
||||
templateMap[$k.st.ToString()] = new ReplacementDescriptor($v.st != null ? $v.st.ToString() : "<sorry, untranslated expression>", $v.precedence);
|
||||
}
|
||||
)*) -> string(payload = {fillTemplate($t.st.ToString(), templateMap)})
|
||||
;
|
||||
namespace_or_type_name:
|
||||
t1=type_or_generic -> { $t1.st }
|
||||
// keving: external aliases not supported
|
||||
@ -670,8 +683,13 @@ type
|
||||
StringTemplate nm = null;
|
||||
List<string> stars = new List<string>();
|
||||
string opt = null;
|
||||
Dictionary<string,ReplacementDescriptor> templateMap = new Dictionary<string,ReplacementDescriptor>();
|
||||
}:
|
||||
^(TYPE (tp=predefined_type {nm=$tp.st;} | tn=type_name {nm=$tn.st;} | tv='void' { nm=%void();}) rank_specifiers? ('*' { stars.Add("*");})* ('?' { opt = "?";} )?) -> type(name={ nm }, stars={ stars }, rs={ $rank_specifiers.st }, opt={ opt })
|
||||
^(TYPE (
|
||||
tp=predefined_type {nm=$tp.st;}
|
||||
| tn=type_name {nm=$tn.st;}
|
||||
| tv='void' { nm=%void();}
|
||||
) rank_specifiers? ('*' { stars.Add("*");})* ('?' { opt = "?";} )?) -> type(name={ nm }, stars={ stars }, rs={ $rank_specifiers.st }, opt={ opt })
|
||||
;
|
||||
non_nullable_type:
|
||||
type -> { $type.st } ;
|
||||
|
@ -46,6 +46,10 @@ scope SymTab {
|
||||
|
||||
@members
|
||||
{
|
||||
// in_member_name is set while we are processing member_name. It stops type_or_generic from
|
||||
// treating its input as a type (and translating it).
|
||||
// TODO: Decide what should really be done here with <type>.member_name
|
||||
private bool in_member_name = false;
|
||||
|
||||
private string CompUnitName = null;
|
||||
|
||||
@ -180,7 +184,7 @@ scope SymTab {
|
||||
}
|
||||
|
||||
protected TypeRepTemplate SymTabLookup(string name) {
|
||||
return SymTabLookup(name, new UnknownRepTemplate("TYPE OF " + name));
|
||||
return SymTabLookup(name, null);
|
||||
}
|
||||
|
||||
protected TypeRepTemplate SymTabLookup(string name, TypeRepTemplate def) {
|
||||
@ -226,6 +230,13 @@ scope SymTab {
|
||||
return (CommonTree)adaptor.RulePostProcessing(root);
|
||||
}
|
||||
|
||||
protected CommonTree wrapType(CommonTree t, IToken tok) {
|
||||
CommonTree root = (CommonTree)adaptor.Nil;
|
||||
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(JAVAWRAPPERTYPE, tok, "TYPE"), root);
|
||||
adaptor.AddChild(root, dupTree(t));
|
||||
|
||||
return (CommonTree)adaptor.RulePostProcessing(root);
|
||||
}
|
||||
protected CommonTree wrapTypeOfType(TypeRepTemplate t, IToken tok) {
|
||||
CommonTree root = (CommonTree)adaptor.Nil;
|
||||
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(JAVAWRAPPEREXPRESSION, tok, "EXPRESSION"), root);
|
||||
@ -455,8 +466,6 @@ type_declaration:
|
||||
// Identifiers
|
||||
qualified_identifier:
|
||||
identifier ('.' identifier)*;
|
||||
namespace_name
|
||||
: namespace_or_type_name ;
|
||||
|
||||
modifiers:
|
||||
modifier+ ;
|
||||
@ -500,64 +509,64 @@ scope {
|
||||
}:
|
||||
^(index=INDEX ie=expression expression_list?)
|
||||
{
|
||||
if ($ie.dotNetType != null && !$ie.dotNetType.IsUnknownType) {
|
||||
$dotNetType = new UnknownRepTemplate($ie.dotNetType.TypeName+".INDEXER");
|
||||
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);
|
||||
AddToImports(indexerResult.Result.Imports);
|
||||
$dotNetType = indexerResult.ResultType;
|
||||
}
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($index.token.Line, "Could not resolve index expression");
|
||||
}
|
||||
expType = $ie.dotNetType ?? (new UnknownRepTemplate("INDEXER.BASE"));
|
||||
if (expType.IsUnknownType) {
|
||||
WarningFailedResolve($index.token.Line, "Could not find type of indexed expression");
|
||||
}
|
||||
$dotNetType = new UnknownRepTemplate(expType.TypeName+".INDEXER");
|
||||
ResolveResult indexerResult = expType.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);
|
||||
AddToImports(indexerResult.Result.Imports);
|
||||
$dotNetType = indexerResult.ResultType;
|
||||
}
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($index.token.Line, "Could not find type of indexed expression");
|
||||
WarningFailedResolve($index.token.Line, "Could not resolve index expression against " + expType.TypeName);
|
||||
}
|
||||
}
|
||||
| (^(APPLY (^('.' expression identifier)|identifier) argument_list?)) =>
|
||||
^(APPLY (^('.' e2=expression {expType = $e2.dotNetType; implicitThis = false;} i2=identifier)|i2=identifier) argument_list?)
|
||||
{
|
||||
if (expType != null && !expType.IsUnknownType) {
|
||||
$dotNetType = new UnknownRepTemplate(expType.TypeName+".APPLY");
|
||||
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"] = wrapExpression($e2.tree, $i2.tree.Token);
|
||||
}
|
||||
for (int idx = 0; idx < methodRep.Params.Count; idx++) {
|
||||
myMap[methodRep.Params[idx].Name] = wrapArgument($argument_list.argTrees[idx], $i2.tree.Token);
|
||||
if (methodRep.Params[idx].Name.StartsWith("TYPEOF") && $argument_list.argTreeTypeofTypes[idx] != null) {
|
||||
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
|
||||
myMap[methodRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($argument_list.argTreeTypeofTypes[idx], $i2.tree.Token);
|
||||
}
|
||||
}
|
||||
ret = mkJavaWrapper(methodResult.Result.Java, myMap, $i2.tree.Token);
|
||||
AddToImports(methodResult.Result.Imports);
|
||||
$dotNetType = methodResult.ResultType;
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($i2.tree.Token.Line, "Could not resolve method application");
|
||||
}
|
||||
if (expType == null) {
|
||||
expType = new UnknownRepTemplate("APPLY.BASE");
|
||||
}
|
||||
if (expType.IsUnknownType) {
|
||||
WarningFailedResolve($i2.tree.Token.Line, "Could not find type needed to resolve method application");
|
||||
}
|
||||
$dotNetType = new UnknownRepTemplate(expType.TypeName+".APPLY");
|
||||
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"] = wrapExpression($e2.tree, $i2.tree.Token);
|
||||
}
|
||||
for (int idx = 0; idx < methodRep.Params.Count; idx++) {
|
||||
myMap[methodRep.Params[idx].Name] = wrapArgument($argument_list.argTrees[idx], $i2.tree.Token);
|
||||
if (methodRep.Params[idx].Name.StartsWith("TYPEOF") && $argument_list.argTreeTypeofTypes[idx] != null) {
|
||||
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
|
||||
myMap[methodRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($argument_list.argTreeTypeofTypes[idx], $i2.tree.Token);
|
||||
}
|
||||
}
|
||||
ret = mkJavaWrapper(methodResult.Result.Java, myMap, $i2.tree.Token);
|
||||
AddToImports(methodResult.Result.Imports);
|
||||
$dotNetType = methodResult.ResultType;
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($i2.tree.Token.Line, "Could not find type needed to resolve method application");
|
||||
WarningFailedResolve($i2.tree.Token.Line, "Could not resolve method application against " + expType.TypeName);
|
||||
}
|
||||
}
|
||||
| ^(APPLY {$primary_expression::parentIsApply = true; } expression {$primary_expression::parentIsApply = false; } argument_list?)
|
||||
@ -565,6 +574,8 @@ scope {
|
||||
| ^(POSTDEC expression) { $dotNetType = $expression.dotNetType; }
|
||||
| ^(d1='.' e1=expression i1=identifier generic_argument_list?)
|
||||
{
|
||||
// TODO: generic_argument_list is ignored ....
|
||||
|
||||
// Possibilities:
|
||||
// - accessing a property/field of some object
|
||||
// - a qualified type name
|
||||
@ -612,7 +623,7 @@ scope {
|
||||
// - part of a type name
|
||||
bool found = false;
|
||||
TypeRepTemplate idType = SymTabLookup($identifier.thetext);
|
||||
if (idType != null && !idType.IsUnknownType) {
|
||||
if (idType != null) {
|
||||
$dotNetType = idType;
|
||||
found = true;
|
||||
}
|
||||
@ -658,6 +669,9 @@ scope {
|
||||
{
|
||||
ClassRepTemplate conType = $type.dotNetType as ClassRepTemplate;
|
||||
$dotNetType = $type.dotNetType;
|
||||
if (conType == null) {
|
||||
conType = new UnknownRepTemplate("CONSTRUCTOR");
|
||||
}
|
||||
ResolveResult conResult = conType.Resolve($argument_list.argTypes, AppEnv);
|
||||
if (conResult != null) {
|
||||
ConstructorRepTemplate conRep = conResult.Result as ConstructorRepTemplate;
|
||||
@ -665,12 +679,20 @@ scope {
|
||||
for (int idx = 0; idx < conRep.Params.Count; idx++) {
|
||||
myMap[conRep.Params[idx].Name] = wrapArgument($argument_list.argTrees[idx], $n.token);
|
||||
}
|
||||
if ($type.argTrees != null && $type.argTrees.Count == $type.dotNetType.TypeParams.Length) {
|
||||
int idx = 0;
|
||||
foreach (CommonTree ty in $type.argTrees)
|
||||
{
|
||||
myMap[$type.dotNetType.TypeParams[idx]] = wrapType(ty, $n.token);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
ret = mkJavaWrapper(conResult.Result.Java, myMap, $n.token);
|
||||
AddToImports(conResult.Result.Imports);
|
||||
$dotNetType = conResult.ResultType;
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($n.token.Line, "Could not resolve constructor");
|
||||
WarningFailedResolve($n.token.Line, "Could not resolve constructor against " + conType.TypeName);
|
||||
}
|
||||
}
|
||||
| 'new' (
|
||||
@ -697,7 +719,7 @@ primary_expression_part:
|
||||
| '++'
|
||||
| '--' ;
|
||||
access_identifier:
|
||||
access_operator type_or_generic ;
|
||||
access_operator type_or_generic[""] ;
|
||||
access_operator:
|
||||
'.' | '->' ;
|
||||
brackets_or_arguments:
|
||||
@ -864,37 +886,94 @@ commas:
|
||||
// Type Section
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
type_name returns [string name, TypeRepTemplate dotNetType]:
|
||||
namespace_or_type_name { $name = $namespace_or_type_name.name; $dotNetType = findType($namespace_or_type_name.name, $namespace_or_type_name.tyargs); } ;
|
||||
namespace_or_type_name returns [string name, List<TypeRepTemplate> tyargs]
|
||||
// i.e not a predefined type.
|
||||
type_name returns [TypeRepTemplate dotNetType, List<CommonTree> argTrees, bool hasTyArgs]
|
||||
@init {
|
||||
TypeRepTemplate tyRep = null;
|
||||
}:
|
||||
type_or_generic { $name = $type_or_generic.name; $tyargs = $type_or_generic.tyargs; }
|
||||
| ^('::' namespace_or_type_name type_or_generic) { $name = "System.Object"; } // give up, we don't support these
|
||||
| ^(d='.' n1=namespace_or_type_name tg1=type_or_generic) { WarningAssert($n1.tyargs == null, $d.token.Line, "Didn't expect type arguments in prefix of type name"); $name = $n1.name + "." + $type_or_generic.name; $tyargs = $type_or_generic.tyargs; tyRep = findType($name, $tyargs); if (tyRep != null) AddToImports(tyRep.Imports); }
|
||||
-> { tyRep != null }? IDENTIFIER[$d.token, tyRep.Java]
|
||||
-> ^($d $n1 $tg1)
|
||||
$hasTyArgs = false;
|
||||
Dictionary<string,CommonTree> tyMap = new Dictionary<string,CommonTree>();
|
||||
}
|
||||
@after {
|
||||
AddToImports($dotNetType.Imports);
|
||||
}
|
||||
:
|
||||
tg=type_or_generic[""] { $dotNetType = $tg.dotNetType; $argTrees = $tg.argTrees; $hasTyArgs = $tg.hasTyArgs; }
|
||||
| ^('::' ct=type_name ctg=type_or_generic[$ct.dotNetType == null ? "::" : $ct.dotNetType.TypeName+"::"])
|
||||
{
|
||||
// give up, we don't support these, pretty printer will wrap in a comment
|
||||
$dotNetType = $ctg.dotNetType;
|
||||
$hasTyArgs = $ctg.hasTyArgs;
|
||||
$argTrees = $ctg.argTrees;
|
||||
}
|
||||
| ^(d='.' dt=type_name dtg=type_or_generic[$dt.dotNetType == null ? "." : $dt.dotNetType.TypeName+"."])
|
||||
{
|
||||
WarningAssert(!$dt.hasTyArgs, $d.token.Line, "Didn't expect type arguments in prefix of type name");
|
||||
|
||||
$dotNetType = $dtg.dotNetType;
|
||||
if (!$dotNetType.IsUnknownType) {
|
||||
if ($dotNetType.TypeParams.Length == $dtg.argTrees.Count) {
|
||||
int i = 0;
|
||||
foreach (CommonTree ty in $dtg.argTrees) {
|
||||
tyMap[$dotNetType.TypeParams[i]] = wrapType(ty, $dt.tree.Token);
|
||||
i++;
|
||||
}
|
||||
$hasTyArgs = true;
|
||||
$argTrees = $dtg.argTrees;
|
||||
}
|
||||
}
|
||||
}
|
||||
-> {!$dotNetType.IsUnknownType}? { mkJavaWrapper($dotNetType.Java, tyMap, $dt.tree.Token) }
|
||||
-> ^($d $dt $dtg)
|
||||
;
|
||||
|
||||
type_or_generic returns [string name, List<TypeRepTemplate> tyargs]
|
||||
:
|
||||
(identifier_type generic_argument_list) => t=identifier_type { $name = $identifier_type.thetext; } generic_argument_list { $tyargs = $generic_argument_list.argTypes; }
|
||||
| t=identifier_type { $name = $identifier_type.thetext; } ;
|
||||
|
||||
identifier_type returns [string thetext]
|
||||
type_or_generic[String prefix] returns [TypeRepTemplate dotNetType, List<CommonTree> argTrees, bool hasTyArgs]
|
||||
@init {
|
||||
TypeRepTemplate tyRep = null;
|
||||
$hasTyArgs = false;
|
||||
$argTrees = new List<CommonTree>();
|
||||
Dictionary<string,CommonTree> tyMap = new Dictionary<string,CommonTree>();
|
||||
}
|
||||
@after{
|
||||
$thetext = $t.thetext;
|
||||
}:
|
||||
t=identifier { tyRep = findType($t.thetext); if (tyRep != null) AddToImports(tyRep.Imports); }
|
||||
-> { tyRep != null }? IDENTIFIER[$t.tree.Token, tyRep.Java]
|
||||
-> $t;
|
||||
|
||||
@after {
|
||||
AddToImports($dotNetType.Imports);
|
||||
}
|
||||
:
|
||||
// (identifier generic_argument_list) => t=identifier ga=generic_argument_list
|
||||
t=identifier (ga=generic_argument_list {$hasTyArgs = true;})?
|
||||
{
|
||||
$dotNetType = findType(prefix+$t.thetext, $ga.argTypes);
|
||||
if (!$dotNetType.IsUnknownType) {
|
||||
if ($hasTyArgs && $dotNetType.TypeParams.Length == $ga.argTrees.Count) {
|
||||
int i = 0;
|
||||
foreach (CommonTree ty in $ga.argTrees) {
|
||||
tyMap[$dotNetType.TypeParams[i]] = wrapType(ty, $t.tree.Token);
|
||||
i++;
|
||||
}
|
||||
$argTrees = $ga.argTrees;
|
||||
}
|
||||
}
|
||||
}
|
||||
-> {!this.in_member_name && !$dotNetType.IsUnknownType}? { mkJavaWrapper($dotNetType.Java, tyMap, $t.tree.Token) }
|
||||
-> $t $ga?
|
||||
;
|
||||
// | ity=identifier_type[prefix]
|
||||
// { $dotNetType = $ity.dotNetType);
|
||||
// }
|
||||
// -> {!$dotNetType.IsUnknownType}? { mkJavaWrapper($dotNetType.Java, null, $ity.tree.Token) }
|
||||
// -> $ity
|
||||
// ;
|
||||
//
|
||||
// identifier_type[string prefix] returns [string thetext]
|
||||
// @init {
|
||||
// TypeRepTemplate tyRep = null;
|
||||
// }
|
||||
// @after{
|
||||
// $thetext = $t.thetext;
|
||||
// AddToImports($dotNetType.Imports);
|
||||
// }:
|
||||
// t=identifier { tyRep = findType(prefix+$t.thetext); }
|
||||
// -> { mkJavaWrapper(tyRep.Java, null, $t.tree.Token) }
|
||||
// ;
|
||||
//
|
||||
qid: // qualified_identifier v2
|
||||
^(access_operator qid type_or_generic)
|
||||
^(access_operator qid type_or_generic[""])
|
||||
| qid_start
|
||||
;
|
||||
qid_start:
|
||||
@ -910,21 +989,22 @@ qid_start:
|
||||
qid_part:
|
||||
access_identifier;
|
||||
|
||||
generic_argument_list returns [List<TypeRepTemplate> argTypes]:
|
||||
'<' type_arguments '>' { $argTypes = $type_arguments.tyTypes; };
|
||||
type_arguments returns [List<TypeRepTemplate> tyTypes]
|
||||
generic_argument_list returns [List<TypeRepTemplate> argTypes, List<CommonTree> argTrees]:
|
||||
'<' type_arguments '>' { $argTypes = $type_arguments.tyTypes; $argTrees = $type_arguments.argTrees; };
|
||||
type_arguments returns [List<TypeRepTemplate> tyTypes, List<CommonTree> argTrees]
|
||||
@init {
|
||||
$tyTypes = new List<TypeRepTemplate>();
|
||||
$argTrees = new List<CommonTree>();
|
||||
}:
|
||||
t1=type { $tyTypes.Add($t1.dotNetType); } (',' tn=type { $tyTypes.Add($tn.dotNetType); })* ;
|
||||
t1=type { $tyTypes.Add($t1.dotNetType); $argTrees.Add(dupTree($t1.tree)); } (',' tn=type { $tyTypes.Add($tn.dotNetType); $argTrees.Add(dupTree($tn.tree)); })* ;
|
||||
|
||||
// keving: TODO: Look for type vars
|
||||
type returns [TypeRepTemplate dotNetType]
|
||||
type returns [TypeRepTemplate dotNetType, List<CommonTree> argTrees]
|
||||
:
|
||||
^(TYPE (predefined_type { $dotNetType = $predefined_type.dotNetType; }
|
||||
| type_name { $dotNetType = $type_name.dotNetType; }
|
||||
| type_name { $dotNetType = $type_name.dotNetType; $argTrees = $type_name.argTrees; }
|
||||
| 'void' { $dotNetType = AppEnv["System.Void"]; } )
|
||||
(rank_specifiers[$dotNetType] { $dotNetType = $rank_specifiers.dotNetType; })? '*'* '?'?);
|
||||
(rank_specifiers[$dotNetType] { $dotNetType = $rank_specifiers.dotNetType; $argTrees = null; })? '*'* '?'?);
|
||||
|
||||
non_nullable_type returns [TypeRepTemplate dotNetType]:
|
||||
type { $dotNetType = $type.dotNetType; } ;
|
||||
@ -973,6 +1053,7 @@ assignment
|
||||
@init {
|
||||
CommonTree ret = null;
|
||||
bool isThis = false;
|
||||
TypeRepTemplate expType = null;
|
||||
}
|
||||
@after {
|
||||
if (ret != null)
|
||||
@ -982,103 +1063,105 @@ assignment
|
||||
(^('.' se=expression i=identifier generic_argument_list?) | i=identifier { isThis = true;}) a=assignment_operator rhs=expression
|
||||
{
|
||||
TypeRepTemplate seType = (isThis ? SymTabLookup("this") : $se.dotNetType);
|
||||
if (seType != null && !seType.IsUnknownType) {
|
||||
ResolveResult fieldResult = seType.Resolve($i.thetext, AppEnv);
|
||||
if (fieldResult != null && fieldResult.Result is PropRepTemplate) {
|
||||
PropRepTemplate propRep = fieldResult.Result as PropRepTemplate;
|
||||
if (!String.IsNullOrEmpty(propRep.JavaSet)) {
|
||||
CommonTree newRhsExp = $rhs.tree;
|
||||
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
||||
bool goodTx = true;
|
||||
if ($a.tree.Token.Type != ASSIGN) {
|
||||
if (!String.IsNullOrEmpty(propRep.JavaGet)) {
|
||||
// we have prop <op>= rhs
|
||||
// need to translate to setProp(getProp <op> rhs)
|
||||
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
||||
if (!isThis)
|
||||
rhsMap["this"] = wrapExpression($se.tree, $i.tree.Token);
|
||||
CommonTree rhsPropTree = mkJavaWrapper(propRep.JavaGet, rhsMap, $a.tree.Token);
|
||||
newRhsExp = mkOpExp(mkOpExp($a.tree), rhsPropTree, $rhs.tree);
|
||||
}
|
||||
else {
|
||||
goodTx = false;
|
||||
}
|
||||
if (seType == null) {
|
||||
seType = new UnknownRepTemplate("FIELD.BASE");
|
||||
}
|
||||
if (seType.IsUnknownType) {
|
||||
WarningFailedResolve($i.tree.Token.Line, "Could not find type of expression for field /property access");
|
||||
}
|
||||
ResolveResult fieldResult = seType.Resolve($i.thetext, AppEnv);
|
||||
if (fieldResult != null) {
|
||||
if (fieldResult.Result is PropRepTemplate) {
|
||||
PropRepTemplate propRep = fieldResult.Result as PropRepTemplate;
|
||||
if (!String.IsNullOrEmpty(propRep.JavaSet)) {
|
||||
CommonTree newRhsExp = $rhs.tree;
|
||||
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
||||
bool goodTx = true;
|
||||
if ($a.tree.Token.Type != ASSIGN) {
|
||||
if (!String.IsNullOrEmpty(propRep.JavaGet)) {
|
||||
// we have prop <op>= rhs
|
||||
// need to translate to setProp(getProp <op> rhs)
|
||||
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
||||
if (!isThis)
|
||||
rhsMap["this"] = wrapExpression($se.tree, $i.tree.Token);
|
||||
CommonTree rhsPropTree = mkJavaWrapper(propRep.JavaGet, rhsMap, $a.tree.Token);
|
||||
newRhsExp = mkOpExp(mkOpExp($a.tree), rhsPropTree, $rhs.tree);
|
||||
}
|
||||
Dictionary<string,CommonTree> valMap = new Dictionary<string,CommonTree>();
|
||||
if (!isThis)
|
||||
valMap["this"] = wrapExpression($se.tree, $i.tree.Token);
|
||||
valMap["value"] = wrapExpression(newRhsExp, $i.tree.Token);
|
||||
if (goodTx) {
|
||||
ret = mkJavaWrapper(propRep.JavaSet, valMap, $a.tree.Token);
|
||||
AddToImports(propRep.Imports);
|
||||
else {
|
||||
goodTx = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($i.tree.Token.Line, "Could not resolve field or property expression");
|
||||
}
|
||||
}
|
||||
Dictionary<string,CommonTree> valMap = new Dictionary<string,CommonTree>();
|
||||
if (!isThis)
|
||||
valMap["this"] = wrapExpression($se.tree, $i.tree.Token);
|
||||
valMap["value"] = wrapExpression(newRhsExp, $i.tree.Token);
|
||||
if (goodTx) {
|
||||
ret = mkJavaWrapper(propRep.JavaSet, valMap, $a.tree.Token);
|
||||
AddToImports(propRep.Imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($i.tree.Token.Line, "Could not find type of expression for field /property access");
|
||||
WarningFailedResolve($i.tree.Token.Line, "Could not resolve field or property expression against " + seType.ToString());
|
||||
}
|
||||
}
|
||||
| (^(INDEX expression expression_list?) assignment_operator) =>
|
||||
^(INDEX ie=expression expression_list?) ia=assignment_operator irhs=expression
|
||||
{
|
||||
if ($ie.dotNetType != null && !$ie.dotNetType.IsUnknownType) {
|
||||
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)) {
|
||||
CommonTree newRhsExp = $irhs.tree;
|
||||
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
||||
bool goodTx = true;
|
||||
if ($ia.tree.Token.Type != ASSIGN) {
|
||||
if (!String.IsNullOrEmpty(indexerRep.JavaGet)) {
|
||||
// we have indexable[args] <op>= rhs
|
||||
// need to translate to set___idx(args, get___idx(args) <op> rhs)
|
||||
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
||||
rhsMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
||||
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
||||
rhsMap[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
|
||||
rhsMap[indexerRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($expression_list.expTreeTypeofTypes[idx], $ie.tree.Token);
|
||||
}
|
||||
}
|
||||
|
||||
CommonTree rhsIdxTree = mkJavaWrapper(indexerRep.JavaGet, rhsMap, $ia.tree.Token);
|
||||
newRhsExp = mkOpExp(mkOpExp($ia.tree), rhsIdxTree, $irhs.tree);
|
||||
}
|
||||
else {
|
||||
goodTx = false;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
||||
myMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
||||
myMap["value"] = wrapExpression(newRhsExp, newRhsExp.Token);
|
||||
expType = $ie.dotNetType ?? (new UnknownRepTemplate("INDEXER.BASE"));
|
||||
if (expType.IsUnknownType) {
|
||||
WarningFailedResolve($ie.tree.Token.Line, "Could not find type of expression for Indexer");
|
||||
}
|
||||
ResolveResult indexerResult = expType.ResolveIndexer($expression_list.expTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
||||
if (indexerResult != null) {
|
||||
IndexerRepTemplate indexerRep = indexerResult.Result as IndexerRepTemplate;
|
||||
if (!String.IsNullOrEmpty(indexerRep.JavaSet)) {
|
||||
CommonTree newRhsExp = $irhs.tree;
|
||||
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
||||
bool goodTx = true;
|
||||
if ($ia.tree.Token.Type != ASSIGN) {
|
||||
if (!String.IsNullOrEmpty(indexerRep.JavaGet)) {
|
||||
// we have indexable[args] <op>= rhs
|
||||
// need to translate to set___idx(args, get___idx(args) <op> rhs)
|
||||
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
||||
rhsMap["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);
|
||||
}
|
||||
rhsMap[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
|
||||
rhsMap[indexerRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($expression_list.expTreeTypeofTypes[idx], $ie.tree.Token);
|
||||
}
|
||||
}
|
||||
if (goodTx) {
|
||||
ret = mkJavaWrapper(indexerRep.JavaSet, myMap, $ie.tree.Token);
|
||||
AddToImports(indexerRep.Imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($ie.tree.Token.Line, "Could not resolve index expression");
|
||||
}
|
||||
|
||||
CommonTree rhsIdxTree = mkJavaWrapper(indexerRep.JavaGet, rhsMap, $ia.tree.Token);
|
||||
newRhsExp = mkOpExp(mkOpExp($ia.tree), rhsIdxTree, $irhs.tree);
|
||||
}
|
||||
else {
|
||||
goodTx = false;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
||||
myMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
||||
myMap["value"] = wrapExpression(newRhsExp, newRhsExp.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);
|
||||
}
|
||||
}
|
||||
if (goodTx) {
|
||||
ret = mkJavaWrapper(indexerRep.JavaSet, myMap, $ie.tree.Token);
|
||||
AddToImports(indexerRep.Imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
WarningFailedResolve($ie.tree.Token.Line, "Could not find type of expression for index access");
|
||||
WarningFailedResolve($ie.tree.Token.Line, "Could not resolve index expression against " + expType.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
| unary_expression assignment_operator expression ;
|
||||
|
||||
|
||||
@ -1562,8 +1645,17 @@ method_header:
|
||||
^(METHOD_HEADER attributes? modifiers? type member_name type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list?);
|
||||
method_body:
|
||||
block ;
|
||||
member_name:
|
||||
type_or_generic ('.' type_or_generic)*
|
||||
member_name
|
||||
@init {
|
||||
// in_member_name is used by type_or-generic so that we don't treat the member name as a type.
|
||||
string preTy = null;
|
||||
bool save_in_member_name = this.in_member_name;
|
||||
this.in_member_name = true;
|
||||
}
|
||||
@after{
|
||||
this.in_member_name = save_in_member_name;
|
||||
}:
|
||||
t1=type_or_generic[""] { preTy = ($t1.dotNetType == null ? "" : $t1.dotNetType.TypeName); }('.' tn=type_or_generic[preTy+"."] { preTy = ($tn.dotNetType == null ? "" : $tn.dotNetType.TypeName); })*
|
||||
//(type '.') => type '.' identifier
|
||||
//| identifier
|
||||
;
|
||||
|
@ -134,6 +134,7 @@ tokens {
|
||||
JAVAWRAPPER;
|
||||
JAVAWRAPPEREXPRESSION;
|
||||
JAVAWRAPPERARGUMENT;
|
||||
JAVAWRAPPERTYPE;
|
||||
SEP;
|
||||
KGHOLE;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user