Beispiel #1
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);
                }
            }
Beispiel #2
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);
                }
            }
        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);
                    }
                }
            }
        }