Ejemplo n.º 1
0
 internal XSharpLibraryNode(XEntityDefinition scope, string namePrefix, IVsHierarchy hierarchy, uint itemId)
     : base(scope.FullName)
 {
     if (scope.Kind == Kind.Namespace)
     {
         this.NodeType = LibraryNodeType.Namespaces;
     }
     else if (scope.Kind.IsType())
     {
         this.NodeType = LibraryNodeType.Classes;
     }
     else
     {
         this.NodeType = LibraryNodeType.Members;
     }
     //
     this.filesId = new List <uint>();
     //
     this.ownerHierarchy = hierarchy;
     this.Depends(itemId);
     this.member = scope;
     // Can we Goto ?
     if ((ownerHierarchy != null) && (VSConstants.VSITEMID_NIL != itemId))
     {
         this.CanGoToSource = true;
     }
     //
     this.buildImageData(scope.Kind, scope.Modifiers);
 }
Ejemplo n.º 2
0
 internal XSharpLibraryNode(XSharpLibraryNode node) :
     base(node)
 {
     this.filesId = new List <uint>();
     this.Depends(node.filesId);
     this.ownerHierarchy = node.ownerHierarchy;
     this.fileMoniker    = node.fileMoniker;
     this.member         = node.member;
     this.NodeType       = node.NodeType;
 }
Ejemplo n.º 3
0
 internal XSharpLibraryNode(string namePrefix, LibraryNodeType nType)
     : base(namePrefix)
 {
     //
     this.filesId = new List <uint>();
     //
     this.ownerHierarchy = null;
     this.Depends(0);
     this.member   = null;
     this.NodeType = nType;
 }
Ejemplo n.º 4
0
        private void initText(XEntityDefinition member)
        {
            string descText = this.Name;

            //
            if (member != null)
            {
                if (member.Parent is XTypeDefinition)
                {
                    nameSp    = ((XTypeDefinition)member.Parent).Namespace;
                    className = ((XTypeDefinition)member.Parent).Name;
                }
                //
                descText = member.Name;
                if (member is XMemberDefinition)
                {
                    var tm = member as XMemberDefinition;
                    if (tm.Kind == Kind.Constructor)
                    {
                        descText = "Constructor";
                    }
                    else
                    {
                        descText = member.Name;
                    }
                    if ((tm.Kind == Kind.Method) || (tm.Kind == Kind.Function) || (tm.Kind == Kind.Procedure) || (tm.Kind == Kind.Constructor))
                    {
                        descText += "( ";
                        if (tm.HasParameters)
                        {
                            //
                            descText += tm.ParameterList;
                        }
                        descText += ")";
                    }
                }
                else if (member is XTypeDefinition)
                {
                    var tm = member as XTypeDefinition;
                    if ((tm.Kind == Kind.Namespace) && (String.IsNullOrEmpty(descText)))
                    {
                        descText = "Default NameSpace";
                    }
                }
            }
            nodeText = descText;
        }
