Exemple #1
0
 public void AddChildren(APIRecord Record)
 {
     foreach (APIRecord DerivedRecord in Record.DerivedRecords)
     {
         APIHierarchyNode DerivedNode = new APIHierarchyNode(DerivedRecord.FullName, DerivedRecord.LinkPath, true);
         Children.Add(DerivedNode);
         DerivedNode.AddChildren(DerivedRecord);
     }
 }
Exemple #2
0
        public static bool CreateParametersStruct(APIPage Parent, List <APIMember> Children, DoxygenEntity Entity)
        {
            string Name        = Entity.Name;
            int    ClassMaxIdx = Name.IndexOf("_event");

            if (ClassMaxIdx == -1)
            {
                return(false);
            }

            string    ClassName   = Name.Substring(0, ClassMaxIdx);
            APIRecord ClassRecord = Children.OfType <APIRecord>().FirstOrDefault(x => x.Name.EndsWith(ClassName) && x.Name.Length == ClassName.Length + 1);

            if (ClassRecord == null)
            {
                return(false);
            }

            if (!Name.EndsWith("_Parms"))
            {
                return(false);
            }
            int    MemberMinIdx = ClassMaxIdx + 6;
            int    MemberMaxIdx = Name.Length - 6;
            string MemberName   = Name.Substring(MemberMinIdx, MemberMaxIdx - MemberMinIdx);

            APIRecord Delegate = Children.OfType <APIRecord>().FirstOrDefault(x => x.Name == "F" + MemberName);

            if (Delegate != null)
            {
                Delegate.DelegateEventParameters = new APIEventParameters(Parent, Delegate, Entity);
                Children.Add(Delegate.DelegateEventParameters);
                return(true);
            }

            APIFunction Function = ClassRecord.Children.OfType <APIFunction>().FirstOrDefault(x => x.Name == MemberName);

            if (Function != null)
            {
                Function.EventParameters = new APIEventParameters(Parent, Function, Entity);
                Children.Add(Function.EventParameters);
                return(true);
            }

            return(false);
        }
        public static List<APIMember> CreateChildren(APIPage Parent, IEnumerable<DoxygenEntity> Entities)
        {
            List<APIMember> Children = new List<APIMember>();
            Dictionary<APIFunctionKey, List<DoxygenEntity>> PendingFunctionGroups = new Dictionary<APIFunctionKey, List<DoxygenEntity>>();

            // List of autogenerated structs
            List<DoxygenEntity> GeneratedEntities = new List<DoxygenEntity>();

            // Parse the entities
            foreach (DoxygenEntity Entity in Entities)
            {
                if (Entity.Kind == "class" || Entity.Kind == "struct" || Entity.Kind == "union")
                {
                    if (Entity.Kind == "struct" && Entity.Name.Contains("_event") && Entity.Name.EndsWith("_Parms"))
                    {
                        GeneratedEntities.Add(Entity);
                    }
                    else
                    {
                        APIRecord Record = new APIRecord(Parent, Entity);
                        Record.Children.AddRange(CreateChildren(Record, Entity.Members));
                        Children.Add(Record);
                    }
                }
                else if (Entity.Kind == "function")
                {
                    APIFunctionKey FunctionKey = APIFunctionKey.FromEntity(Parent, Entity);
                    if (!Program.IgnoredFunctionMacros.Contains(FunctionKey.Name))
                    {
                        List<DoxygenEntity> EntityList;
                        if (!PendingFunctionGroups.TryGetValue(FunctionKey, out EntityList))
                        {
                            EntityList = new List<DoxygenEntity>();
                            PendingFunctionGroups.Add(FunctionKey, EntityList);
                        }
                        EntityList.Add(Entity);
                    }
                }
                else if (Entity.Kind == "variable")
                {
                    if (IsConstantVariable(Entity))
                    {
                        Children.Add(new APIConstantVariable(Parent, Entity));
                    }
                    else
                    {
                        Children.Add(new APIVariable(Parent, Entity.Node));
                    }
                }
                else if (Entity.Kind == "typedef")
                {
                    Children.Add(new APITypeDef(Parent, Entity.Node));
                }
                else if (Entity.Kind == "enum")
                {
                    if (Entity.Name != null && Entity.Name.StartsWith("@"))
                    {
                        // It's an enum constant
                        Children.AddRange(APIConstantEnum.Read(Parent, Entity));
                    }
                    else
                    {
                        // It's an enum
                        Children.Add(new APIEnum(Parent, Entity, Entity.Name));
                    }
                }
            }

            // Fixup the functions
            foreach (KeyValuePair<APIFunctionKey, List<DoxygenEntity>> PendingFunctionGroup in PendingFunctionGroups)
            {
                if (PendingFunctionGroup.Value.Count == 1)
                {
                    APIFunction Function = new APIFunction(Parent, PendingFunctionGroup.Value[0], PendingFunctionGroup.Key);
                    Children.Add(Function);
                }
                else
                {
                    APIFunctionGroup FunctionGroup = new APIFunctionGroup(Parent, PendingFunctionGroup.Key, PendingFunctionGroup.Value);
                    Children.Add(FunctionGroup);
                }
            }

            // Attach all the autogenerated structures to their parent functions
            foreach(DoxygenEntity Entity in GeneratedEntities)
            {
                if(!CreateParametersStruct(Parent, Children, Entity))
                {
                    APIRecord Record = new APIRecord(Parent, Entity);
                    Record.Children.AddRange(CreateChildren(Record, Entity.Members));
                    Children.Add(Record);
                }
            }

            // Sort the children by name
            Children.Sort((x, y) => String.Compare(x.Name, y.Name));
            return Children;
        }
