From 2f87602d6c52f93866b3aa966b563800dc5a9b2d Mon Sep 17 00:00:00 2001 From: Kevin Glynn Date: Sat, 8 Jan 2011 17:15:48 +0100 Subject: [PATCH] rewrite since namespace aliases need to be kept separate from the search path --- .../src/cs2j/CLR/TranslationTemplate.cs | 67 +++++---- CSharpTranslator/antlr3/src/cs2j/CLR/cs2j.cs | 16 +- .../antlr3/src/cs2j/CSharp/CommonWalker.cs | 16 +- .../antlr3/src/cs2j/CSharp/JavaMaker.g | 45 ++++-- .../antlr3/src/cs2j/CSharp/NetMaker.g | 138 ++++++++++-------- .../src/cs2j/CSharp/TemplateExtracter.g | 84 +++++++---- .../antlr3/src/cs2j/Utils/DirectoryHT.cs | 27 ++++ 7 files changed, 255 insertions(+), 138 deletions(-) diff --git a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs index 7518359..9b76d8b 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs +++ b/CSharpTranslator/antlr3/src/cs2j/CLR/TranslationTemplate.cs @@ -95,30 +95,28 @@ namespace RusticiSoftware.Translator.CLR #endregion } - // A use entry. An optional alias and a fully qualified namespace - public class UseRepTemplate : IEquatable + // A namespace alias entry. + public class AliasRepTemplate : IEquatable { public string Alias { get; set; } public string Namespace { get; set; } - public UseRepTemplate () : this(null) + public AliasRepTemplate () { + Alias = null; + Namespace = null; } - public UseRepTemplate (string u) : this(null, u) - { - } - - public UseRepTemplate (string a, string u) + public AliasRepTemplate (string a, string u) { Alias = a; Namespace = u; } #region Equality - public bool Equals (UseRepTemplate other) + public bool Equals (AliasRepTemplate other) { if (other == null) return false; @@ -129,19 +127,19 @@ namespace RusticiSoftware.Translator.CLR public override bool Equals (object obj) { - UseRepTemplate temp = obj as UseRepTemplate; + AliasRepTemplate temp = obj as AliasRepTemplate; if (!Object.ReferenceEquals (temp, null)) return this.Equals (temp); return false; } - public static bool operator == (UseRepTemplate a1, UseRepTemplate a2) + public static bool operator == (AliasRepTemplate a1, AliasRepTemplate a2) { return Object.Equals (a1, a2); } - public static bool operator != (UseRepTemplate a1, UseRepTemplate a2) + public static bool operator != (AliasRepTemplate a1, AliasRepTemplate a2) { return !(a1 == a2); } @@ -880,12 +878,17 @@ namespace RusticiSoftware.Translator.CLR // Path to use when resolving types [XmlArrayItem("Use")] - public UseRepTemplate[] Uses { get; set; } + public string[] Uses { get; set; } + + // Aliases for namespaces + [XmlArrayItem("Alias")] + public AliasRepTemplate[] Aliases { get; set; } public TypeRepTemplate () : base() { TypeName = null; Uses = null; + Aliases = null; } @@ -894,11 +897,12 @@ namespace RusticiSoftware.Translator.CLR TypeName = typeName; } - protected TypeRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] imports, string javaTemplate) : base(imports, javaTemplate) + protected TypeRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] imports, string javaTemplate) : base(imports, javaTemplate) { TypeName = tName; TypeParams = tParams; Uses = usePath; + Aliases = aliases; } public override string mkJava() { @@ -1003,6 +1007,14 @@ namespace RusticiSoftware.Translator.CLR return false; } } + if (Aliases != other.Aliases) { + if (Aliases == null || other.Aliases == null || Aliases.Length != other.Aliases.Length) + return false; + for (int i = 0; i < Aliases.Length; i++) { + if (Aliases[i] != other.Aliases[i]) + return false; + } + } if (TypeParams != other.TypeParams) { if (TypeParams == null || other.TypeParams == null || TypeParams.Length != other.TypeParams.Length) return false; @@ -1039,7 +1051,12 @@ namespace RusticiSoftware.Translator.CLR { int hashCode = base.GetHashCode (); if (Uses != null) { - foreach (UseRepTemplate e in Uses) { + foreach (string e in Uses) { + hashCode ^= e.GetHashCode(); + } + } + if (Aliases != null) { + foreach (AliasRepTemplate e in Aliases) { hashCode ^= e.GetHashCode(); } } @@ -1298,8 +1315,8 @@ namespace RusticiSoftware.Translator.CLR { } - protected InterfaceRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List ms, List ps, List es, List ixs, string[] imps, string javaTemplate) - : base(tName, tParams, usePath, imps, javaTemplate) + protected InterfaceRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List ms, List ps, List es, List ixs, string[] imps, string javaTemplate) + : base(tName, tParams, usePath, aliases, imps, javaTemplate) { Inherits = inherits; _methods = ms; @@ -1483,17 +1500,17 @@ namespace RusticiSoftware.Translator.CLR { } - public ClassRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts, + public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts, string[] imports, string javaTemplate) - : base(tName, tParams, usePath, inherits, ms, ps, es, ixs, imports, javaTemplate) + : base(tName, tParams, usePath, aliases, inherits, ms, ps, es, ixs, imports, javaTemplate) { _constructors = cs; _fields = fs; _casts = cts; } - public ClassRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts) - : base(tName, tParams, usePath, inherits, ms, ps, es, ixs, null, null) + public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts) + : base(tName, tParams, usePath, aliases, inherits, ms, ps, es, ixs, null, null) { _constructors = cs; _fields = fs; @@ -1621,14 +1638,14 @@ namespace RusticiSoftware.Translator.CLR { } - public StructRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts, - string[] imports, string javaTemplate) : base(tName, tParams, usePath, inherits, cs, ms, ps, fs, es, ixs, cts, + public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts, + string[] imports, string javaTemplate) : base(tName, tParams, usePath, aliases, inherits, cs, ms, ps, fs, es, ixs, cts, imports, javaTemplate) { } - public StructRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts) - : base(tName, tParams, usePath, inherits, cs, ms, ps, fs, es, ixs, cts, null, null) + public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List cs, List ms, List ps, List fs, List es, List ixs, List cts) + : base(tName, tParams, usePath, aliases, inherits, cs, ms, ps, fs, es, ixs, cts, null, null) { } diff --git a/CSharpTranslator/antlr3/src/cs2j/CLR/cs2j.cs b/CSharpTranslator/antlr3/src/cs2j/CLR/cs2j.cs index 3ba34a5..74867aa 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CLR/cs2j.cs +++ b/CSharpTranslator/antlr3/src/cs2j/CLR/cs2j.cs @@ -305,10 +305,15 @@ namespace RusticiSoftware.Translator.CSharp if (cfg.DebugLevel >= 10) { - Console.Out.WriteLine("Search Path:"); - for (int j = 0; j < javaMaker.CUMap[typeName].SearchPathKeys.Count; j++) + Console.Out.WriteLine("Namepace Search Path:"); + foreach (String ns in javaMaker.CUMap[typeName].SearchPath) { - Console.Out.WriteLine("{0} => {1}", javaMaker.CUMap[typeName].SearchPathKeys[j], javaMaker.CUMap[typeName].SearchPathValues[j]); + Console.Out.WriteLine(ns); + } + Console.Out.WriteLine("Namepace Alias Map:"); + for (int j = 0; j < javaMaker.CUMap[typeName].NameSpaceAliasKeys.Count; j++) + { + Console.Out.WriteLine("{0} => {1}", javaMaker.CUMap[typeName].NameSpaceAliasKeys[j], javaMaker.CUMap[typeName].NameSpaceAliasValues[j]); } } @@ -358,8 +363,9 @@ namespace RusticiSoftware.Translator.CSharp netMaker.Cfg = cfg; netMaker.AppEnv = AppEnv; - netMaker.SearchPathKeys = javaMaker.CUMap[typeName].SearchPathKeys; - netMaker.SearchPathValues = javaMaker.CUMap[typeName].SearchPathValues; + netMaker.SearchPath = javaMaker.CUMap[typeName].SearchPath; + netMaker.AliasKeys = javaMaker.CUMap[typeName].NameSpaceAliasKeys; + netMaker.AliasNamespaces = javaMaker.CUMap[typeName].NameSpaceAliasValues; if (cfg.DebugLevel > 5) Console.Out.WriteLine("Translating {0} Net Calls to Java", javaFName); NetMaker.compilation_unit_return javaCompilationUnit = netMaker.compilation_unit(); diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/CommonWalker.cs b/CSharpTranslator/antlr3/src/cs2j/CSharp/CommonWalker.cs index 573f6d8..03ab98b 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/CommonWalker.cs +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/CommonWalker.cs @@ -100,14 +100,20 @@ namespace RusticiSoftware.Translator.CSharp // Wraps a compilation unit with its imports search path public class CUnit { - public CUnit(CommonTree inTree, List inSearchKeys, List inSearchValues) { + public CUnit(CommonTree inTree, List inSearchPath, List inAliasKeys, List inAliasValues) { Tree = inTree; - SearchPathKeys = inSearchKeys; - SearchPathValues = inSearchValues; + SearchPath = inSearchPath; + NameSpaceAliasKeys = inAliasKeys; + NameSpaceAliasValues = inAliasValues; } public CommonTree Tree {get; set;} - public List SearchPathKeys {get; set;} - public List SearchPathValues {get; set;} + + // namespaces in scope + public List SearchPath {get; set;} + + // aliases for namespaces + public List NameSpaceAliasKeys {get; set;} + public List NameSpaceAliasValues {get; set;} } } diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g index caf0fd3..7eddd4a 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g @@ -20,11 +20,13 @@ scope NSContext { int filler; string currentNS; - // all namespaces in scope, these two lists are actually a map from alias to namespace - // so aliases[i] -> namespaces[i] - // for namespaces without an alias we just map them to themselves - List aliases; + // namespaces in scope List namespaces; + + // Alias map: these two lists are actually a map from alias to namespace + // so aliases[i] -> namespaces[i] + List aliasKeys; + List aliasNamespaces; } // A scope to keep track of the current type context @@ -55,12 +57,12 @@ scope TypeContext { } } - protected List CollectAliases { + protected List CollectSearchPath { get { List ret = new List(); Object[] nsCtxtArr = $NSContext.ToArray(); for (int i = nsCtxtArr.Length - 1; i >= 0; i--) { - foreach (string v in ((NSContext_scope)nsCtxtArr[i]).aliases) { + foreach (string v in ((NSContext_scope)nsCtxtArr[i]).namespaces) { ret.Add(v); } } @@ -68,12 +70,25 @@ scope TypeContext { } } - protected List CollectNamespaces { + protected List CollectAliasKeys { get { List ret = new List(); Object[] nsCtxtArr = $NSContext.ToArray(); for (int i = nsCtxtArr.Length - 1; i >= 0; i--) { - foreach (string v in ((NSContext_scope)nsCtxtArr[i]).namespaces) { + foreach (string v in ((NSContext_scope)nsCtxtArr[i]).aliasKeys) { + ret.Add(v); + } + } + return ret; + } + } + + protected List CollectAliasNamespaces { + get { + List ret = new List(); + Object[] nsCtxtArr = $NSContext.ToArray(); + for (int i = nsCtxtArr.Length - 1; i >= 0; i--) { + foreach (string v in ((NSContext_scope)nsCtxtArr[i]).aliasNamespaces) { ret.Add(v); } } @@ -236,8 +251,9 @@ compilation_unit scope NSContext; @init { $NSContext::currentNS = ""; - $NSContext::aliases = new List(); $NSContext::namespaces = new List(); + $NSContext::aliasKeys = new List(); + $NSContext::aliasNamespaces = new List(); } : namespace_body; @@ -246,14 +262,14 @@ namespace_declaration scope NSContext; @init { $NSContext::currentNS = ""; - $NSContext::aliases = new List(); $NSContext::namespaces = new List(); + $NSContext::aliasKeys = new List(); + $NSContext::aliasNamespaces = new List(); }: 'namespace' qi=qualified_identifier { // extend parent namespace $NSContext::currentNS = this.ParentNameSpace + $qi.thetext; - $NSContext::aliases.Add($NSContext::currentNS); $NSContext::namespaces.Add($NSContext::currentNS); } namespace_block ';'? ; @@ -271,9 +287,10 @@ using_directive: (using_alias_directive | using_namespace_directive) ; using_alias_directive: - 'using' identifier '=' namespace_or_type_name ';' {$NSContext::aliases.Add($identifier.text);$NSContext::namespaces.Add($namespace_or_type_name.thetext); } ; + 'using' identifier '=' namespace_or_type_name ';' + {$NSContext::aliasKeys.Add($identifier.text);$NSContext::aliasNamespaces.Add($namespace_or_type_name.thetext); } ; using_namespace_directive: - 'using' namespace_name ';' {$NSContext::aliases.Add($namespace_name.thetext);$NSContext::namespaces.Add($namespace_name.thetext); }; + 'using' namespace_name ';' {$NSContext::namespaces.Add($namespace_name.thetext); }; namespace_member_declarations: namespace_member_declaration+ ; namespace_member_declaration @@ -282,7 +299,7 @@ namespace_member_declaration } @after { if (isCompUnit) { - CUMap.Add(ns+"."+$ty.name, new CUnit($namespace_member_declaration.tree,CollectAliases,CollectNamespaces)); + CUMap.Add(ns+"."+$ty.name, new CUnit($namespace_member_declaration.tree,CollectSearchPath,CollectAliasKeys,CollectAliasNamespaces)); CUKeys.Add(ns+"."+$ty.name); }; } diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g index 842ed74..6e1a342 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g @@ -13,11 +13,15 @@ scope NSContext { string currentNS; - // all namespaces in scope, these two lists are actually a map from alias to namespace - // so aliases[i] -> namespaces[i] - // for namespaces without an alias we just map them to themselves - List aliases; + // all namespaces in scope List namespaces; + // all namespaces in all scopes + List globalNamespaces; +} + +// A scope to keep track of the mapping from variables to types +scope SymTab { + Dictionary symtab; } @namespace { RusticiSoftware.Translator.CSharp } @@ -31,8 +35,9 @@ scope NSContext { @members { // Initial namespace search path gathered in JavaMaker - public List SearchPathKeys { get; set; } - public List SearchPathValues { get; set; } + public List SearchPath { get; set; } + public List AliasKeys { get; set; } + public List AliasNamespaces { get; set; } private Set Imports { get; set; } @@ -59,27 +64,19 @@ scope NSContext { } protected TypeRepTemplate findType(string name) { - TypeRepTemplate ret = null; - object[] ctxts = $NSContext.ToArray(); - foreach (NSContext_scope ctxt in ctxts) { - for (int i = ctxt.namespaces.Count - 1; i >= 0; i--) { - String ns = ctxt.namespaces[i]; - String fullName = (ns ?? "") + (String.IsNullOrEmpty(ns) ? "" : ".") + name; - if (AppEnv.ContainsKey(fullName)) { - ret = AppEnv[fullName]; - break; - } - } - } - // Check if name is fully qualified - if (ret == null && AppEnv.ContainsKey(name)) { - ret = AppEnv[name]; - } -// if (ret != null) -// Console.Out.WriteLine("findType: found {0}", ret.TypeName); - return ret; + return AppEnv.Search($NSContext::globalNamespaces, name); } + private TypeRepTemplate objectType = null; + + protected TypeRepTemplate ObjectType { + get { + if (objectType == null) { + objectType = findType("System.Object"); + } + return objectType; + } + } } compilation_unit @@ -89,8 +86,8 @@ scope NSContext; Imports = new Set(); // TODO: Do we need to ensure we have access to System? If so, can add it here. - $NSContext::aliases = SearchPathKeys; - $NSContext::namespaces = SearchPathValues; + $NSContext::namespaces = SearchPath ?? new List(); + $NSContext::globalNamespaces = SearchPath ?? new List(); }: ^(pkg=PACKAGE ns=PAYLOAD { $NSContext::currentNS = $ns.text; } m=modifiers? dec=type_declaration ) -> ^($pkg $ns { mkImports() } $m? $dec); @@ -119,7 +116,7 @@ class_member_declaration: | ^(INTERFACE attributes? modifiers? interface_declaration) | ^(CLASS attributes? modifiers? class_declaration) | ^(INDEXER attributes? modifiers? type type_name? indexer_declaration) - | ^(FIELD attributes? modifiers? type field_declaration) + | ^(FIELD attributes? modifiers? type field_declaration[$type.dotNetType]) | ^(OPERATOR attributes? modifiers? type operator_declaration) | ^(ENUM attributes? modifiers? enum_declaration) | ^(DELEGATE attributes? modifiers? delegate_declaration) @@ -390,7 +387,9 @@ pointer_type returns [TypeRepTemplate dotNetType]: /////////////////////////////////////////////////////// // Statement Section /////////////////////////////////////////////////////// -block: +block +scope SymTab; +: ';' | '{' statement_list? '}'; statement_list: @@ -399,7 +398,7 @@ statement_list: /////////////////////////////////////////////////////// // Expression Section /////////////////////////////////////////////////////// -expression: +expression returns [TypeRepTemplate dotNetType]: (unary_expression assignment_operator) => assignment | non_assignment_expression ; @@ -407,21 +406,21 @@ expression_list: expression (',' expression)* ; assignment: unary_expression assignment_operator expression ; -unary_expression: +unary_expression returns [TypeRepTemplate dotNetType]: //('(' arguments ')' ('[' | '.' | '(')) => primary_or_array_creation_expression //(cast_expression) => cast_expression - ^(CAST_EXPR type unary_expression) + ^(CAST_EXPR type unary_expression) { $dotNetType = $type.dotNetType; } | primary_or_array_creation_expression - | ^(MONOPLUS unary_expression) - | ^(MONOMINUS unary_expression) - | ^(MONONOT unary_expression) - | ^(MONOTWIDDLE unary_expression) - | ^(PREINC unary_expression) - | ^(PREDEC unary_expression) - | ^(MONOSTAR unary_expression) - | ^(ADDRESSOF unary_expression) - | ^(PARENS expression) + | ^(MONOPLUS u1=unary_expression) { $dotNetType = $u1.dotNetType; } + | ^(MONOMINUS u2=unary_expression) { $dotNetType = $u2.dotNetType; } + | ^(MONONOT u3=unary_expression) { $dotNetType = $u3.dotNetType; } + | ^(MONOTWIDDLE u4=unary_expression) { $dotNetType = $u4.dotNetType; } + | ^(PREINC u5=unary_expression) { $dotNetType = $u5.dotNetType; } + | ^(PREDEC u6=unary_expression) { $dotNetType = $u6.dotNetType; } + | ^(MONOSTAR unary_expression) { $dotNetType = ObjectType; } + | ^(ADDRESSOF unary_expression) { $dotNetType = ObjectType; } + | ^(PARENS expression) { $dotNetType = $expression.dotNetType; } ; //cast_expression: // '(' type ')' non_assignment_expression ; @@ -613,17 +612,20 @@ attribute_argument_expression: /////////////////////////////////////////////////////// class_declaration -scope NSContext; +scope NSContext,SymTab; @init { - $NSContext::aliases = new List(); $NSContext::namespaces = new List(); + $NSContext::globalNamespaces = new List(((NSContext_scope)$NSContext.ToArray()[1]).globalNamespaces); + $SymTab::symtab = new Dictionary(); } : ^(CLASS identifier { $NSContext::currentNS = ParentNameSpace + "." + $identifier.thetext; } type_parameter_constraints_clauses? type_parameter_list? class_implements? { - $NSContext::aliases.Add($NSContext::currentNS); - $NSContext::namespaces.Add($NSContext::currentNS); + $NSContext::namespaces.Add($NSContext::currentNS); + $NSContext::globalNamespaces.Add($NSContext::currentNS); + // TODO: base to map to parent type + $SymTab::symtab["this"] = AppEnv.Search($NSContext::currentNS); } class_body ) ; @@ -668,15 +670,17 @@ constant_expression: expression; /////////////////////////////////////////////////////// -field_declaration: - variable_declarators ; -variable_declarators: - variable_declarator (',' variable_declarator)* ; -variable_declarator: +field_declaration[TypeRepTemplate fieldType]: + variable_declarators[$fieldType] ; +variable_declarators[TypeRepTemplate varType]: + variable_declarator[varType] (',' variable_declarator[varType])* ; +variable_declarator[TypeRepTemplate varType]: type_name ('=' variable_initializer)? ; // eg. event EventHandler IInterface.VariableName = Foo; /////////////////////////////////////////////////////// -method_declaration: +method_declaration +scope SymTab; +: method_header method_body ; method_header: ^(METHOD_HEADER attributes? modifiers? type member_name type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list?); @@ -708,7 +712,7 @@ accessor_body: event_declaration: 'event' type ((member_name '{') => member_name '{' event_accessor_declarations '}' - | variable_declarators ';') // typename=foo; + | variable_declarators[$type.dotNetType] ';') // typename=foo; ; event_modifiers: modifier+ ; @@ -862,7 +866,7 @@ statement_plus: | embedded_statement ; embedded_statement: -block + block | ^(IF boolean_expression SEP embedded_statement else_statement?) | ^('switch' expression switch_section*) | iteration_statement // while, do, for, foreach @@ -978,7 +982,7 @@ predefined_type returns [TypeRepTemplate dotNetType] string ns = ""; } @after { - $dotNetType = AppEnv[ns]; + $dotNetType = AppEnv.Search(ns); }: 'bool' { ns = "System.Boolean"; } | 'byte' { ns = "System.Byte"; } @@ -1011,16 +1015,22 @@ also_keyword: | 'equals' | 'select' | 'pragma' | 'let' | 'remove' | 'get' | 'set' | 'var' | '__arglist' | 'dynamic' | 'elif' | 'endif' | 'define' | 'undef'; -literal: - Real_literal - | NUMBER - | LONGNUMBER +literal returns [TypeRepTemplate dotNetType] +@init { + string ns = "System.Object"; +} +@after { + $dotNetType = AppEnv.Search(ns); +}: + Real_literal + | NUMBER { ns = "System.Int32"; } + | LONGNUMBER { ns = "System.Int64"; } | Hex_number - | Character_literal - | STRINGLITERAL - | Verbatim_string_literal - | TRUE - | FALSE - | NULL + | Character_literal { ns = "System.Char"; } + | STRINGLITERAL { ns = "System.String"; } + | Verbatim_string_literal { ns = "System.String"; } + | TRUE { ns = "System.Bool"; } + | FALSE { ns = "System.Bool"; } + | NULL { ns = "System.Object"; } ; diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/TemplateExtracter.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/TemplateExtracter.g index 6d34cdb..900f68f 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/TemplateExtracter.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/TemplateExtracter.g @@ -17,7 +17,8 @@ options { // A scope to keep track of the namespaces available at any point in the program scope NSContext { - IList nss; + IList searchpath; + IList aliases; string currentNS; TypeRepTemplate currentTypeRep; } @@ -34,20 +35,41 @@ scope NSContext { @members { - protected UseRepTemplate[] NameSpaceContext { + protected string[] CollectUses { get { // We return the elements in source order (hopefully less confusing) // so when looking for types we search from last element to first. // here we are getting scopes in the opposite order so we need some // jiggery pokery to restore desired order. - List rets = new List(); + List rets = new List(); // returns in LIFO order, like you would expect from a stack // sigh, in C# we can't index into the scopes like you can in Java // so we resort to a bit of low level hackery to get the ns lists foreach (NSContext_scope nscontext in $NSContext) { - IList nss = nscontext.nss; - for (int i = nss.Count - 1; i >= 0; i--) { - rets.Add(nss[i]); + IList uses = nscontext.searchpath; + for (int i = uses.Count - 1; i >= 0; i--) { + rets.Add(uses[i]); + } + } + // And now return reversed list + rets.Reverse(); + return rets.ToArray(); + } + } + protected AliasRepTemplate[] CollectAliases { + get { + // We return the elements in source order (hopefully less confusing) + // so when looking for types we search from last element to first. + // here we are getting scopes in the opposite order so we need some + // jiggery pokery to restore desired order. + List rets = new List(); + // returns in LIFO order, like you would expect from a stack + // sigh, in C# we can't index into the scopes like you can in Java + // so we resort to a bit of low level hackery to get the ns lists + foreach (NSContext_scope nscontext in $NSContext) { + IList aliases = nscontext.aliases; + for (int i = aliases.Count - 1; i >= 0; i--) { + rets.Add(aliases[i]); } } // And now return reversed list @@ -74,7 +96,8 @@ compilation_unit scope NSContext; @init{ // For initial, file level scope - $NSContext::nss = new List(); + $NSContext::searchpath = new List(); + $NSContext::aliases = new List(); $NSContext::currentNS = ""; $NSContext::currentTypeRep = null; } @@ -87,13 +110,14 @@ scope NSContext; namespace_declaration scope NSContext; @init{ - $NSContext::nss = new List(); + $NSContext::searchpath = new List(); + $NSContext::aliases = new List(); $NSContext::currentTypeRep = null; } : 'namespace' qi=qualified_identifier { Debug("namespace: " + $qi.thetext); - $NSContext::nss.Add(new UseRepTemplate($qi.thetext)); + $NSContext::searchpath.Add($qi.thetext); // extend parent namespace $NSContext::currentNS = ParentNameSpace + (String.IsNullOrEmpty(ParentNameSpace) ? "" : ".") + $qi.thetext; } @@ -112,11 +136,11 @@ using_directive: (using_alias_directive | using_namespace_directive) ; using_alias_directive -@after{ $NSContext::nss.Add(new UseRepTemplate($i.thetext, $ns.thetext));} +@after{ $NSContext::aliases.Add(new AliasRepTemplate($i.thetext, $ns.thetext));} : 'using' i=identifier '=' ns=namespace_or_type_name ';' ; using_namespace_directive -@after{ $NSContext::nss.Add(new UseRepTemplate($ns.thetext)); } +@after{ $NSContext::searchpath.Add($ns.thetext); } : 'using' ns=namespace_name ';' ; namespace_member_declarations: @@ -641,20 +665,22 @@ attribute_argument_expression: class_declaration scope NSContext; @init { - $NSContext::nss = new List(); + $NSContext::searchpath = new List(); + $NSContext::aliases = new List(); ClassRepTemplate klass = new ClassRepTemplate(); } : 'class' type_or_generic { Debug("Processing class: " + $type_or_generic.type); - klass.Uses = this.NameSpaceContext; + klass.Uses = this.CollectUses; + klass.Aliases = this.CollectAliases; klass.TypeName = this.ParentNameSpace + "." + mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments); if ($type_or_generic.generic_arguments.Count > 0) { klass.TypeParams = $type_or_generic.generic_arguments.ToArray(); } // Nested types can see things in this space - $NSContext::nss.Add(new UseRepTemplate(klass.TypeName)); + $NSContext::searchpath.Add(klass.TypeName); $NSContext::currentNS = klass.TypeName; $NSContext::currentTypeRep = klass; AppEnv[klass.TypeName] = klass; @@ -776,17 +802,19 @@ remove_accessor_declaration: enum_declaration scope NSContext; @init { - $NSContext::nss = new List(); + $NSContext::searchpath = new List(); + $NSContext::aliases = new List(); EnumRepTemplate eenum = new EnumRepTemplate(); } : 'enum' identifier enum_base? { Debug("Processing enum: " + $identifier.text); - eenum.Uses = this.NameSpaceContext; + eenum.Uses = this.CollectUses; + eenum.Aliases = this.CollectAliases; eenum.TypeName = this.ParentNameSpace + "." + $identifier.text; // Nested types can see things in this space - $NSContext::nss.Add(new UseRepTemplate(eenum.TypeName)); + $NSContext::searchpath.Add(eenum.TypeName); $NSContext::currentNS = eenum.TypeName; $NSContext::currentTypeRep = eenum; AppEnv[eenum.TypeName] = eenum; @@ -814,7 +842,8 @@ integral_type: delegate_declaration scope NSContext; @init { - $NSContext::nss = new List(); + $NSContext::searchpath = new List(); + $NSContext::aliases = new List(); DelegateRepTemplate dlegate = new DelegateRepTemplate(); } : @@ -822,7 +851,8 @@ scope NSContext; '(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' { Debug("Processing delegate: " + $identifier.text); - dlegate.Uses = this.NameSpaceContext; + dlegate.Uses = this.CollectUses; + dlegate.Aliases = this.CollectAliases; dlegate.TypeName = this.ParentNameSpace + "." + mkTypeName($identifier.text, $variant_generic_parameter_list.tyargs); if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) { dlegate.TypeParams = $variant_generic_parameter_list.tyargs.ToArray(); @@ -903,20 +933,22 @@ parameter_array returns [ParamRepTemplate param]: interface_declaration scope NSContext; @init { - $NSContext::nss = new List(); + $NSContext::searchpath = new List(); + $NSContext::aliases = new List(); InterfaceRepTemplate iface = new InterfaceRepTemplate(); } : 'interface' identifier variant_generic_parameter_list? { Debug("Processing interface: " + $identifier.text); - iface.Uses = this.NameSpaceContext; + iface.Uses = this.CollectUses; + iface.Aliases = this.CollectAliases; iface.TypeName = this.ParentNameSpace + "." + mkTypeName($identifier.text, $variant_generic_parameter_list.tyargs); if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) { iface.TypeParams = $variant_generic_parameter_list.tyargs.ToArray(); } // Nested types can see things in this space - $NSContext::nss.Add(new UseRepTemplate(iface.TypeName)); + $NSContext::searchpath.Add(iface.TypeName); $NSContext::currentNS = iface.TypeName; $NSContext::currentTypeRep = iface; AppEnv[iface.TypeName] = iface; @@ -987,20 +1019,22 @@ method_modifiers: struct_declaration scope NSContext; @init { - $NSContext::nss = new List(); + $NSContext::searchpath = new List(); + $NSContext::aliases = new List(); StructRepTemplate strukt = new StructRepTemplate(); } : 'struct' type_or_generic { Debug("Processing struct: " + $type_or_generic.type); - strukt.Uses = this.NameSpaceContext; + strukt.Uses = this.CollectUses; + strukt.Aliases = this.CollectAliases; strukt.TypeName = this.ParentNameSpace + "." + mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments); if ($type_or_generic.generic_arguments.Count > 0) { strukt.TypeParams = $type_or_generic.generic_arguments.ToArray(); } // Nested types can see things in this space - $NSContext::nss.Add(new UseRepTemplate(strukt.TypeName)); + $NSContext::searchpath.Add(strukt.TypeName); $NSContext::currentNS = strukt.TypeName; $NSContext::currentTypeRep = strukt; AppEnv[strukt.TypeName] = strukt; diff --git a/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs b/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs index 03278ef..bf9f72b 100644 --- a/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs +++ b/CSharpTranslator/antlr3/src/cs2j/Utils/DirectoryHT.cs @@ -171,6 +171,33 @@ namespace RusticiSoftware.Translator.Utils } } + // search for name, given searchPath + // searchPath is searched in reverse order + public TValue Search(List searchPath, string name) { + TValue ret = default(TValue); + bool found = false; + for (int i = searchPath.Count-1; i >= 0; i--) { + String ns = searchPath[i]; + String fullName = (ns ?? "") + (String.IsNullOrEmpty(ns) ? "" : ".") + name; + if (this.ContainsKey(fullName)) { + ret = this[fullName]; + found = true; + break; + } + } + // Check if name is fully qualified + if (!found && this.ContainsKey(name)) { + ret = this[name]; + } + // if (ret != null) + // Console.Out.WriteLine("findType: found {0}", ret.TypeName); + return ret; + } + + public TValue Search(string name) { + return Search(new List(), name); + } + public void Add(KeyValuePair item) { this.Add(item.Key, item.Value);