/// <summary> /// Create the text for a property using the property name and the accessors /// </summary> /// <param name="elem">Property we are updating</param> /// <param name="ep">The point we are inserting the text</param> private static void ProcessPropertyUpdate(CodeProperty elem, EditPoint2 ep) { string descriptionText = string.Empty; if (elem.Getter != null) { switch (elem.Getter.Access) { case vsCMAccess.vsCMAccessPrivate: break; default: descriptionText = "Gets"; break; } } if (elem.Setter != null) { switch (elem.Setter.Access) { case vsCMAccess.vsCMAccessPrivate: break; default: if (descriptionText.Length > 0) { descriptionText += " or sets"; } else { descriptionText = "Sets"; } break; } } descriptionText += " " + elem.Name; TextPoint tp = elem.GetStartPoint(); ep.MoveToPoint(tp); string spacer = string.Empty; for (int i = 0; i < tp.LineCharOffset - 1; i++) { spacer += " "; } ep.LineUp(); ep.Insert(Environment.NewLine); ep.Insert(spacer + "/// <summary>"); ep.Insert(Environment.NewLine + spacer + string.Format("/// {0}", descriptionText)); ep.Insert(Environment.NewLine + spacer + "/// </summary>"); ep.Insert(spacer); }
/// <summary> /// Returns inner text of the variable (modifiers, name and initializer) /// </summary> public static string GetText(this CodeProperty codeProperty) { if (codeProperty == null) { throw new ArgumentNullException("codeProperty"); } TextPoint startPoint = codeProperty.GetStartPoint(vsCMPart.vsCMPartBody); TextPoint endPoint = codeProperty.GetEndPoint(vsCMPart.vsCMPartBody); EditPoint ep = startPoint.CreateEditPoint(); if (ep == null) { return(null); } else { return(ep.GetText(endPoint)); } }
/// <summary> /// Used by C# ad-hoc methods (move and inline) to get information about the block of code, where right-click was performed. /// This methods makes use of document's FileCodeModel, which is not available for ASP .NET files - these files are thus /// handled by their own parser. /// </summary> /// <param name="text">Text of the block (e.g. code of a method, declaration of a variable...)</param> /// <param name="startPoint">Beginning of the text</param> /// <param name="codeFunctionName">Name of the function, where right-click was performed, null if right-click was performed on a variable.</param> /// <param name="codeVariableName">Name of the variable, where right-click was performed, null otherwise.</param> /// <param name="codeClass">Name of the class, where the code block is located.</param> /// <param name="selectionSpan">Current selection span.</param> /// <returns>True, if all necessary information was succesfully obtained, false otherwise.</returns> protected bool GetCodeBlockFromSelection(out string text, out TextPoint startPoint, out string codeFunctionName, out string codeVariableName, out CodeElement2 codeClass, out TextSpan selectionSpan, out bool isConst, out object codeModelSource) { // get current selection span TextSpan[] spans = new TextSpan[1]; int hr = textView.GetSelectionSpan(spans); Marshal.ThrowExceptionForHR(hr); selectionSpan = spans[0]; object o; hr = textLines.CreateTextPoint(selectionSpan.iStartLine, selectionSpan.iStartIndex, out o); Marshal.ThrowExceptionForHR(hr); TextPoint selectionPoint = (TextPoint)o; startPoint = null; text = null; bool ok = false; codeFunctionName = null; codeVariableName = null; codeClass = null; isConst = false; codeModelSource = null; // It is impossible to find out the code block, where right-click was performed. Following code // assumes that valid string literals or references can only be found in a method, in a class variable (as initializers) // or in a property code. C# syntax permits more locations (attributes, default argument values in .NET 4+) but we can ignore // these, because they are all evaluated at compile-time, making resource references impossible. // assume we are in a function (method) try { CodeFunction2 codeFunction = (CodeFunction2)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementFunction); codeFunctionName = codeFunction.Name; codeClass = codeFunction.GetClass(); // extension codeModelSource = codeFunction; text = codeFunction.GetText(); if (!string.IsNullOrEmpty(text)) { startPoint = codeFunction.GetStartPoint(vsCMPart.vsCMPartBody); ok = true; } } catch (Exception) { // it's not a method - maybe a property? try { CodeProperty codeProperty = (CodeProperty)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementProperty); codeFunctionName = codeProperty.Name; codeClass = codeProperty.GetClass(); codeModelSource = codeProperty; text = codeProperty.GetText(); if (!string.IsNullOrEmpty(text)) { startPoint = codeProperty.GetStartPoint(vsCMPart.vsCMPartBody); ok = true; } } catch (Exception) { // not a property, either. It must be a variable - or there's no valid code block try { CodeVariable2 codeVariable = (CodeVariable2)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementVariable); if (codeVariable.InitExpression != null) { codeVariableName = codeVariable.Name; codeClass = codeVariable.GetClass(); isConst = codeVariable.ConstKind == vsCMConstKind.vsCMConstKindConst; codeModelSource = codeVariable; startPoint = codeVariable.StartPoint; text = codeVariable.GetText(); if ((codeClass.Kind == vsCMElement.vsCMElementStruct && codeVariable.IsShared) || (codeClass.Kind == vsCMElement.vsCMElementClass || codeClass.Kind == vsCMElement.vsCMElementModule) && !string.IsNullOrEmpty(text)) { ok = true; } } } catch (Exception) { return(false); } } } return(ok); }