diff --git a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs index 4a9937b..ad0b32a 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs +++ b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Text; +using System.Text.RegularExpressions; using System.IO; using System.Xml; using System.Xml.Serialization; @@ -18,13 +19,65 @@ using RusticiSoftware.Translator.Utils; namespace RusticiSoftware.Translator.CLR { + public class TemplateUtilities + { + public static string Substitute(string c, Dictionary argMap) + { + String ret = c; + if (argMap.ContainsKey(c)) + { + ret = argMap[c].TypeName; + } + return ret; + } + + public static string SubstituteInType(String type, Dictionary argMap) + { + if (String.IsNullOrEmpty(type)) + return type; + + string ret = type; + // type is either "string" or "string" + Match match = Regex.Match(type, @"^([\w|\.]+)(?:\s*\[\s*([\w|\.]+)(?:\s*,\s*([\w|\.]+))*\s*\])?$"); + if (match.Success) + { + CaptureCollection captures = match.Captures; + StringBuilder buf = new StringBuilder(); + buf.Append(Substitute(captures[0].Value, argMap)); + if ( captures.Count > 1) + { + bool first = true; + buf.Append("["); + for (int i = 1; i < captures.Count; i++) + { + if (!first) + { + buf.Append(", "); + } + buf.Append(Substitute(captures[i].Value, argMap)); + first = false; + } + buf.Append("]"); + } + ret = buf.ToString(); + } + return ret; + } + } + + public interface IApplyTypeArgs + { + // Instantiate type arguments "in-situ" + void Apply(Dictionary args); + } + public enum Javastyle { Clean, MarkAuto } // Simple pairs to represent formal parameters - public class ParamRepTemplate : IEquatable + public class ParamRepTemplate : IEquatable, IApplyTypeArgs { private string _type; public string Type { @@ -59,6 +112,11 @@ namespace RusticiSoftware.Translator.CLR IsByRef = isbyref; } + public void Apply(Dictionary args) + { + Type = TemplateUtilities.SubstituteInType(Type, args); + } + #region Equality public bool Equals (ParamRepTemplate other) { @@ -154,7 +212,7 @@ namespace RusticiSoftware.Translator.CLR // Never directly create a TranslationBase. Its a common root for translatable language entities - public abstract class TranslationBase : IEquatable + public abstract class TranslationBase : IEquatable, IApplyTypeArgs { // Java imports required to make Java translation run private string[] _imports = null; @@ -252,6 +310,15 @@ namespace RusticiSoftware.Translator.CLR } + // Instantiate type arguments + public virtual void Apply(Dictionary args) + { + if (!String.IsNullOrEmpty(SurroundingTypeName)) + { + SurroundingTypeName = TemplateUtilities.SubstituteInType(SurroundingTypeName, args); + } + } + #region Equality public bool Equals (TranslationBase other) @@ -351,6 +418,18 @@ namespace RusticiSoftware.Translator.CLR } + public override void Apply(Dictionary args) + { + if (Params != null) + { + foreach(ParamRepTemplate p in Params) + { + p.Apply(args); + } + } + base.Apply(args); + } + #region Equality public bool Equals (ConstructorRepTemplate other) @@ -476,6 +555,16 @@ namespace RusticiSoftware.Translator.CLR return methStr.ToString() + mkJavaParams(Params); } + // TODO: filter out redefined type names + public override void Apply(Dictionary args) + { + if (Return != null) + { + Return = TemplateUtilities.SubstituteInType(Return,args); + } + base.Apply(args); + } + #region Equality public bool Equals (MethodRepTemplate other) { @@ -598,6 +687,19 @@ namespace RusticiSoftware.Translator.CLR } } + public override void Apply(Dictionary args) + { + if (From != null) + { + From = TemplateUtilities.SubstituteInType(From, args); + } + if (To != null) + { + To = TemplateUtilities.SubstituteInType(To, args); + } + base.Apply(args); + } + #region Equality public bool Equals (CastRepTemplate other) { @@ -667,6 +769,15 @@ namespace RusticiSoftware.Translator.CLR return "${this}." + Name; } + public override void Apply(Dictionary args) + { + if (Type != null) + { + Type = TemplateUtilities.SubstituteInType(Type, args); + } + base.Apply(args); + } + #region Equality public bool Equals (FieldRepTemplate other) { @@ -986,6 +1097,39 @@ namespace RusticiSoftware.Translator.CLR } } + + public void Apply(TypeRepTemplate[] args) + { + if (args.Length == TypeParams.Length) + { + Dictionary paramMap = new Dictionary(); + for (int i = 0; i < args.Length; i++) + { + paramMap[TypeParams[i]] = args[i]; + } + this.Apply(paramMap); + } + } + + public override void Apply(Dictionary args) + { + if (Casts != null) + { + foreach(CastRepTemplate c in Casts) + { + c.Apply(args); + } + } + if (Inherits != null) + { + for(int i = 0; i < Inherits.Length; i++) + { + Inherits[i] = TemplateUtilities.SubstituteInType(Inherits[i],args); + } + } + base.Apply(args); + } + // Resolve a method call (name and arg types) public virtual ResolveResult Resolve(String name, List args, DirectoryHT AppEnv) { @@ -1451,6 +1595,22 @@ namespace RusticiSoftware.Translator.CLR return "${delegate}.Invoke" + mkJavaParams(Params); } + public override void Apply(Dictionary args) + { + if (Params != null) + { + foreach(ParamRepTemplate p in Params) + { + p.Apply(args); + } + } + if (Return != null) + { + Return = TemplateUtilities.SubstituteInType(Return, args); + } + base.Apply(args); + } + #region Equality public bool Equals (DelegateRepTemplate other) { @@ -1566,6 +1726,39 @@ namespace RusticiSoftware.Translator.CLR } + public override void Apply(Dictionary args) + { + if (Methods != null) + { + foreach(MethodRepTemplate m in Methods) + { + m.Apply(args); + } + } + if (Properties != null) + { + foreach(PropRepTemplate p in Properties) + { + p.Apply(args); + } + } + if (Events != null) + { + foreach(FieldRepTemplate e in Events) + { + e.Apply(args); + } + } + if (Indexers != null) + { + foreach(MethodRepTemplate i in Indexers) + { + i.Apply(args); + } + } + base.Apply(args); + } + // Returns true if we are a subclass of other, or implements its interface public override bool IsA (TypeRepTemplate other, DirectoryHT AppEnv) { InterfaceRepTemplate i = other as InterfaceRepTemplate; @@ -1825,6 +2018,42 @@ namespace RusticiSoftware.Translator.CLR _casts = cts; } + public override void Apply(Dictionary args) + { + if (Constructors != null) + { + foreach(ConstructorRepTemplate c in Constructors) + { + c.Apply(args); + } + } + if (Fields != null) + { + foreach(FieldRepTemplate f in Fields) + { + f.Apply(args); + } + } + + if (UnaryOps != null) + { + foreach(MethodRepTemplate u in UnaryOps) + { + u.Apply(args); + } + } + + if (BinaryOps != null) + { + foreach(MethodRepTemplate b in BinaryOps) + { + b.Apply(args); + } + } + base.Apply(args); + } + + public override ResolveResult Resolve(String name, DirectoryHT AppEnv) { diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g index a60f904..713753a 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g @@ -28,6 +28,7 @@ scope SymTab { @header { + using System.Text; using RusticiSoftware.Translator.Utils; using RusticiSoftware.Translator.CLR; } @@ -67,6 +68,25 @@ scope SymTab { return AppEnv.Search($NSContext::globalNamespaces, name, new UnknownRepTemplate(name)); } + protected TypeRepTemplate findType(string name, TypeRepTemplate[] args) { + StringBuilder argNames = new StringBuilder(); + bool first = true; + if (args != null && args.Length > 0) { + argNames.Append("<"); + foreach (TypeRepTemplate ty in args) { + if (!first) { + argNames.Append(", "); + first = false; + } + argNames.Append(ty.TypeName); + } + argNames.Append(">"); + } + TypeRepTemplate tyRep = AppEnv.Search($NSContext::globalNamespaces, name, new UnknownRepTemplate(name + argNames.ToString())); + tyRep.Apply(args); + return tyRep; + } + private ClassRepTemplate objectType = null; protected ClassRepTemplate ObjectType { @@ -493,10 +513,13 @@ ref_variable_reference returns [TypeRepTemplate dotNetType, TypeRepTemplate type // lvalue variable_reference returns [TypeRepTemplate dotNetType, TypeRepTemplate typeofType]: expression { $dotNetType = $expression.dotNetType; $typeofType = $expression.typeofType; }; -rank_specifiers: - rank_specifier+ ; -rank_specifier: - '[' /*dim_separators?*/ ']' ; +rank_specifiers[TypeRepTemplate inTy] returns [TypeRepTemplate dotNetType] +@init { + TypeRepTemplate ty = $inTy; +}: + (rank_specifier[ty] { ty = $rank_specifier.dotNetType;} )+ { $dotNetType = ty; }; +rank_specifier[TypeRepTemplate inTy] returns [TypeRepTemplate dotNetType]: + '[' /*dim_separators?*/ ']' { if ($inTy != null) { $dotNetType = findType("System.Array", new TypeRepTemplate[] {$inTy}); } } ; // keving // dim_separators: // ','+ ; @@ -521,14 +544,14 @@ primary_or_array_creation_expression returns [TypeRepTemplate dotNetType, String array_creation_expression: ^('new' (type ('[' expression_list ']' - ( rank_specifiers? array_initializer? // new int[4] + ( rank_specifiers[$type.dotNetType]? array_initializer? // new int[4] // | invocation_part* | ( ((arguments ('['|'.'|'->')) => arguments invocation_part)// new object[2].GetEnumerator() | invocation_part)* arguments ) // new int[4]() | array_initializer ) - | rank_specifier // [,] + | rank_specifier[null] // [,] (array_initializer // var a = new[] { 1, 10, 100, 1000 }; // int[] ) )) ; @@ -674,13 +697,12 @@ type_arguments returns [List tyTexts] }: t1=type { $tyTexts.Add($t1.dotNetType.TypeName); } (',' tn=type { $tyTexts.Add($tn.dotNetType.TypeName); })* ; -// TODO add arrays type returns [TypeRepTemplate dotNetType] : ^(TYPE (predefined_type { $dotNetType = $predefined_type.dotNetType; } | type_name { $dotNetType = $type_name.dotNetType; } | 'void' { $dotNetType = AppEnv["System.Void"]; } ) - rank_specifiers? '*'* '?'?); + (rank_specifiers[$dotNetType] { $dotNetType = $rank_specifiers.dotNetType; })? '*'* '?'?); non_nullable_type returns [TypeRepTemplate dotNetType]: type { $dotNetType = $type.dotNetType; } ;