// Recursively examine code elements.
        private void FindClassesRecursive(List <NamespaceClass> classes, CodeElement2 codeElement, bool isXaml, string rootNamespace)
        {
            try
            {
                if (codeElement.Kind == vsCMElement.vsCMElementClass)
                {
                    var ct = (CodeClass2)codeElement;
                    classes.Add(new NamespaceClass(ct.Namespace?.Name ?? rootNamespace, ct.Name));
                }
                else if (codeElement.Kind == vsCMElement.vsCMElementNamespace)
                {
                    foreach (CodeElement2 childElement in codeElement.Children)
                    {
                        FindClassesRecursive(classes, childElement, isXaml, rootNamespace);

                        // If a xaml.cs or xaml.vb code behind file, the first class must be the view type, so we can stop early.
                        if (isXaml && classes.Count > 0)
                        {
                            return;
                        }
                    }
                }
            }
            catch
            {
                //Console.WriteLine(new string('\t', tabs) + "codeElement without name: {0}", codeElement.Kind.ToString());
            }
        }
Beispiel #2
0
        public int Compare(object first, object second)
        {
            CodeElement2 f = (CodeElement2)first;
            CodeElement2 s = (CodeElement2)second;

            return(f.Name.CompareTo(s.Name));
        }
        /// <summary>
        /// Obtains a reflection wrapper for a code element.
        /// </summary>
        /// <param name="target">The element, or null if none.</param>
        /// <returns>The reflection wrapper, or null if none.</returns>
        public ICodeElementInfo Wrap(CodeElement2 target)
        {
            if (target == null)
            {
                return(null);
            }

            switch (target.Kind)
            {
            case vsCMElement.vsCMElementClass:
            case vsCMElement.vsCMElementStruct:
            case vsCMElement.vsCMElementInterface:
            case vsCMElement.vsCMElementDelegate:
            case vsCMElement.vsCMElementEnum:
                return(Wrap((CodeType)target));

            case vsCMElement.vsCMElementFunction:
                return(Wrap((CodeFunction2)target));

            case vsCMElement.vsCMElementProperty:
                return(Wrap((CodeProperty2)target));

            case vsCMElement.vsCMElementVariable:
                return(Wrap((CodeVariable2)target));

            case vsCMElement.vsCMElementEvent:
                return(Wrap((CodeEvent)target));

            case vsCMElement.vsCMElementParameter:
                return(Wrap((CodeParameter2)target));
            }

            throw new NotSupportedException("Unsupported code element type: " + target);
        }
        /// <summary>
        /// Searches given Visual Basic code and returns list of result items
        /// </summary>
        /// <param name="functionText">Text to search</param>
        /// <param name="startPoint">Information about position of the text (line, column...)</param>
        /// <param name="parentNamespace">Namespace where this code belongs (can be null)</param>
        /// <param name="codeClassOrStruct">Class, struct or module where this code belongs (cannot be null)</param>
        /// <param name="codeFunctionName">Name of the function, where this code belongs (can be null)</param>
        /// <param name="codeVariableName">Name of the variable that is initialized by this code (can be null)</param>
        /// <param name="isWithinLocFalse">True if [Localizable(false)] was set</param>
        /// <returns>
        /// List of result items
        /// </returns>
        public override IList LookupInVB(string functionText, TextPoint startPoint, CodeNamespace parentNamespace,
                                         CodeElement2 codeClassOrStruct, string codeFunctionName, string codeVariableName, bool isWithinLocFalse)
        {
            if (codeClassOrStruct == null)
            {
                throw new ArgumentNullException("codeClassOrStruct");
            }
            if (functionText == null)
            {
                throw new ArgumentNullException("functionText");
            }
            if (startPoint == null)
            {
                throw new ArgumentNullException("startPoint");
            }

            // set information about processed item
            if (!generatedProjectItems.ContainsKey(currentlyProcessedItem))
            {
                generatedProjectItems.Add(currentlyProcessedItem, currentlyProcessedItem.IsGenerated());
            }

            // run VB lookuper on code text, obtaining list of string literals
            var list = VBStringLookuper.Instance.LookForStrings(currentlyProcessedItem, generatedProjectItems[currentlyProcessedItem], functionText, startPoint,
                                                                parentNamespace, codeClassOrStruct.Name, codeFunctionName, codeVariableName, isWithinLocFalse);

            // add string literals to the results list
            foreach (VBStringResultItem item in list)
            {
                Results.Add(item);
            }

            return(list);
        }
        private void ModuleRenamed(object source, ElementPropertyChangedEventArgs e)
        {
            //If an element with the old name exists it means the designer is auto-assigning a new name
            //to a newly dropped element and there's no need to rename the corresponding code element. In
            //fact that would be wrong because we would end up renaming the code element corresponding to the
            //model element with the old name, whose name hasn't changed.
            if (((Module)e.ModelElement).CountModulesWithName((string)e.OldValue) > 0)
            {
                return;
            }

            FileCodeModel2 fcm = GetGeneratedFileCodeModel();

            if (fcm == null)
            {
                return;
            }
            CodeElement2 field = FindElement(fcm.CodeElements, (string)e.OldValue, vsCMElement.vsCMElementVariable);

            if (field != null)
            {
                field.RenameSymbol((string)e.NewValue);
            }

            UpdateView();
        }
