1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00

rewrite since namespace aliases need to be kept separate from the search path

This commit is contained in:
Kevin Glynn 2011-01-08 17:15:48 +01:00
parent 6270613b46
commit 2f87602d6c
7 changed files with 255 additions and 138 deletions

View File

@ -95,30 +95,28 @@ namespace RusticiSoftware.Translator.CLR
#endregion
}
// A use entry. An optional alias and a fully qualified namespace
public class UseRepTemplate : IEquatable<UseRepTemplate>
// A namespace alias entry.
public class AliasRepTemplate : IEquatable<AliasRepTemplate>
{
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<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, string[] imps, string javaTemplate)
: base(tName, tParams, usePath, imps, javaTemplate)
protected InterfaceRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> es, List<MethodRepTemplate> 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<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts,
public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> 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<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> 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<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> 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<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> 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<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> 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<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> 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<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts)
: base(tName, tParams, usePath, aliases, inherits, cs, ms, ps, fs, es, ixs, cts, null, null)
{
}

View File

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

View File

@ -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<string> inSearchKeys, List<string> inSearchValues) {
public CUnit(CommonTree inTree, List<string> inSearchPath, List<string> inAliasKeys, List<string> inAliasValues) {
Tree = inTree;
SearchPathKeys = inSearchKeys;
SearchPathValues = inSearchValues;
SearchPath = inSearchPath;
NameSpaceAliasKeys = inAliasKeys;
NameSpaceAliasValues = inAliasValues;
}
public CommonTree Tree {get; set;}
public List<string> SearchPathKeys {get; set;}
public List<string> SearchPathValues {get; set;}
// namespaces in scope
public List<string> SearchPath {get; set;}
// aliases for namespaces
public List<string> NameSpaceAliasKeys {get; set;}
public List<string> NameSpaceAliasValues {get; set;}
}
}

View File

@ -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<string> aliases;
// namespaces in scope
List<string> namespaces;
// Alias map: these two lists are actually a map from alias to namespace
// so aliases[i] -> namespaces[i]
List<string> aliasKeys;
List<string> aliasNamespaces;
}
// A scope to keep track of the current type context
@ -55,12 +57,12 @@ scope TypeContext {
}
}
protected List<string> CollectAliases {
protected List<string> CollectSearchPath {
get {
List<string> ret = new List<string>();
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<string> CollectNamespaces {
protected List<string> CollectAliasKeys {
get {
List<string> ret = new List<string>();
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<string> CollectAliasNamespaces {
get {
List<string> ret = new List<string>();
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<string>();
$NSContext::namespaces = new List<string>();
$NSContext::aliasKeys = new List<string>();
$NSContext::aliasNamespaces = new List<string>();
}
:
namespace_body;
@ -246,14 +262,14 @@ namespace_declaration
scope NSContext;
@init {
$NSContext::currentNS = "";
$NSContext::aliases = new List<string>();
$NSContext::namespaces = new List<string>();
$NSContext::aliasKeys = new List<string>();
$NSContext::aliasNamespaces = new List<string>();
}:
'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);
};
}

View File

@ -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<string> aliases;
// all namespaces in scope
List<string> namespaces;
// all namespaces in all scopes
List<string> globalNamespaces;
}
// A scope to keep track of the mapping from variables to types
scope SymTab {
Dictionary<string,TypeRepTemplate> symtab;
}
@namespace { RusticiSoftware.Translator.CSharp }
@ -31,8 +35,9 @@ scope NSContext {
@members
{
// Initial namespace search path gathered in JavaMaker
public List<string> SearchPathKeys { get; set; }
public List<string> SearchPathValues { get; set; }
public List<string> SearchPath { get; set; }
public List<string> AliasKeys { get; set; }
public List<string> AliasNamespaces { get; set; }
private Set<string> 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<string>();
// 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<string>();
$NSContext::globalNamespaces = SearchPath ?? new List<string>();
}:
^(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<string>();
$NSContext::namespaces = new List<string>();
$NSContext::globalNamespaces = new List<string>(((NSContext_scope)$NSContext.ToArray()[1]).globalNamespaces);
$SymTab::symtab = new Dictionary<string, TypeRepTemplate>();
}
:
^(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"; }
;

View File

@ -17,7 +17,8 @@ options {
// A scope to keep track of the namespaces available at any point in the program
scope NSContext {
IList<UseRepTemplate> nss;
IList<string> searchpath;
IList<AliasRepTemplate> 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<UseRepTemplate> rets = new List<UseRepTemplate>();
List<string> rets = new List<string>();
// 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<UseRepTemplate> nss = nscontext.nss;
for (int i = nss.Count - 1; i >= 0; i--) {
rets.Add(nss[i]);
IList<string> 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<AliasRepTemplate> rets = new List<AliasRepTemplate>();
// 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<AliasRepTemplate> 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<UseRepTemplate>();
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
$NSContext::currentNS = "";
$NSContext::currentTypeRep = null;
}
@ -87,13 +110,14 @@ scope NSContext;
namespace_declaration
scope NSContext;
@init{
$NSContext::nss = new List<UseRepTemplate>();
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
$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<UseRepTemplate>();
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
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<UseRepTemplate>();
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
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<UseRepTemplate>();
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
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<UseRepTemplate>();
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
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<UseRepTemplate>();
$NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
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;

View File

@ -171,6 +171,33 @@ namespace RusticiSoftware.Translator.Utils
}
}
// search for name, given searchPath
// searchPath is searched in reverse order
public TValue Search(List<string> 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<string>(), name);
}
public void Add(KeyValuePair<string, TValue> item)
{
this.Add(item.Key, item.Value);