Beispiel #1
0
        /// <summary>
        /// Parses a .Net XML documentation type, method, or other member name.
        /// </summary>
        /// <param name="name">
        ///   <list>
        ///     <item>Names starting with "T:" are parsed as Type names.</item>
        ///     <item>Names starting with "M:" are parsed as Method names.</item>
        ///     <item>Names starting with "F:" are parsed as Member names.</item>
        ///     <item>Names starting with "P:" are parsed as Member names.</item>
        ///     <item>Names starting with "E:" are parsed as Member names.</item>
        ///     <item>All others are parsed as Member names.</item>
        ///   </list>
        /// </param>
        public static DotNetQualifiedName FromVisualStudioXml(string name)
        {
            if (String.IsNullOrEmpty(name))
            {
                return(new DotNetQualifiedName());
            }

            if (name.Length < 2 || name[1] != ':')
            {
                return(MemberNameFromVisualStudioXml(name));
            }

            switch (name[0])
            {
            case 'T': return(DotNetQualifiedClassName.FromVisualStudioXml(name));

            case 'M': return(DotNetQualifiedMethodName.FromVisualStudioXml(name));

            case 'F':
            case 'P':
            case 'E': return(MemberNameFromVisualStudioXml(name));

            default: return(MemberNameFromVisualStudioXml(name));
            }
        }
        /// <summary>
        /// Parses a .Net XML documentation type name or namespace name.
        /// </summary>
        /// <remarks>
        /// Does not differentiate between types and namespaces
        /// because a nested type will have other type names in its namespace path
        /// and there are no important diffences in parsing the two.
        /// </remarks>
        /// <example>
        ///   <para>
        ///     How .Net xml documentation formats generic types:
        ///     Backtics are followed by integers, identifying generic types.
        ///   </para>
        ///   <para>
        ///     Single backtics (such as `1) on a class declaration indicate a count of generic types for the class.
        ///     For example, <![CDATA[MyGenericType<T,U,V>]]> is documented as <c>MyGenericType`3</c>.
        ///     Anywhere else within this object's documentation that a single backtic appears, it indicates the zero-based index of the generic type in reference to the class declaration.
        ///     For example, the constructor <![CDATA[MyGenericType(T,U,V)]]> is documented as <c>MyGenericType.#ctor(`0,`1,`2)</c>.
        ///   </para>
        /// </example>
        /// <param name="name">Name may or may not start with "T:"</param>
        public new static DotNetQualifiedClassName FromVisualStudioXml(string name)
        {
            if (name.StartsWith("T:"))
            {
                name = name.Substring(2);
            }

            int    divider       = name.LastIndexOf('.');
            string localName     = name;
            string fullNamespace = null;

            if (divider != -1)
            {
                localName     = name.Substring(divider + 1);
                fullNamespace = name.Substring(0, divider);
            }

            int classGenericTypeCount = 0;

            if (localName.Contains("`"))
            {
                Int32.TryParse(localName.Substring(localName.IndexOf('`') + 1), out classGenericTypeCount);
                localName = localName.Substring(0, localName.IndexOf('`'));
            }

            if (String.IsNullOrEmpty(fullNamespace))
            {
                return(new DotNetQualifiedClassName(localName, classGenericTypeCount));
            }

            return(new DotNetQualifiedClassName(localName, DotNetQualifiedClassName.FromVisualStudioXml(fullNamespace), classGenericTypeCount));
        }
Beispiel #3
0
        /// <summary>
        /// Parse .Net XML documentation for Type data.
        /// </summary>
        /// <param name="memberElement">Expects tag name "member".</param>
        /// <example><![CDATA[<member name="T:Namespace.Type"></member>]]></example>
        public static DotNetType FromVisualStudioXml(XElement memberElement)
        {
            DotNetQualifiedClassName name = DotNetQualifiedClassName.FromVisualStudioXml(memberElement.GetAttributeValue("name"));
            DotNetType type = new DotNetType(name);

            type.ParseVisualStudioXmlDocumentation(memberElement);
            return(type);
        }
        /// <summary>
        /// Returns deep clone of qualified name.
        /// </summary>
        public new DotNetQualifiedClassName Clone()
        {
            DotNetQualifiedClassName clonedFullNamespace = null;

            if (FullNamespace != null)
            {
                clonedFullNamespace = FullClassNamespace.Clone();
            }

            return(new DotNetQualifiedClassName(localName, clonedFullNamespace, GenericTypeCount));
        }
