/// <summary> /// Retourne le nom complet du type se trouvant dans un des assemblys donnés, ainsi que /// l'assembly dans lequel il se trouve. /// </summary> /// <param name="loadedAssemblies">Assemblies chargés</param> /// <param name="loadedNamespaces">Namespaces chargés</param> /// <param name="incompleteTypeName">Nom incomplet du type à retrouver.</param> /// <returns></returns> public static Tuple <Assembly, string> FindFullName(Dictionary <string, Assembly> loadedAssemblies, List <string> loadedNamespaces, string incompleteTypeName) { ExpressionTree.GlobalContext glob = new ExpressionTree.GlobalContext(); ExpressionTree.Context context = new ExpressionTree.Context(glob); glob.LoadedAssemblies = loadedAssemblies; glob.LoadedNamespaces = loadedNamespaces; return(FindFullName(context, incompleteTypeName)); }
/// <summary> /// Retourne le nom complet du type dans l'assembly donné. /// En gros cela rajoute le nom de l'assembly au nom du type donné. /// </summary> /// <param name="context">Contexte actuel.</param> /// <param name="assembly">Assembly contenant le type.</param> /// <param name="incompleteTypeName">Nom incomplet du type à retrouver.</param> /// <returns></returns> public static string FindFullName(ExpressionTree.Context context, Assembly assembly, string incompleteTypeName, bool throwOnError) { // Vérifie d'abord parmi les types système. var sysType = SystemType(incompleteTypeName); if (sysType != null) { return(sysType.FullName); } string namespaceName = null; // Vérifie que le nom du type ne soit pas déjà complet : if (assembly.GetType(incompleteTypeName) != null) { return(incompleteTypeName); } // Si ce n'est pas le cas : foreach (string _namespace in context.GlobalContext.LoadedNamespaces) { // On ajoute Namespace+Type string temp = String.Format("{0}.{1}", _namespace, incompleteTypeName); // Si le type existe dans cet assembly. if (assembly.GetType(temp) != null) { if (namespaceName == null) { namespaceName = _namespace; } else { // Balance l'exception même si throwOnError vaut true. throw new InterpreterException(String.Format("Le type {0} existe dans les namespaces {1} et {2}", incompleteTypeName, namespaceName, _namespace)); } } } if (namespaceName == null) { if (throwOnError) { throw new InterpreterException(String.Format("Le type {0} ne peut pas être reconnu dans l'assembly {1}", incompleteTypeName, assembly.FullName)); } else { return(null); } } else { return(String.Format("{0}.{1}", namespaceName, incompleteTypeName)); } }
/// <summary> /// Retourne le nom complet du type se trouvant dans un des assemblys donnés, ainsi que /// l'assembly dans lequel il se trouve. /// </summary> /// <param name="context">Contexte actuel.</param> /// <param name="incompleteTypeName">Nom incomplet du type à retrouver.</param> /// <returns></returns> public static Tuple <Assembly, string> FindFullName(ExpressionTree.Context context, string incompleteTypeName) { // Vérifie d'abord parmi les types système. var sysType = SystemType(incompleteTypeName); if (sysType != null) { return(new Tuple <Assembly, string>(Assembly.GetAssembly(sysType), sysType.FullName)); } string fullName = null; // Assemblies du contexte. IEnumerable <Assembly> assemblies = context.GlobalContext.LoadedAssemblies.Values; Assembly assembly = null; foreach (Assembly a in assemblies) { string temp = FindFullName(context, a, incompleteTypeName, false); if (temp != null) { // Vérifie qu'on a pas déja un résultat // Si c'est le cas, le type existe dans 2 assemblies. if (fullName == null) { fullName = temp; assembly = a; } else { throw new InterpreterException(String.Format("Le type {0} existe dans les assemblys {1} et {2}", incompleteTypeName, a.FullName, assembly.FullName)); } } } if (fullName == null) { throw new InterpreterException(String.Format("Le type {0} n'a pas été trouvé.", incompleteTypeName)); } else { return(new Tuple <Assembly, string>(assembly, fullName)); } }
/// <summary> /// Recherche un type défini par un nom donné. /// Cette méthode n'est pas faîte pour être exécutée un trop grand nombre de fois. /// Il est préférable de mettre en cache les résultats. /// </summary> /// <param name="context">Contexte où se trouve le type.</param> /// <param name="typename">Nom complet du type. Ex : Machin.Truc.Bidule. /// Si le nom n'est pas complet, le paramètre isFullTypeName doit valoir false.</param> /// <param name="assemblyNamme">Nom de l'assembly contenant le type. /// Null ou "default" signifie qu'il s'agit de l'assembly en cours d'exécution.</param> /// <returns>Un tuple contenant : le type de l'objet, le type des arguments génériques si le type /// concerné est générique, sinon, null.</returns> public static Type FindType(ExpressionTree.Context context, string assemblyName, string typename, List <ExpressionTree.IGettable> genericParameters, List <List <ExpressionTree.IGettable> > indexingParameters, bool isFullTypeName) { // Assembly content le type Assembly assembly; bool isGeneric = genericParameters.Count != 0; bool isArray = indexingParameters.Count != 0; // Build le vrai nom complet du type. // ---------------------------------- StringBuilder fullTypeNameBuilder = new StringBuilder(); fullTypeNameBuilder.Append(typename); if (isGeneric) { fullTypeNameBuilder.Append('`'); fullTypeNameBuilder.Append(genericParameters.Count); } if (isArray) { foreach (List <ExpressionTree.IGettable> parameters in indexingParameters) { fullTypeNameBuilder.Append('['); for (int i = 0; i < parameters.Count - 1; i++) { fullTypeNameBuilder.Append(','); } fullTypeNameBuilder.Append(']'); } } typename = fullTypeNameBuilder.ToString(); // Trouve l'assembly contenant le nom du type. if (assemblyName == null) { assembly = null; } else if (assemblyName == "default") { // méthode sale pour obtenir l'assembly contenant les types systèmes. assembly = Assembly.GetAssembly(typeof(char)); } else { assembly = context.GlobalContext.LoadedAssemblies[assemblyName]; } // Maintenant il faut juste trouver le type dans un assembly. // ----------------------------------------------------------- // Si le nom du type n'est pas complet, on essaie de retrouver le nom complet : if (!isFullTypeName) { if (assembly == null) { // Assembly / nom complet du type var tup = FindFullName(context, typename); assembly = tup.Item1; typename = tup.Item2; } else { typename = FindFullName(context, assembly, typename, true); } } else { // Si on a pas le nom de l'assembly : on va chercher ! if (assembly == null) { assembly = SeekAssemblyContainingType(context.GlobalContext.LoadedAssemblies.Values, typename); } } if (genericParameters.Count == 0) { // On n'a qu'à chercher le type dans l'assembly. return(assembly.GetType(typename)); } else { Type[] genericParams = new Type[genericParameters.Count]; for (int i = 0; i < genericParameters.Count; i++) { genericParams[i] = ((ExpressionTree.InternalTypeRepresentation)genericParameters[i].GetValue(context)).T; } return(assembly.GetType(typename).MakeGenericType(genericParams)); } }