コード例 #1
0
        private CustomAnalysisTag RepurposeTagForSupplementaryAction(CustomAnalysisTag tag, AnalysisAction suppAction, string elementXaml)
        {
            var ae = RapidXamlElementExtractor.GetElement(elementXaml, tag.AnalyzedElement.Location.Start);

            var catd = new CustomAnalysisTagDependencies
            {
                AnalyzedElement = ae,
                Action          = suppAction,
                ElementName     = ae.Name,
                FileName        = tag.FileName,
                InsertPos       = tag.InsertPosition,
                Logger          = tag.Logger,
                ProjectFilePath = tag.ProjectFilePath,
                Snapshot        = tag.Snapshot,
                //// Don't need to set VsAbstraction as tags only need it for referencing settings but supplementary actions don't need to know about settings.
            };

            if (suppAction.Location == null)
            {
                if (tag.Action == ActionType.RenameElement)
                {
                    catd.Span = new Span(tag.Span.Start, tag.Name.Length);
                }
                else
                {
                    catd.Span = tag.Span;
                }
            }
            else
            {
                catd.Span = suppAction.Location.ToSpanPlusStartPos(tag.InsertPosition);
            }

            return(new CustomAnalysisTag(catd));
        }
コード例 #2
0
        private CustomAnalysisTag RepurposeTagForSupplementaryAction(CustomAnalysisTag tag, AnalysisAction suppAction)
        {
            var catd = new CustomAnalysisTagDependencies
            {
                AnalyzedElement = tag.AnalyzedElement,
                Action          = suppAction,
                ElementName     = tag.ElementName,
                FileName        = tag.FileName,
                InsertPos       = tag.InsertPosition,
                Logger          = tag.Logger,
                ProjectFilePath = tag.ProjectFilePath,
                Snapshot        = tag.Snapshot,
                //// Don't need to set VsAbstraction as tags only need it for referencing settings but supplementary actions don't need to know about settings.
            };

            if (suppAction.Location == null)
            {
                catd.Span = tag.Span;
            }
            else
            {
                catd.Span = suppAction.Location.ToSpanPlusStartPos(tag.InsertPosition);
            }

            return(new CustomAnalysisTag(catd));
        }
コード例 #3
0
        public CustomAnalysisAction(string file, CustomAnalysisTag tag)
            : base(file)
        {
            this.Tag         = tag;
            this.DisplayText = tag.ActionText;

            this.CustomFeatureUsageOverride = tag.CustomFeatureUsageOverride;
        }
コード例 #4
0
        public static CustomAnalysisAction[] Create(CustomAnalysisTag tag, string file)
        {
            var result = new List <CustomAnalysisAction>
            {
                new CustomAnalysisAction(file, tag),
            };

            foreach (var altAction in tag.AlternativeActions)
            {
                result.Add(new CustomAnalysisAction(file, tag.RecreateForAlternativeAction(altAction)));
            }

            return(result.ToArray());
        }
コード例 #5
0
        private string AddXmlns(CustomAnalysisTag faTag, string xaml, List <string> output)
        {
            var element = RapidXamlElementExtractor.GetElement(xaml);

            bool exists = false;

            foreach (var attr in element.InlineAttributes)
            {
                if (attr.Name.StartsWith("xmlns:"))
                {
                    var alias = attr.Name.Substring(6);

                    if (alias == faTag.Name)
                    {
                        if (attr.StringValue == faTag.Value)
                        {
                            output.Add("XMLNS is already specified in the document.");
                        }
                        else
                        {
                            output.Add("XMLNS is already specified in the document but with a different value.");
                        }

                        exists = true;
                        break;
                    }
                }
            }

            if (!exists)
            {
                var insertPos = element.InlineAttributes?.LastOrDefault()?.Location?.End();

                output.Add($"Adding xmlns alias for '{faTag.Name}'");

                if (insertPos != null)
                {
                    xaml = xaml.Insert(insertPos.Value, $" xmlns:{faTag.Name}=\"{faTag.Value}\"");
                }
                else
                {
                    xaml = xaml.Insert(
                        element.Location.Start + element.Name.Length + 1,
                        $" xmlns:{faTag.Name}=\"{faTag.Value}\"");
                }
            }

            return(xaml);
        }
