1
0
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:
Kevin Glynn 2011-05-19 16:37:45 +02:00
parent ff574c6af9
commit 84a767f445
12 changed files with 1336 additions and 431 deletions

View 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>

View 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();
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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>]""

View File

@ -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;
}
}
}

View File

@ -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, "}"])
;

View File

@ -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:

View File

@ -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:

View File

@ -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>

View File

@ -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 '}' ;