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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string SubstituteInType(String type, Dictionary<string,TypeRepTemplate> argMap)
|
public static string SubstituteInType(String type, Dictionary<string,TypeRepTemplate> argMap)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(type))
|
if (String.IsNullOrEmpty(type))
|
||||||
@ -88,7 +88,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
public string Type {
|
public string Type {
|
||||||
get { return _type; }
|
get { return _type; }
|
||||||
set {
|
set {
|
||||||
_type=value.Replace('<','[').Replace('>',']');
|
_type=value.Replace("<","*[").Replace(">","]*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
@ -281,7 +281,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
public string SurroundingTypeName {
|
public string SurroundingTypeName {
|
||||||
get { return _surroundingTypeName; }
|
get { return _surroundingTypeName; }
|
||||||
set {
|
set {
|
||||||
_surroundingTypeName=value.Replace('<','[').Replace('>',']');
|
_surroundingTypeName=value.Replace("<","*[").Replace(">","]*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public virtual string[] mkImports() {
|
public virtual string[] mkImports() {
|
||||||
@ -632,15 +632,41 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
// Method name
|
// Method name
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
private string[] _typeParams = null;
|
||||||
[XmlArrayItem("Name")]
|
[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
|
// Return type
|
||||||
private string _return;
|
private string _return;
|
||||||
public string Return {
|
public string Return {
|
||||||
get { return _return; }
|
get { return _return; }
|
||||||
set {
|
set {
|
||||||
_return=value.Replace('<','[').Replace('>',']');
|
_return=value.Replace("<","*[").Replace(">","]*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,6 +696,15 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
TypeParams[i] = copyFrom.TypeParams[i];
|
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))
|
if (!String.IsNullOrEmpty(copyFrom.Return))
|
||||||
{
|
{
|
||||||
Return = copyFrom.Return;
|
Return = copyFrom.Return;
|
||||||
@ -749,6 +784,14 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
return false;
|
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);
|
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() ;
|
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();
|
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 {
|
public string From {
|
||||||
get { return _from; }
|
get { return _from; }
|
||||||
set {
|
set {
|
||||||
_from=value.Replace('<','[').Replace('>',']');
|
_from=value.Replace("<","*[").Replace(">","]*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,7 +852,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
public string To {
|
public string To {
|
||||||
get { return _to; }
|
get { return _to; }
|
||||||
set {
|
set {
|
||||||
_to=value.Replace('<','[').Replace('>',']');
|
_to=value.Replace("<","*[").Replace(">","]*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,7 +978,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
public string Type {
|
public string Type {
|
||||||
get { return _type; }
|
get { return _type; }
|
||||||
set {
|
set {
|
||||||
_type=value.Replace('<','[').Replace('>',']');
|
_type=value.Replace("<","*[").Replace(">","]*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
@ -1414,8 +1462,48 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
[XmlElementAttribute("Name")]
|
[XmlElementAttribute("Name")]
|
||||||
public string TypeName { get; set; }
|
public string TypeName { get; set; }
|
||||||
|
|
||||||
|
private string[] _typeParams = null;
|
||||||
[XmlArrayItem("Name")]
|
[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
|
// Path to use when resolving types
|
||||||
[XmlArrayItem("Use")]
|
[XmlArrayItem("Use")]
|
||||||
@ -1449,7 +1537,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
if (value != null) {
|
if (value != null) {
|
||||||
_inherits= new string[value.Length];
|
_inherits= new string[value.Length];
|
||||||
for (int i = 0; i < value.Length; i++) {
|
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 {
|
else {
|
||||||
@ -1490,36 +1578,20 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
|
|
||||||
// Equivalent to "this is TypeVarRepTemplate"
|
// Equivalent to "this is TypeVarRepTemplate"
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public bool IsTypeVar
|
public virtual bool IsTypeVar
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (this is TypeVarRepTemplate);
|
return (this is TypeVarRepTemplate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Equivalent to "this is UnknownRepTemplate"
|
||||||
// Type Arguments that this (generic) type has been instantiated with
|
|
||||||
private TypeRepTemplate[] _instantiatedTypes = null;
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public TypeRepTemplate[] InstantiatedTypes
|
public virtual bool IsUnknownType
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_instantiatedTypes == null)
|
return (this is UnknownRepTemplate);
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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)
|
if (copyFrom.Uses != null)
|
||||||
{
|
{
|
||||||
len = copyFrom.Uses.Length;
|
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.
|
// 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) {
|
protected Dictionary<string,TypeRepTemplate> mkTypeMap(ICollection<TypeRepTemplate> args) {
|
||||||
Dictionary<string,TypeRepTemplate> ret = new Dictionary<string,TypeRepTemplate>();
|
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;
|
int i = 0;
|
||||||
foreach (TypeRepTemplate sub in args)
|
foreach (TypeRepTemplate sub in args)
|
||||||
{
|
{
|
||||||
if (sub.IsTypeVar)
|
|
||||||
{
|
|
||||||
remTypeParams.Add(sub.TypeName);
|
|
||||||
}
|
|
||||||
ret[TypeParams[i]] = sub;
|
ret[TypeParams[i]] = sub;
|
||||||
|
InstantiatedTypes[i] = sub;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
TypeParams = remTypeParams.ToArray();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1666,16 +1744,6 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
Inherits[i] = TemplateUtilities.SubstituteInType(Inherits[i],args);
|
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);
|
base.Apply(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2077,9 +2145,9 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
}
|
}
|
||||||
if (InstantiatedTypes != null)
|
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
|
else
|
||||||
{
|
{
|
||||||
fmt.Append(TypeName.Substring(incNameSpace ? 0 : TypeName.LastIndexOf('.')+1));
|
fmt.Append(TypeName.Substring(incNameSpace ? 0 : TypeName.LastIndexOf('.')+1));
|
||||||
if (InstantiatedTypes.Length > 0)
|
if (InstantiatedTypes != null && InstantiatedTypes.Length > 0)
|
||||||
{
|
{
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
fmt.Append("<");
|
fmt.Append("<");
|
||||||
@ -2291,7 +2359,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
public string Return {
|
public string Return {
|
||||||
get { return _return; }
|
get { return _return; }
|
||||||
set {
|
set {
|
||||||
_return=value.Replace('<','[').Replace('>',']');
|
_return=value.Replace("<","*[").Replace(">","]*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2974,7 +3042,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
|||||||
{
|
{
|
||||||
ResolveResult res = new ResolveResult();
|
ResolveResult res = new ResolveResult();
|
||||||
res.Result = c;
|
res.Result = c;
|
||||||
res.ResultType = BuildType(TypeName, AppEnv);
|
res.ResultType = this;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,6 +273,8 @@ options {
|
|||||||
|
|
||||||
public string fillTemplate(string template, Dictionary<string,ReplacementDescriptor> templateMap) {
|
public string fillTemplate(string template, Dictionary<string,ReplacementDescriptor> templateMap) {
|
||||||
string ret = template;
|
string ret = template;
|
||||||
|
// *[ -> < and ]* -> >
|
||||||
|
ret = ret.Replace("*[","<").Replace("]*",">");
|
||||||
foreach (string v in templateMap.Keys) {
|
foreach (string v in templateMap.Keys) {
|
||||||
MatchEvaluator myEvaluator = new MatchEvaluator(templateMap[v].replace);
|
MatchEvaluator myEvaluator = new MatchEvaluator(templateMap[v].replace);
|
||||||
ret = Regex.Replace(ret, Regex.Escape("${" + v) + "(?::(?<prec>\\d+))?}", myEvaluator);
|
ret = Regex.Replace(ret, Regex.Escape("${" + v) + "(?::(?<prec>\\d+))?}", myEvaluator);
|
||||||
@ -481,6 +483,7 @@ rank_specifier:
|
|||||||
wrapped returns [int precedence]:
|
wrapped returns [int precedence]:
|
||||||
^(JAVAWRAPPEREXPRESSION expression) { $precedence = $expression.precedence; } -> { $expression.st }
|
^(JAVAWRAPPEREXPRESSION expression) { $precedence = $expression.precedence; } -> { $expression.st }
|
||||||
| ^(JAVAWRAPPERARGUMENT argument_value) { $precedence = $argument_value.precedence; } -> { $argument_value.st }
|
| ^(JAVAWRAPPERARGUMENT argument_value) { $precedence = $argument_value.precedence; } -> { $argument_value.st }
|
||||||
|
| ^(JAVAWRAPPERTYPE type) { $precedence = int.MaxValue; } -> { $type.st }
|
||||||
;
|
;
|
||||||
|
|
||||||
delegate_creation_expression:
|
delegate_creation_expression:
|
||||||
@ -627,8 +630,18 @@ commas:
|
|||||||
// Type Section
|
// Type Section
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
|
||||||
type_name:
|
type_name
|
||||||
namespace_or_type_name -> { $namespace_or_type_name.st };
|
@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:
|
namespace_or_type_name:
|
||||||
t1=type_or_generic -> { $t1.st }
|
t1=type_or_generic -> { $t1.st }
|
||||||
// keving: external aliases not supported
|
// keving: external aliases not supported
|
||||||
@ -670,8 +683,13 @@ type
|
|||||||
StringTemplate nm = null;
|
StringTemplate nm = null;
|
||||||
List<string> stars = new List<string>();
|
List<string> stars = new List<string>();
|
||||||
string opt = null;
|
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:
|
non_nullable_type:
|
||||||
type -> { $type.st } ;
|
type -> { $type.st } ;
|
||||||
|
@ -46,6 +46,10 @@ scope SymTab {
|
|||||||
|
|
||||||
@members
|
@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;
|
private string CompUnitName = null;
|
||||||
|
|
||||||
@ -180,7 +184,7 @@ scope SymTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected TypeRepTemplate SymTabLookup(string name) {
|
protected TypeRepTemplate SymTabLookup(string name) {
|
||||||
return SymTabLookup(name, new UnknownRepTemplate("TYPE OF " + name));
|
return SymTabLookup(name, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TypeRepTemplate SymTabLookup(string name, TypeRepTemplate def) {
|
protected TypeRepTemplate SymTabLookup(string name, TypeRepTemplate def) {
|
||||||
@ -226,6 +230,13 @@ scope SymTab {
|
|||||||
return (CommonTree)adaptor.RulePostProcessing(root);
|
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) {
|
protected CommonTree wrapTypeOfType(TypeRepTemplate t, IToken tok) {
|
||||||
CommonTree root = (CommonTree)adaptor.Nil;
|
CommonTree root = (CommonTree)adaptor.Nil;
|
||||||
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(JAVAWRAPPEREXPRESSION, tok, "EXPRESSION"), root);
|
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(JAVAWRAPPEREXPRESSION, tok, "EXPRESSION"), root);
|
||||||
@ -455,8 +466,6 @@ type_declaration:
|
|||||||
// Identifiers
|
// Identifiers
|
||||||
qualified_identifier:
|
qualified_identifier:
|
||||||
identifier ('.' identifier)*;
|
identifier ('.' identifier)*;
|
||||||
namespace_name
|
|
||||||
: namespace_or_type_name ;
|
|
||||||
|
|
||||||
modifiers:
|
modifiers:
|
||||||
modifier+ ;
|
modifier+ ;
|
||||||
@ -500,64 +509,64 @@ scope {
|
|||||||
}:
|
}:
|
||||||
^(index=INDEX ie=expression expression_list?)
|
^(index=INDEX ie=expression expression_list?)
|
||||||
{
|
{
|
||||||
if ($ie.dotNetType != null && !$ie.dotNetType.IsUnknownType) {
|
expType = $ie.dotNetType ?? (new UnknownRepTemplate("INDEXER.BASE"));
|
||||||
$dotNetType = new UnknownRepTemplate($ie.dotNetType.TypeName+".INDEXER");
|
if (expType.IsUnknownType) {
|
||||||
ResolveResult indexerResult = $ie.dotNetType.ResolveIndexer($expression_list.expTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
WarningFailedResolve($index.token.Line, "Could not find type of indexed expression");
|
||||||
if (indexerResult != null) {
|
}
|
||||||
IndexerRepTemplate indexerRep = indexerResult.Result as IndexerRepTemplate;
|
$dotNetType = new UnknownRepTemplate(expType.TypeName+".INDEXER");
|
||||||
if (!String.IsNullOrEmpty(indexerRep.JavaGet)) {
|
ResolveResult indexerResult = expType.ResolveIndexer($expression_list.expTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
||||||
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
if (indexerResult != null) {
|
||||||
myMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
IndexerRepTemplate indexerRep = indexerResult.Result as IndexerRepTemplate;
|
||||||
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
if (!String.IsNullOrEmpty(indexerRep.JavaGet)) {
|
||||||
myMap[indexerRep.Params[idx].Name] = wrapArgument($expression_list.expTrees[idx], $ie.tree.Token);
|
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
||||||
if (indexerRep.Params[idx].Name.StartsWith("TYPEOF") && $expression_list.expTreeTypeofTypes[idx] != null) {
|
myMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
||||||
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
|
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
||||||
myMap[indexerRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($expression_list.expTreeTypeofTypes[idx], $ie.tree.Token);
|
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
|
||||||
ret = mkJavaWrapper(indexerResult.Result.Java, myMap, $ie.tree.Token);
|
myMap[indexerRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($expression_list.expTreeTypeofTypes[idx], $ie.tree.Token);
|
||||||
AddToImports(indexerResult.Result.Imports);
|
}
|
||||||
$dotNetType = indexerResult.ResultType;
|
}
|
||||||
}
|
ret = mkJavaWrapper(indexerResult.Result.Java, myMap, $ie.tree.Token);
|
||||||
}
|
AddToImports(indexerResult.Result.Imports);
|
||||||
else {
|
$dotNetType = indexerResult.ResultType;
|
||||||
WarningFailedResolve($index.token.Line, "Could not resolve index expression");
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
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 (^('.' expression identifier)|identifier) argument_list?)) =>
|
||||||
^(APPLY (^('.' e2=expression {expType = $e2.dotNetType; implicitThis = false;} i2=identifier)|i2=identifier) argument_list?)
|
^(APPLY (^('.' e2=expression {expType = $e2.dotNetType; implicitThis = false;} i2=identifier)|i2=identifier) argument_list?)
|
||||||
{
|
{
|
||||||
if (expType != null && !expType.IsUnknownType) {
|
if (expType == null) {
|
||||||
$dotNetType = new UnknownRepTemplate(expType.TypeName+".APPLY");
|
expType = new UnknownRepTemplate("APPLY.BASE");
|
||||||
ResolveResult methodResult = expType.Resolve($i2.thetext, $argument_list.argTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
}
|
||||||
if (methodResult != null) {
|
if (expType.IsUnknownType) {
|
||||||
Debug($i2.tree.Token.Line + ": Found '" + $i2.thetext + "'");
|
WarningFailedResolve($i2.tree.Token.Line, "Could not find type needed to resolve method application");
|
||||||
MethodRepTemplate methodRep = methodResult.Result as MethodRepTemplate;
|
}
|
||||||
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
$dotNetType = new UnknownRepTemplate(expType.TypeName+".APPLY");
|
||||||
if (!implicitThis) {
|
ResolveResult methodResult = expType.Resolve($i2.thetext, $argument_list.argTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
||||||
myMap["this"] = wrapExpression($e2.tree, $i2.tree.Token);
|
if (methodResult != null) {
|
||||||
}
|
Debug($i2.tree.Token.Line + ": Found '" + $i2.thetext + "'");
|
||||||
for (int idx = 0; idx < methodRep.Params.Count; idx++) {
|
MethodRepTemplate methodRep = methodResult.Result as MethodRepTemplate;
|
||||||
myMap[methodRep.Params[idx].Name] = wrapArgument($argument_list.argTrees[idx], $i2.tree.Token);
|
Dictionary<string,CommonTree> myMap = new Dictionary<string,CommonTree>();
|
||||||
if (methodRep.Params[idx].Name.StartsWith("TYPEOF") && $argument_list.argTreeTypeofTypes[idx] != null) {
|
if (!implicitThis) {
|
||||||
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
|
myMap["this"] = wrapExpression($e2.tree, $i2.tree.Token);
|
||||||
myMap[methodRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($argument_list.argTreeTypeofTypes[idx], $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);
|
||||||
ret = mkJavaWrapper(methodResult.Result.Java, myMap, $i2.tree.Token);
|
if (methodRep.Params[idx].Name.StartsWith("TYPEOF") && $argument_list.argTreeTypeofTypes[idx] != null) {
|
||||||
AddToImports(methodResult.Result.Imports);
|
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
|
||||||
$dotNetType = methodResult.ResultType;
|
myMap[methodRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($argument_list.argTreeTypeofTypes[idx], $i2.tree.Token);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
WarningFailedResolve($i2.tree.Token.Line, "Could not resolve method application");
|
ret = mkJavaWrapper(methodResult.Result.Java, myMap, $i2.tree.Token);
|
||||||
}
|
AddToImports(methodResult.Result.Imports);
|
||||||
|
$dotNetType = methodResult.ResultType;
|
||||||
}
|
}
|
||||||
else {
|
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?)
|
| ^(APPLY {$primary_expression::parentIsApply = true; } expression {$primary_expression::parentIsApply = false; } argument_list?)
|
||||||
@ -565,6 +574,8 @@ scope {
|
|||||||
| ^(POSTDEC expression) { $dotNetType = $expression.dotNetType; }
|
| ^(POSTDEC expression) { $dotNetType = $expression.dotNetType; }
|
||||||
| ^(d1='.' e1=expression i1=identifier generic_argument_list?)
|
| ^(d1='.' e1=expression i1=identifier generic_argument_list?)
|
||||||
{
|
{
|
||||||
|
// TODO: generic_argument_list is ignored ....
|
||||||
|
|
||||||
// Possibilities:
|
// Possibilities:
|
||||||
// - accessing a property/field of some object
|
// - accessing a property/field of some object
|
||||||
// - a qualified type name
|
// - a qualified type name
|
||||||
@ -612,7 +623,7 @@ scope {
|
|||||||
// - part of 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 && !idType.IsUnknownType) {
|
if (idType != null) {
|
||||||
$dotNetType = idType;
|
$dotNetType = idType;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
@ -658,6 +669,9 @@ scope {
|
|||||||
{
|
{
|
||||||
ClassRepTemplate conType = $type.dotNetType as ClassRepTemplate;
|
ClassRepTemplate conType = $type.dotNetType as ClassRepTemplate;
|
||||||
$dotNetType = $type.dotNetType;
|
$dotNetType = $type.dotNetType;
|
||||||
|
if (conType == null) {
|
||||||
|
conType = new UnknownRepTemplate("CONSTRUCTOR");
|
||||||
|
}
|
||||||
ResolveResult conResult = conType.Resolve($argument_list.argTypes, AppEnv);
|
ResolveResult conResult = conType.Resolve($argument_list.argTypes, AppEnv);
|
||||||
if (conResult != null) {
|
if (conResult != null) {
|
||||||
ConstructorRepTemplate conRep = conResult.Result as ConstructorRepTemplate;
|
ConstructorRepTemplate conRep = conResult.Result as ConstructorRepTemplate;
|
||||||
@ -665,12 +679,20 @@ scope {
|
|||||||
for (int idx = 0; idx < conRep.Params.Count; idx++) {
|
for (int idx = 0; idx < conRep.Params.Count; idx++) {
|
||||||
myMap[conRep.Params[idx].Name] = wrapArgument($argument_list.argTrees[idx], $n.token);
|
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);
|
ret = mkJavaWrapper(conResult.Result.Java, myMap, $n.token);
|
||||||
AddToImports(conResult.Result.Imports);
|
AddToImports(conResult.Result.Imports);
|
||||||
$dotNetType = conResult.ResultType;
|
$dotNetType = conResult.ResultType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WarningFailedResolve($n.token.Line, "Could not resolve constructor");
|
WarningFailedResolve($n.token.Line, "Could not resolve constructor against " + conType.TypeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| 'new' (
|
| 'new' (
|
||||||
@ -697,7 +719,7 @@ primary_expression_part:
|
|||||||
| '++'
|
| '++'
|
||||||
| '--' ;
|
| '--' ;
|
||||||
access_identifier:
|
access_identifier:
|
||||||
access_operator type_or_generic ;
|
access_operator type_or_generic[""] ;
|
||||||
access_operator:
|
access_operator:
|
||||||
'.' | '->' ;
|
'.' | '->' ;
|
||||||
brackets_or_arguments:
|
brackets_or_arguments:
|
||||||
@ -864,37 +886,94 @@ commas:
|
|||||||
// Type Section
|
// Type Section
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
|
||||||
type_name returns [string name, TypeRepTemplate dotNetType]:
|
// i.e not a predefined type.
|
||||||
namespace_or_type_name { $name = $namespace_or_type_name.name; $dotNetType = findType($namespace_or_type_name.name, $namespace_or_type_name.tyargs); } ;
|
type_name returns [TypeRepTemplate dotNetType, List<CommonTree> argTrees, bool hasTyArgs]
|
||||||
namespace_or_type_name returns [string name, List<TypeRepTemplate> tyargs]
|
|
||||||
@init {
|
@init {
|
||||||
TypeRepTemplate tyRep = null;
|
$hasTyArgs = false;
|
||||||
}:
|
Dictionary<string,CommonTree> tyMap = new Dictionary<string,CommonTree>();
|
||||||
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
|
@after {
|
||||||
| ^(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); }
|
AddToImports($dotNetType.Imports);
|
||||||
-> { tyRep != null }? IDENTIFIER[$d.token, tyRep.Java]
|
}
|
||||||
-> ^($d $n1 $tg1)
|
:
|
||||||
|
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]
|
type_or_generic[String prefix] returns [TypeRepTemplate dotNetType, List<CommonTree> argTrees, bool hasTyArgs]
|
||||||
:
|
|
||||||
(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]
|
|
||||||
@init {
|
@init {
|
||||||
TypeRepTemplate tyRep = null;
|
$hasTyArgs = false;
|
||||||
|
$argTrees = new List<CommonTree>();
|
||||||
|
Dictionary<string,CommonTree> tyMap = new Dictionary<string,CommonTree>();
|
||||||
}
|
}
|
||||||
@after{
|
@after {
|
||||||
$thetext = $t.thetext;
|
AddToImports($dotNetType.Imports);
|
||||||
}:
|
}
|
||||||
t=identifier { tyRep = findType($t.thetext); if (tyRep != null) AddToImports(tyRep.Imports); }
|
:
|
||||||
-> { tyRep != null }? IDENTIFIER[$t.tree.Token, tyRep.Java]
|
// (identifier generic_argument_list) => t=identifier ga=generic_argument_list
|
||||||
-> $t;
|
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
|
qid: // qualified_identifier v2
|
||||||
^(access_operator qid type_or_generic)
|
^(access_operator qid type_or_generic[""])
|
||||||
| qid_start
|
| qid_start
|
||||||
;
|
;
|
||||||
qid_start:
|
qid_start:
|
||||||
@ -910,21 +989,22 @@ qid_start:
|
|||||||
qid_part:
|
qid_part:
|
||||||
access_identifier;
|
access_identifier;
|
||||||
|
|
||||||
generic_argument_list returns [List<TypeRepTemplate> argTypes]:
|
generic_argument_list returns [List<TypeRepTemplate> argTypes, List<CommonTree> argTrees]:
|
||||||
'<' type_arguments '>' { $argTypes = $type_arguments.tyTypes; };
|
'<' type_arguments '>' { $argTypes = $type_arguments.tyTypes; $argTrees = $type_arguments.argTrees; };
|
||||||
type_arguments returns [List<TypeRepTemplate> tyTypes]
|
type_arguments returns [List<TypeRepTemplate> tyTypes, List<CommonTree> argTrees]
|
||||||
@init {
|
@init {
|
||||||
$tyTypes = new List<TypeRepTemplate>();
|
$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
|
// 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 (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"]; } )
|
| '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]:
|
non_nullable_type returns [TypeRepTemplate dotNetType]:
|
||||||
type { $dotNetType = $type.dotNetType; } ;
|
type { $dotNetType = $type.dotNetType; } ;
|
||||||
@ -973,6 +1053,7 @@ assignment
|
|||||||
@init {
|
@init {
|
||||||
CommonTree ret = null;
|
CommonTree ret = null;
|
||||||
bool isThis = false;
|
bool isThis = false;
|
||||||
|
TypeRepTemplate expType = null;
|
||||||
}
|
}
|
||||||
@after {
|
@after {
|
||||||
if (ret != null)
|
if (ret != null)
|
||||||
@ -982,103 +1063,105 @@ assignment
|
|||||||
(^('.' se=expression i=identifier generic_argument_list?) | i=identifier { isThis = true;}) a=assignment_operator rhs=expression
|
(^('.' se=expression i=identifier generic_argument_list?) | i=identifier { isThis = true;}) a=assignment_operator rhs=expression
|
||||||
{
|
{
|
||||||
TypeRepTemplate seType = (isThis ? SymTabLookup("this") : $se.dotNetType);
|
TypeRepTemplate seType = (isThis ? SymTabLookup("this") : $se.dotNetType);
|
||||||
if (seType != null && !seType.IsUnknownType) {
|
if (seType == null) {
|
||||||
ResolveResult fieldResult = seType.Resolve($i.thetext, AppEnv);
|
seType = new UnknownRepTemplate("FIELD.BASE");
|
||||||
if (fieldResult != null && fieldResult.Result is PropRepTemplate) {
|
}
|
||||||
PropRepTemplate propRep = fieldResult.Result as PropRepTemplate;
|
if (seType.IsUnknownType) {
|
||||||
if (!String.IsNullOrEmpty(propRep.JavaSet)) {
|
WarningFailedResolve($i.tree.Token.Line, "Could not find type of expression for field /property access");
|
||||||
CommonTree newRhsExp = $rhs.tree;
|
}
|
||||||
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
ResolveResult fieldResult = seType.Resolve($i.thetext, AppEnv);
|
||||||
bool goodTx = true;
|
if (fieldResult != null) {
|
||||||
if ($a.tree.Token.Type != ASSIGN) {
|
if (fieldResult.Result is PropRepTemplate) {
|
||||||
if (!String.IsNullOrEmpty(propRep.JavaGet)) {
|
PropRepTemplate propRep = fieldResult.Result as PropRepTemplate;
|
||||||
// we have prop <op>= rhs
|
if (!String.IsNullOrEmpty(propRep.JavaSet)) {
|
||||||
// need to translate to setProp(getProp <op> rhs)
|
CommonTree newRhsExp = $rhs.tree;
|
||||||
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
||||||
if (!isThis)
|
bool goodTx = true;
|
||||||
rhsMap["this"] = wrapExpression($se.tree, $i.tree.Token);
|
if ($a.tree.Token.Type != ASSIGN) {
|
||||||
CommonTree rhsPropTree = mkJavaWrapper(propRep.JavaGet, rhsMap, $a.tree.Token);
|
if (!String.IsNullOrEmpty(propRep.JavaGet)) {
|
||||||
newRhsExp = mkOpExp(mkOpExp($a.tree), rhsPropTree, $rhs.tree);
|
// we have prop <op>= rhs
|
||||||
}
|
// need to translate to setProp(getProp <op> rhs)
|
||||||
else {
|
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
||||||
goodTx = false;
|
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>();
|
else {
|
||||||
if (!isThis)
|
goodTx = false;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Dictionary<string,CommonTree> valMap = new Dictionary<string,CommonTree>();
|
||||||
else {
|
if (!isThis)
|
||||||
WarningFailedResolve($i.tree.Token.Line, "Could not resolve field or property expression");
|
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 {
|
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 expression expression_list?) assignment_operator) =>
|
||||||
^(INDEX ie=expression expression_list?) ia=assignment_operator irhs=expression
|
^(INDEX ie=expression expression_list?) ia=assignment_operator irhs=expression
|
||||||
{
|
{
|
||||||
if ($ie.dotNetType != null && !$ie.dotNetType.IsUnknownType) {
|
expType = $ie.dotNetType ?? (new UnknownRepTemplate("INDEXER.BASE"));
|
||||||
ResolveResult indexerResult = $ie.dotNetType.ResolveIndexer($expression_list.expTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
if (expType.IsUnknownType) {
|
||||||
if (indexerResult != null) {
|
WarningFailedResolve($ie.tree.Token.Line, "Could not find type of expression for Indexer");
|
||||||
IndexerRepTemplate indexerRep = indexerResult.Result as IndexerRepTemplate;
|
}
|
||||||
if (!String.IsNullOrEmpty(indexerRep.JavaSet)) {
|
ResolveResult indexerResult = expType.ResolveIndexer($expression_list.expTypes ?? new List<TypeRepTemplate>(), AppEnv);
|
||||||
CommonTree newRhsExp = $irhs.tree;
|
if (indexerResult != null) {
|
||||||
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
IndexerRepTemplate indexerRep = indexerResult.Result as IndexerRepTemplate;
|
||||||
bool goodTx = true;
|
if (!String.IsNullOrEmpty(indexerRep.JavaSet)) {
|
||||||
if ($ia.tree.Token.Type != ASSIGN) {
|
CommonTree newRhsExp = $irhs.tree;
|
||||||
if (!String.IsNullOrEmpty(indexerRep.JavaGet)) {
|
// if assignment operator is a short cut operator then only translate if we also have JavaGet
|
||||||
// we have indexable[args] <op>= rhs
|
bool goodTx = true;
|
||||||
// need to translate to set___idx(args, get___idx(args) <op> rhs)
|
if ($ia.tree.Token.Type != ASSIGN) {
|
||||||
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
if (!String.IsNullOrEmpty(indexerRep.JavaGet)) {
|
||||||
rhsMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
// we have indexable[args] <op>= rhs
|
||||||
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
// need to translate to set___idx(args, get___idx(args) <op> rhs)
|
||||||
rhsMap[indexerRep.Params[idx].Name] = wrapArgument($expression_list.expTrees[idx], $ie.tree.Token);
|
Dictionary<string,CommonTree> rhsMap = new Dictionary<string,CommonTree>();
|
||||||
if (indexerRep.Params[idx].Name.StartsWith("TYPEOF") && $expression_list.expTreeTypeofTypes[idx] != null) {
|
rhsMap["this"] = wrapExpression($ie.tree, $ie.tree.Token);
|
||||||
// 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);
|
|
||||||
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
for (int idx = 0; idx < indexerRep.Params.Count; idx++) {
|
||||||
myMap[indexerRep.Params[idx].Name] = wrapArgument($expression_list.expTrees[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 (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
|
// 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 + "_TYPE"] = wrapTypeOfType($expression_list.expTreeTypeofTypes[idx], $ie.tree.Token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (goodTx) {
|
|
||||||
ret = mkJavaWrapper(indexerRep.JavaSet, myMap, $ie.tree.Token);
|
CommonTree rhsIdxTree = mkJavaWrapper(indexerRep.JavaGet, rhsMap, $ia.tree.Token);
|
||||||
AddToImports(indexerRep.Imports);
|
newRhsExp = mkOpExp(mkOpExp($ia.tree), rhsIdxTree, $irhs.tree);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
goodTx = false;
|
||||||
else {
|
}
|
||||||
WarningFailedResolve($ie.tree.Token.Line, "Could not resolve index expression");
|
}
|
||||||
}
|
|
||||||
|
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 {
|
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 ;
|
| 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_HEADER attributes? modifiers? type member_name type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list?);
|
||||||
method_body:
|
method_body:
|
||||||
block ;
|
block ;
|
||||||
member_name:
|
member_name
|
||||||
type_or_generic ('.' type_or_generic)*
|
@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
|
//(type '.') => type '.' identifier
|
||||||
//| identifier
|
//| identifier
|
||||||
;
|
;
|
||||||
|
@ -134,6 +134,7 @@ tokens {
|
|||||||
JAVAWRAPPER;
|
JAVAWRAPPER;
|
||||||
JAVAWRAPPEREXPRESSION;
|
JAVAWRAPPEREXPRESSION;
|
||||||
JAVAWRAPPERARGUMENT;
|
JAVAWRAPPERARGUMENT;
|
||||||
|
JAVAWRAPPERTYPE;
|
||||||
SEP;
|
SEP;
|
||||||
KGHOLE;
|
KGHOLE;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user