コード例 #6
0
        public CustomAnalysisAction(string file, CustomAnalysisTag tag)
            : base(file)
        {
            this.Tag = tag;

            if (string.IsNullOrWhiteSpace(tag.ActionText))
            {
                this.DisplayText = Resources.StringRes.UI_XamlAnalysisFixUnavailable;
                this.IsEnabled   = false;
            }
            else
            {
                this.DisplayText = tag.ActionText;
            }

            this.CustomFeatureUsageOverride = tag.CustomFeatureUsageOverride;
        }
コード例 #7
0
        private CustomAnalysisTag RepurposeTagForSupplementaryAction(CustomAnalysisTag tag, AnalysisAction suppAction)
        {
            var catd = new CustomAnalysisTagDependencies
            {
                AnalyzedElement = tag.AnalyzedElement,
                Action          = suppAction,
                ElementName     = tag.ElementName,
                FileName        = tag.FileName,
                InsertPos       = tag.InsertPosition,
                Logger          = tag.Logger,
                Snapshot        = tag.Snapshot,
            };

            if (suppAction.Location == null)
            {
                catd.Span = tag.Span;
            }
            else
            {
                catd.Span = suppAction.Location.ToSpanPlusStartPos(tag.InsertPosition);
            }

            return(new CustomAnalysisTag(catd));
        }
コード例 #8
0
#pragma warning disable IDE0060 // Remove unused parameter - cancellationToken
        private void InnerExecute(VisualStudioTextManipulation vs, CustomAnalysisTag tag, CancellationToken cancellationToken)
#pragma warning restore IDE0060 // Remove unused parameter
        {
            switch (tag.Action)
            {
            case RapidXaml.ActionType.AddAttribute:
                var lineNumber = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition) + 1;

                // Can't rely on the original element name as this may be supplemental after it's been renamed
                if (XamlElementProcessor.IsSelfClosing(tag.AnalyzedElement.OriginalString.AsSpan()))
                {
                    var before = $"/>";
                    var after  = $"{tag.Name}=\"{tag.Value}\" />";

                    vs.ReplaceInActiveDocOnLine(before, after, lineNumber);
                }
                else
                {
                    var before = $">";
                    var after  = $"{tag.Name}=\"{tag.Value}\" /";

                    vs.ReplaceInActiveDocOnLine(before, after, lineNumber);
                }

                break;

            case RapidXaml.ActionType.AddChild:

                var origXaml = tag.AnalyzedElement.OriginalString;

                // Allow for self-closing elements
                if (origXaml.EndsWith("/>"))
                {
                    var replacementXaml = $">{Environment.NewLine}{tag.Content}{Environment.NewLine}</{tag.ElementName}>";

                    var insertLine = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition) + 1;
                    vs.ReplaceInActiveDocOnLine("/>", replacementXaml, insertLine);
                }
                else
                {
                    // Allows for opening and closing tags on same or different lines
                    var insertLine = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition) + 1;
                    vs.InsertIntoActiveDocOnLineAfterClosingTag(insertLine, tag.Content);
                }

                break;

            case RapidXaml.ActionType.HighlightWithoutAction:
                // As the name implies, do nothing.
                break;

            case RapidXaml.ActionType.RemoveAttribute:
                if (tag.IsInlineAttribute ?? false)
                {
                    var currentAttribute = $" {tag.Name}=\"{tag.Value}\"";
                    vs.RemoveInActiveDocOnLine(currentAttribute, tag.GetDesignerLineNumber());
                }
                else
                {
                    var attrs = tag.AnalyzedElement.GetAttributes(tag.Name).ToList();

                    if (attrs.Count() == 1)
                    {
                        var attr     = attrs.First();
                        var toRemove =
                            tag.AnalyzedElement.OriginalString.Substring(
                                attr.Location.Start - tag.InsertPosition,
                                attr.Location.Length);

                        vs.RemoveInActiveDocOnLine(toRemove, tag.GetDesignerLineNumber());
                    }
                }

                break;

            case RapidXaml.ActionType.RemoveChild:
                vs.RemoveInActiveDocOnLine(tag.Element.OriginalString, tag.GetDesignerLineNumber());
                break;

            case RapidXaml.ActionType.ReplaceElement:
                vs.ReplaceInActiveDocOnLine(
                    tag.AnalyzedElement.OriginalString,
                    tag.Content,
                    tag.Snapshot.GetLineNumberFromPosition(tag.AnalyzedElement.Location.Start));
                break;

            case RapidXaml.ActionType.RenameElement:
                // Just change opening tags as Visual Studio will change closing tags automatically
                var renameLineNumber = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition);
                vs.ReplaceInActiveDocOnLine(tag.ElementName, tag.Name, renameLineNumber);

                foreach (var childAttr in tag.AnalyzedElement.ChildAttributes)
                {
                    renameLineNumber = tag.Snapshot.GetLineNumberFromPosition(childAttr.Location.Start);
                    vs.ReplaceInActiveDocOnLine($"{tag.ElementName}.{childAttr.Name}", $"{tag.Name}.{childAttr.Name}", renameLineNumber);
                }

                break;
            }
        }