Beispiel #6
0
        /// <summary>
        /// Get Custom Attributes
        /// </summary>
        /// <param name="ce"></param>
        /// <returns></returns>
        /// <remarks>
        /// Requires Named Argument when declaring the Custom Attribute, otherwise Name will be empty.
        /// Not using reflection because it requires successful build
        /// </remarks>
        public static IEnumerable <CodeAttribute2> GetCustomAttributes(this CodeElement2 ce)
        {
            //!Property
            var prop = ce as CodeProperty2;

            if (prop != null)
            {
                return(prop.Attributes.Cast <CodeAttribute2>());
            }

            //!Function
            var func = ce as CodeFunction2;

            if (func != null)
            {
                return(func.Attributes.Cast <CodeAttribute2>());
            }

            //!Class
            var cc = ce as CodeClass2;

            if (cc != null)
            {
                return(cc.Attributes.Cast <CodeAttribute2>());
            }

            throw new Exception("CodeElement not recognized");
            //return Enumerable.Empty<CodeAttribute2>();
        }
Beispiel #7
0
        public CodeMember(CodeElement2 element, CodeElement2 type, Language language)
        {
            this.element     = element;
            this.TypeElement = type;
            this.language    = language;

            this.Name = element.Name;
            this.RequiresSeparatorLine = element.Kind != vsCMElement.vsCMElementVariable;
            switch (element.Kind)
            {
            case vsCMElement.vsCMElementFunction:
                CodeFunction2 function = (CodeFunction2)element;
                MemberKind    kind;
                switch (function.FunctionKind)
                {
                case vsCMFunction.vsCMFunctionConstructor:
                    kind = MemberKind.Constructor;
                    break;

                case vsCMFunction.vsCMFunctionDestructor:
                    kind = MemberKind.Destructor;
                    break;

                case vsCMFunction.vsCMFunctionOperator:
                    kind = MemberKind.Operator;
                    break;

                default:
                    kind = MemberKind.Function;
                    break;
                }

                this.Initialize(
                    kind,
                    function.Access,
                    function.IsShared,
                    function.OverrideKind,
                    functionKind: function.FunctionKind,
                    parameters: function.Parameters);
                break;

            case vsCMElement.vsCMElementProperty:
                CodeProperty2 property = (CodeProperty2)element;
                this.Initialize(MemberKind.Property, property.Access, property.IsShared, property.OverrideKind, parameters: property.Parameters);
                break;

            case vsCMElement.vsCMElementVariable:
                CodeVariable2 variable = (CodeVariable2)element;
                this.Initialize(MemberKind.Variable, variable.Access, variable.IsShared, constKind: variable.ConstKind);
                break;

            case vsCMElement.vsCMElementEvent:
                CodeEvent evt = (CodeEvent)element;
                this.Initialize(MemberKind.Event, evt.Access, evt.IsShared, evt.OverrideKind);
                break;

            default:
                throw new NotSupportedException("Unsupported element kind: " + element.Kind);
            }
        }
        private void ReorderMembers(CodeElement2 type, IEnumerable <CodeMember> members, string orderedCode, TextPoint startPoint)
        {
            // Removing members will shift the startPoint back one line.
            // So we'll use the absolute offset to jump back to that insert point.
            int startPointOffset = 0;

            if (startPoint != null)
            {
                startPointOffset = startPoint.AbsoluteCharOffset;
            }

            FileCodeModel2 codeModel = this.textHandler.Document.ProjectItem.FileCodeModel as FileCodeModel2;

            codeModel.BeginBatch();
            try
            {
                foreach (CodeMember member in members)
                {
                    member.Remove();
                }
            }
            finally
            {
                codeModel.EndBatch();
            }

            if (startPoint != null)
            {
                EditPoint startEdit = startPoint.CreateEditPoint();
                startEdit.MoveToAbsoluteOffset(startPointOffset);
                startEdit.StartOfLine();

                // If the line above startEdit isn't empty and isn't the start of the class/struct/interface/enum,
                // then insert a blank line so the sortedCode will be separated from the code above it.
                EditPoint lineAboveEdit = startEdit.CreateEditPoint();
                lineAboveEdit.LineUp();
                lineAboveEdit.StartOfLine();
                string lineText = lineAboveEdit.GetText(lineAboveEdit.LineLength).Trim();
                if (lineText.Length != 0 &&
                    lineAboveEdit.Line > type.StartPoint.Line &&
                    (this.language != Language.CSharp || lineText != "{"))
                {
                    startEdit.Insert(Environment.NewLine);
                }

                startEdit.Insert(orderedCode);

                // If the line after startEdit isn't empty and isn't the end of the class/struct/interface/enum,
                // then insert a blank line so the sortedCode will be separated from the code below it.
                startEdit.StartOfLine();
                lineText = startEdit.GetText(startEdit.LineLength).Trim();
                if (lineText.Length != 0 &&
                    startEdit.Line < type.EndPoint.Line &&
                    (this.language != Language.CSharp || lineText != "}"))
                {
                    startEdit.Insert(Environment.NewLine);
                }
            }
        }
