Beispiel #1
0
        private async void MenuItem_BeforeQueryStatus(object sender, EventArgs e)
        {
            try
            {
                if (sender is OleMenuCommand menuCmd)
                {
                    bool showCommandButton = false;

                    var settings = CodeParserBase.GetSettings();

                    if (settings.IsActiveProfileSet)
                    {
                        var profile = settings.GetActiveProfile();
                        var dte     = await Instance.ServiceProvider.GetServiceAsync(typeof(DTE)) as DTE;

                        var logic = new SetDataContextCommandLogic(profile, this.Logger, new VisualStudioAbstraction(this.Logger, this.ServiceProvider, dte));

                        showCommandButton = logic.ShouldEnableCommand();
                    }

                    menuCmd.Visible = menuCmd.Enabled = showCommandButton;
                }
            }
            catch (Exception exc)
            {
                this.Logger.RecordException(exc);
                throw;  // Remove for launch. see issue #90
            }
        }
Beispiel #2
0
        public void ReadOnlyPropertiesMatchNotReadOnlyRatherThanFallback()
        {
            var readonlyProfile = new Profile
            {
                Name           = "readonlyProfile",
                ProjectType    = ProjectType.Uwp,
                ClassGrouping  = "Grid",
                FallbackOutput = "<Fallback />",
                Mappings       = new ObservableCollection <Mapping>
                {
                    new Mapping
                    {
                        Type         = StringPropertyName,
                        NameContains = "",
                        Output       = "<ReadAndWrite />",
                        IfReadOnly   = false,
                    },
                },
            };

            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), readonlyProfile.ProjectType, 4, readonlyProfile);
            var result = cpb.GetPropertyOutput(StringPropertyName, "MyProperty", isReadOnly: true);

            Assert.AreEqual("<ReadAndWrite />", result);
        }
        public void MultipleNameContainsIsIdentified()
        {
            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, this.testProfile);
            var result = cpb.GetPropertyOutput("string", "EnteredPassword", isReadOnly: false);

            Assert.AreEqual(ReadWritePasswordStringOutput.Replace("$name$", "EnteredPassword"), result);
        }
        public void SpecificGenericsMatchBeforeWildCard()
        {
            var wildcardGenericsProfile = new Profile
            {
                Name           = "wildcardGenericsProfile",
                ClassGrouping  = "Grid",
                FallbackOutput = "<Fallback />",
                Mappings       = new ObservableCollection <Mapping>
                {
                    new Mapping
                    {
                        Type         = "List<T>",
                        NameContains = "",
                        Output       = "<Wildcard />",
                        IfReadOnly   = false,
                    },
                    new Mapping
                    {
                        Type         = "List<string>",
                        NameContains = "",
                        Output       = "<ListOfStrings />",
                        IfReadOnly   = false,
                    },
                },
            };

            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, wildcardGenericsProfile);
            var result = cpb.GetPropertyOutput("List<string>", "MyProperty", isReadOnly: false);

            Assert.AreEqual("<ListOfStrings />", result);
        }
        public void CanHandleMultipleNumberReplacements()
        {
            var gridProfile = new Profile
            {
                Name              = "GridTestProfile",
                ClassGrouping     = "Grid",
                FallbackOutput    = "<TextBlock Text=\"FALLBACK_$name$\" />",
                SubPropertyOutput = "<TextBlock Text=\"SUBPROP_$name$\" />",
                Mappings          = new ObservableCollection <Mapping>
                {
                    new Mapping
                    {
                        Type         = StringPropertyName,
                        NameContains = "",
                        Output       = "<TextBlock Text=\"$name$\" Grid.Row=\"$incint$\" /><TextBlock Text=\"$name$\" Grid.Row=\"$incint$\" />",
                        IfReadOnly   = false,
                    },
                },
            };

            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, gridProfile);
            var result = cpb.GetPropertyOutput(StringPropertyName, "MyProperty", false);

            var expected = "<TextBlock Text=\"MyProperty\" Grid.Row=\"1\" />" + Environment.NewLine +
                           "<TextBlock Text=\"MyProperty\" Grid.Row=\"2\" />";

            StringAssert.AreEqual(expected, result);
        }
        public void ReadWritePropertyIsIdentified()
        {
            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, this.testProfile);
            var result = cpb.GetPropertyOutput("string", "AnotherProperty", isReadOnly: true);

            Assert.AreEqual(ReadonlyStringOutput.Replace("$name$", "AnotherProperty"), result);
        }
        public void GetsNonFilteredOutputIfNameDoesntMatch()
        {
            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, this.testProfile);
            var result = cpb.GetPropertyOutput("string", "MyProperty", isReadOnly: false);

            Assert.AreEqual(ReadWriteStringOutput.Replace("$name$", "MyProperty"), result);
        }
        public void GetFallbackIfTypeNotMapped()
        {
            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, this.testProfile);
            var result = cpb.GetPropertyOutput("bool", "IsAdmin", isReadOnly: false);

            Assert.AreEqual(FallbackOutput, result);
        }
