protected void FillInheritedMembers(ArticleItemYaml yaml, XElement node)
        {
            var allMembers = from m in node.NullableElement("listofallmembers").Elements("member")
                             where !YamlUtility.IsFiltered(m.NullableAttribute("prot").NullableValue())
                             select m.NullableAttribute("refid").NullableValue();

            yaml.InheritedMembers = allMembers.Except(yaml.Children).ToList();
            _references.AddRange(yaml.InheritedMembers.Select(i => new ReferenceViewModel {
                Uid = i
            }));
        }
Exemple #2
0
        public Task RunAsync(BuildContext context)
        {
            var config = context.GetSharedObject(Constants.Config) as ConfigModel;

            if (config == null)
            {
                throw new ApplicationException(string.Format("Key: {0} doesn't exist in build context", Constants.Config));
            }

            var    extendedIdMappings = context.GetSharedObject(Constants.ExtendedIdMappings) as ConcurrentDictionary <string, string>;
            string inputPath          = StepUtility.GetProcessedXmlOutputPath(config.OutputPath);

            // Parse Index file
            string indexFile = Path.Combine(inputPath, Constants.IndexFileName);

            using (var stream = File.OpenRead(indexFile))
            {
                XDocument doc = XDocument.Load(stream);
                _changeDict = (from ele in doc.Root.Elements("compound")
                               let uid = (string)ele.Attribute("refid")
                                         let type = ParseType((string)ele.Attribute("kind"))
                                                    where uid != null && type.HasValue
                                                    select new HierarchyChange
                {
                    Uid = uid,
                    Name = (string)ele.Element("name"),
                    File = extendedIdMappings.ContainsKey(uid) ? extendedIdMappings[uid] + Constants.XmlExtension : uid + Constants.XmlExtension,
                    Type = type.Value,
                }).ToDictionary(c => c.Uid);
            }

            // Parse File to get parent/children info and package-private/private items
            // assume that couldn't define public class inside package-private/private class
            var itemsToRemove = new List <string>();

            foreach (var pair in _changeDict)
            {
                using (var stream = File.OpenRead(Path.Combine(inputPath, pair.Value.File)))
                {
                    HashSet <string> children = new HashSet <string>();
                    string           parent   = pair.Key;
                    XDocument        doc      = XDocument.Load(stream);
                    var def = doc.Root.Element("compounddef");
                    if (def == null)
                    {
                        throw new ApplicationException(string.Format("there is no compounddef section for {0}", parent));
                    }

                    // filter out package-private item
                    var prot = (string)def.Attribute("prot");
                    if (YamlUtility.IsFiltered(prot))
                    {
                        itemsToRemove.Add(pair.Key);

                        // add innerclass because Doxygen would still output nested public classes
                        var inner = def.Elements("innerclass").Select(i => (string)i.Attribute("refid"));
                        itemsToRemove.AddRange(inner);
                        continue;
                    }

                    // check innerclass's access label because Doxygen would still output nested private/package-private classes
                    var innerClasses = def.Elements("innerclass").Where(e => !YamlUtility.IsFiltered((string)e.Attribute("prot")));
                    foreach (var inner in innerClasses)
                    {
                        string          innerId = (string)inner.Attribute("refid");
                        HierarchyChange change;
                        if (innerId == null || !_changeDict.TryGetValue(innerId, out change))
                        {
                            throw new ApplicationException(string.Format("Inner {0} isn't in change dict.", innerId));
                        }
                        change.Parent = parent;
                        children.Add(innerId);
                    }
                    pair.Value.Children = children;
                }
            }
            foreach (var key in itemsToRemove)
            {
                _changeDict.Remove(key);
            }

            // remove namespace that is empty and update its parent
            var dict = new Dictionary <string, HierarchyChange>(_changeDict);

            foreach (var change in from c in _changeDict.Values
                     where c.Type == HierarchyType.Namespace
                     orderby c.Children.Count
                     select c)
            {
                if (change.Children.Count() == 0)
                {
                    if (!dict.Remove(change.Uid))
                    {
                        throw new ApplicationException(string.Format("fail to remove empty namespace change: {0}", change.Uid));
                    }

                    if (change.Parent != null)
                    {
                        dict[change.Parent].Children.Remove(change.Uid);
                    }
                }
            }
            _changeDict = dict;

            // update innerclass's parent to its outerclass's parent recursively until namespace
            foreach (var pair in _changeDict)
            {
                string parent         = pair.Value.Parent;
                string originalParent = parent;
                while (parent != null)
                {
                    var parentChange = _changeDict[parent];
                    if (parentChange.Type == HierarchyType.Namespace)
                    {
                        pair.Value.Parent = parent;
                        if (originalParent != parent)
                        {
                            _changeDict[parent].Children.Add(pair.Key);
                            _changeDict[originalParent].Children.Remove(pair.Key);
                        }
                        break;
                    }
                    parent = parentChange.Parent;
                }
            }

            context.SetSharedObject(Constants.Changes, _changeDict);
            return(Task.FromResult(1));
        }