aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.IDE/Images/Reference.png
blob: fa543094754d1411c0da803d65536e618fed8c5e (plain)
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 10 00 00 00 10 08 06 00 00 00 1f f3 ff .PNG........IHDR................
0020 61 00 00 00 09 70 48 59 73 00 00 0e c3 00 00 0e c3 01 c7 6f a8 64 00 00 00 3f 49 44 41 54 78 5e a....pHYs..........o.d...?IDATx^
0040 ed 92 3b 0a 00 30 08 43 3d 5b ee 7f 9e ac ed 16 0a fd 0c 0d 4e 1a 08 08 ca 23 a8 51 40 24 c7 cb ..;..0.C=[..........N....#.Q@$..
0060 d7 81 15 00 e0 68 01 f6 86 0f 90 7f 01 aa ed 04 d9 3b f0 af e0 ff 41 2b 26 eb 92 4a 88 44 31 e8 .....h...........;....A+&..J.D1.
0080 1f 00 00 00 00 49 45 4e 44 ae 42 60 82 .....IEND.B`.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Tango.Scripting.Editors.Intellisense
{
    public static class Utils
    {
        private static String dotNetXmlFolder = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.X";
        private static Dictionary<Assembly, XmlDocument> _assemblies_docs_cache;

        static Utils()
        {
            _assemblies_docs_cache = new Dictionary<Assembly, XmlDocument>();
        }

        public static void LoadKnownTypeDocs(KnownType knownType)
        {
            XmlDocument xmlDoc = null;

            if (_assemblies_docs_cache.ContainsKey(knownType.Type.Assembly))
            {
                xmlDoc = _assemblies_docs_cache[knownType.Type.Assembly];
            }

            if (xmlDoc == null)
            {
                String dllPath = knownType.Type.Assembly.Location;

                string docuPath = dllPath.Substring(0, dllPath.LastIndexOf(".")) + ".XML";

                if (File.Exists(docuPath))
                {
                    xmlDoc = new XmlDocument();
                    xmlDoc.Load(docuPath);
                }
                else if (File.Exists(System.IO.Path.Combine(dotNetXmlFolder, System.IO.Path.GetFileName(docuPath))))
                {
                    xmlDoc = new XmlDocument();
                    xmlDoc.Load(System.IO.Path.Combine(dotNetXmlFolder, System.IO.Path.GetFileName(docuPath)));
                }

                if (xmlDoc != null)
                {
                    _assemblies_docs_cache.Add(knownType.Type.Assembly, xmlDoc);
                }
            }

            if (xmlDoc == null)
            {
                xmlDoc = new XmlDocument();
            }

            //Load Type Summary
            {
                string path = "T:" + knownType.Type.FullName;
                XmlNode xmlDocuOfType = xmlDoc.SelectSingleNode("//member[starts-with(@name, '" + path + "')]");

                if (xmlDocuOfType != null)
                {
                    XmlNode summaryNode = xmlDocuOfType.SelectSingleNode("summary");
                    knownType.Summary = summaryNode.InnerText;
                }
            }

            //Load Constructors...
            {
                string path = "M:" + knownType.Type.FullName + ".#ctor";

                var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType<XmlNode>().ToList();

                for (int i = 0; i < knownType.Constructors.Count; i++)
                {
                    var constructor = knownType.Constructors[i];
                    XmlNode cDoc = null;

                    if (i < docNodes.Count)
                    {
                        cDoc = docNodes[i];
                    }

                    constructor.Summary = cDoc != null ? cDoc.SelectSingleNode("summary").InnerXml : $"Initializes a new instance of {knownType.FriendlyName}.";

                    var parameters = constructor.Parameters.ToList();
                    var parametersNodes = cDoc != null ? cDoc.SelectNodes("param").OfType<XmlNode>().ToList() : new List<XmlNode>();

                    for (int j = 0; j < parameters.Count; j++)
                    {
                        var parameter = parameters[j];
                        XmlNode pNode = null;

                        if (j < parametersNodes.Count)
                        {
                            pNode = parametersNodes[j];
                        }

                        parameter.Description = pNode != null ? pNode.InnerText : null;
                    }
                }
            }

            //Load Methods...
            {
                string path = "M:" + knownType.Type.FullName;

                var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType<XmlNode>().ToList();

                for (int i = 0; i < knownType.Methods.Count; i++)
                {
                    var method = knownType.Methods[i];
                    XmlNode mDoc = null;

                    mDoc = docNodes.FirstOrDefault(x => x.Attributes["name"].InnerText.Contains(knownType.Type.Name + "." + method.Name));
                    method.Summary = mDoc != null ? mDoc.SelectSingleNode("summary").InnerXml.Remove("(<see cref=\".:)|(\" \\/>)") : "No documentation";

                    var parameters = method.Parameters.ToList();
                    var parametersNodes = mDoc != null ? mDoc.SelectNodes("param").OfType<XmlNode>().ToList() : new List<XmlNode>();

                    bool isLinq = knownType.Type == typeof(Enumerable);

                    for (int j = 0; j < parameters.Count; j++)
                    {
                        var parameter = parameters[j];

                        XmlNode pNode = null;

                        if (j < parametersNodes.Count)
                        {
                            pNode = parametersNodes[j];
                        }

                        parameter.Description = pNode != null ? pNode.InnerText.Remove("(<see cref=\".:)|(\" \\/>)") : null;
                    }
                }
            }

            //Load Properties
            {
                string path = "P:" + knownType.Type.FullName;

                var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType<XmlNode>().ToList();

                for (int i = 0; i < knownType.Properties.Count; i++)
                {
                    var property = knownType.Properties[i];
                    var pDoc = docNodes.FirstOrDefault(x => x.Attributes["name"].InnerText.Contains(knownType.Type.Name + "." + property.Name));


                    if (pDoc != null)
                    {
                        var summaryNode = pDoc.SelectSingleNode("summary");
                        property.Summary = summaryNode != null ? summaryNode.InnerXml : "No documentation";
                    }
                }
            }

            //Load Enum Values
            {
                if (knownType.Type.IsEnum)
                {
                    for (int i = 0; i < knownType.Fields.Count; i++)
                    {
                        var field = knownType.Fields[i];
                        var pDoc = xmlDoc.SelectSingleNode("//member[starts-with(@name, '" + $"F:{knownType.Type.FullName}.{field.Name}" + "')]");

                        if (pDoc != null)
                        {
                            var summaryNode = pDoc.SelectSingleNode("summary");
                            field.Summary = summaryNode != null ? summaryNode.InnerXml : "No documentation";
                        }
                    }
                }
            }
        }
    }
}