#pragma warning disable CS0628 // New protected member declared in sealed class
        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
#pragma warning restore CS0628 // New protected member declared in sealed class
        {
            // When initialized asynchronously, the current thread may be a background thread at this point.
            // Do any initialization that requires the UI thread after switching to the UI thread.
            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            try
            {
                await SharedRapidXamlPackage.InitializeAsync(cancellationToken, this);

                SharedRapidXamlPackage.Logger.RecordNotice(StringRes.Info_LaunchVersionGeneration.WithParams(CoreDetails.GetVersion()));
                SharedRapidXamlPackage.Logger.RecordNotice(string.Empty);

                await CopyToClipboardCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await SendToToolboxCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await OpenOptionsCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await RapidXamlDropHandlerProvider.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                // Set the ServiceProvider of CodeParserBase as it's needed to get settings
                CodeParserBase.ServiceProvider = this;

                if (SharedRapidXamlPackage.Logger != null)
                {
                    SharedRapidXamlPackage.Logger.UseExtendedLogging = CodeParserBase.GetSettings().ExtendedOutputEnabled;
                }
            }
            catch (Exception exc)
            {
                SharedRapidXamlPackage.Logger?.RecordException(exc);
            }
        }
        public void ReadOnlyTakesPriorityOverContains()
        {
            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, this.testProfile);
            var result = cpb.GetPropertyOutput("string", "EnteredPwd", isReadOnly: true);

            Assert.AreEqual(ReadonlyStringOutput.Replace("$name$", "EnteredPwd"), result);
        }
        public void TypeNameIsCaseInsensitive()
        {
            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, this.testProfile);
            var result = cpb.GetPropertyOutput("INT", "number1", isReadOnly: false);

            Assert.AreEqual(ReadWriteNumberIntOutput, result);
        }
        public void SingleNameContainsIsIdentified()
        {
            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, this.testProfile);
            var result = cpb.GetPropertyOutput("int", "number1", isReadOnly: false);

            Assert.AreEqual(ReadWriteNumberIntOutput, result);
        }
        public void GetSelectionPropertiesName_Five()
        {
            var result = CodeParserBase.GetSelectionPropertiesName(new List <string> {
                "one", "two", "three", "four", "five"
            });

            Assert.IsTrue(result.Equals("one, two and 3 other properties"));
        }
        public void GetSelectionPropertiesName_Two()
        {
            var result = CodeParserBase.GetSelectionPropertiesName(new List <string> {
                "one", "two"
            });

            Assert.IsTrue(result.Equals("one and two"));
        }
Beispiel #15
0
        public void GetSelectionPropertiesName_Four()
        {
            var result = CodeParserBase.GetSelectionMemberName(new List <string> {
                "one", "two", "three", "four"
            });

            Assert.IsTrue(result.Equals("one, two and 2 other members"));
        }
Beispiel #16
0
        public void GetSelectionPropertiesName_One()
        {
            var result = CodeParserBase.GetSelectionMemberName(new List <string> {
                "one"
            });

            Assert.IsTrue(result.Equals("one"));
        }
