using System;
using System.Collections.Generic;
using System.Resources;
namespace Python.Runtime
{
///
/// This class is responsible for efficiently maintaining the bits
/// of information we need to support aliases with 'nice names'.
///
internal class GenericUtil
{
private static Dictionary>> mapping;
private GenericUtil()
{
}
public static void Reset()
{
mapping = new Dictionary>>();
}
///
/// Register a generic type that appears in a given namespace.
///
internal static void Register(Type t)
{
if (null == t.Namespace || null == t.Name)
{
return;
}
Dictionary> nsmap = null;
mapping.TryGetValue(t.Namespace, out nsmap);
if (nsmap == null)
{
nsmap = new Dictionary>();
mapping[t.Namespace] = nsmap;
}
string basename = t.Name;
int tick = basename.IndexOf("`");
if (tick > -1)
{
basename = basename.Substring(0, tick);
}
List gnames = null;
nsmap.TryGetValue(basename, out gnames);
if (gnames == null)
{
gnames = new List();
nsmap[basename] = gnames;
}
gnames.Add(t.Name);
}
///
/// xxx
///
public static List GetGenericBaseNames(string ns)
{
Dictionary> nsmap = null;
mapping.TryGetValue(ns, out nsmap);
if (nsmap == null)
{
return null;
}
var names = new List();
foreach (string key in nsmap.Keys)
{
names.Add(key);
}
return names;
}
///
/// xxx
///
public static Type GenericForType(Type t, int paramCount)
{
return GenericByName(t.Namespace, t.Name, paramCount);
}
public static Type GenericByName(string ns, string name, int paramCount)
{
foreach (Type t in GenericsByName(ns, name))
{
if (t.GetGenericArguments().Length == paramCount)
{
return t;
}
}
return null;
}
public static List GenericsForType(Type t)
{
return GenericsByName(t.Namespace, t.Name);
}
public static List GenericsByName(string ns, string basename)
{
Dictionary> nsmap = null;
mapping.TryGetValue(ns, out nsmap);
if (nsmap == null)
{
return null;
}
int tick = basename.IndexOf("`");
if (tick > -1)
{
basename = basename.Substring(0, tick);
}
List names = null;
nsmap.TryGetValue(basename, out names);
if (names == null)
{
return null;
}
var result = new List();
foreach (string name in names)
{
string qname = ns + "." + name;
Type o = AssemblyManager.LookupType(qname);
if (o != null)
{
result.Add(o);
}
}
return result;
}
///
/// xxx
///
public static string GenericNameForBaseName(string ns, string name)
{
Dictionary> nsmap = null;
mapping.TryGetValue(ns, out nsmap);
if (nsmap == null)
{
return null;
}
List gnames = null;
nsmap.TryGetValue(name, out gnames);
if (gnames?.Count > 0)
{
return gnames[0];
}
return null;
}
}
}