Esempio n. 1
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));
        }
        protected static List <PreviewChangesNode> CreatePreviewNodesForVsLang(
            IList <FileChange> fileChanges, bool placeNodesUnderSingleRoot = false)
        {
            var vsLangObjectNodes      = new List <PreviewChangesNode>();
            var rootToFileToChangesMap = new Dictionary <string, Dictionary <string, List <PreviewChangesNode> > >();
            var isCSharpChange         = true;

            foreach (var fileChange in fileChanges)
            {
                if (fileChange.ChangeList != null)
                {
                    if (fileChange.ChangeList.Count > 0)
                    {
                        using (var textBuffer = VsTextLinesFromFile.Load(fileChange.FileName))
                        {
                            if (textBuffer != null)
                            {
                                foreach (
                                    var vsLangTextChange in
                                    fileChange.ChangeList.SelectMany(cl => cl.Value).OfType <VsLangTextChangeProposal>())
                                {
                                    if (vsLangTextChange.IsRootChange)
                                    {
                                        // Create object definition node
                                        var rootNode = new PreviewChangesNode(
                                            vsLangTextChange.ObjectDefinitionFullName
                                            , new VSTREEDISPLAYDATA()
                                            , vsLangTextChange.ObjectDefinitionFullName
                                            , new List <PreviewChangesNode>()
                                            , vsLangTextChange);

                                        rootNode.CheckState = vsLangTextChange.Included
                                                                  ? __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Checked
                                                                  : __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Unchecked;
                                        vsLangObjectNodes.Add(rootNode);

                                        // It's possible that a non-root change was processed first, in which case the dictionary will already be updated
                                        // with the root node name. This means we need to check the dictionary before adding to it.
                                        if (!rootToFileToChangesMap.ContainsKey(vsLangTextChange.ObjectDefinitionFullName))
                                        {
                                            rootToFileToChangesMap.Add(
                                                vsLangTextChange.ObjectDefinitionFullName,
                                                new Dictionary <string, List <PreviewChangesNode> >());
                                        }
                                    }
                                    else
                                    {
                                        // Get display text, trim the leading space of the text for display purpose.
                                        var displayText = string.Empty;
                                        int lineLength;

                                        if (ErrorHandler.Succeeded(textBuffer.GetLengthOfLine(vsLangTextChange.StartLine, out lineLength)))
                                        {
                                            if (
                                                ErrorHandler.Succeeded(
                                                    textBuffer.GetLineText(
                                                        vsLangTextChange.StartLine, 0, vsLangTextChange.StartLine, lineLength,
                                                        out displayText)))
                                            {
                                                var length = displayText.Length;
                                                displayText = displayText.TrimStart();
                                                var spaceLength = length - displayText.Length;

                                                Debug.Assert(
                                                    spaceLength <= vsLangTextChange.StartColumn,
                                                    "Start column of selection is negative, HydratedVsLangRefactor.CreatePreviewNodeForChanges()");

                                                if (spaceLength <= vsLangTextChange.StartColumn)
                                                {
                                                    var changeNodeDisplayData = new VSTREEDISPLAYDATA();
                                                    changeNodeDisplayData.State            = (uint)_VSTREEDISPLAYSTATE.TDS_FORCESELECT;
                                                    changeNodeDisplayData.ForceSelectStart =
                                                        (ushort)(vsLangTextChange.StartColumn - spaceLength);
                                                    changeNodeDisplayData.ForceSelectLength = (ushort)(vsLangTextChange.Length);

                                                    var changeNode = new PreviewChangesNode(
                                                        displayText, changeNodeDisplayData, displayText, null, vsLangTextChange);

                                                    // Add checked checkbox
                                                    changeNode.ShowCheckBox = true;
                                                    changeNode.CheckState   = vsLangTextChange.Included
                                                                                ? __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Checked
                                                                                : __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Unchecked;

                                                    // Apply the language service to this change.
                                                    Guid languageServiceId;
                                                    textBuffer.GetLanguageServiceID(out languageServiceId);
                                                    changeNode.LanguageServiceID = languageServiceId;

                                                    Dictionary <string, List <PreviewChangesNode> > fileToChangesMap;
                                                    if (rootToFileToChangesMap.TryGetValue(
                                                            vsLangTextChange.ObjectDefinitionFullName, out fileToChangesMap))
                                                    {
                                                        List <PreviewChangesNode> changeNodes;
                                                        if (fileToChangesMap.TryGetValue(fileChange.FileName, out changeNodes))
                                                        {
                                                            changeNodes.Add(changeNode);
                                                        }
                                                        else
                                                        {
                                                            // There are no changes for the file listed under this root node, so we need to create it
                                                            changeNodes = new List <PreviewChangesNode> {
                                                                changeNode
                                                            };
                                                            fileToChangesMap.Add(fileChange.FileName, changeNodes);
                                                        }
                                                    }
                                                    else
                                                    {
                                                        // There are no changes processed yet for this object name, so we need to update our dictionary with
                                                        // markers for creating a new root node, a new file node, and a new change node.
                                                        fileToChangesMap = new Dictionary <string, List <PreviewChangesNode> >();
                                                        fileToChangesMap.Add(
                                                            fileChange.FileName, new List <PreviewChangesNode> {
                                                            changeNode
                                                        });
                                                        rootToFileToChangesMap.Add(
                                                            vsLangTextChange.ObjectDefinitionFullName, fileToChangesMap);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Now that all the changes have been sorted under the correct root nodes in our dictionary, create the File nodes that connect
            // the root nodes to the change nodes.
            foreach (var rootNode in vsLangObjectNodes)
            {
                Dictionary <string, List <PreviewChangesNode> > fileToChangesMap;
                if (rootToFileToChangesMap.TryGetValue(rootNode.DisplayText, out fileToChangesMap))
                {
                    if (fileToChangesMap != null)
                    {
                        foreach (var fileName in fileToChangesMap.Keys)
                        {
                            var fileNodeDisplayData = new VSTREEDISPLAYDATA();

                            if (FileExtensions.VbExt.Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase))
                            {
                                fileNodeDisplayData.Image = fileNodeDisplayData.SelectedImage = CommonConstants.OM_GLYPH_VBPROJECT;
                                isCSharpChange            = false;
                            }
                            else
                            {
                                fileNodeDisplayData.Image = fileNodeDisplayData.SelectedImage = CommonConstants.OM_GLYPH_CSHARPFILE;
                            }

                            var shortFileName = Path.GetFileName(fileName);
                            var checkState    = DetermineCheckState(fileToChangesMap[fileName]);
                            var fileNode      = new PreviewChangesNode(shortFileName, fileNodeDisplayData, shortFileName, null, null);
                            fileNode.AddChildNodes(fileToChangesMap[fileName]);

                            // Add checked checkbox
                            fileNode.ShowCheckBox = true;
                            fileNode.CheckState   = checkState;
                            rootNode.AddChildNode(fileNode);

                            // Update root check state
                            if (rootNode.ChildList.Count == 1)
                            {
                                // This is the first child, so the root should match the child check state
                                rootNode.CheckState = checkState;
                            }
                            else
                            {
                                switch (rootNode.CheckState)
                                {
                                case __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Checked:
                                {
                                    if (checkState == __PREVIEWCHANGESITEMCHECKSTATE.PCCS_PartiallyChecked ||
                                        checkState == __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Unchecked)
                                    {
                                        rootNode.CheckState = __PREVIEWCHANGESITEMCHECKSTATE.PCCS_PartiallyChecked;
                                    }
                                    break;
                                }

                                case __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Unchecked:
                                {
                                    if (checkState == __PREVIEWCHANGESITEMCHECKSTATE.PCCS_PartiallyChecked ||
                                        checkState == __PREVIEWCHANGESITEMCHECKSTATE.PCCS_Checked)
                                    {
                                        rootNode.CheckState = __PREVIEWCHANGESITEMCHECKSTATE.PCCS_PartiallyChecked;
                                    }
                                    break;
                                }
                                }
                            }
                        }
                    }
                }
            }

            if (placeNodesUnderSingleRoot)
            {
                PreviewChangesNode rootNode;
                var fileNodeDisplayData = new VSTREEDISPLAYDATA();

                if (isCSharpChange)
                {
                    fileNodeDisplayData.Image = fileNodeDisplayData.SelectedImage = CommonConstants.OM_GLYPH_CSHARPFILE;
                    rootNode = new PreviewChangesNode(CSharpRootNodeText, fileNodeDisplayData, null, null, null);
                }
                else
                {
                    fileNodeDisplayData.Image = fileNodeDisplayData.SelectedImage = CommonConstants.OM_GLYPH_VBPROJECT;
                    rootNode = new PreviewChangesNode(VBRootNodeText, fileNodeDisplayData, null, null, null);
                }

                rootNode.ShowCheckBox = true;
                rootNode.CheckState   = DetermineCheckState(vsLangObjectNodes);
                rootNode.AddChildNodes(vsLangObjectNodes);
                return(new List <PreviewChangesNode> {
                    rootNode
                });
            }
            else
            {
                return(vsLangObjectNodes);
            }
        }