// 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()); } }
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(); }
/// <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>(); }
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); } } }
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); }
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> /// 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)); }
/// <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)); }
///<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); }
/// <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); } }
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); }
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 }); }
/// <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)); } }
/// <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); }
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()); }
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); } } }
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); } }
/// <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; }