Beispiel #17
0
        public async Task <ParserOutput> GetXamlAsync(IAsyncServiceProvider serviceProvider)
        {
            ParserOutput result = null;

            if (CodeParserBase.GetSettings().Profiles.Any())
            {
                if (!(await serviceProvider.GetServiceAsync(typeof(EnvDTE.DTE)) is DTE dte))
                {
                    SharedRapidXamlPackage.Logger?.RecordError(StringRes.Error_FailedToGetDteInGetXamlAsync);
                }
                else
                {
                    var activeDocument = dte.ActiveDocument;

                    var textView = await GetTextViewAsync(serviceProvider);

                    var selection = textView.Selection;

                    bool isSelection = selection.Start.Position != selection.End.Position;

                    var caretPosition = textView.Caret.Position.BufferPosition;

                    var document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

                    var semanticModel = await document.GetSemanticModelAsync();

                    var vs         = new VisualStudioAbstraction(this.Logger, this.AsyncPackage, dte);
                    var xamlIndent = await vs.GetXamlIndentAsync();

                    var proj = dte.Solution.GetProjectContainingFile(document.FilePath);

                    if (proj == null)
                    {
                        // Default to the "active project" if file is not part of a known project
                        proj = ((Array)dte.ActiveSolutionProjects).GetValue(0) as Project;
                    }

                    var projType = vs.GetProjectType(proj);

                    this.Logger?.RecordInfo(StringRes.Info_DetectedProjectType.WithParams(projType.GetDescription()));

                    IDocumentParser parser = null;

                    if (activeDocument.Language == "CSharp")
                    {
                        parser = new CSharpParser(this.Logger, projType, xamlIndent);
                    }
                    else if (activeDocument.Language == "Basic")
                    {
                        parser = new VisualBasicParser(this.Logger, projType, xamlIndent);
                    }

                    result = isSelection
                        ? parser?.GetSelectionOutput(await document.GetSyntaxRootAsync(), semanticModel, selection.Start.Position, selection.End.Position)
                        : parser?.GetSingleItemOutput(await document.GetSyntaxRootAsync(), semanticModel, caretPosition.Position);
                }
            }
        public void RecordInfo(string message)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            if (CodeParserBase.GetSettings().ExtendedOutputEnabled)
            {
                RxtOutputPane.Instance.Write(TimeStampMessage(message));
            }
        }
        public void RecordError(string message)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // Activate the pane (bring to front) so errors are obvious
            if (CodeParserBase.GetSettings().ExtendedOutputEnabled)
            {
                RxtOutputPane.Instance.Write(TimeStampMessage(message));
                RxtOutputPane.Instance.Activate();
            }
            else
            {
                GeneralOutputPane.Instance.Write(TimeStampMessage(message));
                GeneralOutputPane.Instance.Activate();
            }
        }
        public void CorrectlySplitCamelCasePropertyNames()
        {
            var profile = TestProfile.CreateEmpty();

            profile.Mappings.Add(new Mapping
            {
                Type         = "string",
                IfReadOnly   = false,
                NameContains = string.Empty,
                Output       = "$namewithspaces$",
            });

            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, profile);
            var result = cpb.GetPropertyOutput("string", "MyProperty", isReadOnly: false);

            Assert.AreEqual("My Property", result);
        }