Exemple #4
0
        public static List <APIMember> CreateChildren(APIPage Parent, IEnumerable <DoxygenEntity> Entities)
        {
            List <APIMember> Children = new List <APIMember>();
            Dictionary <APIFunctionKey, List <DoxygenEntity> > PendingFunctionGroups = new Dictionary <APIFunctionKey, List <DoxygenEntity> >();

            // List of autogenerated structs
            List <DoxygenEntity> GeneratedEntities = new List <DoxygenEntity>();

            // Parse the entities
            foreach (DoxygenEntity Entity in Entities)
            {
                if (Entity.Kind == "class" || Entity.Kind == "struct" || Entity.Kind == "union")
                {
                    if (Entity.Kind == "struct" && Entity.Name.Contains("_event") && Entity.Name.EndsWith("_Parms"))
                    {
                        GeneratedEntities.Add(Entity);
                    }
                    else
                    {
                        APIRecord Record = new APIRecord(Parent, Entity);
                        Record.Children.AddRange(CreateChildren(Record, Entity.Members));
                        Children.Add(Record);
                    }
                }
                else if (Entity.Kind == "function")
                {
                    APIFunctionKey FunctionKey = APIFunctionKey.FromEntity(Parent, Entity);
                    if (!Program.IgnoredFunctionMacros.Contains(FunctionKey.Name))
                    {
                        List <DoxygenEntity> EntityList;
                        if (!PendingFunctionGroups.TryGetValue(FunctionKey, out EntityList))
                        {
                            EntityList = new List <DoxygenEntity>();
                            PendingFunctionGroups.Add(FunctionKey, EntityList);
                        }
                        EntityList.Add(Entity);
                    }
                }
                else if (Entity.Kind == "variable")
                {
                    if (IsConstantVariable(Entity))
                    {
                        Children.Add(new APIConstantVariable(Parent, Entity));
                    }
                    else
                    {
                        Children.Add(new APIVariable(Parent, Entity.Node));
                    }
                }
                else if (Entity.Kind == "typedef")
                {
                    Children.Add(new APITypeDef(Parent, Entity));
                }
                else if (Entity.Kind == "enum")
                {
                    if (Entity.Name != null && Entity.Name.StartsWith("@"))
                    {
                        // It's an enum constant
                        Children.AddRange(APIConstantEnum.Read(Parent, Entity));
                    }
                    else
                    {
                        // It's an enum
                        Children.Add(new APIEnum(Parent, Entity, Entity.Name));
                    }
                }
            }

            // Fixup the functions
            foreach (KeyValuePair <APIFunctionKey, List <DoxygenEntity> > PendingFunctionGroup in PendingFunctionGroups)
            {
                if (PendingFunctionGroup.Value.Count == 1)
                {
                    APIFunction Function = new APIFunction(Parent, PendingFunctionGroup.Value[0], PendingFunctionGroup.Key);
                    Children.Add(Function);
                }
                else
                {
                    APIFunctionGroup FunctionGroup = new APIFunctionGroup(Parent, PendingFunctionGroup.Key, PendingFunctionGroup.Value);
                    Children.Add(FunctionGroup);
                }
            }

            // Attach all the autogenerated structures to their parent functions
            foreach (DoxygenEntity Entity in GeneratedEntities)
            {
                if (!CreateParametersStruct(Parent, Children, Entity))
                {
                    APIRecord Record = new APIRecord(Parent, Entity);
                    Record.Children.AddRange(CreateChildren(Record, Entity.Members));
                    Children.Add(Record);
                }
            }

            // Sort the children by name
            Children.Sort((x, y) => String.Compare(x.Name, y.Name));
            return(Children);
        }