Beispiel #9
0
        private void Init(CodeElement2 ele)
        {
            Init();
            ParentElement = ele;
            var attrs = ele.GetCustomAttribute(this.GetType()).GetCodeAttributeArguments();

            CopyPropertyFromAttributeArguments(attrs);
        }
        private string RenameMethod(CodeElement item)
        {
            //var sb = new StringBuilder();
            if (item.Kind == vsCMElement.vsCMElementFunction)
            {
                //Debug.WriteLine("RenameMethod.FullName:" + item.FullName);
                if (methodWhiteList.Contains(item.Name) || interFaceFunction.Contains(item.Name) || item.Name.Contains(alien))
                {
                    Print("WriteListFunction :" + item.Name);
                    return("");
                }
                try
                {
                    CodeFunction2 code3 = item as CodeFunction2;
                    PrintFunction2Info(code3);
                    if (code3.OverrideKind == vsCMOverrideKind.vsCMOverrideKindOverride ||
                        code3.OverrideKind == vsCMOverrideKind.vsCMOverrideKindNew ||
                        code3.OverrideKind == vsCMOverrideKind.vsCMOverrideKindAbstract ||
                        code3.OverrideKind == vsCMOverrideKind.vsCMOverrideKindVirtual)
                    {
                        PrintDetial("SpecialFunction :" + item.Name);
                        return("");
                    }
                    if (code3.IsShared)
                    {
                        PrintDetial("StaticFunction :" + item.Name);
                        return("");
                    }
                    if (item.Name.Contains(stringGlobal))
                    {
                        PrintDetial("GlobalFunction :" + item.Name);
                        return("");
                    }

                    CodeElement2 code2  = item as CodeElement2;
                    var          one    = nameCounter++;
                    var          alien2 = alien + nameCounter++;
                    var          three  = nameCounter++;
                    PrintDetial("RenameFunction :" + item.Name);
                    var randomOne   = GetRandomName(3, 5, useUpper: true);
                    var randomThree = GetRandomName(3, 5, useUpper: true);
                    var replacement = string.Format("{0}{1}{2}{3}{4}", randomOne, one, item.Name.Insert(item.Name.Length / 2, alien2), randomThree, three);
                    code2.RenameSymbol(replacement);

                    //sb += ("    " + code.Name + " " + code.IsCodeType + " " + code.Kind + "\n");
                }
                catch (Exception ex)
                {
                    //except += " error: " + ex.Message + "\n" + item.Name;
                    CodeFunction2 code3 = item as CodeFunction2;
                    PrintFunction2Info(code3);
                }
            }
            else
            {
            }
            return("");
        }
        private bool IsMemberSelected(CodeElement2 member)
        {
            TextPoint memberStart = member.StartPoint;
            TextPoint memberEnd   = member.EndPoint;

            bool result = (memberStart.GreaterThan(this.selectionStart) || memberStart.EqualTo(this.selectionStart)) &&
                          (memberEnd.LessThan(this.selectionEnd) || memberEnd.EqualTo(this.selectionEnd));

            return(result);
        }
Beispiel #12
0
        private static VsObjectSearchResult CreateVBCodeElementSearchResult(CodeElement2 codeElement)
        {
            var    column = codeElement.StartPoint.LineCharOffset;
            var    line   = codeElement.StartPoint.Line;
            int    lineLength;
            string lineText;
            string prefix;

            // Try to locate the element name on the startline.
            using (var textBuffer = VsTextLinesFromFile.Load(codeElement.ProjectItem.get_FileNames(1)))
            {
                // Buffer values are zero based, codeElement values are 1 based.
                var bufferLine = line - 1;
                NativeMethods.ThrowOnFailure(textBuffer.GetLengthOfLine(bufferLine, out lineLength));
                NativeMethods.ThrowOnFailure(textBuffer.GetLineText(bufferLine, 0, bufferLine, lineLength, out lineText));
            }

            // Skip past the prefix, which is different depending on whether we are processing a class/property/function
            switch (codeElement.Kind)
            {
            case vsCMElement.vsCMElementClass:
                prefix = VBClassKeyword;
                break;

            case vsCMElement.vsCMElementProperty:
                prefix = VBPropertyKeyword;
                break;

            case vsCMElement.vsCMElementFunction:
                prefix = VBFunctionKeyword;
                break;

            default:
                throw new NotImplementedException(
                          "CreateVBCodeElementSearchResult() does not implement handlers for CodeElement type: " + codeElement.Kind.ToString());
            }

            var prefixStartIndex = lineText.IndexOf(prefix, 0, StringComparison.OrdinalIgnoreCase);

            if (prefixStartIndex >= 0)
            {
                var prefixEndIndex = prefixStartIndex + prefix.Length;
                if (prefixEndIndex < lineText.Length)
                {
                    var elementNameStartIndex = lineText.IndexOf(codeElement.Name, prefixEndIndex, StringComparison.OrdinalIgnoreCase);
                    if (elementNameStartIndex >= 0)
                    {
                        // Buffer values are zero based, FindAllRef values are 1 based.
                        column = elementNameStartIndex + 1;
                    }
                }
            }

            return(new VsObjectSearchResult(codeElement.ProjectItem.get_FileNames(1), codeElement.FullName, line, column));
        }
Beispiel #13
0
        /// <summary>
        /// Returns class, struct or module, where given variable in defined
        /// </summary>
        public static CodeElement2 GetClass(this CodeVariable2 codeVariable)
        {
            if (codeVariable == null)
            {
                throw new ArgumentNullException("codeVariable");
            }

            CodeElement2 parent = codeVariable.Parent as CodeElement2;

            return(GetClassInternal(parent));
        }
Beispiel #14
0
        /// <summary>
        /// Returns class, struct or module, where given property in defined
        /// </summary>
        public static CodeElement2 GetClass(this CodeProperty codeProperty)
        {
            if (codeProperty == null)
            {
                throw new ArgumentNullException("codeProperty");
            }

            CodeElement2 parent = codeProperty.Parent as CodeElement2;

            return(GetClassInternal(parent));
        }
Beispiel #15
0
        ///<inheritdoc/>
        public override int GetHashCode()
        {
            int hash = 17;

            // Overflow is fine, just wrap
            unchecked
            {
                hash = (hash * 29) + CodeElement1.GetHashCode();
                hash = (hash * 29) + CodeElement2.GetHashCode();
                hash = (hash * 29) + Status.GetHashCode();
                hash = (hash * 29) + Damage.GetHashCode();
                hash = (hash * 29) + Malfunction.GetHashCode();
            }

            return(hash);
        }