Ejemplo n.º 5
0
 internal XSharpLibraryNode(XEntityDefinition scope, string namePrefix, IVsHierarchy hierarchy, uint itemId)
     : base(String.IsNullOrEmpty(scope.FullName) ? namePrefix : scope.FullName)
 {
     if (scope.Kind == Kind.Namespace)
     {
         this.NodeType = LibraryNodeType.Namespaces;
     }
     else if (scope.Kind.IsType())
     {
         this.NodeType = LibraryNodeType.Classes;
     }
     else
     {
         this.NodeType = LibraryNodeType.Members;
     }
     //
     this.filesId = new List <uint>();
     //
     this.ownerHierarchy = hierarchy;
     this.Depends(itemId);
     //this.member = scope;
     // Can we Goto ?
     if ((ownerHierarchy != null) && (VSConstants.VSITEMID_NIL != itemId))
     {
         this.CanGoToSource = true;
         this.editorInfo    = new SourcePosition()
         {
             FileName = scope.File.FullPath,
             Line     = scope.Range.StartLine + 1,
             Column   = scope.Range.StartColumn,
         };
     }
     //
     this.buildImageData(scope.Kind, scope.Modifiers);
     this.initText(scope);
     this.initDescription(scope);
 }
        public override bool OnSynchronizeDropdowns(
            Microsoft.VisualStudio.Package.LanguageService languageService,
            IVsTextView textView,
            int line,
            int col,
            ArrayList dropDownTypes,
            ArrayList dropDownMembers,
            ref int selectedType,
            ref int selectedMember)
        {
            //
            var sortItems       = _optionsPage.SortNavigationBars;
            var includeFields   = _optionsPage.IncludeFieldsInNavigationBars;
            var currentTypeOnly = _optionsPage.ShowMembersOfCurrentTypeOnly;

            if (_optionsPage.DisableEditorDropdowns)
            {
                dropDownTypes.Clear();
                dropDownMembers.Clear();
                selectedType = selectedMember = -1;
                return(true);
            }
            // when the line did not change, we do nothing for performance reasons
            // this speeds up typing  for buffers with lots of entities
            if (line == lastLine)
            {
                // same line, no changes
                return(false);
            }
            lastLine = line;
            IVsTextLines buffer;

            textView.GetBuffer(out buffer);
            var file = _lang.getFile(buffer);

            if (file == null || file.TypeList == null)
            {
                return(false);
            }
            XEntityDefinition selectedElement = file.FindMemberAtRow(line);

            if (selectedElement != null && selectedElement.Range.StartLine > line)
            {
                // we may be before the first element. THen rebuild the list
                selectedElement = null;
            }
            else if (selectedElement == _lastSelected && selectedElement != null)
            {
                // Same element, no changes
                return(false);
            }
            // check if we are on the same type. When not then we need to reload the members.
            // Note that the first item in the members combo can also be a type (Classname)
            XTypeDefinition parentType = null;

            if (selectedElement is XMemberDefinition)
            {
                parentType = (XTypeDefinition)selectedElement.Parent;
            }
            else if (selectedElement is XTypeDefinition)
            {
                parentType = selectedElement as XTypeDefinition;
            }
            else
            {
                parentType = file.GlobalType;
            }
            bool newType = true;

            if (parentType != null && _lastType != null && parentType.FullName == _lastType.FullName)
            {
                newType = false;
            }
            // when we are on the same type and there are no new methods then we can
            // select the element in the members combo and we do not have to rebuild the members
            // list. We must set the selectedType and selectedMember
            if (!newType && file.ContentHashCode == _lastHashCode && lastIncludeFields == includeFields && lastCurrentTypeOnly == currentTypeOnly)
            {
                // no need to rebuild the list. Just focus to another element
                // locate item in members collection
                selectedMember = -1;
                selectedType   = -1;
                if (selectedElement != null)
                {
                    for (int i = 0; i < dropDownMembers.Count; i++)
                    {
                        var member = (XDropDownMember)dropDownMembers[i];
                        if (member.Element.ComboPrototype == selectedElement.ComboPrototype)
                        {
                            selectedMember = i;
                            break;
                        }
                    }
                }
                // find the parentType in the types combo
                if (selectedMember != -1 && parentType != null) // should never be null
                {
                    for (int i = 0; i < dropDownTypes.Count; i++)
                    {
                        var member = (XDropDownMember)dropDownTypes[i];
                        var type   = member.Element as XTypeDefinition;
                        if (type.FullName == parentType.FullName)
                        {
                            selectedType = i;
                            break;
                        }
                    }
                }
                // normally we should always find it. But if it fails then we simply build the list below.
                if (selectedMember != -1 && selectedType != -1)
                {
                    // remember for later. No need to remember the type because it has not changed
                    _lastSelected = selectedElement;
                    return(true);
                }
            }
            dropDownTypes.Clear();
            dropDownMembers.Clear();
            int nSelType = -1;
            int nSelMbr  = -1;
            //int distanceM = int.MaxValue;
            DROPDOWNFONTATTR ft;

            //
            //
            if (file.TypeList.Count > 0)
            {
                nSelType = 0;
            }

            List <XTypeDefinition> xList = file.TypeList.Values.ToList <XTypeDefinition>();

            if (sortItems)
            {
                xList.Sort(delegate(XTypeDefinition elt1, XTypeDefinition elt2)
                {
                    return(elt1.FullName.CompareTo(elt2.FullName));
                });
            }
            XTypeDefinition typeGlobal = null;
            int             nSelect    = 0;

            XMemberDefinition currentMember = null;
            XTypeDefinition   currentType   = null;

            if (selectedElement is XMemberDefinition)
            {
                currentMember = selectedElement as XMemberDefinition;
                currentType   = (XTypeDefinition)currentMember.Parent;
            }
            else if (selectedElement is XTypeDefinition)
            {
                currentType   = selectedElement as XTypeDefinition;
                currentMember = null;
            }
            nSelect = 0;
            XDropDownMember elt;

            // C# shows all items PLAIN
            // but when the selection is not really on an item, but for example on a comment
            // between methods, or on the comments between the namespace and the first class
            // then the next method/class is selected and displayed in GRAY
            // C# also includes members (for partial classes) that are defined in other source files
            // these are colored GRAY
            foreach (XTypeDefinition eltType in xList)
            {
                if (eltType.Kind == Kind.Namespace)
                {
                    continue;
                }
                //
                if (XTypeDefinition.IsGlobalType(eltType))
                {
                    typeGlobal = eltType;
                }
                TextSpan sp = this.TextRangeToTextSpan(eltType.Range);
                ft = DROPDOWNFONTATTR.FONTATTR_PLAIN;
                string name = eltType.FullName;
                if (string.IsNullOrEmpty(name))
                {
                    name = "?";
                }
                elt     = new XDropDownMember(name, sp, eltType.Glyph, ft, eltType);
                nSelect = dropDownTypes.Add(elt);
                if (eltType?.FullName == currentType?.FullName)
                {
                    nSelType = nSelect;
                }
            }

            if (currentType == null)
            {
                currentType = typeGlobal;
            }
            bool hasPartial = false;

            if (currentType != null)    // should not happen since all files have a global type
            {
                nSelMbr = 0;
                var members = new List <XEntityDefinition>();
                if (currentTypeOnly)
                {
                    if (currentType != typeGlobal && currentType.IsPartial)
                    {
                        // retrieve members from other files ?
                        var usings = new List <string>();
                        usings.Add(currentType.Namespace);
                        var fullType = file.Project.Lookup(currentType.Name, usings);
                        hasPartial = true;
                        members.AddRange(fullType.XMembers);
                    }
                    else
                    {
                        members.AddRange(currentType.XMembers);
                        foreach (XTypeDefinition child in currentType.Children)
                        {
                            members.Add(child);
                            members.AddRange(child.XMembers);
                        }
                    }
                }
                else
                {
                    members.AddRange(file.EntityList.Where(member => includeFields || (member.Kind != Kind.Field && member.Kind != Kind.VODefine)));
                    foreach (var ent in file.EntityList)
                    {
                        if (ent is XTypeDefinition)
                        {
                            var xType = ent as XTypeDefinition;
                            if (xType.IsPartial)
                            {
                                // load methods from other files
                                var usings = new List <string>();
                                usings.Add(xType.Namespace);
                                var fullType = file.Project.Lookup(xType.Name, usings);
                                hasPartial = true;
                                foreach (var member in fullType.XMembers)
                                {
                                    if (string.Compare(member.File.FullPath, file.FullPath, true) != 0)
                                    {
                                        if (includeFields || (member.Kind != Kind.Field && member.Kind != Kind.VODefine))
                                        {
                                            members.Add(member);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (sortItems)
                {
                    members = members.OrderBy(x => x.FullName).ToList();
                }
                // Add member for class declaration. This also makes sure that there at least one
                // element in the members list, which is convenient.
                TextSpan spM = this.TextRangeToTextSpan(currentType.Range);
                ft = DROPDOWNFONTATTR.FONTATTR_PLAIN;
                if (currentTypeOnly)
                {
                    // Add a 'root' element for the type.
                    if (currentType != typeGlobal)
                    {
                        if (currentType.Kind != Kind.Delegate)
                        {
                            elt = new XDropDownMember("(" + currentType.Name + ")", spM, currentType.Glyph, ft, currentType);
                            dropDownMembers.Add(elt);
                        }
                    }
                    else
                    {
                        elt = new XDropDownMember(currentType.Name, spM, currentType.Glyph, ft, currentType);
                        dropDownMembers.Add(elt);
                    }
                }
                foreach (XEntityDefinition member in members)
                {
                    bool otherFile;
                    if (includeFields || (member.Kind != Kind.Field && member.Kind != Kind.VODefine))
                    {
                        spM       = this.TextRangeToTextSpan(member.Range);
                        otherFile = false;
                        ft        = DROPDOWNFONTATTR.FONTATTR_PLAIN;
                        if (hasPartial)
                        {
                            otherFile = string.Compare(member.File.FullPath, file.FullPath, true) != 0;
                        }

                        string prototype = member.ComboPrototype;
                        bool   addPrefix = false;

                        if (currentTypeOnly)
                        {
                            if (member.Parent != currentType && member.Kind.IsClassMember(file.Project.Dialect))
                            {
                                addPrefix = true;
                            }
                        }
                        else
                        {
                            if (member.Parent is XEntityDefinition && member.Parent.Name != XLiterals.GlobalName && member.Kind.IsClassMember(file.Project.Dialect))
                            {
                                addPrefix = true;
                            }
                        }

                        if (addPrefix)
                        {
                            var parent = member.Parent as XEntityDefinition;
                            if (member.Modifiers.HasFlag(Modifiers.Static) || member is XTypeDefinition)
                            {
                                prototype = parent.ComboPrototype + "." + prototype;
                            }
                            else
                            {
                                prototype = parent.ComboPrototype + ":" + prototype;
                            }
                        }
                        if (otherFile)
                        {
                            ft         = DROPDOWNFONTATTR.FONTATTR_GRAY;
                            prototype += " (" + System.IO.Path.GetFileName(member.File.SourcePath) + ")";
                        }
                        elt     = new XDropDownMember(prototype, spM, member.Glyph, ft, member);
                        nSelect = dropDownMembers.Add(elt);
                        if (member.Range.ContainsInclusive(line, col))
                        {
                            nSelMbr = nSelect;
                        }
                    }
                }
            }
            // save the info so we can optimize the next call.
            _members            = dropDownMembers;
            _file               = file;
            _lastSelected       = selectedElement;
            _lastType           = currentType;
            _lastHashCode       = file.ContentHashCode;
            selectedType        = nSelType;
            selectedMember      = nSelMbr;
            lastIncludeFields   = includeFields;
            lastCurrentTypeOnly = currentTypeOnly;
            return(true);
        }
 internal XDropDownMember(string label, TextSpan span, int glyph, DROPDOWNFONTATTR fontAttribute, XEntityDefinition element) :
     base(label, span, glyph, fontAttribute)
 {
     Element = element;
 }
Ejemplo n.º 8
0
        private void initDescription(XEntityDefinition member) //, _VSOBJDESCOPTIONS flags, IVsObjectBrowserDescription3 description)
        {
            description = new List <Tuple <string, VSOBDESCRIPTIONSECTION> >();
            //
            string descText = this.Name;
            //
            string namesp    = "";
            string className = "";

            if (member != null)
            {
                if (member.Parent != null)
                {
                    if (member.Parent is IXType)
                    {
                        namesp    = ((IXType)member.Parent).Namespace;
                        className = ((IXType)member.Parent).Name;
                    }
                }
                //
                string modifier = "";
                string access   = "";
                if ((member is XTypeDefinition) && (member.Kind != Kind.Namespace))
                {
                    modifier = member.Modifiers.ToDisplayString();
                    access   = member.Visibility.ToDisplayString();
                }
                else if ((member is XMemberDefinition) && ((member.Kind != Kind.Function) && (member.Kind != Kind.Procedure)))
                {
                    modifier = member.Modifiers.ToDisplayString();
                    access   = member.Visibility.ToDisplayString();
                }
                //
                if (!String.IsNullOrEmpty(modifier))
                {
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(modifier + " ", VSOBDESCRIPTIONSECTION.OBDS_ATTRIBUTE));
                }
                //
                if (!String.IsNullOrEmpty(access))
                {
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(access + " ", VSOBDESCRIPTIONSECTION.OBDS_ATTRIBUTE));
                    //description.AddDescriptionText3(access, VSOBDESCRIPTIONSECTION.OBDS_MISC, null);
                }
                //
                if (member.Kind != Kind.Field)
                {
                    VSOBDESCRIPTIONSECTION descName = VSOBDESCRIPTIONSECTION.OBDS_MISC;
                    descText = XSettings.FormatKeyword(member.Kind.DisplayName()) + " ";
                    if (member.Kind == Kind.Constructor)
                    {
                        descName = VSOBDESCRIPTIONSECTION.OBDS_NAME;
                    }
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, descName));
                    //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null);
                }
                if (member.Kind != Kind.Constructor)
                {
                    descText = member.Name;
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_NAME));
                }
                //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_NAME, null);
                // Parameters ?
                if (member.Kind.HasParameters())
                {
                    descText = "(";
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null);
                    XMemberDefinition realmember;
                    XTypeDefinition   type = member as XTypeDefinition;
                    if (member.Kind == Kind.Delegate && type?.XMembers.Count > 0)
                    {
                        realmember = type.XMembers[0];
                    }
                    else
                    {
                        realmember = member as XMemberDefinition;
                    }

                    if (realmember != null && realmember.HasParameters)
                    {
                        //
                        int paramNum = 1;
                        foreach (XVariable param in realmember.Parameters)
                        {
                            descText = param.Name;
                            description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_PARAM));
                            descText = param.ParamTypeDesc;
                            description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                            //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_PARAM, null);
                            descText = param.TypeName;
                            //
                            IVsNavInfo navInfo = buildNavInfo(member.File, param.TypeName);
                            //
                            description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE));
                            //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE, navInfo);
                            // Need a comma ?
                            if (paramNum < realmember.ParameterCount)
                            {
                                paramNum++;
                                descText = ",";
                                description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_COMMA));
                                //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_COMMA, null);
                            }
                        }
                    }
                    descText = ")";
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null);
                }
                if (member.Kind.HasReturnType())
                {
                    descText = XLiterals.AsKeyWord;
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null);
                    descText = member.TypeName;
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE));
                    //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE, null);
                }

                //
                //if (!((member.Kind == Kind.Function) || (member.Kind == Kind.Procedure) || (member.Kind == Kind.VODLL)) &&
                //    ((member.Parent is XTypeDefinition) && (member.Parent.Kind == Kind.Class)))
                //{
                //    descText = " CLASS ";
                //    description.Add(new Tuple<string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                //    //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null);
                //    descText = className;
                //    description.Add(new Tuple<string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE));
                //    //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE, null);
                //}
                //
                description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(null, VSOBDESCRIPTIONSECTION.OBDS_ENDDECL));
                //description.AddDescriptionText3(null, VSOBDESCRIPTIONSECTION.OBDS_ENDDECL, null);
            }
            //
            if (member.File?.Project != null)
            {
                string        summary = null, returns = null, remarks = null;
                List <string> pNames        = new List <string>();
                List <string> pDescriptions = new List <string>();
                if (member is XMemberDefinition)
                {
                    summary = XSharpXMLDocMember.GetMemberSummary((XMemberDefinition)member, member.File?.Project, out returns, out remarks);
                    XSharpXMLDocMember.GetMemberParameters((XMemberDefinition)member, member.File?.Project, pNames, pDescriptions);
                }
                else if (member is XTypeDefinition)
                {
                    summary = XSharpXMLDocMember.GetTypeSummary((XTypeDefinition)member, member.File?.Project, out returns, out remarks);
                }
                if (!String.IsNullOrEmpty(summary))
                {
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nSummary:\n", VSOBDESCRIPTIONSECTION.OBDS_NAME));
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(summary, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                }
                if (pNames.Count > 0)
                {
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nParameters:", VSOBDESCRIPTIONSECTION.OBDS_NAME));
                    for (int i = 0; i < pNames.Count; i++)
                    {
                        description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n" + pNames[i], VSOBDESCRIPTIONSECTION.OBDS_PARAM));
                        description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(" : ", VSOBDESCRIPTIONSECTION.OBDS_MISC));
                        description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(pDescriptions[i], VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    }
                }
                if (!String.IsNullOrEmpty(returns))
                {
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nReturn:\n", VSOBDESCRIPTIONSECTION.OBDS_NAME));
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(returns, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                }
                if (!String.IsNullOrEmpty(remarks))
                {
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC));
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nRemarks:\n", VSOBDESCRIPTIONSECTION.OBDS_NAME));
                    description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(remarks, VSOBDESCRIPTIONSECTION.OBDS_MISC));
                }
            }
        }