Beispiel #5
0
        /// <summary>
        /// Parses a .Net XML documentation member name.
        /// </summary>
        /// <remarks>
        /// There is no support for generic types here because .Net XMl documentation does not include member types, just the names.
        /// </remarks>
        /// <remarks>
        /// Does not parse method names; use DotNetQualifiedMethodName.FromVisualStudioXml(string) instead.
        /// </remarks>
        /// <example>
        /// Expected formats:
        /// - "F:NamespaceA.NamespaceB.MemberC"
        /// - "P:NamespaceA.NamespaceB.MemberC"
        /// - "E:NamespaceA.NamespaceB.MemberC"
        /// - "NamespaceA.NamespaceB.MemberC"
        /// - "NamespaceA.NamespaceB.InterfaceNamespace#Interface#MemberC"
        /// </example>
        /// <param name="name">Name may or may not start with /[FPE]:/</param>
        private static DotNetQualifiedName MemberNameFromVisualStudioXml(string name)
        {
            if (name.StartsWith("F:"))
            {
                name = name.Substring(2);
            }
            if (name.StartsWith("P:"))
            {
                name = name.Substring(2);
            }
            if (name.StartsWith("E:"))
            {
                name = name.Substring(2);
            }

            int    divider       = name.LastIndexOf('.');
            string localName     = name;
            string fullNamespace = null;

            if (divider != -1)
            {
                localName     = name.Substring(divider + 1);
                fullNamespace = name.Substring(0, divider);
            }

            DotNetQualifiedName explicitInterface = null;

            if (localName.Contains("#"))
            {
                int    lastIndex     = localName.LastIndexOf("#");
                string interfaceName = localName.Substring(0, lastIndex).Replace("#", ".");
                explicitInterface = DotNetQualifiedName.FromVisualStudioXml(interfaceName);
                localName         = localName.Substring(lastIndex + 1);
            }

            if (String.IsNullOrEmpty(fullNamespace))
            {
                return(new DotNetQualifiedName(localName, explicitInterface));
            }

            return(new DotNetQualifiedName(localName, DotNetQualifiedClassName.FromVisualStudioXml(fullNamespace), explicitInterface));
        }
Beispiel #6
0
 /// <summary></summary>
 public DotNetType(DotNetQualifiedClassName name) : base(name)
 {
     Category = TypeCategory.Unknown;
     IsSealed = false;
 }
Beispiel #7
0
 /// <summary>
 /// Constructors need to reference the actual name of their type so they display the right name with aliases.
 /// </summary>
 internal void SetClassName(DotNetQualifiedClassName className)
 {
     MethodName.SetClassName(className);
 }
 /// <summary></summary>
 public DotNetQualifiedClassName(string localName, DotNetQualifiedClassName fullNamespace, int genericTypeCount = 0) : base(localName, fullNamespace, null)
 {
     GenericTypeCount = genericTypeCount;
 }
Beispiel #9
0
        /// <summary>
        /// Insert a new namespace into its proper position, based on the current node as the root.
        /// </summary>
        public void Insert(DotNetQualifiedClassName name)
        {
            //first root
            if (this.Value == null && this.Children.Count == 0)
            {
                this.Value = name;
                return;
            }

            if (this.Value == null)            //null root over multiple top-level namespaces
            {
                //this belongs below a child
                foreach (DotNetQualifiedClassNameTreeNode childNode in this.Children)
                {
                    if (name.IsWithin(childNode.Value))
                    {
                        childNode.Insert(name);
                        return;
                    }
                }
                //this is at the same level as children
                DotNetQualifiedClassNameTreeNode newNode = new DotNetQualifiedClassNameTreeNode(name);
                this.AddChild(newNode);
                //children that belong below the new node
                int index = 0;
                while (index < this.Children.Count)
                {
                    if (this.Children[index].Value.IsWithin(name))
                    {
                        this.TransferChildTo(this.Children[index], newNode);
                        continue;
                    }
                    index++;
                }
                //all children are within new name
                if (this.Children.Count == 1)
                {
                    newNode.TransferChildrenTo(this);
                    this.Value = newNode.Value;
                    this.Children.Remove(newNode);
                }
            }
            else                               //normal, full tree
            {
                if (this.Value.IsWithin(name)) //new root
                {
                    DotNetQualifiedClassNameTreeNode rootTransfer = new DotNetQualifiedClassNameTreeNode(this.Value);
                    this.TransferChildrenTo(rootTransfer);
                    this.Value = name;
                    this.AddChild(rootTransfer);
                    return;
                }
                else if (name.IsWithin(this.Value))                //descendent of root
                {
                    //belongs below a child
                    foreach (DotNetQualifiedClassNameTreeNode childNode in this.Children)
                    {
                        if (name.IsWithin(childNode.Value))
                        {
                            childNode.Insert(name);
                            return;
                        }
                    }
                    //belongs at same level as children
                    DotNetQualifiedClassNameTreeNode newNode = new DotNetQualifiedClassNameTreeNode(name);
                    this.AddChild(newNode);
                    //children that belong below the new node
                    int index = 0;
                    while (index < this.Children.Count)
                    {
                        if (this.Children[index].Value.IsWithin(name))
                        {
                            this.TransferChildTo(this.Children[index], newNode);
                            continue;
                        }
                        index++;
                    }
                }
                else                 //same level as root
                {
                    DotNetQualifiedClassNameTreeNode rootTransfer = new DotNetQualifiedClassNameTreeNode(this.Value);
                    this.TransferChildrenTo(rootTransfer);
                    this.Value = null;
                    this.AddChild(rootTransfer);
                    DotNetQualifiedClassNameTreeNode newNode = new DotNetQualifiedClassNameTreeNode(name);
                    this.AddChild(newNode);
                }
            }
        }
Beispiel #10
0
 internal DotNetQualifiedClassNameTreeNode(DotNetQualifiedClassName value)
 {
     Value    = value;
     Parent   = null;
     Children = new List <DotNetQualifiedClassNameTreeNode>();
 }