Beispiel #16
0
        /// <summary>
        /// Returns given element if it's class, struct or module, null otherwise
        /// </summary>
        private static CodeElement2 GetClassInternal(CodeElement2 parent)
        {
            if (parent == null)
            {
                return(null);
            }

            if (parent.Kind == vsCMElement.vsCMElementClass || parent.Kind == vsCMElement.vsCMElementModule ||
                parent.Kind == vsCMElement.vsCMElementStruct)
            {
                return(parent);
            }
            else
            {
                return(null);
            }
        }
Beispiel #17
0
        CodeElement2 FindElement(CodeElements elements, string name, vsCMElement kind)
        {
            foreach (CodeElement2 ce in elements)
            {
                if (ce.Kind == kind && ce.Name == name)
                {
                    return(ce);
                }

                CodeElement2 found = FindElement(ce.Children, name, kind);
                if (found != null)
                {
                    return(found);
                }
            }
            return(null);
        }
Beispiel #18
0
        private string[] getItemSourceCode(CodeElement2 codeElement)
        {
            if (codeElement == null)
            {
                throw new ArgumentNullException("codeElement == null in getItemSourceCode");
            }

            Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();

            EditPoint begin = codeElement.StartPoint.CreateEditPoint();
            EditPoint end   = codeElement.EndPoint.CreateEditPoint();

            string fullSource = begin.GetText(end);

            // Find the first open curly brace
            int openCurlyBracePos  = fullSource.IndexOf('{');
            int closeCurlyBracePos = fullSource.LastIndexOf("}");

            if (openCurlyBracePos == -1)
            {
                openCurlyBracePos = fullSource.IndexOf(';');
            }

            string prototype      = String.Empty;
            string implementation = String.Empty;

            if (openCurlyBracePos > -1)
            {
                if (closeCurlyBracePos > -1)
                {
                    implementation = fullSource.Substring(openCurlyBracePos, closeCurlyBracePos - openCurlyBracePos + 1);
                }
                else
                {
                    implementation = "{}";
                }

                prototype = fullSource.Substring(0, openCurlyBracePos);

                implementation.Trim();
                prototype.Trim();
            }

            return(new string[] { prototype, implementation });
        }
Beispiel #19
0
        /// <summary>
        /// Returns class, struct or module, where given method in defined
        /// </summary>
        public static CodeElement2 GetClass(this CodeFunction2 codeFunction)
        {
            if (codeFunction == null)
            {
                throw new ArgumentNullException("codeFunction");
            }

            CodeElement2 parent = codeFunction.Parent as CodeElement2;

            if (parent is CodeProperty)
            {
                return(GetClassInternal((CodeElement2)((CodeProperty)parent).Parent));
            }
            else
            {
                return(GetClassInternal(parent));
            }
        }
Beispiel #20
0
        /// <summary>
        /// Returns an identifier to use for a unique CodeElement.
        /// </summary>
        /// <param name="element">The CodeElement to ID.</param>
        /// <returns>A string that identifies the element.</returns>
        /// <remarks>
        /// Each language has limitations when creating a 'unique' identifier.
        /// If the language is VB, a method identifier may not actually
        /// remain unique, because VB creates the identifier based on the original
        /// method signature and never updates it if the signature changes.
        /// For example, if a method is copied and pasted to create a similar method, the new
        /// method initially has the same signature as the old one and thus VB's ElementID
        /// will return the same identifier for the clone as it returned for the copied method.
        /// If the language is C#, the code element throws and exception when accessing the
        /// ElementID, so the function prototype is used here to generate an ID instead.
        /// </remarks>
        public static string GetUniqueElementId(CodeElement element)
        {
            string strElementID = null;

            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            try
            {
                // VB will return an ElementID for the element.
                if (element.Language == CodeModelLanguageConstants.vsCMLanguageVB)
                {
                    CodeElement2 codeElement2 = element as CodeElement2;
                    if (codeElement2 != null)
                    {
                        strElementID = codeElement2.ElementID;
                    }
                }

                // For non-VB languages, construct an ID from the best available signature.
                if (strElementID == null)
                {
                    switch (element.Kind)
                    {
                    case vsCMElement.vsCMElementFunction:
                        CodeFunction codeFunction = ((CodeFunction)element);
                        strElementID = codeFunction.get_Prototype((int)vsCMPrototype.vsCMPrototypeParamTypes);
                        break;

                    default:
                        strElementID = element.FullName;
                        break;
                    }
                }
            }
            catch (Exception)
            {
                strElementID = element.Name;
            }

            return(strElementID);
        }
        public static CodeElement2 FindMember(CodeElements elements, string elementName)
        {
            List <Tuple <CodeElement2, List <CodeElement2> > > typeMembersTuples = FindMembers(elements, e => e.Name == elementName);
            List <CodeElement2> matched = typeMembersTuples.SelectMany(tuple => tuple.Item2).ToList();

            CodeElement2 result = null;

            if (matched.Count == 1)
            {
                result = matched[0];
            }
            else if (matched.Count > 1)
            {
                throw new ArgumentException(
                          $"Multiple elements were found named {elementName} (in {string.Join(", ", typeMembersTuples.Select(t => t.Item1.Name))}).");
            }

            return(result);
        }
