Exemple #1
0
 private static CodeFunction GetCodeFunction(FileCodeModel2 fcm, TextPoint point)
 {
     try {
         var element = fcm.CodeElementFromPoint(point, vsCMElement.vsCMElementFunction);
         return((CodeFunction)element);
     } catch {
         return(null);
     }
 }
        /// <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);
        }
Exemple #3
0
        public static CodeElement GetCodeElement(DTE dte, vsCMElement[] searchScopes)
        {
            if (dte.ActiveDocument == null)
            {
                return(null);
            }
            if (dte.ActiveDocument.ProjectItem == null)
            {
                return(null);
            }
            if (dte.ActiveDocument.ProjectItem.FileCodeModel == null)
            {
                return(null);
            }
            TextSelection selection = (TextSelection)dte.ActiveWindow.Selection;

            if (selection == null || selection.ActivePoint == null)
            {
                return(null);
            }
            EditPoint    selPoint    = selection.ActivePoint.CreateEditPoint();
            CodeLanguage currentLang = CodeLanguage.CSharp;

            selPoint.StartOfLine();
            while (true)
            {
                string BlockText = selPoint.GetText(selPoint.LineLength).Trim();
                // *** Skip over any XML Doc comments and Attributes
                if (currentLang == CodeLanguage.CSharp && BlockText.StartsWith("/// ") ||
                    currentLang == CodeLanguage.CSharp && BlockText.StartsWith("[") ||
                    currentLang == CodeLanguage.VB && BlockText.StartsWith("''' ") ||
                    currentLang == CodeLanguage.VB && BlockText.StartsWith("<"))
                {
                    selPoint.LineDown(1);
                    selPoint.StartOfLine();
                }
                else
                {
                    break;
                }
            }

            // *** Make sure the cursor is placed inside of the definition always
            // *** Especially required for single line methods/fields/events etc.
            selPoint.EndOfLine();
            selPoint.CharLeft(1);              // Force into the text

            string xBlockText = selPoint.GetText(selPoint.LineLength).Trim();

            // get the element under the cursor
            CodeElement    element   = null;
            FileCodeModel2 CodeModel = dte.ActiveDocument.ProjectItem.FileCodeModel as FileCodeModel2;

            // *** Supported scopes - set up here in the right parsing order
            // *** from lowest level to highest level
            // *** NOTE: Must be adjusted to match any CodeElements supported

            foreach (vsCMElement scope in searchScopes)
            {
                try
                {
                    element = CodeModel.CodeElementFromPoint(selPoint, scope);
                    if (element != null)
                    {
                        break;                         // if no exception - break
                    }
                }
                catch {; }
            }
            if (element == null)
            {
                return(null);
            }
            return(element);
        }