mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
big delegates commit. Autogenerated code for delegate support is pretty much done now
This commit is contained in:
parent
ff574c6af9
commit
84a767f445
209
CS2JLibrary/NetFramework/System/Collections/Generic/IList'1.xml
Normal file
209
CS2JLibrary/NetFramework/System/Collections/Generic/IList'1.xml
Normal file
@ -0,0 +1,209 @@
|
||||
<?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@twigletsoftware.com)
|
||||
|
||||
-->
|
||||
<Interface 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.List</Import>
|
||||
</Imports>
|
||||
<Java>List*[${T}]*</Java>
|
||||
<Name>System.Collections.Generic.IList</Name>
|
||||
<TypeParams>
|
||||
<Name>T</Name>
|
||||
</TypeParams>
|
||||
<Uses />
|
||||
<Inherits>
|
||||
<!-- <Type>IList<T>, ICollection<T>,
|
||||
IEnumerable<T>, IList, ICollection, IEnumerable</Type> -->
|
||||
</Inherits>
|
||||
<Iterable>
|
||||
<ElementType>T</ElementType>
|
||||
<Java>${expr}</Java>
|
||||
</Iterable>
|
||||
<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 />
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>rUong3D9EauJhCA+cIiWlGuXn08=</DigestValue></Reference></SignedInfo><SignatureValue>esb0vH9iEN6TefBNnLiampoglnuOe2oggi0NVh+r9eoUKf6vzAQCfNGubdlKaf8IausdKZ3wS212MtQtXkJ8TFKPjK+gOpmoVhFKd/6rPnT5xt89+N7s5cByTPW8epjPNnAH7pEiRbzk5+JpH/xKeNCCoGoADV4L/E0TIsZRCH4=</SignatureValue></Signature></Interface>
|
93
CS2JLibrary/src/CS2JNet/JavaSupport/util/ListSupport.java
Normal file
93
CS2JLibrary/src/CS2JNet/JavaSupport/util/ListSupport.java
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright 2010,2011 Kevin Glynn (kevin.glynn@twigletsoftware.com)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author(s):
|
||||
|
||||
Kevin Glynn (kevin.glynn@twigletsoftware.com)
|
||||
*/
|
||||
|
||||
package CS2JNet.JavaSupport.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author keving
|
||||
*
|
||||
*/
|
||||
public class ListSupport {
|
||||
|
||||
// If the sequence of elements in stretch appears in l, then returns a new list, a copy of l without
|
||||
// the final such sequence. Otherwise returns l.
|
||||
public static <T> List<T> removeFinalStretch(List<T> l, List<T> stretch) {
|
||||
List<T> ret = l;
|
||||
boolean found = true;
|
||||
int endIdx = l.size() - 1;
|
||||
while (endIdx >= stretch.size() - 1) {
|
||||
// is this the start of a sequence of stretch?
|
||||
found = true;
|
||||
for (int j = 0; j < stretch.size(); j++) {
|
||||
if (l.get(endIdx - j) != stretch.get(stretch.size() - j - 1)) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
endIdx--;
|
||||
}
|
||||
if (found) {
|
||||
// stretch starts at l(endIdx - stretch.size())
|
||||
// don't use subList, create a totally new list.
|
||||
ret = new ArrayList<T>(l.size() - stretch.size());
|
||||
for (int i = 0; i <= endIdx - stretch.size(); i++){
|
||||
ret.add(l.get(i));
|
||||
}
|
||||
for (int i = endIdx+1; i < l.size(); i++){
|
||||
ret.add(l.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<Integer> master = Arrays.asList(new Integer[] {0,1,2,3,4,5,1,2,3,4,5});
|
||||
List<Integer> find0 = Arrays.asList(new Integer[] {0});
|
||||
List<Integer> find1 = Arrays.asList(new Integer[] {2,3,4});
|
||||
List<Integer> find2 = Arrays.asList(new Integer[] {2,4});
|
||||
List<Integer> find3 = Arrays.asList(new Integer[] {4,5});
|
||||
|
||||
for (int i : removeFinalStretch(master,find0)) {
|
||||
System.out.printf("%1d ",i);
|
||||
}
|
||||
System.out.println();
|
||||
for (int i : removeFinalStretch(master,find1)) {
|
||||
System.out.printf("%1d ",i);
|
||||
}
|
||||
System.out.println();
|
||||
for (int i : removeFinalStretch(master,find2)) {
|
||||
System.out.printf("%1d ",i);
|
||||
}
|
||||
System.out.println();
|
||||
for (int i : removeFinalStretch(master,find3)) {
|
||||
System.out.printf("%1d ",i);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
@ -224,8 +224,9 @@ namespace Twiglet.CS2J.Utility
|
||||
MethodInfo invoker = t.GetMethod("Invoke");
|
||||
if (invoker == null)
|
||||
throw new Exception("Unexpected: class " + t.FullName + " inherits from System.Delegate but doesn't have an Invoke method");
|
||||
buildParameters(d.Params, invoker);
|
||||
d.Return = TypeHelper.buildTypeName(invoker.ReturnType);
|
||||
List<ParamRepTemplate> pars = new List<ParamRepTemplate>();
|
||||
buildParameters(pars, invoker);
|
||||
d.Invoke = new InvokeRepTemplate(TypeHelper.buildTypeName(invoker.ReturnType), "Invoke", null, pars);
|
||||
}
|
||||
|
||||
private IList<TypeRepTemplate> mkTemplates(string typeName)
|
||||
|
@ -11,6 +11,15 @@ namespace Twiglet.CS2J.Translator
|
||||
public class Fragments
|
||||
{
|
||||
|
||||
public static string DelegateObject(String delName, String args, String body)
|
||||
{
|
||||
return delegateObject.Replace("${D}",delName).Replace("${A}",args).Replace("${B}",body);
|
||||
}
|
||||
|
||||
private static string delegateObject = @"
|
||||
new ${D}() { public void Invoke(${A}) { ${B}; } }
|
||||
";
|
||||
|
||||
public static string GenericCollectorMethods(string T, string S)
|
||||
{
|
||||
return genericCollectorMethodsStr.Replace("${T}", T).Replace("${S}", S);
|
||||
@ -153,6 +162,39 @@ namespace Twiglet.CS2J.Translator
|
||||
}
|
||||
";
|
||||
|
||||
public static string MultiDelegateMethods(string Del, string DelClass, string TyArgs)
|
||||
{
|
||||
return multiDelegateMethodsStr.Replace("${Del}", Del).Replace("${DelClass}", DelClass).Replace("${TyArgs}", TyArgs);
|
||||
}
|
||||
|
||||
private static string multiDelegateMethodsStr = @"
|
||||
private System.Collections.Generic.IList<${Del}> _invocationList = new ArrayList<${Del}>();
|
||||
|
||||
public static ${Del} Combine ${TyArgs} (${Del} a, ${Del} b) throws Exception {
|
||||
${DelClass} ret = new ${DelClass}();
|
||||
ret._invocationList = a.GetInvocationList();
|
||||
ret._invocationList.addAll(b.GetInvocationList());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ${Del} Remove ${TyArgs} (${Del} a, ${Del} b) throws Exception {
|
||||
System.Collections.Generic.IList<${Del}> aInvList = a.GetInvocationList();
|
||||
System.Collections.Generic.IList<${Del}> newInvList = ListSupport.removeFinalStretch(aInvList, b.GetInvocationList());
|
||||
if (aInvList == newInvList) {
|
||||
return a;
|
||||
}
|
||||
else {
|
||||
${DelClass} ret = new ${DelClass}();
|
||||
ret._invocationList = newInvList;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public System.Collections.Generic.IList<${Del}> GetInvocationList() throws Exception {
|
||||
return _invocationList;
|
||||
}
|
||||
";
|
||||
|
||||
public static string GenIterator = @"
|
||||
public Iterator<${T}> iterator() {
|
||||
Iterator<${T}> ret = null;
|
||||
|
@ -279,7 +279,16 @@ braceblock(statements) ::= <<
|
||||
|
||||
cast_expr(type, exp) ::= ""(<type>)<exp>""
|
||||
construct(type, args, inits) ::= ""new <type>(<args>)<if(inits)> /* [UNIMPLEMENTED] <inits> */<endif>""
|
||||
array_construct(type, args, inits) ::= ""new <type><if(args)>[<args>]<endif><if(inits)><inits><endif>""
|
||||
delegate(type, args, body) ::= <<
|
||||
new <type>(<args>)
|
||||
{
|
||||
<body>
|
||||
}
|
||||
>>
|
||||
lambda(args, body) ::= <<
|
||||
(<args>) => <body>
|
||||
>>
|
||||
array_construct(type, args, inits) ::= ""new <type>[<if(args)><args><endif>]<if(inits)><inits><endif>""
|
||||
array_initializer(init) ::= ""{ <init> }""
|
||||
application(func, funcparens, args) ::= ""<optparens(parens=funcparens,e=func)>(<args>)""
|
||||
index(func, funcparens, args) ::= ""<optparens(parens=funcparens,e=func)>[<args>]""
|
||||
|
@ -897,6 +897,22 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
|
||||
}
|
||||
|
||||
public class InvokeRepTemplate : MethodRepTemplate
|
||||
{
|
||||
public InvokeRepTemplate()
|
||||
{
|
||||
|
||||
}
|
||||
public InvokeRepTemplate (string retType, string methodName, string[] tParams, List<ParamRepTemplate> pars) : base(retType, methodName, tParams, pars)
|
||||
{
|
||||
}
|
||||
|
||||
public override string mkJava()
|
||||
{
|
||||
return "${this:16}.Invoke" + mkJavaParams(this.Params);
|
||||
}
|
||||
}
|
||||
|
||||
// A user-defined cast from one type to another
|
||||
public class CastRepTemplate : TranslationBase, IEquatable<CastRepTemplate>
|
||||
{
|
||||
@ -2540,41 +2556,16 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
[XmlType("Delegate")]
|
||||
public class DelegateRepTemplate : TypeRepTemplate, IEquatable<DelegateRepTemplate>
|
||||
{
|
||||
private List<ParamRepTemplate> _params = null;
|
||||
[XmlArrayItem("Param")]
|
||||
public List<ParamRepTemplate> Params {
|
||||
private InvokeRepTemplate _invoke = null;
|
||||
public InvokeRepTemplate Invoke {
|
||||
get {
|
||||
if (_params == null)
|
||||
_params = new List<ParamRepTemplate> ();
|
||||
return _params;
|
||||
return _invoke;
|
||||
}
|
||||
set {
|
||||
_params = value;
|
||||
_invoke = value;
|
||||
}
|
||||
}
|
||||
|
||||
private string _return;
|
||||
public string Return {
|
||||
get { return _return; }
|
||||
set {
|
||||
_return=value.Replace("<","*[").Replace(">","]*");
|
||||
}
|
||||
}
|
||||
|
||||
protected string _javaInvoke = null;
|
||||
[XmlElementAttribute("Invoke")]
|
||||
public virtual string JavaInvoke {
|
||||
get {
|
||||
if (_javaInvoke == null) {
|
||||
return "${this:16}.Invoke" + mkJavaParams(Params);
|
||||
}
|
||||
else {
|
||||
return _javaInvoke;
|
||||
}
|
||||
}
|
||||
set { _javaInvoke = value; }
|
||||
}
|
||||
|
||||
public DelegateRepTemplate()
|
||||
: base()
|
||||
{
|
||||
@ -2583,41 +2574,15 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public DelegateRepTemplate(DelegateRepTemplate copyFrom)
|
||||
: base(copyFrom)
|
||||
{
|
||||
foreach (ParamRepTemplate p in copyFrom.Params)
|
||||
if (copyFrom.Invoke != null)
|
||||
{
|
||||
Params.Add(new ParamRepTemplate(p));
|
||||
Invoke = copyFrom.Invoke;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(copyFrom.Return))
|
||||
{
|
||||
Return = copyFrom.Return;
|
||||
}
|
||||
if (!String.IsNullOrEmpty(copyFrom.JavaInvoke))
|
||||
{
|
||||
JavaInvoke = copyFrom.JavaInvoke;
|
||||
}
|
||||
}
|
||||
|
||||
public DelegateRepTemplate(string retType, List<ParamRepTemplate> args)
|
||||
: base()
|
||||
{
|
||||
Return = retType;
|
||||
_params = args;
|
||||
}
|
||||
|
||||
public override void Apply(Dictionary<string,TypeRepTemplate> args)
|
||||
{
|
||||
if (Params != null)
|
||||
{
|
||||
foreach(ParamRepTemplate p in Params)
|
||||
{
|
||||
p.Apply(args);
|
||||
}
|
||||
}
|
||||
if (Return != null)
|
||||
{
|
||||
Return = TemplateUtilities.SubstituteInType(Return, args);
|
||||
}
|
||||
Invoke.Apply(args);
|
||||
base.Apply(args);
|
||||
}
|
||||
public override TypeRepTemplate Instantiate(ICollection<TypeRepTemplate> args)
|
||||
@ -2633,16 +2598,7 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
if (Params != other.Params) {
|
||||
if (Params == null || other.Params == null || Params.Count != other.Params.Count)
|
||||
return false;
|
||||
for (int i = 0; i < Params.Count; i++) {
|
||||
if (Params[i] != other.Params[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Return == other.Return && JavaInvoke == other.JavaInvoke && base.Equals(other);
|
||||
return Invoke == other.Invoke && base.Equals(other);
|
||||
}
|
||||
|
||||
public override bool Equals (object obj)
|
||||
@ -2668,12 +2624,8 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
int hashCode = base.GetHashCode ();
|
||||
if (Params != null) {
|
||||
foreach (ParamRepTemplate e in Params) {
|
||||
hashCode ^= e.GetHashCode();
|
||||
}
|
||||
}
|
||||
return (Return ?? String.Empty).GetHashCode() ^ (JavaInvoke ?? String.Empty).GetHashCode() ^ hashCode;
|
||||
|
||||
return (Invoke ?? new InvokeRepTemplate()).GetHashCode() ^ hashCode;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@ -2897,6 +2849,56 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
}
|
||||
}
|
||||
}
|
||||
// Look for a property which holds a delegate with the right type
|
||||
if (Properties != null)
|
||||
{
|
||||
foreach (PropRepTemplate p in Properties)
|
||||
{
|
||||
if (p.Name == name)
|
||||
{
|
||||
// Is p's type a delegate?
|
||||
DelegateRepTemplate del = BuildType(p.Type, AppEnv, null) as DelegateRepTemplate;
|
||||
if (del != null)
|
||||
{
|
||||
bool matchingArgs = true;
|
||||
if (del.Invoke.Params == null || args == null)
|
||||
{
|
||||
// Are they both zero length?
|
||||
matchingArgs = (del.Invoke.Params == null || del.Invoke.Params.Count == 0) && (args == null || args.Count == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Are num args the same?
|
||||
if (del.Invoke.Params.Count != args.Count)
|
||||
{
|
||||
matchingArgs = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check that for each argument in the caller its type 'IsA' the type of the formal argument
|
||||
for (int idx = 0; idx < del.Invoke.Params.Count; idx++) {
|
||||
if (args[idx] == null || !args[idx].IsA(BuildType(del.Invoke.Params[idx].Type, AppEnv, new UnknownRepTemplate(del.Invoke.Params[idx].Type)),AppEnv))
|
||||
{
|
||||
matchingArgs = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchingArgs)
|
||||
{
|
||||
ResolveResult delRes = new ResolveResult();
|
||||
delRes.Result = del;
|
||||
delRes.ResultType = BuildType(del.Invoke.Return, AppEnv);
|
||||
DelegateResolveResult res = new DelegateResolveResult();
|
||||
res.Result = p;
|
||||
res.ResultType = BuildType(p.Type, AppEnv);
|
||||
res.DelegateResult = delRes;
|
||||
return res; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return base.Resolve(name, args, AppEnv);
|
||||
}
|
||||
|
||||
@ -3202,6 +3204,63 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
}
|
||||
|
||||
|
||||
public override ResolveResult Resolve(String name, List<TypeRepTemplate> args, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
|
||||
// Look for a property which holds a delegate with the right type
|
||||
if (Fields != null)
|
||||
{
|
||||
foreach (FieldRepTemplate f in Fields)
|
||||
{
|
||||
if (f.Name == name)
|
||||
{
|
||||
// Is f's type a delegate?
|
||||
DelegateRepTemplate del = BuildType(f.Type, AppEnv, null) as DelegateRepTemplate;
|
||||
if (del != null)
|
||||
{
|
||||
bool matchingArgs = true;
|
||||
if (del.Invoke.Params == null || args == null)
|
||||
{
|
||||
// Are they both zero length?
|
||||
matchingArgs = (del.Invoke.Params == null || del.Invoke.Params.Count == 0) && (args == null || args.Count == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Are num args the same?
|
||||
if (del.Invoke.Params.Count != args.Count)
|
||||
{
|
||||
matchingArgs = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check that for each argument in the caller its type 'IsA' the type of the formal argument
|
||||
for (int idx = 0; idx < del.Invoke.Params.Count; idx++) {
|
||||
if (args[idx] == null || !args[idx].IsA(BuildType(del.Invoke.Params[idx].Type, AppEnv, new UnknownRepTemplate(del.Invoke.Params[idx].Type)),AppEnv))
|
||||
{
|
||||
matchingArgs = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchingArgs)
|
||||
{
|
||||
ResolveResult delRes = new ResolveResult();
|
||||
delRes.Result = del;
|
||||
delRes.ResultType = BuildType(del.Invoke.Return, AppEnv);
|
||||
DelegateResolveResult res = new DelegateResolveResult();
|
||||
res.Result = f;
|
||||
res.ResultType = BuildType(f.Type, AppEnv);
|
||||
res.DelegateResult = delRes;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return base.Resolve(name, args, AppEnv);
|
||||
}
|
||||
|
||||
public override ResolveResult Resolve(String name, bool forWrite, DirectoryHT<TypeRepTemplate> AppEnv)
|
||||
{
|
||||
|
||||
@ -3585,6 +3644,13 @@ namespace Twiglet.CS2J.Translator.TypeRep
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Used when the result of resolving the callee of an APPLY node is a pointer to a delegate
|
||||
public class DelegateResolveResult : ResolveResult
|
||||
{
|
||||
public ResolveResult DelegateResult
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -190,6 +190,99 @@ scope TypeContext {
|
||||
return root;
|
||||
}
|
||||
|
||||
protected CommonTree mkGenericArgs(IToken tok, List<string> tyVars) {
|
||||
if (tyVars == null || tyVars.Count == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CommonTree root = (CommonTree)adaptor.Nil;
|
||||
adaptor.AddChild(root, (CommonTree)adaptor.Create(LTHAN, tok, "<"));
|
||||
bool isFirst = true;
|
||||
foreach (string v in tyVars) {
|
||||
if (!isFirst) {
|
||||
adaptor.AddChild(root, (CommonTree)adaptor.Create(COMMA, tok, ","));
|
||||
}
|
||||
isFirst = false;
|
||||
CommonTree ty = (CommonTree)adaptor.Nil;
|
||||
ty = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(TYPE, tok, "TYPE"), ty);
|
||||
adaptor.AddChild(ty, (CommonTree)adaptor.Create(IDENTIFIER, tok, v));
|
||||
adaptor.AddChild(root, ty);
|
||||
}
|
||||
adaptor.AddChild(root, (CommonTree)adaptor.Create(GT, tok, ">"));
|
||||
return root;
|
||||
|
||||
}
|
||||
|
||||
protected CommonTree mkPackage(IToken tok, CommonTree tree, String nameSpace) {
|
||||
|
||||
CommonTree root = (CommonTree)adaptor.Nil;
|
||||
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(PACKAGE, tok, "package"), root);
|
||||
adaptor.AddChild(root, (CommonTree)adaptor.Create(PAYLOAD, tok, nameSpace));
|
||||
adaptor.AddChild(root, dupTree(tree));
|
||||
return root;
|
||||
}
|
||||
|
||||
protected CommonTree mkFlattenDictionary(IToken tok, Dictionary<string,CommonTree> treeDict) {
|
||||
|
||||
CommonTree root = (CommonTree)adaptor.Nil;
|
||||
foreach (CommonTree tree in treeDict.Values) {
|
||||
if (tree != null) {
|
||||
adaptor.AddChild(root, dupTree(tree));
|
||||
}
|
||||
}
|
||||
root = (CommonTree)adaptor.RulePostProcessing(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
protected CommonTree mkArgsFromParams(IToken tok, CommonTree pars) {
|
||||
CommonTree root = (CommonTree)adaptor.Nil;
|
||||
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(ARGS, tok, "ARGS"), root);
|
||||
|
||||
// take every second child
|
||||
for (int i = 1; i < adaptor.GetChildCount(pars); i+=2) {
|
||||
adaptor.AddChild(root, dupTree((CommonTree)adaptor.GetChild(pars, i)));
|
||||
}
|
||||
root = (CommonTree)adaptor.RulePostProcessing(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
protected CommonTree mkType(IToken tok, CommonTree id, List<String> tyVars) {
|
||||
|
||||
CommonTree root = (CommonTree)adaptor.Nil;
|
||||
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(TYPE, tok, "TYPE"), root);
|
||||
adaptor.AddChild(root, dupTree(id));
|
||||
|
||||
if (tyVars != null && tyVars.Count > 0) {
|
||||
adaptor.AddChild(root, mkGenericArgs(tok, tyVars));
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected string mkTypeString(string tyName, List<String> tyargs) {
|
||||
StringBuilder ty = new StringBuilder();
|
||||
ty.Append(tyName);
|
||||
ty.Append(mkTypeArgString(tyargs));
|
||||
return ty.ToString();
|
||||
}
|
||||
|
||||
protected string mkTypeArgString(List<String> tyargs) {
|
||||
StringBuilder ty = new StringBuilder();
|
||||
if (tyargs != null && tyargs.Count > 0) {
|
||||
ty.Append("<");
|
||||
bool isFirst = true;
|
||||
foreach (String v in tyargs) {
|
||||
if (!isFirst) {
|
||||
ty.Append(",");
|
||||
}
|
||||
isFirst = false;
|
||||
ty.Append(v);
|
||||
}
|
||||
ty.Append(">");
|
||||
}
|
||||
return ty.ToString();
|
||||
}
|
||||
|
||||
// for ["conn", "conn1", "conn2"] generate:
|
||||
//
|
||||
// if (conn != null)
|
||||
@ -384,31 +477,38 @@ namespace_member_declaration
|
||||
}
|
||||
@after {
|
||||
if (isCompUnit) {
|
||||
if (CUKeys.Contains(ns+"."+$ty.name)) {
|
||||
{ Warning($ty.start.Token.Line, "[UNSUPPORTED] Cannot have a class with multiple generic type overloadings: " + ns+"."+$ty.name); }
|
||||
}
|
||||
else {
|
||||
CUMap.Add(ns+"."+$ty.name, new CUnit($namespace_member_declaration.tree,CollectSearchPath,CollectAliasKeys,CollectAliasNamespaces));
|
||||
CUKeys.Add(ns+"."+$ty.name);
|
||||
}
|
||||
};
|
||||
}
|
||||
:
|
||||
foreach (KeyValuePair<String, CommonTree> treeEntry in $ty.compUnits) {
|
||||
if (treeEntry.Value != null) {
|
||||
if (CUKeys.Contains(ns+"."+treeEntry.Key)) {
|
||||
{ Warning(treeEntry.Value.Token.Line, "[UNSUPPORTED] Cannot have a class with multiple generic type overloadings: " + ns+"."+treeEntry.Key); }
|
||||
}
|
||||
else {
|
||||
CUMap.Add(ns+"."+treeEntry.Key, new CUnit(mkPackage(treeEntry.Value.Token, treeEntry.Value, ns),CollectSearchPath,CollectAliasKeys,CollectAliasNamespaces));
|
||||
CUKeys.Add(ns+"."+treeEntry.Key);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}:
|
||||
namespace_declaration
|
||||
| attributes? modifiers? ty=type_declaration[$attributes.tree, mangleModifiersForType($modifiers.tree)] { isCompUnit = true; } -> ^(PACKAGE[$ty.start.Token, "package"] PAYLOAD[ns] $ty);
|
||||
| attributes? modifiers? ty=type_declaration[$attributes.tree, mangleModifiersForType($modifiers.tree)] { isCompUnit = true; }
|
||||
;
|
||||
// type_declaration is only called at the top level, so each of the types declared
|
||||
// here will become a Java compilation unit (and go to its own file)
|
||||
type_declaration[CommonTree atts, CommonTree mods] returns [string name]
|
||||
type_declaration[CommonTree atts, CommonTree mods] returns [Dictionary<String,CommonTree> compUnits]
|
||||
@init {
|
||||
$compUnits = new Dictionary<String,CommonTree>();
|
||||
}
|
||||
:
|
||||
('partial') => p='partial'! { Warning($p.line, "[UNSUPPORTED] 'partial' definition"); }
|
||||
(pc=class_declaration[$atts, $mods, true /* toplevel */] { $name=$pc.name; }
|
||||
| ps=struct_declaration[$atts, $mods, true /* toplevel */] { $name=$ps.name; }
|
||||
| pi=interface_declaration[$atts, $mods] { $name=$pi.name; })
|
||||
| c=class_declaration[$atts, $mods, true /* toplevel */] { $name=$c.name; }
|
||||
| s=struct_declaration[$atts, $mods, true /* toplevel */] { $name=$s.name; }
|
||||
| i=interface_declaration[$atts, $mods] { $name=$i.name; }
|
||||
| e=enum_declaration[$atts, $mods] { $name=$e.name; }
|
||||
| d=delegate_declaration[$atts, $mods] { $name=$d.name; }
|
||||
(pc=class_declaration[$atts, $mods, true /* toplevel */] { $compUnits.Add($pc.name, $pc.tree); }
|
||||
| ps=struct_declaration[$atts, $mods, true /* toplevel */] { $compUnits.Add($ps.name, $ps.tree); }
|
||||
| pi=interface_declaration[$atts, $mods] { $compUnits.Add($pi.name, $pi.tree); } )
|
||||
| c=class_declaration[$atts, $mods, true /* toplevel */] { $compUnits.Add($c.name, $c.tree); }
|
||||
| s=struct_declaration[$atts, $mods, true /* toplevel */] { $compUnits.Add($s.name, $s.tree); }
|
||||
| i=interface_declaration[$atts, $mods] { $compUnits.Add($i.name, $i.tree); }
|
||||
| e=enum_declaration[$atts, $mods] { $compUnits.Add($e.name, $e.tree); }
|
||||
| d=delegate_declaration[$atts, $mods] { $compUnits = $d.compUnits; }
|
||||
;
|
||||
// Identifiers
|
||||
qualified_identifier returns [string thetext]:
|
||||
@ -448,7 +548,7 @@ class_member_declaration:
|
||||
| cd=class_declaration[$a.tree, $m.tree, false /* toplevel */] -> $cd
|
||||
| sd=struct_declaration[$a.tree, $m.tree, false /* toplevel */] -> $sd
|
||||
| ed=enum_declaration[$a.tree, $m.tree] -> $ed
|
||||
| dd=delegate_declaration[$a.tree, $m.tree] -> $dd
|
||||
| dd=delegate_declaration[$a.tree, $m.tree] -> { mkFlattenDictionary($dd.tree.Token,$dd.compUnits) }
|
||||
| co3=conversion_operator_declaration -> ^(CONVERSION_OPERATOR[$co3.start.Token, "CONVERSION"] $a? $m? $co3)
|
||||
| con3=constructor_declaration[$a.tree, $m.tree, $m.modList] -> $con3
|
||||
| de3=destructor_declaration -> $de3
|
||||
@ -462,12 +562,8 @@ primary_expression:
|
||||
// keving:TODO fixup
|
||||
| 'new' ( (object_creation_expression ('.'|'->'|'[')) =>
|
||||
(oc1=object_creation_expression -> $oc1) (pp4=primary_expression_part[ $primary_expression.tree ] -> $pp4 )+ // new Foo(arg, arg).Member
|
||||
// try the simple one first, this has no argS and no expressions
|
||||
// symantically could be object creation
|
||||
// keving: No, try object_creation_expression first, it could be new type ( xx ) {}
|
||||
// can also match delegate_creation, will have to distinguish in NetMaker.g
|
||||
| (object_creation_expression) => oc2=object_creation_expression -> $oc2
|
||||
| delegate_creation_expression -> delegate_creation_expression // new FooDelegate (MyFunction)
|
||||
// | delegate_creation_expression -> delegate_creation_expression // new FooDelegate (MyFunction)
|
||||
| anonymous_object_creation_expression -> anonymous_object_creation_expression) // new {int X, string Y}
|
||||
| sizeof_expression // sizeof (struct)
|
||||
| checked_expression // checked (...
|
||||
@ -617,9 +713,9 @@ unchecked_expression:
|
||||
default_value_expression:
|
||||
'default'^ '('! type ')'! ;
|
||||
anonymous_method_expression:
|
||||
'delegate'^ explicit_anonymous_function_signature? block;
|
||||
'delegate'^ explicit_anonymous_function_signature? block;
|
||||
explicit_anonymous_function_signature:
|
||||
'(' explicit_anonymous_function_parameter_list? ')' ;
|
||||
'(' explicit_anonymous_function_parameter_list? ')' -> ^(PARAMS explicit_anonymous_function_parameter_list?);
|
||||
explicit_anonymous_function_parameter_list:
|
||||
explicit_anonymous_function_parameter (',' explicit_anonymous_function_parameter)* ;
|
||||
explicit_anonymous_function_parameter:
|
||||
@ -875,16 +971,16 @@ conditional_expression:
|
||||
lambda_expression:
|
||||
anonymous_function_signature '=>' anonymous_function_body;
|
||||
anonymous_function_signature:
|
||||
'(' (explicit_anonymous_function_parameter_list
|
||||
| implicit_anonymous_function_parameter_list)? ')'
|
||||
| implicit_anonymous_function_parameter_list
|
||||
'(' (explicit_anonymous_function_parameter_list -> ^(PARAMS explicit_anonymous_function_parameter_list)
|
||||
| implicit_anonymous_function_parameter_list -> ^(PARAMS_TYPELESS implicit_anonymous_function_parameter_list))? ')'
|
||||
| implicit_anonymous_function_parameter_list -> ^(PARAMS_TYPELESS implicit_anonymous_function_parameter_list)
|
||||
;
|
||||
implicit_anonymous_function_parameter_list:
|
||||
implicit_anonymous_function_parameter (',' implicit_anonymous_function_parameter)* ;
|
||||
implicit_anonymous_function_parameter:
|
||||
identifier;
|
||||
anonymous_function_body:
|
||||
expression
|
||||
expression -> OPEN_BRACE[$expression.tree.Token, "{"] expression CLOSE_BRACE[$expression.tree.Token, "}"]
|
||||
| block ;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
@ -1107,8 +1203,13 @@ method_body [bool smotherExceptions] returns [CommonTree exceptionList]:
|
||||
;
|
||||
|
||||
throw_exceptions:
|
||||
{IsJavaish}?=> 'throws'! t1=identifier { $t1.tree.Type = EXCEPTION; } (','! tn=identifier { $tn.tree.Type = EXCEPTION; } )*
|
||||
{IsJavaish}?=> 'throws'! javaException (','! javaException)*
|
||||
;
|
||||
|
||||
javaException:
|
||||
identifier -> EXCEPTION[$identifier.tree.Token, $identifier.tree.Token.Text]
|
||||
;
|
||||
|
||||
member_name returns [string rawId, string full_name]
|
||||
@init {
|
||||
$full_name = "";
|
||||
@ -1234,14 +1335,39 @@ integral_type:
|
||||
'sbyte' | 'byte' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' | 'char' ;
|
||||
|
||||
// B.2.12 Delegates
|
||||
delegate_declaration[CommonTree atts, CommonTree mods] returns [string name]
|
||||
delegate_declaration[CommonTree atts, CommonTree mods] returns [Dictionary<String, CommonTree> compUnits]
|
||||
scope TypeContext;
|
||||
@init {
|
||||
$compUnits = new Dictionary<String,CommonTree>();
|
||||
CommonTree delClassMemberNodes = null;
|
||||
CommonTree ifTree = null;
|
||||
String delName = "";
|
||||
String multiDelName = "";
|
||||
}
|
||||
@after {
|
||||
$compUnits.Add(delName, dupTree($delegate_declaration.tree));
|
||||
}
|
||||
:
|
||||
d='delegate' return_type identifier { $name = $identifier.text; $TypeContext::typeName = $identifier.text; } variant_generic_parameter_list?
|
||||
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' magicInvoker[$d.token, $return_type.tree, $identifier.tree, $formal_parameter_list.tree] ->
|
||||
d='delegate' return_type identifier { delName = $identifier.text; $TypeContext::typeName = $identifier.text; } variant_generic_parameter_list? {ifTree = mkType($d.token, $identifier.tree, $variant_generic_parameter_list.tyargs); }
|
||||
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';'
|
||||
magicDelegateInterface[$d.token, $return_type.tree, $identifier.tree, $formal_parameter_list.tree, $variant_generic_parameter_list.tyargs]
|
||||
magicMultiInvokerMethod[$d.token, $return_type.tree, $return_type.thetext == "Void" || $return_type.thetext == "System.Void", ifTree, $formal_parameter_list.tree, mkArgsFromParams($d.token, $formal_parameter_list.tree), $variant_generic_parameter_list.tyargs]
|
||||
{
|
||||
multiDelName = "__Multi" + delName;
|
||||
delClassMemberNodes = this.parseString("class_member_declarations", Fragments.MultiDelegateMethods(mkTypeString(delName, $variant_generic_parameter_list.tyargs), mkTypeString(multiDelName, $variant_generic_parameter_list.tyargs),mkTypeArgString($variant_generic_parameter_list.tyargs)));
|
||||
AddToImports("java.util.List");
|
||||
AddToImports("java.util.ArrayList");
|
||||
AddToImports("CS2JNet.JavaSupport.util.ListSupport");
|
||||
}
|
||||
magicMultiDelClass[$d.token, $atts, $mods, multiDelName, ifTree, $type_parameter_constraints_clauses.tree, $variant_generic_parameter_list.tree, $magicMultiInvokerMethod.tree, delClassMemberNodes]
|
||||
{
|
||||
$compUnits.Add(multiDelName, $magicMultiDelClass.tree);
|
||||
}
|
||||
->
|
||||
// ^(DELEGATE[$d.token, "DELEGATE"] { dupTree($atts) } { dupTree($mods) } return_type identifier type_parameter_constraints_clauses? variant_generic_parameter_list?
|
||||
// '(' formal_parameter_list? ')' );
|
||||
^(INTERFACE[$d.token, "interface"] { dupTree($atts) } { dupTree($mods) } identifier type_parameter_constraints_clauses? variant_generic_parameter_list? magicInvoker);
|
||||
^(INTERFACE[$d.token, "interface"] { dupTree($atts) } { dupTree($mods) } identifier { dupTree($type_parameter_constraints_clauses.tree) } { dupTree($variant_generic_parameter_list.tree) } magicDelegateInterface)
|
||||
;
|
||||
delegate_modifiers:
|
||||
modifier+ ;
|
||||
// 4.0
|
||||
@ -1279,9 +1405,9 @@ type_variable_name:
|
||||
// keving: TOTEST we drop new constraints, but what will happen in Java for this case?
|
||||
constructor_constraint:
|
||||
'new' '(' ')' ;
|
||||
return_type:
|
||||
type
|
||||
| void_type ;
|
||||
return_type returns [string thetext]:
|
||||
type {$thetext = $type.thetext; }
|
||||
| void_type {$thetext = "System.Void"; };
|
||||
formal_parameter_list returns [int numArgs]
|
||||
@init {
|
||||
$numArgs = 0;
|
||||
@ -1917,9 +2043,59 @@ magicThrowsException[bool isOn, IToken tok]:
|
||||
->
|
||||
;
|
||||
|
||||
magicInvoker[IToken tok, CommonTree return_type, CommonTree identifier, CommonTree formal_parameter_list]:
|
||||
magicThrowsException[true, tok]
|
||||
-> OPEN_BRACE[tok, "{"]
|
||||
^(METHOD[tok, "METHOD"] { dupTree(return_type) } IDENTIFIER[tok,"Invoke"] { dupTree(formal_parameter_list) } magicThrowsException)
|
||||
magicDelegateInterface[IToken tok, CommonTree return_type, CommonTree identifier, CommonTree formal_parameter_list, List<String> tyArgs]
|
||||
@init {
|
||||
AddToImports("java.util.List");
|
||||
}:
|
||||
e1=magicThrowsException[true, tok]
|
||||
e2=magicThrowsException[true, tok]
|
||||
-> OPEN_BRACE[tok, "{"] // System.Collections.Generic.IList
|
||||
^(METHOD[tok, "METHOD"] { dupTree(return_type) } IDENTIFIER[tok,"Invoke"] { dupTree(formal_parameter_list) } $e1)
|
||||
^(METHOD[tok, "METHOD"] ^(TYPE ^(DOT[tok, "."] ^(DOT[tok, "."] ^(DOT[tok, "."] IDENTIFIER[tok, "System"] IDENTIFIER[tok, "Collections"]) IDENTIFIER[tok, "Generic"]) IDENTIFIER[tok, "IList"] LTHAN[tok,"<"] ^(TYPE { dupTree( identifier) } { mkGenericArgs(tok, tyArgs) }) GT[tok,">"])) IDENTIFIER[tok,"GetInvocationList"] $e2)
|
||||
CLOSE_BRACE[tok, "}"]
|
||||
;
|
||||
|
||||
// First execute all but the last one, then execute the last one and (if non-void) return its result.
|
||||
magicMultiInvokerMethod[IToken tok, CommonTree return_type, bool retIsVoid, CommonTree type, CommonTree formal_parameter_list, CommonTree argument_list, List<String> tyArgs]
|
||||
:
|
||||
e1=magicThrowsException[true, tok]
|
||||
-> {retIsVoid}?
|
||||
^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
||||
OPEN_BRACE[tok, "{"]
|
||||
^(FOREACH[tok, "foreach"]
|
||||
{ $type } IDENTIFIER[tok, "d"] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"]))
|
||||
SEP[tok, "SEP"]
|
||||
OPEN_BRACE[tok, "{"]
|
||||
^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"d"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"]
|
||||
CLOSE_BRACE[tok, "}"]
|
||||
)
|
||||
CLOSE_BRACE[tok, "}"]
|
||||
magicThrowsException
|
||||
)
|
||||
-> ^(METHOD[tok, "METHOD"] PUBLIC[tok, "public"] { dupTree($return_type) } IDENTIFIER[tok,"Invoke"] { dupTree($formal_parameter_list) }
|
||||
OPEN_BRACE[tok, "{"]
|
||||
{ $type } IDENTIFIER[tok, "prev"] ASSIGN[tok, "="] NULL[tok, "null"] SEMI[tok,";"]
|
||||
^(FOREACH[tok, "foreach"]
|
||||
{ $type } IDENTIFIER[tok, "d"] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] THIS[tok,"this"] IDENTIFIER[tok,"GetInvocationList"]))
|
||||
SEP[tok, "SEP"]
|
||||
OPEN_BRACE[tok, "{"]
|
||||
^(IF[tok, "if"] ^(NOT_EQUAL[tok, "!="] IDENTIFIER[tok,"prev"] NULL[tok, "null"]) SEP ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"prev"] IDENTIFIER[tok,"Invoke"]) { $argument_list }) SEMI[tok, ";"])
|
||||
IDENTIFIER[tok, "prev"] ASSIGN[tok, "="] IDENTIFIER[tok, "d"] SEMI[tok,";"]
|
||||
CLOSE_BRACE[tok, "}"]
|
||||
)
|
||||
^(RETURN[tok, "return"] ^(APPLY[tok, "APPLY"] ^(DOT[tok,"."] IDENTIFIER[tok,"prev"] IDENTIFIER[tok,"Invoke"]) { $argument_list }))
|
||||
CLOSE_BRACE[tok, "}"]
|
||||
magicThrowsException
|
||||
)
|
||||
;
|
||||
|
||||
magicPackage[IToken tok, CommonTree cu, String ns]:
|
||||
-> { $cu != null }? ^(PACKAGE[tok, "package"] PAYLOAD[tok, ns] { dupTree(cu) })
|
||||
->
|
||||
;
|
||||
|
||||
magicMultiDelClass[IToken tok, CommonTree atts, CommonTree mods, string className, CommonTree delIface, CommonTree paramConstraints, CommonTree tyParamList, CommonTree invokeMethod, CommonTree members]:
|
||||
-> ^(CLASS[tok, "class"] { dupTree($atts) } { dupTree($mods) } IDENTIFIER[tok, className] { dupTree(paramConstraints) } { dupTree(tyParamList) } ^(IMPLEMENTS[tok, "implements"] { dupTree(delIface) })
|
||||
OPEN_BRACE[tok, "{"] {dupTree(invokeMethod)} { dupTree(members) } CLOSE_BRACE[tok, "}"])
|
||||
;
|
||||
|
||||
|
@ -156,6 +156,7 @@ options {
|
||||
precedence[i] = int.MaxValue;
|
||||
}
|
||||
precedence[ASSIGN] = 1;
|
||||
precedence[LAMBDA] = 1;
|
||||
precedence[PLUS_ASSIGN] = 1;
|
||||
precedence[MINUS_ASSIGN] = 1;
|
||||
precedence[STAR_ASSIGN] = 1;
|
||||
@ -378,7 +379,7 @@ primary_expression returns [int precedence]
|
||||
// | ('base' brackets) => 'this' brackets primary_expression_part*
|
||||
// | primary_expression_start primary_expression_part*
|
||||
| ^(NEW type argument_list? object_or_collection_initializer?) { $precedence = precedence[NEW]; }-> construct(type = {$type.st}, args = {$argument_list.st}, inits = {$object_or_collection_initializer.st})
|
||||
| ^(NEW_DELEGATE delegate_creation_expression) // new FooDelegate (MyFunction)
|
||||
| ^(NEW_DELEGATE type argument_list? class_body) -> delegate(type = {$type.st}, args = {$argument_list.st}, body={$class_body.st})
|
||||
| ^(NEW_ANON_OBJECT anonymous_object_creation_expression) // new {int X, string Y}
|
||||
| sizeof_expression // sizeof (struct)
|
||||
| checked_expression -> { $checked_expression.st } // checked (...
|
||||
@ -430,7 +431,7 @@ primary_expression_part:
|
||||
access_identifier:
|
||||
access_operator type_or_generic ;
|
||||
access_operator returns [int precedence]:
|
||||
(op='.' | op='->') { $precedence = precedence[$op.token.Type]; } -> string(payload = { $op.token.Text }) ;
|
||||
(op=DOT | op='->') { $precedence = precedence[$op.token.Type]; } -> string(payload = { $op.token.Text }) ;
|
||||
brackets_or_arguments:
|
||||
brackets | arguments ;
|
||||
brackets:
|
||||
@ -479,15 +480,25 @@ rank_specifier:
|
||||
// dim_separators:
|
||||
// ','+ ;
|
||||
|
||||
wrapped returns [int precedence]:
|
||||
wrapped returns [int precedence]
|
||||
@init {
|
||||
$precedence = int.MaxValue;
|
||||
Dictionary<string,ReplacementDescriptor> templateMap = new Dictionary<string,ReplacementDescriptor>();
|
||||
}:
|
||||
^(JAVAWRAPPEREXPRESSION expression) { $precedence = $expression.precedence; } -> { $expression.st }
|
||||
| ^(JAVAWRAPPERARGUMENT argument_value) { $precedence = $argument_value.precedence; } -> { $argument_value.st }
|
||||
| ^(JAVAWRAPPERTYPE type) { $precedence = int.MaxValue; } -> { $type.st }
|
||||
| ^(JAVAWRAPPERTYPE type) -> { $type.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)})
|
||||
;
|
||||
|
||||
delegate_creation_expression:
|
||||
//delegate_creation_expression:
|
||||
// 'new'
|
||||
type_name '(' type_name ')' ;
|
||||
// type_name '(' type_name ')' ;
|
||||
anonymous_object_creation_expression:
|
||||
// 'new'
|
||||
anonymous_object_initializer ;
|
||||
@ -504,7 +515,7 @@ primary_or_array_creation_expression returns [int precedence]:
|
||||
// new Type[2] { }
|
||||
array_creation_expression returns [int precedence]:
|
||||
^(NEW_ARRAY
|
||||
(type ('[' expression_list ']' rank_specifiers? ai1=array_initializer? -> array_construct(type = { $type.st }, args = { $expression_list.st }, inits = { $ai1.st }) // new int[4]
|
||||
(type ('[' expression_list? ']' rank_specifiers? ai1=array_initializer? -> array_construct(type = { $type.st }, args = { $expression_list.st }, inits = { $ai1.st }) // new int[4]
|
||||
| ai2=array_initializer -> array_construct(type = { $type.st }, inits = { $ai2.st })
|
||||
)
|
||||
| rank_specifier array_initializer // var a = new[] { 1, 10, 100, 1000 }; // int[]
|
||||
@ -552,16 +563,7 @@ default_value_expression
|
||||
} -> unsupported(reason = {"default expressions are not yet supported"}, text = { someText } )
|
||||
;
|
||||
anonymous_method_expression:
|
||||
^('delegate' explicit_anonymous_function_signature? block);
|
||||
explicit_anonymous_function_signature:
|
||||
'(' explicit_anonymous_function_parameter_list? ')' ;
|
||||
explicit_anonymous_function_parameter_list:
|
||||
explicit_anonymous_function_parameter (',' explicit_anonymous_function_parameter)* ;
|
||||
explicit_anonymous_function_parameter:
|
||||
anonymous_function_parameter_modifier? type identifier;
|
||||
anonymous_function_parameter_modifier:
|
||||
'ref' | 'out';
|
||||
|
||||
^('delegate' formal_parameter_list? block);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
object_creation_expression:
|
||||
@ -785,7 +787,7 @@ non_assignment_expression returns [int precedence]
|
||||
$precedence = int.MaxValue;
|
||||
}:
|
||||
//'non ASSIGNment'
|
||||
(anonymous_function_signature '=>') => lambda_expression
|
||||
(anonymous_function_signature '=>') => lambda_expression { $precedence = precedence[LAMBDA]; } -> { $lambda_expression.st; }
|
||||
| (query_expression) => query_expression
|
||||
| ^(cop=COND_EXPR ce1=non_assignment_expression ce2=expression ce3=expression) { $precedence = precedence[$cop.token.Type]; }
|
||||
-> cond( condexp = { $ce1.st }, thenexp = { $ce2.st }, elseexp = { $ce3.st },
|
||||
@ -809,19 +811,20 @@ non_assignment_expression returns [int precedence]
|
||||
// lambda Section
|
||||
///////////////////////////////////////////////////////
|
||||
lambda_expression:
|
||||
anonymous_function_signature '=>' anonymous_function_body;
|
||||
anonymous_function_signature? '=>' block
|
||||
{
|
||||
StringTemplate lambdaText = %lambda();
|
||||
%{lambdaText}.args = $anonymous_function_signature.st;
|
||||
%{lambdaText}.body = $block.st;
|
||||
$st = %unsupported();
|
||||
%{$st}.reason = "to translate lambda expressions we need an explicit delegate type, try adding a cast";
|
||||
%{$st}.text = lambdaText;
|
||||
}
|
||||
;
|
||||
anonymous_function_signature:
|
||||
'(' (explicit_anonymous_function_parameter_list
|
||||
| implicit_anonymous_function_parameter_list)? ')'
|
||||
| implicit_anonymous_function_parameter_list
|
||||
^(PARAMS fps+=formal_parameter+) -> list(items= {$fps}, sep={", "})
|
||||
| ^(PARAMS_TYPELESS ids+=identifier+) -> list(items= {$ids}, sep={", "})
|
||||
;
|
||||
implicit_anonymous_function_parameter_list:
|
||||
implicit_anonymous_function_parameter (',' implicit_anonymous_function_parameter)* ;
|
||||
implicit_anonymous_function_parameter:
|
||||
identifier;
|
||||
anonymous_function_body:
|
||||
expression
|
||||
| block ;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// LINQ Section
|
||||
@ -1286,9 +1289,9 @@ jump_statement:
|
||||
| ^('return' expression?) -> return(exp = { $expression.st })
|
||||
| ^('throw' expression?) -> throw(exp = { $expression.st });
|
||||
goto_statement:
|
||||
'goto' ( identifier
|
||||
| 'case' constant_expression
|
||||
| 'default') ';' ;
|
||||
'goto' ( identifier -> op(op={"goto"}, post={$identifier.st})
|
||||
| 'case' constant_expression -> op(op={"goto case"}, post={$constant_expression.st})
|
||||
| 'default' -> string(payload={"goto default"}) ) ';' ;
|
||||
catch_clauses:
|
||||
c+=catch_clause+ -> seplist(items={ $c }, sep = { "\n" }) ;
|
||||
catch_clause:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -867,6 +867,7 @@ scope NSContext;
|
||||
$NSContext::searchpath = new List<string>();
|
||||
$NSContext::aliases = new List<AliasRepTemplate>();
|
||||
DelegateRepTemplate dlegate = new DelegateRepTemplate();
|
||||
ClassRepTemplate multiDelegateClass = new ClassRepTemplate();
|
||||
}
|
||||
:
|
||||
'delegate' return_type identifier variant_generic_parameter_list?
|
||||
@ -878,12 +879,26 @@ scope NSContext;
|
||||
if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) {
|
||||
dlegate.TypeParams = $variant_generic_parameter_list.tyargs.ToArray();
|
||||
}
|
||||
dlegate.Return=$return_type.thetext;
|
||||
dlegate.Params=$formal_parameter_list.paramlist;
|
||||
dlegate.Invoke = new InvokeRepTemplate($return_type.thetext, "Invoke", null, $formal_parameter_list.paramlist);
|
||||
AppEnv[genericNameSpace] = dlegate;
|
||||
dlegate.Uses = this.CollectUses;
|
||||
dlegate.Aliases = this.CollectAliases;
|
||||
dlegate.Imports = new string[] {dlegate.TypeName};
|
||||
|
||||
// now add a class for the MultiDelegateClass that we will be generating
|
||||
genericNameSpace = NSPrefix(ParentNameSpace) + mkGenericTypeAlias("__Multi"+$identifier.text, $variant_generic_parameter_list.tyargs);
|
||||
multiDelegateClass.TypeName = NSPrefix(ParentNameSpace) + "__Multi" + $identifier.text;
|
||||
multiDelegateClass.Inherits = new String[] { dlegate.TypeName };
|
||||
if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) {
|
||||
multiDelegateClass.TypeParams = $variant_generic_parameter_list.tyargs.ToArray();
|
||||
}
|
||||
multiDelegateClass.Methods.Add(new MethodRepTemplate($return_type.thetext, "Invoke", null, $formal_parameter_list.paramlist));
|
||||
multiDelegateClass.Methods.Add(new MethodRepTemplate("System.Collections.Generic.List*[" + dlegate.TypeName + "]*", "GetInvocationList", null, null));
|
||||
AppEnv[genericNameSpace] = multiDelegateClass;
|
||||
multiDelegateClass.Uses = this.CollectUses;
|
||||
multiDelegateClass.Aliases = this.CollectAliases;
|
||||
multiDelegateClass.Imports = new string[] {multiDelegateClass.TypeName};
|
||||
|
||||
}
|
||||
;
|
||||
delegate_modifiers:
|
||||
|
@ -24,7 +24,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Commandlineparameters>-translator-timestamp-files=false -translator-keep-parens=false -netdir=/Users/keving/gitrepos/cs2j/CS2JLibrary/NetFramework/ -dumpxmls -xmldir=/Users/keving/tmp/xml/se -odir=/Users/keving/tmp/java/se/src -appdir=/Users/keving/svnrepos/ScormEngineNet/src/app/ScormEngine.Core /Users/keving/svnrepos/ScormEngineNet/src/app/ScormEngine.Core/Logic/Integration/IntegrationInterface.cs</Commandlineparameters>
|
||||
<Commandlineparameters>--debug 5 -experimental-transforms=true -translator-timestamp-files=false -translator-keep-parens=false -netdir=/Users/keving/gitrepos/cs2j/CS2JLibrary/NetFramework/ -dumpxmls -xmldir=/Users/keving/tmp/xml/libomv -odir=/Users/keving/tmp/java/libomv/src -csdir=/Users/keving/Projects/libomv-0.8.3-source/Programs/VisualParamGenerator/ -excsdir=/Users/keving/Projects/libomv-0.8.3-source/Programs/VisualParamGenerator/template.cs</Commandlineparameters>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
|
@ -30,6 +30,7 @@ tokens {
|
||||
DESTRUCTOR;
|
||||
METHOD_HEADER;
|
||||
PARAMS;
|
||||
PARAMS_TYPELESS;
|
||||
SWITCH_SECTION;
|
||||
|
||||
MONOPLUS;
|
||||
@ -126,6 +127,9 @@ tokens {
|
||||
MOD = '%';
|
||||
STAR = '*';
|
||||
|
||||
LAMBDA = '=>';
|
||||
COMMA = ',';
|
||||
|
||||
TYPE;
|
||||
TYPE_VAR;
|
||||
TYPE_DYNAMIC;
|
||||
@ -271,6 +275,9 @@ public class_member_declaration:
|
||||
)
|
||||
;
|
||||
|
||||
public java_delegate_creation_expression:
|
||||
'new' type '(' ')' '{' class_member_declaration '}';
|
||||
|
||||
public primary_expression:
|
||||
('this' brackets) => 'this' brackets primary_expression_part*
|
||||
| ('base' brackets) => 'base' brackets primary_expression_part*
|
||||
@ -771,12 +778,19 @@ public variable_declarator:
|
||||
public method_declaration:
|
||||
method_header method_body ;
|
||||
public method_header:
|
||||
member_name '(' formal_parameter_list? ')' type_parameter_constraints_clauses? ;
|
||||
member_name '(' formal_parameter_list? ')' type_parameter_constraints_clauses?
|
||||
// Only have throw Exceptions if IsJavaish
|
||||
throw_exceptions?
|
||||
;
|
||||
public method_body:
|
||||
block ;
|
||||
public member_name:
|
||||
qid ; // IInterface<int>.Method logic added.
|
||||
|
||||
throw_exceptions:
|
||||
{IsJavaish}?=> 'throws' identifier (',' identifier)*
|
||||
;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
public property_declaration:
|
||||
member_name '{' accessor_declarations '}' ;
|
||||
|
Loading…
x
Reference in New Issue
Block a user