Beispiel #22
0
            private static CodeFunction2[] FindMethods(CodeClass2 classModel, string name)
            {
                List <CodeFunction2> methods = new List <CodeFunction2>();

                foreach (object child in classModel.Children)
                {
                    CodeElement2 element = new CodeElement2(child);
                    if ((element.Reference == null) || (element.Kind != vsCMElement.vsCMElementFunction))
                    {
                        continue;
                    }

                    if (string.CompareOrdinal(element.Name, name) == 0)
                    {
                        methods.Add(new CodeFunction2(child));
                    }
                }
                return(methods.ToArray());
            }
Beispiel #23
0
        private static List <Tuple <CodeElement2, List <CodeElement2> > > FindMembers(
            CodeElement2 type,
            CodeElements codeMembers,
            Predicate <CodeElement2> includeMember)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            List <Tuple <CodeElement2, List <CodeElement2> > > result = new();

            List <CodeElement2> typeMembers = null;

            foreach (CodeElement2 member in codeMembers)
            {
                switch (member.Kind)
                {
                case vsCMElement.vsCMElementFunction:
                case vsCMElement.vsCMElementProperty:
                case vsCMElement.vsCMElementVariable:
                case vsCMElement.vsCMElementEvent:
                    // Note: We can't include nested types and let the sorting logic try to move them too
                    // because that would invalidate all of their CodeElement position info.  Instead, we'll
                    // just recursively get their non-type members below.
                    if (includeMember == null || includeMember(member))
                    {
                        if (typeMembers == null)
                        {
                            typeMembers = new List <CodeElement2>();
                            result.Add(Tuple.Create(type, typeMembers));
                        }

                        typeMembers.Add(member);
                    }

                    break;
                }
            }

            // Recursively look for nested classes, structs, interfaces, and enums.
            result.AddRange(FindMembers(codeMembers, includeMember));

            return(result);
        }
        private IEnumerable <CodeElement2> GetDescendents([NotNull] CodeElement2 node)
        {
            Debug.ArgumentNotNull(node, nameof(node));

            foreach (var child in node.Children)
            {
                var codeElement = child as CodeElement2;
                if (codeElement == null)
                {
                    continue;
                }

                yield return(codeElement);

                foreach (var descendent in GetDescendents(codeElement))
                {
                    yield return(descendent);
                }
            }
        }
Beispiel #25
0
            private static CodeClass2 FindClass(FileCodeModel2 model, string name)
            {
                // Create a queue to "recurse" through all the child elements of the file
                Queue <CodeElement2> remaining = new Queue <CodeElement2>();

                // Start with the top level elements
                foreach (object element in model.CodeElements)
                {
                    remaining.Enqueue(new CodeElement2(element));
                }

                // "Recurse" through their children
                while (remaining.Count > 0)
                {
                    CodeElement2 element = remaining.Dequeue();

                    // Ignore anything that isn't a type or a namespace
                    if (element == null || element.Reference == null || (!element.IsCodeType && element.Kind != vsCMElement.vsCMElementNamespace))
                    {
                        continue;
                    }

                    // If it's a class with a matching name, return it
                    if ((element.Kind == vsCMElement.vsCMElementClass) && (string.CompareOrdinal(element.FullName, name) == 0))
                    {
                        return(new CodeClass2(element.Reference));
                    }

                    // Add any children of the type
                    if (element.Children != null)
                    {
                        foreach (object child in element.Children)
                        {
                            remaining.Enqueue(new CodeElement2(child));
                        }
                    }
                }

                // Return null if we couldn't find a node corresponding to the class name
                return(null);
            }
        /// <summary>
        /// 
        /// </summary>
        public BaseInfo(BaseInfo parent, CodeElement2 item)
        {
            this.Name = item.Name;
            this.FullName = item.FullName;
            this.IsCodeType = item.IsCodeType;
            this.Root = parent;
            this.Source = item;

            try
            {
                this.Project = new NodeProject(item.ProjectItem.ContainingProject);
                this.Location = new LocationInfo(item.StartPoint, item.EndPoint);
            }
            catch (Exception)
            {
                this.Location = new LocationInfo(null, null);
            }

            this.IsArray = false;
            this.ElementType = null;
        }
        private void ReorderMembers(CodeElement2 type, List <CodeMember> members, bool forceReorder)
        {
            TextPoint orderedStartPoint;
            string    orderedCode = GetCode(members, out orderedStartPoint);

            if (!forceReorder)
            {
                List <CodeMember> membersByStartPoint = new List <CodeMember>(members);
                membersByStartPoint.Sort((x, y) => x.CompareByStartPoint(y));
                TextPoint originalStartPoint;
                string    originalCode = GetCode(membersByStartPoint, out originalStartPoint);

                // If "reordering" won't change anything, then skip the remove(s)+insert so the document
                // won't be "modified" and potentially checked out.
                forceReorder = orderedCode != originalCode;
            }

            if (forceReorder)
            {
                this.ReorderMembers(type, members, orderedCode, orderedStartPoint);
            }
        }
