/// <summary> /// Finds a type (e.g. a class) within this namespace. This namespace and all parent namespaces /// will be searched (where this namespace will be searched first). Child namespace won't be searched. /// The type is searched for as if it would be used directly within a <c>namespace</c> block (or within a nested /// class directly inside a <c>namespace</c> block). /// </summary> /// <typeparam name="T">the type of the definition to be returned (e.g. <see cref="ClassDefinition"/>).</typeparam> /// <param name="name">the name of the type. The name must be specified without namespace. </param> /// <param name="raiseException">indicates whether an exception is to be thrown when the type can't /// be found. If this is <c>false</c>, an instance of <see cref="DefInternal"/> will be returned when /// the type couldn't be found.</param> /// <returns></returns> /// <seealso cref="AbstractTypeDefinition.DetermineType"/> public virtual T DetermineType <T>(string name, bool raiseException = true) where T : AbstractTypeDefinition { // Search this namespace AbstractTypeDefinition type = FindTypeInList <T>(name, _containedTypes); // Search parent namespace for the type. if (type == null) { if (ParentNamespace != null) { return(ParentNamespace.DetermineType <T>(name, raiseException)); } if (raiseException) { throw new Exception("Could not find type"); } return((T)(object)new DefInternal(this, name)); } if (type is AbstractTypeDefinition && type.IsIgnored) { // Short circuit out to handle OGRE 1.6 memory allocator types // TODO by manski: ??? Document this more clearly. return((T)type); } return((T)type.ResolveType()); }
/// <summary> /// Determines a type (e.g. class, enum, typedef) as if it was used directly at a certain position in the code /// (i.e. from the type definition's perspective). Consider the following C# code example: /// /// <code> /// namespace MyNamespace { /// public class MyClass { /// } /// /// public class MySecondClass { /// public MyClass MyVar; // Using MyClass /// } /// /// public class MyThirdClass { /// public MyClass MyVar; // Using MyClass /// /// public class MyClass { /// } /// } /// } /// </code> /// /// The type returned for <c>MyClass</c> will be different depending on where the type is used. /// If it's used by <c>MySecondClass</c> it's the first class <c>MyClass</c>. If it's used /// by <c>MyThirdClass</c> it's the inner class. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name">the name of the type. Can be fully qualified (i.e. with namespace and surrounding /// class).</param> /// <param name="raiseException">indicates whether an exception is to be thrown when the type can't /// be found. If this is <c>false</c>, an instance of <see cref="DefInternal"/> will be returned when /// the type couldn't be found.</param> /// <returns></returns> public virtual T DetermineType <T>(string name, bool raiseException = true) where T : AbstractTypeDefinition { if (name.StartsWith(this.MetaDef.NativeNamespace + "::")) { name = name.Substring(name.IndexOf("::") + 2); return(Namespace.DetermineType <T>(name, raiseException)); } return((IsNested) ? SurroundingClass.DetermineType <T>(name, raiseException) : Namespace.DetermineType <T>(name, raiseException)); }