コード例 #9
0
        private string UpdateElementXaml(CustomAnalysisTag cat, List <string> output)
        {
            var orig    = cat.AnalyzedElement.OriginalString;
            var newXaml = orig;

            switch (cat.Action)
            {
            case ActionType.AddAttribute:
                output.Add($"Adding attribute '{cat.Name}' to {cat.ElementName}");

                if (orig.EndsWith("/>"))
                {
                    newXaml = orig.Substring(0, orig.Length - 2) + $"{cat.Name}=\"{cat.Value}\" />";
                }
                else
                {
                    newXaml = orig.Substring(0, cat.Span.End - cat.AnalyzedElement.Location.Start) + $" {cat.Name}=\"{cat.Value}\"" + orig.Substring(cat.Span.End - cat.AnalyzedElement.Location.Start);
                }

                break;

            case ActionType.AddChild:
                output.Add($"Adding child element to {cat.ElementName}");

                if (orig.EndsWith("/>"))
                {
                    var replacementXaml = $">{Environment.NewLine}{cat.Content}{Environment.NewLine}</{cat.ElementName}>";

                    newXaml = orig.Substring(0, orig.Length - 2) + replacementXaml;
                }
                else
                {
                    var insertPos = orig.IndexOf('>');

                    newXaml = orig.Substring(0, insertPos + 1) + $"{Environment.NewLine}{cat.Content}" + orig.Substring(insertPos + 1);
                }

                break;

            case ActionType.HighlightWithoutAction:
                // NOOP - Nothing to fix here
                break;

            case ActionType.RemoveAttribute:

                var attrs = cat.AnalyzedElement.GetAttributes(cat.Name).ToList();

                if (attrs.Count() == 1)
                {
                    output.Add($"Removing attribute '{cat.Name}' from {cat.ElementName}");

                    var attr = attrs.First();
                    newXaml = orig.Substring(0, attr.Location.Start - cat.AnalyzedElement.Location.Start) + orig.Substring(attr.Location.End() - cat.AnalyzedElement.Location.Start);
                }
                else
                {
                    output.Add($"Not removing attribute '{cat.Name}' from {cat.ElementName} as it doesn't exist");
                }

                break;

            case ActionType.RemoveChild:
                var children = cat.AnalyzedElement.GetChildren(cat.Element.Name).ToList();

                if (children.Count() >= 1)
                {
                    children.Reverse();

                    foreach (var child in children)
                    {
                        output.Add($"Removing child '{cat.Element.Name}' from {cat.ElementName}");

                        newXaml = newXaml.Substring(0, child.Location.Start - cat.AnalyzedElement.Location.Start) + newXaml.Substring(child.Location.End() - cat.AnalyzedElement.Location.Start);
                    }
                }
                else
                {
                    output.Add($"Not removing child '{cat.Name}' from {cat.ElementName} as it doesn't exist");
                }

                break;

            case ActionType.RenameElement:
                output.Add($"Renaming an instance of {cat.ElementName} to {cat.Name}");

                if (orig.EndsWith("/>"))
                {
                    newXaml = $"<{cat.Name}" + orig.Substring(cat.Span.End - cat.AnalyzedElement.Location.Start);
                }
                else
                {
                    var startNameEnd = cat.ElementName.Length + 1;
                    var endNameStart = orig.LastIndexOf("</");

                    var updated = $"<{cat.Name}" + orig.Substring(startNameEnd, endNameStart - startNameEnd) + $"</{cat.Name}>";
                    newXaml = updated;
                }

                break;

            case ActionType.ReplaceElement:
                output.Add($"Replacing {cat.ElementName}");

                newXaml = cat.Content;

                break;

            default:
                break;
            }

            return(newXaml);
        }