Beispiel #21
0
        public async Task <ParserOutput> GetXamlAsync(IAsyncServiceProvider serviceProvider)
        {
            ParserOutput result = null;

            if (CodeParserBase.GetSettings().Profiles.Any())
            {
                if (!(await serviceProvider.GetServiceAsync(typeof(EnvDTE.DTE)) is DTE dte))
                {
                    RapidXamlPackage.Logger?.RecordError("Failed to get DTE in GetXamlFromCodeWindowBaseCommand.GetXamlAsync");
                }
                else
                {
                    var activeDocument = dte.ActiveDocument;

                    var textView = await GetTextViewAsync(serviceProvider);

                    var selection = textView.Selection;

                    bool isSelection = selection.Start.Position != selection.End.Position;

                    var caretPosition = textView.Caret.Position.BufferPosition;

                    var document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

                    var semanticModel = await document.GetSemanticModelAsync();

                    var vs         = new VisualStudioAbstraction(this.Logger, this.ServiceProvider, dte);
                    var xamlIndent = await vs.GetXamlIndentAsync();

                    IDocumentParser parser = null;

                    if (activeDocument.Language == "CSharp")
                    {
                        parser = new CSharpParser(this.Logger, xamlIndent);
                    }
                    else if (activeDocument.Language == "Basic")
                    {
                        parser = new VisualBasicParser(this.Logger, xamlIndent);
                    }

                    result = isSelection
                        ? parser?.GetSelectionOutput(await document.GetSyntaxRootAsync(), semanticModel, selection.Start.Position, selection.End.Position)
                        : parser?.GetSingleItemOutput(await document.GetSyntaxRootAsync(), semanticModel, caretPosition.Position);
                }
            }
        private void MenuItem_BeforeQueryStatus(object sender, EventArgs e)
        {
            try
            {
                if (sender is OleMenuCommand menuCmd)
                {
                    menuCmd.Visible = menuCmd.Enabled = false;

                    if (!CodeParserBase.GetSettings().IsActiveProfileSet)
                    {
                        menuCmd.Visible = menuCmd.Enabled = true;
                    }
                }
            }
            catch (Exception exc)
            {
                this.Logger.RecordException(exc);
                throw;  // Remove for launch. see issue #90
            }
        }
        private async void MenuItem_BeforeQueryStatus(object sender, EventArgs e)
        {
            try
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                if (sender is OleMenuCommand menuCmd)
                {
                    menuCmd.Visible = menuCmd.Enabled = false;

                    if (!this.IsSingleProjectItemSelection(out var hierarchy, out var itemid))
                    {
                        this.SelectedFileName = null;
                        return;
                    }

                    ((IVsProject)hierarchy).GetMkDocument(itemid, out var itemFullPath);
                    var transformFileInfo = new FileInfo(itemFullPath);

                    // Save the name of the selected file so we have it when the command is executed
                    this.SelectedFileName = transformFileInfo.FullName;

                    if (transformFileInfo.Name.EndsWith(".cs") || transformFileInfo.Name.EndsWith(".vb"))
                    {
                        if (CodeParserBase.GetSettings().IsActiveProfileSet)
                        {
                            menuCmd.Visible = menuCmd.Enabled = true;
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                this.Logger.RecordException(exc);
            }
        }
        public void WriteablePropertiesMatchFallbackIfOnlySpecificReadOnlyDefined()
        {
            var readonlyProfile = new Profile
            {
                Name           = "readonlyProfile",
                ClassGrouping  = "Grid",
                FallbackOutput = "<Fallback />",
                Mappings       = new ObservableCollection <Mapping>
                {
                    new Mapping
                    {
                        Type         = StringPropertyName,
                        NameContains = "",
                        Output       = "<ReadOnly />",
                        IfReadOnly   = true,
                    },
                },
            };

            var cpb    = new CodeParserBase(DefaultTestLogger.Create(), 4, readonlyProfile);
            var result = cpb.GetPropertyOutput(StringPropertyName, "MyProperty", isReadOnly: false);

            Assert.AreEqual("<Fallback />", result);
        }
Beispiel #25
0
        private async void Execute(object sender, EventArgs e)
        {
            try
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                this.Logger?.RecordFeatureUsage(nameof(SetDatacontextCommand));

                var settings = CodeParserBase.GetSettings();
                var profile  = settings.GetActiveProfile();

                if (!(await Instance.ServiceProvider.GetServiceAsync(typeof(DTE)) is DTE dte))
                {
                    RapidXamlPackage.Logger?.RecordError("Failed to get DTE in SetDatacontextCommand.Execute");
                }
                else
                {
                    var vs    = new VisualStudioAbstraction(this.Logger, this.ServiceProvider, dte);
                    var logic = new SetDataContextCommandLogic(profile, this.Logger, vs);

                    var inXamlDoc = dte.ActiveDocument.Name.EndsWith(".xaml", StringComparison.InvariantCultureIgnoreCase);

                    var(viewName, viewModelName, vmNamespace) = logic.InferViewModelNameFromFileName(dte.ActiveDocument.Name);

                    if (inXamlDoc)
                    {
                        if (profile.Datacontext.SetsXamlPageAttribute)
                        {
                            var(add, lineNo, content) = logic.GetPageAttributeToAdd(viewModelName, vmNamespace);

                            if (add)
                            {
                                if (dte.ActiveDocument.Object("TextDocument") is TextDocument objectDoc)
                                {
                                    objectDoc.Selection.GotoLine(lineNo);
                                    objectDoc.Selection.EndOfLine();
                                    objectDoc.Selection.Insert(content);
                                }
                            }
                        }

                        if (profile.Datacontext.SetsAnyCodeBehindContent)
                        {
                            if (profile.Datacontext.SetsCodeBehindPageContent)
                            {
                                // TODO: ISSUE#22 - set the DC in the CB file (C# or VB) may be open and unsaved
                            }

                            if (profile.Datacontext.SetsCodeBehindConstructorContent)
                            {
                                // TODO: ISSUE#22 - set the DC in the CB file (C# or VB) may be open and unsaved
                            }
                        }
                    }
                    else
                    {
                        if (profile.Datacontext.SetsXamlPageAttribute)
                        {
                            // TODO: ISSUE#22 - set the DC in the XAML file (C# or VB) may be open and unsaved
                        }

                        if (profile.Datacontext.SetsAnyCodeBehindContent)
                        {
                            if (dte.ActiveDocument.Object("TextDocument") is TextDocument objectDoc)
                            {
                                var textView = await GetTextViewAsync(Instance.ServiceProvider);

                                var caretPosition = textView.Caret.Position.BufferPosition;
                                var document      = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
                                var documentTree  = await document.GetSyntaxTreeAsync();

                                var documentRoot = documentTree.GetRoot();

                                var toAdd = logic.GetCodeBehindContentToAdd(viewName, viewModelName, vmNamespace, documentRoot);

                                foreach (var(anything, lineNo, contentToAdd) in toAdd)
                                {
                                    if (anything)
                                    {
                                        objectDoc.Selection.GotoLine(lineNo);
                                        objectDoc.Selection.EndOfLine();
                                        objectDoc.Selection.Insert(contentToAdd);
                                    }
                                }
                            }
                        }
                    }

                    this.SuppressAnyException(() => dte.FormatDocument(profile));
                }
            }
Beispiel #26
0
        public void GetSelectionPropertiesName_Null()
        {
            var result = CodeParserBase.GetSelectionMemberName(null);

            Assert.IsTrue(string.IsNullOrEmpty(result));
        }
        public async Task ExecuteAsync(string selectedFileName)
        {
            var vmProj = this.vs.GetActiveProject();

            var fileExt      = this.fileSystem.GetFileExtension(selectedFileName);
            var fileContents = this.fileSystem.GetAllFileText(selectedFileName);

            CodeParserBase parser        = null;
            var            codeBehindExt = string.Empty;
            var            indent        = await this.vs.GetXamlIndentAsync();

            switch (fileExt)
            {
            case ".cs":
                parser        = new CSharpParser(this.logger, indent, this.profileOverride);
                codeBehindExt = ((CSharpParser)parser).FileExtension;
                break;

            case ".vb":
                parser        = new VisualBasicParser(this.logger, indent, this.profileOverride);
                codeBehindExt = ((VisualBasicParser)parser).FileExtension;
                break;
            }

            this.CreateView = false;

            if (parser != null)
            {
                // IndexOf is allowing for "class " in C# and "Class " in VB
                var cursorPos = fileContents.IndexOf("lass ");

                if (cursorPos == -1 && codeBehindExt == "vb")
                {
                    // If not a class, there may be a module
                    cursorPos = fileContents.IndexOf("odule ");
                }

                if (cursorPos < 0)
                {
                    this.logger.RecordInfo(StringRes.Info_CouldNotFindClassInFile.WithParams(selectedFileName));
                    return;
                }

                (var syntaxTree, var semModel) = await this.vs.GetDocumentModelsAsync(selectedFileName);

                var syntaxRoot = await syntaxTree.GetRootAsync();

                var parserOutput = ((IDocumentParser)parser).GetSingleItemOutput(syntaxRoot, semModel, cursorPos);

                var config = parser.Profile.ViewGeneration;

                var vmClassName = parserOutput.Name;

                var baseClassName = vmClassName;

                if (vmClassName.EndsWith(config.ViewModelFileSuffix))
                {
                    baseClassName = vmClassName.Substring(0, vmClassName.LastIndexOf(config.ViewModelFileSuffix, StringComparison.InvariantCulture));
                }

                var viewClassName = $"{baseClassName}{config.XamlFileSuffix}";

                var    vmProjName = vmProj.Name;
                string viewProjName;

                this.ViewProject = null;

                if (config.AllInSameProject)
                {
                    this.ViewProject = vmProj;
                    viewProjName     = this.ViewProject.Name;
                }
                else
                {
                    var expectedViewProjectName = vmProjName.Replace(config.ViewModelProjectSuffix, config.XamlProjectSuffix);

                    this.ViewProject = this.vs.GetProject(expectedViewProjectName);

                    if (this.ViewProject == null)
                    {
                        this.logger.RecordError(StringRes.Error_UnableToFindProjectInSolution.WithParams(expectedViewProjectName));
                    }

                    viewProjName = this.ViewProject?.Name;
                }

                if (this.ViewProject != null)
                {
                    var folder = this.fileSystem.GetDirectoryName(this.ViewProject.FileName);

                    this.ViewFolder = this.fileSystem.PathCombine(folder, config.XamlFileDirectoryName);

                    // We assume that the type name matches the file name.
                    this.XamlFileName = this.fileSystem.PathCombine(this.ViewFolder, $"{viewClassName}.xaml");
                    this.CodeFileName = this.fileSystem.PathCombine(this.ViewFolder, $"{viewClassName}.xaml.{codeBehindExt}");

                    if (this.fileSystem.FileExists(this.XamlFileName))
                    {
                        this.logger.RecordInfo(StringRes.Info_FileExists.WithParams(this.XamlFileName));

                        var overwrite = this.vs.UserConfirms(StringRes.Prompt_FileExistsTitle, StringRes.Propt_FileExistsMessage);

                        if (overwrite)
                        {
                            this.CreateView = true;
                            this.logger.RecordInfo(StringRes.Info_OverwritingFile.WithParams(this.XamlFileName));
                        }
                        else
                        {
                            this.logger.RecordInfo(StringRes.Info_NotOverwritingFile.WithParams(this.XamlFileName));
                        }
                    }
                    else
                    {
                        this.CreateView = true;
                    }

                    if (this.CreateView)
                    {
                        // Allow for different namespace conventions
                        var viewNamespace = parser is CSharpParser
                                          ? $"{viewProjName}.{config.XamlFileDirectoryName}".TrimEnd('.')
                                          : $"{config.XamlFileDirectoryName}".TrimEnd('.');

                        var vmNamespace = $"{vmProjName}.{config.ViewModelDirectoryName}".TrimEnd('.');

                        var replacementValues = (viewProjName, viewNamespace, vmNamespace, viewClassName, vmClassName);

                        this.XamlFileContents = this.ReplacePlaceholders(config.XamlPlaceholder, replacementValues);

                        var placeholderPos         = this.XamlFileContents.IndexOf(Placeholder.GeneratedXAML);
                        var startOfPlaceholderLine = this.XamlFileContents.Substring(0, placeholderPos).LastIndexOf(Environment.NewLine);

                        var insertIndent = placeholderPos - startOfPlaceholderLine - Environment.NewLine.Length;

                        this.XamlFileContents = this.XamlFileContents.Replace(Placeholder.GeneratedXAML, parserOutput.Output.Replace(Environment.NewLine, Environment.NewLine + new string(' ', insertIndent)).Trim());

                        this.CodeFileContents = this.ReplacePlaceholders(config.CodePlaceholder, replacementValues);
                    }
                }
            }
        }
        public void GetSelectionPropertiesName_Empty()
        {
            var result = CodeParserBase.GetSelectionPropertiesName(new List <string>());

            Assert.IsTrue(string.IsNullOrEmpty(result));
        }