Beispiel #28
0
        /// <summary>
        /// Search for the class recursivly (deep search) in the given code element.
        /// </summary>
        /// <param name="p_codeElement"></param>
        /// <param name="p_className"></param>
        /// <returns></returns>
        private static CodeClass2 FindClassRecursive(CodeElement2 p_codeElement, string p_className)
        {
            CodeClass2 foundClass = null;

            if (p_codeElement.Kind == vsCMElement.vsCMElementClass && p_codeElement.Name == p_className)
            {
                foundClass = p_codeElement as CodeClass2;
            }
            else if (p_codeElement.Children != null && p_codeElement.Children.Count > 0)
            {
                foreach (CodeElement2 child in p_codeElement.Children)
                {
                    foundClass = FindClassRecursive(child, p_className);
                    if (foundClass != null)
                    {
                        break;
                    }
                }
            }

            return(foundClass);
        }
        /// <summary>
        /// Recursively explores given code element
        /// </summary>
        /// <param name="parentCommand"></param>
        /// <param name="currentElement">Element to explore</param>
        /// <param name="parentNamespace">Closest parent namespace of the element</param>
        /// <param name="exploreable"></param>
        /// <param name="isLocalizableFalse"></param>
        private void Explore(AbstractBatchCommand parentCommand, CodeElement2 currentElement, CodeElement2 parentNamespace, Predicate <CodeElement> exploreable, bool isLocalizableFalse)
        {
            if (currentElement == null)
            {
                throw new ArgumentNullException("currentElement");
            }

            bool isLocalizableFalseSetOnParent = currentElement.HasLocalizableFalseAttribute(); // is element decorated with [Localizable(false)] ?

            // continue exploring in case of namepsace, class, struct, module, function, variable or property
            foreach (CodeElement2 codeElement in currentElement.Children)
            {
                if (codeElement.Kind == vsCMElement.vsCMElementClass || codeElement.Kind == vsCMElement.vsCMElementModule || codeElement.Kind == vsCMElement.vsCMElementStruct)
                {
                    Explore(parentCommand, codeElement, currentElement.Kind == vsCMElement.vsCMElementNamespace ? currentElement : parentNamespace,
                            exploreable, isLocalizableFalse || isLocalizableFalseSetOnParent);
                }
                if (codeElement.Kind == vsCMElement.vsCMElementNamespace)
                {
                    Explore(parentCommand, codeElement, currentElement, exploreable, isLocalizableFalse || isLocalizableFalseSetOnParent);
                }
                if (codeElement.Kind == vsCMElement.vsCMElementVariable)
                {
                    Explore(parentCommand, codeElement as CodeVariable2, (CodeNamespace)parentNamespace, currentElement,
                            exploreable, isLocalizableFalse || isLocalizableFalseSetOnParent);
                }
                if (codeElement.Kind == vsCMElement.vsCMElementFunction)
                {
                    Explore(parentCommand, codeElement as CodeFunction2, (CodeNamespace)parentNamespace, currentElement,
                            exploreable, isLocalizableFalse || isLocalizableFalseSetOnParent);
                }
                if (codeElement.Kind == vsCMElement.vsCMElementProperty)
                {
                    Explore(parentCommand, codeElement as CodeProperty, (CodeNamespace)parentNamespace, currentElement,
                            exploreable, isLocalizableFalse || isLocalizableFalseSetOnParent);
                }
            }
        }
        /// <inheritdoc />
        protected override IEnumerable <StaticAttributeWrapper> GetMemberCustomAttributes(StaticMemberWrapper member)
        {
            CodeElement2 memberHandle = (CodeElement2)member.Handle;

            switch (memberHandle.Kind)
            {
            case vsCMElement.vsCMElementClass:
                return(WrapAttributes(((CodeClass2)memberHandle).Attributes));

            case vsCMElement.vsCMElementStruct:
                return(WrapAttributes(((CodeStruct2)memberHandle).Attributes));

            case vsCMElement.vsCMElementInterface:
                return(WrapAttributes(((CodeInterface2)memberHandle).Attributes));

            case vsCMElement.vsCMElementDelegate:
                return(WrapAttributes(((CodeDelegate2)memberHandle).Attributes));

            case vsCMElement.vsCMElementEnum:
                return(WrapAttributes(((CodeEnum)memberHandle).Attributes));

            case vsCMElement.vsCMElementFunction:
                return(WrapAttributes(((CodeFunction2)memberHandle).Attributes));

            case vsCMElement.vsCMElementProperty:
                return(WrapAttributes(((CodeProperty2)memberHandle).Attributes));

            case vsCMElement.vsCMElementVariable:
                return(WrapAttributes(((CodeVariable2)memberHandle).Attributes));

            case vsCMElement.vsCMElementEvent:
                return(WrapAttributes(((CodeEvent)memberHandle).Attributes));
            }

            return(EmptyArray <StaticAttributeWrapper> .Instance);
        }
        private static VsObjectSearchResult CreateVBCodeElementSearchResult(CodeElement2 codeElement)
        {
            var column = codeElement.StartPoint.LineCharOffset;
            var line = codeElement.StartPoint.Line;
            int lineLength;
            string lineText;
            string prefix;

            // Try to locate the element name on the startline.
            using (var textBuffer = VsTextLinesFromFile.Load(codeElement.ProjectItem.get_FileNames(1)))
            {
                // Buffer values are zero based, codeElement values are 1 based.
                var bufferLine = line - 1;
                NativeMethods.ThrowOnFailure(textBuffer.GetLengthOfLine(bufferLine, out lineLength));
                NativeMethods.ThrowOnFailure(textBuffer.GetLineText(bufferLine, 0, bufferLine, lineLength, out lineText));
            }

            // Skip past the prefix, which is different depending on whether we are processing a class/property/function
            switch (codeElement.Kind)
            {
                case vsCMElement.vsCMElementClass:
                    prefix = VBClassKeyword;
                    break;
                case vsCMElement.vsCMElementProperty:
                    prefix = VBPropertyKeyword;
                    break;
                case vsCMElement.vsCMElementFunction:
                    prefix = VBFunctionKeyword;
                    break;
                default:
                    throw new NotImplementedException(
                        "CreateVBCodeElementSearchResult() does not implement handlers for CodeElement type: " + codeElement.Kind.ToString());
            }

            var prefixStartIndex = lineText.IndexOf(prefix, 0, StringComparison.OrdinalIgnoreCase);
            if (prefixStartIndex >= 0)
            {
                var prefixEndIndex = prefixStartIndex + prefix.Length;
                if (prefixEndIndex < lineText.Length)
                {
                    var elementNameStartIndex = lineText.IndexOf(codeElement.Name, prefixEndIndex, StringComparison.OrdinalIgnoreCase);
                    if (elementNameStartIndex >= 0)
                    {
                        // Buffer values are zero based, FindAllRef values are 1 based.
                        column = elementNameStartIndex + 1;
                    }
                }
            }

            return new VsObjectSearchResult(codeElement.ProjectItem.get_FileNames(1), codeElement.FullName, line, column);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ClassInfo"/> class.
 /// </summary>
 /// <param name="parent"></param>
 /// <param name="item"></param>
 protected ClassInfo(BaseInfo parent, CodeElement2 item)
     : base(parent, item)
 {
 }
        internal static void CreateChangeProposals(CodeElement2 codeElement, string newName, string oldName,
            string generatedItemPath, IList<ChangeProposal> changeProposals, ObjectSearchLanguage objectSearchLanguage)
        {
            if (codeElement != null)
            {
                var searchResults = VsObjectSearchResult.Search(codeElement.FullName, objectSearchLanguage);

                if (searchResults != null)
                {
                    // VB search results don't include the designer file, since the IVsObjectList item for the designer file in VB does not contain the
                    // column number for designer file references (since VB returns a hierarchical IVsObjectList and does not show column numbers in the
                    // root nodes). So instead we'll put the info from the CodeElement into the search results, which is less
                    // than ideal since the display text is not consistent with the IVsObjectList items...
                    if (objectSearchLanguage == ObjectSearchLanguage.VB
                        && codeElement.ProjectItem != null)
                    {
                        searchResults.Add(CreateVBCodeElementSearchResult(codeElement));
                    }

                    if (searchResults.Count > 0)
                    {
                        var fileToChanges = new Dictionary<string, List<RefactorChange>>();
                        var designerFileChanges = new List<RefactorChange>();

                        foreach (var searchResult in searchResults)
                        {
                            // Don't show changes in generated file in the preview dialog since those changes will always be applied after
                            // hydration completes. Instead we just show the changes from the exercising (application) code.
                            if (!string.Equals(searchResult.FileName, generatedItemPath, StringComparison.OrdinalIgnoreCase))
                            {
                                List<RefactorChange> refactorChanges;
                                if (!fileToChanges.TryGetValue(searchResult.FileName, out refactorChanges))
                                {
                                    refactorChanges = new List<RefactorChange>();
                                    fileToChanges.Add(searchResult.FileName, refactorChanges);
                                }

                                refactorChanges.Add(
                                    new RefactorChange(
                                        searchResult.DisplayText, searchResult.DisplayText, searchResult.LineNumber,
                                        searchResult.ColumnNumber));
                            }
                            else
                            {
                                // We need to know the location of the type definition in the generated code file so we can populate the
                                // root node of the preview window, so we save off a list of all references to the renamed object in
                                // the designer file here.
                                designerFileChanges.Add(
                                    new RefactorChange(
                                        searchResult.DisplayText, searchResult.DisplayText, searchResult.LineNumber,
                                        searchResult.ColumnNumber));
                            }
                        }

                        // Add designer file change
                        var rootFileName = codeElement.ProjectItem.get_FileNames(1);
                        bool doesProjectHaveFileName;
                        var rootProjectName = VsUtils.GetProjectPathWithName(
                            codeElement.ProjectItem.ContainingProject, out doesProjectHaveFileName);

                        // The code element start line will include attributes for the class, so the get the line where the actual class name is
                        // we need to use the results from the IVsObjectSearch and get the search result immediately after the CodeElements startline.
                        var minDelta = int.MaxValue;
                        RefactorChange? rootNodeChange = null;
                        foreach (var change in designerFileChanges)
                        {
                            var lineDelta = change.LineNumber - codeElement.StartPoint.Line;

                            if (lineDelta >= 0
                                && lineDelta < minDelta)
                            {
                                minDelta = lineDelta;
                                rootNodeChange = change;
                            }
                        }

                        if (rootNodeChange != null)
                        {
                            var textChangeProposal = new VsLangTextChangeProposal(
                                rootProjectName, rootFileName, newName, codeElement.FullName, true);
                            textChangeProposal.StartColumn = rootNodeChange.Value.ColumnNumber - 1;
                            textChangeProposal.EndColumn = textChangeProposal.StartColumn + oldName.Length;
                            textChangeProposal.Length = oldName.Length;
                            textChangeProposal.StartLine = rootNodeChange.Value.LineNumber - 1;
                            textChangeProposal.EndLine = textChangeProposal.StartLine;
                            textChangeProposal.Included = true;
                            changeProposals.Add(textChangeProposal);
                        }

                        // Add application code changes
                        foreach (var fileName in fileToChanges.Keys)
                        {
                            var owningProject = VSHelpers.GetProjectForDocument(fileName);
                            var changes = fileToChanges[fileName];

                            if (changes.Count > 0
                                && owningProject != null)
                            {
                                foreach (var change in changes)
                                {
                                    // Text buffer is zero based but find all refs is one based, so subtract 1.
                                    var textBufferLine = change.LineNumber - 1;
                                    var textBufferColumn = change.ColumnNumber - 1;

                                    bool projectHasFilename;
                                    var projectFullPath = VsUtils.GetProjectPathWithName(owningProject, out projectHasFilename);
                                    var textChangeProposal = new VsLangTextChangeProposal(
                                        projectFullPath, fileName, newName, codeElement.FullName);
                                    textChangeProposal.StartColumn = textBufferColumn;
                                    textChangeProposal.EndColumn = textChangeProposal.StartColumn + oldName.Length;
                                    textChangeProposal.Length = oldName.Length;
                                    textChangeProposal.StartLine = textBufferLine;
                                    textChangeProposal.EndLine = textBufferLine;
                                    textChangeProposal.Included = true;
                                    changeProposals.Add(textChangeProposal);
                                }
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// 
 /// </summary>
 public virtual CodeFieldInfo CreateField(ClassInfo parent, CodeElement2 item)
 {
     return new CodeFieldInfo(parent, item);
 }
 private static Namespace ParseUsing(CodeElement2 codeElement)
 {
     var codeImport = (CodeImport) codeElement;
     return new Namespace {Name = codeImport.Namespace};
 }
        private void ToggleSubmembers(CodeElement2 codeElement)
        {
            try {
                EditPoint memberStart = codeElement.GetStartPoint().CreateEditPoint();
                ToggleCommentsAboveMember(memberStart, GetCommentString());
            }
            catch(Exception) { }

            if(codeElement.IsCodeType || IsNamespace(codeElement)) {
                dynamic codeOrNamespace = codeElement;
                foreach(CodeElement2 childCodeElement in codeOrNamespace.Members) {
                    ToggleSubmembers(childCodeElement);
                }
            }
        }
 private static bool IsNamespace(CodeElement2 codeElement)
 {
     return codeElement.Kind == vsCMElement.vsCMElementNamespace;
 }
        public void SortMembers(Options options)
        {
            IEnumerable <Tuple <MemberProperty, bool> > sortOrder = GetSortOrder(options) ?? StyleCopSortOrder;

            // Get a list of all selected members using our CodeMember type since Microsoft didn't define a common member base type.
            List <CodeMember> codeMembers = new List <CodeMember>();

            if (this.memberLists != null)
            {
                foreach (var tuple in this.memberLists)
                {
                    codeMembers.AddRange(tuple.Item2.Select(e => new CodeMember(e, tuple.Item1, this.language)));
                }
            }

            bool execute = true;
            Action <List <CodeMember> > sortMembers = list => list.Sort((x, y) => x.CompareByMemberProperties(y, sortOrder));

            if (!options.OnlyShowSortMembersDialogWhenShiftIsPressed || Utilities.IsShiftPressed)
            {
                SortMembersDialog dialog = new SortMembersDialog();
                try
                {
                    execute = dialog.Execute(codeMembers, options, sortMembers);
                }
                catch (Exception)
                {
                    // Exceptions from any dialog event handler would leave the dialog open but orphaned
                    // (i.e., VS would no longer treat it as a modal).  We need to force the dialog to close.
                    dialog.Close();
                    throw;
                }
            }
            else
            {
                sortMembers(codeMembers);
            }

            if (execute)
            {
                // When we get here the codeMembers list is either sorted or manually ordered the way the user wants.
                // So we just need to apply the members in the requested order.
                this.textHandler.Execute(
                    "Sort Members",
                    () =>
                {
                    // We'll try to group the type members by the first sort property (if it's an enum property) to keep
                    // the members within any existing #regions (assuming the #regions are grouped that way).
                    Tuple <MemberProperty, bool> groupingProperty = sortOrder.First();
                    if (groupingProperty.Item1 != MemberProperty.Kind && groupingProperty.Item1 != MemberProperty.Access)
                    {
                        groupingProperty = null;
                    }

                    foreach (var typeGroup in codeMembers.GroupBy(member => member.TypeElement))
                    {
                        CodeElement2 type = typeGroup.Key;
                        IEnumerable <List <CodeMember> > reorderGroups = GroupMembers(typeGroup.ToList(), groupingProperty);
                        foreach (var reorderGroup in reorderGroups)
                        {
                            this.ReorderMembers(type, reorderGroup, false);
                        }
                    }
                });
            }
        }
 private void Init(CodeElement2 ele)
 {
     Init();
     ParentElement = ele;
     var attrs = ele.GetCustomAttribute(GetType()).GetCodeAttributeArguments();
     CopyPropertyFromAttributeArguments(attrs);
 }
 private static void GetClassElements(CodeElement2 codeElement, Dictionary<string, CodeClass2> dic_FullName_ClassElement)
 {
     var classElement = codeElement as CodeClass2;
     if (classElement != null)
     {
         if (dic_FullName_ClassElement != null)
             dic_FullName_ClassElement[classElement.FullName] = classElement;
         foreach (CodeElement2 member in classElement.Members)
             GetClassElements(member, dic_FullName_ClassElement);
     }
     else
     {
         var codeNamespace = codeElement as CodeNamespace;
         if (codeNamespace != null)
         {
             foreach (CodeElement2 member in codeNamespace.Members)
                 GetClassElements(member, dic_FullName_ClassElement);
         }
     }
 }
 private void ParseCodeElement(CodeElement2 codeElement, List<Namespace> usings, string currentFile)
 {
     switch (codeElement.Kind)
     {
         case vsCMElement.vsCMElementNamespace:
             ParseNameSpace((CodeNamespace)codeElement, usings, currentFile);
             break;
     }
 }
 /// <summary>
 /// 
 /// </summary>
 public CodeMemberInfo(BaseInfo parent, CodeElement2 item)
     : base(parent, item)
 {
     Parent = parent;
 }