Exemple #5
0
        public override void Link()
        {
            // Get the description
            ParseBriefAndFullDescription(Node, out BriefDescription, out FullDescription);

            // Try to link autogenerated exec functions to their original implementation
            if (Utility.IsNullOrWhitespace(BriefDescription) && Utility.IsNullOrWhitespace(FullDescription) && Name.Length >= 5 && Name.StartsWith("exec") && Char.IsUpper(Name[4]))
            {
                APIRecord ParentRecord = Parent as APIRecord;
                if (ParentRecord != null)
                {
                    APIMember TargetMember = ParentRecord.Children.OfType <APIFunction>().FirstOrDefault(x => x.Name == Name.Substring(4));
                    if (TargetMember == null)
                    {
                        TargetMember = ParentRecord.Children.OfType <APIFunctionGroup>().FirstOrDefault(x => x.Name == Name.Substring(4));
                    }
                    if (TargetMember != null)
                    {
                        BriefDescription = String.Format("Wrapper for [{0}]({1}).", TargetMember.Name, TargetMember.LinkPath);
                    }
                }
            }

            // Get the @see directives
            ParseSeeAlso(Node, SeeAlso);

            string RealKeyName = (Entity.Parent != null) ? (Entity.Parent.Name + "::" + Entity.Name) : Entity.Name;

            SnippetText = APISnippets.LoadSnippetTextForSymbol(RealKeyName);

            // Get the modifiers
            IsVirtual = Node.Attributes.GetNamedItem("virt").InnerText == "virtual";
            IsStatic  = Node.Attributes.GetNamedItem("static").InnerText == "yes";

            // Get the metadata
            MetadataDirective = MetadataCache.FindMetadataForMember(Node, "UFUNCTION");

            // Get the template parameters
            TemplateSignature = ParseTemplateSignature(Node);

            // If it's a specialization, add it to the parent class
            if (bIsTemplateSpecialization)
            {
                int StripIdx = FullName.LastIndexOf('<');
                if (StripIdx != -1)
                {
                    APIFunction OriginalTemplateFunction;
                    if (TemplateFunctions.TryGetValue(FullName.Substring(0, StripIdx), out OriginalTemplateFunction))
                    {
                        OriginalTemplateFunction.TemplateSpecializations.Add(this);
                    }
                }
            }

            // Get the parameter declaration nodes
            XmlNodeList ParameterNodes = Node.SelectNodes("param");

            foreach (XmlNode ParameterNode in ParameterNodes)
            {
                Parameters.Add(new APIFunctionParam(this, ParameterNode));
            }

            // If the only parameter is "void", don't bother including it
            if (Parameters.Count == 1 && Parameters[0].Node.SelectSingleNode("type").InnerText == "void")
            {
                Parameters.Clear();
            }

            // Get the parameter description nodes
            XmlNodeList ParameterItemNodes = Node.SelectNodes("detaileddescription/para/parameterlist/parameteritem");

            foreach (XmlNode ParameterItemNode in ParameterItemNodes)
            {
                ParameterSummaries.Add(new APIFunctionParamSummary(this, ParameterItemNode));
            }

            // Get the return type
            XmlNode ReturnTypeNode = Node.SelectSingleNode("type");

            ReturnType = RemoveElaborations(ConvertToMarkdown(ReturnTypeNode));

            // Parse the reimplements list
            using (XmlNodeList ReimplementsList = Node.SelectNodes("reimplements"))
            {
                foreach (XmlNode ReimplementsNode in ReimplementsList)
                {
                    APIFunction Function = ResolveRefLink(ReimplementsNode.Attributes["refid"].Value) as APIFunction;
                    if (Function != null)
                    {
                        Reimplements.Add(Function);
                    }
                }
            }

            // Parse the reimplemented-by list
            using (XmlNodeList ReimplementedByList = Node.SelectNodes("reimplementedby"))
            {
                foreach (XmlNode ReimplementedByNode in ReimplementedByList)
                {
                    APIFunction Function = ResolveRefLink(ReimplementedByNode.Attributes["refid"].Value) as APIFunction;
                    if (Function != null)
                    {
                        ReimplementedBy.Add(Function);
                    }
                }
            }

            // Parse any other notes
            XmlNodeList SimpleNodes = Node.SelectNodes("detaileddescription/para/simplesect");

            foreach (XmlNode node in SimpleNodes)
            {
                switch (node.Attributes.GetNamedItem("kind").InnerText)
                {
                case "return":
                    ReturnDescription = ConvertToMarkdown(node.SelectSingleNode("para"));
                    break;

                case "warning":
                    Warnings.Add(ConvertToMarkdown(node.SelectSingleNode("para")).TrimStart(':'));
                    break;
                }
            }

            // Parse the source lines

            /*
             * XmlNode LocationNode = Node.SelectSingleNode("location");
             * if(LocationNode != null)
             * {
             *      XmlAttribute BodyFileAttribute = LocationNode.Attributes["bodyfile"];
             *      if(BodyFileAttribute != null)
             *      {
             *              string BodyFile = BodyFileAttribute.Value;
             *              if(!BodyFile.ToLowerInvariant().Split('\\', '/').Any(x => Program.ExcludeSourceDirectoriesHash.Contains(x)))
             *              {
             *                      SourceFile File = SourceFileCache.Read(BodyFile);
             *                      if (File != null)
             *                      {
             *                              int BodyStart = Math.Min(Math.Max(Int32.Parse(LocationNode.Attributes["bodystart"].Value) - 1, 0), File.LineOffsets.Length - 1);
             *                              int BodyStartOffset = File.LineOffsets[BodyStart];
             *
             *                              int BodyEnd = Math.Min(Int32.Parse(LocationNode.Attributes["bodyend"].Value), File.LineOffsets.Length - 1);
             *                              int BodyEndOffset = File.LineOffsets[BodyEnd];
             *
             *                              SourceLines = File.Text.Substring(BodyStartOffset, BodyEndOffset - BodyStartOffset).Split('\n');
             *                      }
             *              }
             *      }
             * }
             */
        }
Exemple #6
0
        public APIHierarchyNode AddRoot(APIRecord Record)
        {
            // Try to find the "primary" path to a root object; ignoring interfaces and non-UObject base classes
            List <APIRecord> PrimaryHierarchy = new List <APIRecord>();

            for (APIRecord ParentRecord = Record; ParentRecord != null;)
            {
                // Add the current record
                PrimaryHierarchy.Add(ParentRecord);

                // Try to find a UObject base class
                List <APIRecord> Candidates = new List <APIRecord>();
                foreach (KeyValuePair <XmlNode, APIRecord> BaseRecord in ParentRecord.BaseRecords)
                {
                    if (BaseRecord.Key.InnerText.StartsWith("U") || BaseRecord.Key.InnerText.StartsWith("A"))
                    {
                        Candidates.Add(BaseRecord.Value);
                    }
                }

                // If we didn't get one, add everything else
                if (Candidates.Count == 0)
                {
                    foreach (KeyValuePair <XmlNode, APIRecord> BaseRecord in ParentRecord.BaseRecords)
                    {
                        Candidates.Add(BaseRecord.Value);
                    }
                }

                // Move to the next record
                ParentRecord = (Candidates.Count == 1) ? Candidates[0] : null;
            }

            // Create the hidden root node of the hierarchy
            APIHierarchyNode NextNode = this;

            // Show the list from root; show a flat list of base classes for the last record
            if (PrimaryHierarchy.Last().BaseRecords.Count > 0)
            {
                foreach (KeyValuePair <XmlNode, APIRecord> BaseRecord in PrimaryHierarchy.Last().BaseRecords)
                {
                    if (BaseRecord.Value == null)
                    {
                        NextNode.Children.Add(new APIHierarchyNode(BaseRecord.Key.InnerText, false));
                    }
                    else
                    {
                        NextNode.Children.Add(new APIHierarchyNode(BaseRecord.Value.FullName, BaseRecord.Value.LinkPath, false));
                    }
                }
                NextNode = NextNode.Children.Last();
            }

            // Append the rest of the primary hierarchy
            for (int Idx = PrimaryHierarchy.Count - 1; Idx > 0; Idx--)
            {
                APIRecord ParentRecord = PrimaryHierarchy[Idx];
                NextNode.Children.Add(new APIHierarchyNode(ParentRecord.FullName, ParentRecord.LinkPath, false));
                NextNode = NextNode.Children.Last();
            }

            // Add the current record
            NextNode.Children.Add(new APIHierarchyNode(Record.FullName, false));
            return(NextNode.Children.Last());
        }
        public APIHierarchyNode AddRoot(APIRecord Record)
        {
            // Try to find the "primary" path to a root object; ignoring interfaces and non-UObject base classes
            List<APIRecord> PrimaryHierarchy = new List<APIRecord>();
            for (APIRecord ParentRecord = Record; ParentRecord != null; )
            {
                // Add the current record
                PrimaryHierarchy.Add(ParentRecord);

                // Try to find a UObject base class
                List<APIRecord> Candidates = new List<APIRecord>();
                foreach (KeyValuePair<XmlNode, APIRecord> BaseRecord in ParentRecord.BaseRecords)
                {
                    if (BaseRecord.Key.InnerText.StartsWith("U") || BaseRecord.Key.InnerText.StartsWith("A"))
                    {
                        Candidates.Add(BaseRecord.Value);
                    }
                }

                // If we didn't get one, add everything else
                if (Candidates.Count == 0)
                {
                    foreach (KeyValuePair<XmlNode, APIRecord> BaseRecord in ParentRecord.BaseRecords)
                    {
                        Candidates.Add(BaseRecord.Value);
                    }
                }

                // Move to the next record
                ParentRecord = (Candidates.Count == 1) ? Candidates[0] : null;
            }

            // Create the hidden root node of the hierarchy
            APIHierarchyNode NextNode = this;

            // Show the list from root; show a flat list of base classes for the last record
            if (PrimaryHierarchy.Last().BaseRecords.Count > 0)
            {
                foreach (KeyValuePair<XmlNode, APIRecord> BaseRecord in PrimaryHierarchy.Last().BaseRecords)
                {
                    if (BaseRecord.Value == null)
                    {
                        NextNode.Children.Add(new APIHierarchyNode(BaseRecord.Key.InnerText, false));
                    }
                    else
                    {
                        NextNode.Children.Add(new APIHierarchyNode(BaseRecord.Value.FullName, BaseRecord.Value.LinkPath, false));
                    }
                }
                NextNode = NextNode.Children.Last();
            }

            // Append the rest of the primary hierarchy
            for (int Idx = PrimaryHierarchy.Count - 1; Idx > 0; Idx--)
            {
                APIRecord ParentRecord = PrimaryHierarchy[Idx];
                NextNode.Children.Add(new APIHierarchyNode(ParentRecord.FullName, ParentRecord.LinkPath, false));
                NextNode = NextNode.Children.Last();
            }

            // Add the current record
            NextNode.Children.Add(new APIHierarchyNode(Record.FullName, false));
            return NextNode.Children.Last();
        }
 public void AddChildren(APIRecord Record)
 {
     foreach (APIRecord DerivedRecord in Record.DerivedRecords)
     {
         APIHierarchyNode DerivedNode = new APIHierarchyNode(DerivedRecord.FullName, DerivedRecord.LinkPath, true);
         Children.Add(DerivedNode);
         DerivedNode.AddChildren(DerivedRecord);
     }
 }