Exemple #1
0
        public override async Task <CommandResult> ExecuteAsync(ProjectOrSolution projectOrSolution, CancellationToken cancellationToken = default)
        {
            AssemblyResolver.Register();

            var codeAnalyzerOptions = new CodeAnalyzerOptions(
                ignoreAnalyzerReferences: Options.IgnoreAnalyzerReferences,
                ignoreCompilerDiagnostics: Options.IgnoreCompilerDiagnostics,
                reportNotConfigurable: Options.ReportNotConfigurable,
                reportSuppressedDiagnostics: Options.ReportSuppressedDiagnostics,
                logAnalyzerExecutionTime: Options.ExecutionTime,
                severityLevel: SeverityLevel,
                supportedDiagnosticIds: Options.SupportedDiagnostics,
                ignoredDiagnosticIds: Options.IgnoredDiagnostics,
                projectNames: Options.Projects,
                ignoredProjectNames: Options.IgnoredProjects,
                language: Language);

            IEnumerable <string> analyzerAssemblies = Options.AnalyzerAssemblies;

            if (Options.UseRoslynatorAnalyzers)
            {
                analyzerAssemblies = analyzerAssemblies.Concat(RoslynatorAnalyzersAssemblies);
            }

            CultureInfo culture = (Options.Culture != null) ? CultureInfo.GetCultureInfo(Options.Culture) : null;

            var codeAnalyzer = new CodeAnalyzer(
                analyzerAssemblies: AnalyzerAssemblyLoader.LoadFiles(analyzerAssemblies, loadFixers: false),
                formatProvider: culture,
                options: codeAnalyzerOptions);

            if (projectOrSolution.IsProject)
            {
                Project project = projectOrSolution.AsProject();

                WriteLine($"Analyze '{project.Name}'", ConsoleColor.Cyan, Verbosity.Minimal);

                ProjectAnalysisResult result = await codeAnalyzer.AnalyzeProjectAsync(project, cancellationToken);

                if (Options.Output != null &&
                    result.Diagnostics.Any())
                {
                    DiagnosticXmlSerializer.Serialize(result, project, Options.Output, culture);
                }
            }
            else
            {
                Solution solution = projectOrSolution.AsSolution();

                ImmutableArray <ProjectAnalysisResult> results = await codeAnalyzer.AnalyzeSolutionAsync(solution, cancellationToken);

                if (Options.Output != null &&
                    results.Any(f => f.Diagnostics.Any()))
                {
                    DiagnosticXmlSerializer.Serialize(results, solution, Options.Output, culture);
                }
            }

            return(CommandResult.Success);
        }
        public static StatelessProjectResponse Server_HandleStatelessCodeCompletionRequest(StatelessProjectRequest request)
        {
            // Convert web request model to internal analysis model
            ProjectAnalysisRequest analysisRequest = new ProjectAnalysisRequest();

            analysisRequest.ProjectModel = ProjectModelConverters.FromDtoToModel(request.Project);
            if (request.CodeCompletionParameters != null)
            {
                analysisRequest.CodeCompletionParameters = new ProjectAnalysisCodeCompletionParameters()
                {
                    CtrlSpace = request.CodeCompletionParameters.CtrlSpace,
                    Offset    = request.CodeCompletionParameters.Offset,
                    FileId    = request.CodeCompletionParameters.FileId,
                    Line      = request.CodeCompletionParameters.Line,
                    Column    = request.CodeCompletionParameters.Column
                };
            }

            // Analyze!
            ProjectAnalysisResult analysisResult = NRefactoryUtils.RunFullProjectAnalysis(analysisRequest);

            // Convert analysis result model to web service model
            StatelessProjectResponse response = new StatelessProjectResponse();

            if (analysisResult.CompletionOptions != null)
            {
                response.CompletionOptions = analysisResult.CompletionOptions
                                             .Select(CodeCompletionResultUtility.FromICompletionDataToFileCodeCompletionResult)
                                             .ToArray();
                for (int i = 0, len = response.CompletionOptions.Length; i < len; i++)
                {
                    response.CompletionOptions[i].Id = i;
                }
                response.CompletionWord = analysisResult.CompletionWord;
                if (analysisResult.BestMatchToCompletionWord != null)
                {
                    response.BestMatchToCompletionWord = response.CompletionOptions.FirstOrDefault(x => x.CompletionText == analysisResult.BestMatchToCompletionWord.CompletionText);
                }
            }
            var allErrors = new List <FileParseResult>();

            foreach (var fileModel in analysisRequest.ProjectModel.GetFileDescendants())
            {
                allErrors.AddRange(fileModel.Parser.ErrorsAndWarnings
                                   .Select(x => new FileParseResult()
                {
                    FileId   = fileModel.Id,
                    FileName = fileModel.Name,
                    Line     = x.Region.BeginLine,
                    Column   = x.Region.BeginColumn,
                    Type     = x.ErrorType,
                    Message  = x.Message
                }).ToArray());
            }
            response.Errors    = allErrors.ToArray();
            response.MsElapsed = analysisResult.TimeElapsed.TotalMilliseconds; // string.Format("{0}", analysisResult.TimeElapsed.TotalMilliseconds);

            return(response);
        }
        public static StatelessProjectResponse Server_HandleStatelessCodeCompletionRequest(StatelessProjectRequest request)
        {
            // Convert web request model to internal analysis model
            ProjectAnalysisRequest analysisRequest = new ProjectAnalysisRequest();

            analysisRequest.ProjectModel = ProjectModelConverters.FromDtoToModel(request.Project);
            if (request.CodeCompletionParameters != null)
            {
                analysisRequest.CodeCompletionParameters = new ProjectAnalysisCodeCompletionParameters()
                {
                    CtrlSpace = request.CodeCompletionParameters.CtrlSpace,
                    Offset    = request.CodeCompletionParameters.Offset,
                    FileId    = request.CodeCompletionParameters.FileId,
                    Line      = request.CodeCompletionParameters.Line,
                    Column    = request.CodeCompletionParameters.Column
                };
            }

            // Analyze!
            ProjectAnalysisResult analysisResult = NRefactoryUtils.RunFullProjectAnalysis(analysisRequest);

            // Convert analysis result model to web service model
            StatelessProjectResponse response = new StatelessProjectResponse();

            if (analysisResult.CompletionOptions != null)
            {
                response.CompletionOptions = analysisResult.CompletionOptions
                                             .Select(x => new FileCodeCompletionResult()
                {
                    CompletionText = x.CompletionText,
                    DisplayText    = x.DisplayText,
                    Description    = x.Description,
                    OverloadCount  = x.OverloadedData.Count(),
                    CompletionCategoryDisplayText = (x.CompletionCategory == null ? "" : x.CompletionCategory.DisplayText)
                }).ToArray();
                response.CompletionWord = analysisResult.CompletionWord;
            }
            var allErrors = new List <FileParseResult>();

            foreach (var fileModel in analysisRequest.ProjectModel.GetFileDescendants())
            {
                allErrors.AddRange(fileModel.Parser.ErrorsAndWarnings
                                   .Select(x => new FileParseResult()
                {
                    FileId   = fileModel.Id,
                    FileName = fileModel.Name,
                    Line     = x.Region.BeginLine,
                    Column   = x.Region.BeginColumn,
                    Type     = x.ErrorType,
                    Message  = x.Message
                }).ToArray());
            }
            response.Errors      = allErrors.ToArray();
            response.TimeElapsed = string.Format("{0} ms", analysisResult.TimeElapsed.TotalMilliseconds);

            return(response);
        }
        public static void Serialize(
            ProjectAnalysisResult result,
            Project project,
            string filePath,
            IFormatProvider formatProvider = null)
        {
            XElement summary = CreateSummary(result.GetAllDiagnostics(), formatProvider);

            XElement projectElement = SerializeProjectAnalysisResult(result, project, formatProvider);

            SerializeDocument(filePath, summary, projectElement);
        }
        private static void GetDocumentContext(ProjectAnalysisResult result, int textCursorOffset, ReadOnlyDocument doc)
        {
            #region Debugging Aid

            // Resolve content around text cursor
#if false
            int numberOfCharactersAroundCursorToResolve = 20;
            int firstCharOffset = textCursorOffset - numberOfCharactersAroundCursorToResolve / 2;
            int lastCharOffset  = textCursorOffset + numberOfCharactersAroundCursorToResolve / 2;
#else
            int firstCharOffset = textCursorOffset - 40;
            int lastCharOffset  = textCursorOffset + 20;
#endif

            // shift window to the "right"
            if (firstCharOffset < 0)
            {
                lastCharOffset -= firstCharOffset;
                firstCharOffset = 0;
            }

            // shift window to the "left"
            if (lastCharOffset > doc.TextLength)
            {
                firstCharOffset -= (lastCharOffset - doc.TextLength);
                lastCharOffset   = doc.TextLength;

                // compensate, in case "left" side of window is in the void
                if (firstCharOffset < 0)
                {
                    firstCharOffset = 0;
                }
            }

            //if (doc.TextLength < firstCharOffset + numberOfCharactersAroundCursorToResolve)
            //    numberOfCharactersAroundCursorToResolve = doc.TextLength - firstCharOffset;
            //string surroundingText = doc.GetText(firstCharOffset, numberOfCharactersAroundCursorToResolve);
            //Debug.WriteLine("Text around cursor: [{0}]", surroundingText);

            result.CompletionContextBefore = doc.GetText(firstCharOffset, textCursorOffset - firstCharOffset);
            result.CompletionContextAfter  = doc.GetText(textCursorOffset, lastCharOffset - textCursorOffset);

            Debug.WriteLine("Completion Context: \"{0}\" <cursor> \"{1}\"", result.CompletionContextBefore, result.CompletionContextAfter);

            #endregion
        }
 private static XElement SerializeProjectAnalysisResult(
     ProjectAnalysisResult result,
     Project project,
     IFormatProvider formatProvider)
 {
     return(new XElement(
                "Project",
                new XAttribute("Name", project.Name),
                new XAttribute("FilePath", project.FilePath),
                new XElement("Diagnostics",
                             result.Diagnostics
                             .OrderBy(f => f.Location.SourceTree?.FilePath)
                             .ThenBy(f => f.Id)
                             .ThenBy(f => f.Location.SourceSpan.Start)
                             .Select(f => SerializeDiagnostic(f, formatProvider))
                             )
                ));
 }
Exemple #7
0
 private static XElement SerializeProjectAnalysisResult(
     ProjectAnalysisResult result,
     IFormatProvider formatProvider)
 {
     return(new XElement(
                "Project",
                new XAttribute("Name", result.Project.Name),
                new XAttribute("FilePath", result.Project.FilePath),
                new XElement(
                    "Diagnostics",
                    result.Diagnostics
                    .OrderBy(f => f.LineSpan.Path)
                    .ThenBy(f => f.Descriptor.Id)
                    .ThenBy(f => f.LineSpan.StartLinePosition.Line)
                    .ThenBy(f => f.LineSpan.StartLinePosition.Character)
                    .Select(f => SerializeDiagnostic(f, formatProvider))
                    )
                ));
 }
Exemple #8
0
        public void SetUp()
        {
            var solutionDirectory = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestXml", "TestPorting");

            _tmpDirectory = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestXml", "TmpDirectory");
            DirectoryCopy(solutionDirectory, _tmpDirectory, true);

            _tmpSolutionDirectory = Path.Combine(_tmpDirectory, "src");
            _tmpSolutionFileName  = Path.Combine(_tmpSolutionDirectory, "NopCommerce.sln");
            _tmpProjectPath       = Path.Combine(_tmpSolutionDirectory, "Libraries", "Nop.Core", "Nop.Core.csproj");

            _apiAnalysisHandlerMock.Reset();
            _apiAnalysisHandlerMock.Setup(analyzer => analyzer.AnalyzeSolution(It.IsAny <string>(), It.IsAny <List <string> >(), It.IsAny <string>()))
            .Returns((string solutionFilePath, List <string> projects, string targetFramework) =>
            {
                return(Task.Run(() => projects.Select(project =>
                {
                    var package = new PackageVersionPair
                    {
                        PackageId = "Newtonsoft.Json",
                        Version = "11.0.1"
                    };
                    var packageAnalysisResult = Task.Run(() => new PackageAnalysisResult
                    {
                        PackageVersionPair = package,
                        CompatibilityResults = new Dictionary <string, CompatibilityResult>
                        {
                            { targetFramework, new CompatibilityResult {
                                  Compatibility = Compatibility.COMPATIBLE,
                                  CompatibleVersions = new List <string>
                                  {
                                      "12.0.3", "12.0.4"
                                  }
                              } }
                        },
                        Recommendations = new PortingAssistant.Client.Model.Recommendations
                        {
                            RecommendedActions = new List <RecommendedAction>
                            {
                                new RecommendedAction
                                {
                                    RecommendedActionType = RecommendedActionType.UpgradePackage,
                                    Description = "12.0.3"
                                }
                            }
                        }
                    });

                    var projectAnalysisResult = new ProjectAnalysisResult
                    {
                        ProjectName = Path.GetFileNameWithoutExtension(project),
                        ProjectFilePath = project,
                        PackageAnalysisResults = new Dictionary <PackageVersionPair, Task <PackageAnalysisResult> >
                        {
                            { package, packageAnalysisResult }
                        },
                        SourceFileAnalysisResults = new List <SourceFileAnalysisResult>
                        {
                            _sourceFileAnalysisResult
                        },
                        ProjectGuid = "xxx",
                        ProjectType = nameof(SolutionProjectType.KnownToBeMSBuildFormat),
                        PreportMetaReferences = new List <string> {
                        },
                        MetaReferences = new List <string> {
                        },
                        ExternalReferences = null,
                        ProjectRules = null
                    };

                    return new KeyValuePair <string, ProjectAnalysisResult>(project, projectAnalysisResult);
                }).ToDictionary(k => k.Key, v => v.Value)));
            });
            _apiAnalysisHandlerMock.Setup(analyzer => analyzer.AnalyzeSolutionIncremental(It.IsAny <string>(), It.IsAny <List <string> >(), It.IsAny <string>()))
            .Returns((string solutionFilePath, List <string> projects, string targetFramework) =>
            {
                return(Task.Run(() =>
                {
                    return projects.Select(project =>
                    {
                        var package = new PackageVersionPair
                        {
                            PackageId = "Newtonsoft.Json",
                            Version = "11.0.1"
                        };
                        var packageAnalysisResult = Task.Run(() => new PackageAnalysisResult
                        {
                            PackageVersionPair = package,
                            CompatibilityResults = new Dictionary <string, CompatibilityResult>
                            {
                                { targetFramework, new CompatibilityResult {
                                      Compatibility = Compatibility.COMPATIBLE,
                                      CompatibleVersions = new List <string>
                                      {
                                          "12.0.3", "12.0.4"
                                      }
                                  } }
                            },
                            Recommendations = new PortingAssistant.Client.Model.Recommendations
                            {
                                RecommendedActions = new List <RecommendedAction>
                                {
                                    new RecommendedAction
                                    {
                                        RecommendedActionType = RecommendedActionType.UpgradePackage,
                                        Description = "12.0.3"
                                    }
                                }
                            }
                        });

                        var projectAnalysisResult = new ProjectAnalysisResult
                        {
                            ProjectName = Path.GetFileNameWithoutExtension(project),
                            ProjectFilePath = project,
                            PackageAnalysisResults = new Dictionary <PackageVersionPair, Task <PackageAnalysisResult> >
                            {
                                { package, packageAnalysisResult }
                            },
                            SourceFileAnalysisResults = new List <SourceFileAnalysisResult>
                            {
                                _sourceFileAnalysisResult
                            },
                            ProjectGuid = "xxx",
                            ProjectType = nameof(SolutionProjectType.KnownToBeMSBuildFormat)
                        };

                        return new KeyValuePair <string, ProjectAnalysisResult>(project, projectAnalysisResult);
                    }).ToDictionary(k => k.Key, v => v.Value);
                }));
            });
            _apiAnalysisHandlerMock.Setup(analyzer => analyzer.AnalyzeFileIncremental(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <List <string> >(),
                                                                                      It.IsAny <List <string> >(), It.IsAny <RootNodes>(), It.IsAny <Codelyzer.Analysis.Model.ExternalReferences>(),
                                                                                      It.IsAny <bool>(),
                                                                                      It.IsAny <bool>(),
                                                                                      It.IsAny <string>()))
            .Returns((string filePath, string project, string solutionPath, List <string> preportReferences,
                      List <string> metaReferences, RootNodes projectRules, Codelyzer.Analysis.Model.ExternalReferences externalReferences, bool actionsOnly, bool compatibleOnly, string targetFramework) =>
            {
                return(Task.Run(() =>
                {
                    return new List <SourceFileAnalysisResult> {
                        _sourceFileAnalysisResult
                    };
                }));
            });
            _apiAnalysisHandlerMock.Setup(analyzer => analyzer.AnalyzeFileIncremental(It.IsAny <string>(), It.IsAny <string>(),
                                                                                      It.IsAny <string>(), It.IsAny <string>(), It.IsAny <List <string> >(), It.IsAny <List <string> >(), It.IsAny <RootNodes>(), It.IsAny <Codelyzer.Analysis.Model.ExternalReferences>(),
                                                                                      It.IsAny <bool>(),
                                                                                      It.IsAny <bool>(),
                                                                                      It.IsAny <string>()))
            .Returns((string filePath, string fileContents, string project, string solutionPath, List <string> preportReferences,
                      List <string> metaReferences, RootNodes projectRules, Codelyzer.Analysis.Model.ExternalReferences externalReferences, bool actionsOnly, bool compatibleOnly, string targetFramework) =>
            {
                return(Task.Run(() =>
                {
                    return new List <SourceFileAnalysisResult> {
                        _sourceFileAnalysisResult
                    };
                }));
            });
        }
Exemple #9
0
        public void SetUp()
        {
            var solutionDirectory = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestXml", "TestPorting");

            _tmpDirectory = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestXml", "TmpDirectory");
            DirectoryCopy(solutionDirectory, _tmpDirectory, true);

            _tmpSolutionDirectory = Path.Combine(_tmpDirectory, "src");
            _tmpProjectPath       = Path.Combine(_tmpSolutionDirectory, "Libraries", "Nop.Core", "Nop.Core.csproj");

            _apiAnalysisHandlerMock.Reset();
            _apiAnalysisHandlerMock.Setup(analyzer => analyzer.AnalyzeSolution(It.IsAny <string>(), It.IsAny <List <string> >()))
            .Returns((string solutionFilePath, List <string> projects) =>
            {
                return(Task.Run(() => projects.Select(project =>
                {
                    var package = new PackageVersionPair
                    {
                        PackageId = "Newtonsoft.Json",
                        Version = "11.0.1"
                    };
                    var packageAnalysisResult = Task.Run(() => new PackageAnalysisResult
                    {
                        PackageVersionPair = package,
                        CompatibilityResults = new Dictionary <string, CompatibilityResult>
                        {
                            { "netcoreapp3.1", new CompatibilityResult {
                                  Compatibility = Compatibility.COMPATIBLE,
                                  CompatibleVersions = new List <string>
                                  {
                                      "12.0.3", "12.0.4"
                                  }
                              } }
                        },
                        Recommendations = new Recommendations
                        {
                            RecommendedActions = new List <RecommendedAction>
                            {
                                new RecommendedAction
                                {
                                    RecommendedActionType = RecommendedActionType.UpgradePackage,
                                    Description = "12.0.3"
                                }
                            }
                        }
                    });

                    var projectAnalysisResult = new ProjectAnalysisResult
                    {
                        ProjectName = Path.GetFileNameWithoutExtension(project),
                        ProjectFilePath = project,
                        PackageAnalysisResults = new Dictionary <PackageVersionPair, Task <PackageAnalysisResult> >
                        {
                            { package, packageAnalysisResult }
                        },
                        SourceFileAnalysisResults = new List <SourceFileAnalysisResult>
                        {
                            _sourceFileAnalysisResult
                        },
                        ProjectGuid = "xxx",
                        ProjectType = SolutionProjectType.KnownToBeMSBuildFormat.ToString()
                    };

                    return new KeyValuePair <string, ProjectAnalysisResult>(project, projectAnalysisResult);
                }).ToDictionary(k => k.Key, v => v.Value)));
            });
        }
        public static ProjectAnalysisResult RunFullProjectAnalysis(ProjectAnalysisRequest projectAnalysisRequest) // ProjectModel projectModel, int fileId, int line, int column)
        {
            Stopwatch sw = Stopwatch.StartNew();

            ProjectAnalysisResult projectAnalysisResult = new ProjectAnalysisResult();
            ProjectModel projectModel = projectAnalysisRequest.ProjectModel;


            // Set up the project (if not already done)
            if (projectModel.ProjectContent == null)
            {
                projectModel.ProjectContent = new CSharpProjectContent();
                projectModel.ProjectContent = projectModel.ProjectContent.AddAssemblyReferences(QCReferences.Value);
            }

            // For each new file, we need to integrate it into the project content
            var fileModelsInProject = projectModel.GetFileDescendants().ToArray();
            foreach (var fileModelInProject in fileModelsInProject)
            {
                IntegrateFileModel(projectModel, fileModelInProject);
            }

            // We can return now if no code completion was requested
            if (projectAnalysisRequest.CodeCompletionParameters == null)
            {
                projectAnalysisResult.TimeElapsed = sw.Elapsed;
                return projectAnalysisResult;
            }

            // Now it's time to give attention specifically to the matter of resolving the code completion
            // options.  This, of course, requires a deeper analysis of the specified file...
            
            var codeCompletionParams = projectAnalysisRequest.CodeCompletionParameters;

            // Locate the file in the project
            ProjectFileModel fileModel = projectModel.FindFile(codeCompletionParams.FileId);
            if (fileModel == null)
                throw new Exception("Specified file does not exist in this project");
            

            // Create a TypeSystem.ICompilation that allows resolving within the project.
            var compilation = projectModel.ProjectContent.CreateCompilation();

            #region Resolve text cursor/caret location
            
            // The text cursor position is crucial to creating a properly-scoped type resolution context
            // so as to get relevant code completion suggestions.
            int textCursorOffset;
            TextLocation textCursorLocation;
            ReadOnlyDocument doc = new ReadOnlyDocument(fileModel.Content);
            if (codeCompletionParams.Line == 0 && codeCompletionParams.Column == 0)
            {
                textCursorOffset = codeCompletionParams.Offset;
                textCursorLocation = doc.GetLocation(textCursorOffset);
                codeCompletionParams.Line = textCursorLocation.Line;
                codeCompletionParams.Column = textCursorLocation.Column;
            }
            else
            {
                textCursorLocation = new TextLocation(codeCompletionParams.Line, codeCompletionParams.Column);
                textCursorOffset = doc.GetOffset(textCursorLocation);
                codeCompletionParams.Offset = textCursorOffset;
            }

            #endregion

            #region Create and Refine the type resolution context as much as possible based upon the cursor position

            var typeResolveContext = new CSharpTypeResolveContext(compilation.MainAssembly);
            // Constrain the resolve context by using scope
            typeResolveContext = typeResolveContext
                .WithUsingScope(fileModel.UnresolvedFile.GetUsingScope(textCursorLocation)
                .Resolve(compilation));

            var curDef = fileModel.UnresolvedFile.GetInnermostTypeDefinition(textCursorLocation);
            if (curDef != null)
            {
                var resolvedDef = curDef.Resolve(typeResolveContext).GetDefinition();
                typeResolveContext = typeResolveContext.WithCurrentTypeDefinition(resolvedDef);
                var curMember = resolvedDef.Members.FirstOrDefault(m => m.Region.Begin <= textCursorLocation && textCursorLocation < m.BodyRegion.End);
                if (curMember != null)
                {
                    typeResolveContext = typeResolveContext.WithCurrentMember(curMember);
                }
            }

            #endregion

            // The purpose of the rest of these steps is a little fuzzy in my mind...  
            // I'm still trying to understand them fully and if/why they're all needed.
            // It seems there is some redundancy here...

            var completionContext = new DefaultCompletionContextProvider(doc, fileModel.UnresolvedFile);

            #region Add Preprocessor Symbols??
            completionContext.AddSymbol("TEST");
            foreach (var sym in fileModel.SyntaxTree.ConditionalSymbols)
                completionContext.AddSymbol(sym);
            #endregion

            var completionDataFactory = new TestCompletionDataFactory(new CSharpResolver(typeResolveContext));
            
            var completionEngine = new CSharpCompletionEngine(doc, completionContext, completionDataFactory, projectModel.ProjectContent, typeResolveContext);
            completionEngine.EolMarker = Environment.NewLine;
            completionEngine.FormattingPolicy = FormattingOptionsFactory.CreateMono();
            projectModel.CompletionEngine = completionEngine;

#region Debugging Aid
            // Resolve content around text cursor
            int numberOfCharactersAroundCursorToResolve = 20;
            int firstCharOffset = textCursorOffset - numberOfCharactersAroundCursorToResolve/2;
            if (firstCharOffset < 0)
                firstCharOffset = 0;
            if (doc.TextLength < firstCharOffset+numberOfCharactersAroundCursorToResolve)
                numberOfCharactersAroundCursorToResolve = doc.TextLength - firstCharOffset;
            string surroundingText = doc.GetText(firstCharOffset, numberOfCharactersAroundCursorToResolve);
            Debug.WriteLine("Text around cursor: [{0}]", surroundingText);
#endregion

            // Finally, generate completion data!
            var completionOptions = completionEngine.GetCompletionData(textCursorOffset, projectAnalysisRequest.CodeCompletionParameters.CtrlSpace).ToArray();
            projectAnalysisResult.CompletionOptions = completionEngine.GetCompletionData(textCursorOffset, projectAnalysisRequest.CodeCompletionParameters.CtrlSpace).ToArray();
            projectAnalysisResult.AutoCompleteEmptyMatch = completionEngine.AutoCompleteEmptyMatch;
            projectAnalysisResult.AutoSelect = completionEngine.AutoSelect;
            projectAnalysisResult.DefaultCompletionString = completionEngine.DefaultCompletionString;

            int startPos, wordLength;
            if (completionEngine.TryGetCompletionWord(textCursorOffset, out startPos, out wordLength))
            {
                Debug.WriteLine("TryGetCompletionWord :: startpos:{0}  wordlength:{1}", startPos, wordLength);
                projectAnalysisResult.CompletionWord = doc.GetText(startPos, wordLength);
            }

            projectAnalysisResult.TimeElapsed = sw.Elapsed;

            return projectAnalysisResult;
        }
Exemple #11
0
        public static FileOperationResponse DoAutoComplete(FileOperationRequest request)
        {
            FileOperationResponse response     = new FileOperationResponse();
            ProjectModel          projectModel = null;
            Stopwatch             sw           = Stopwatch.StartNew();

            try
            {
                var projectModelRepo = EndpointHost.AppHost.TryResolve <IProjectModelRepository>();

                projectModel = projectModelRepo.GetProject(request.UserId, request.ProjectId);

                var analysisRequest = new ProjectAnalysisRequest()
                {
                    ProjectModel             = projectModel,
                    CodeCompletionParameters = new ProjectAnalysisCodeCompletionParameters()
                    {
                        FileId    = request.FileId,
                        Line      = request.CompleteCode.LineNumber,
                        Column    = request.CompleteCode.ColumnNumber,
                        Offset    = request.CompleteCode.Offset,
                        CtrlSpace = request.CompleteCode.CtrlSpace
                    }
                };


                // Analyze!
                ProjectAnalysisResult analysisResult = NRefactoryUtils.RunFullProjectAnalysis(analysisRequest);


                // Convert analysis result model to file operation response DTO
                if (analysisResult.CompletionOptions != null)
                {
                    var codeCompletion = response.CodeCompletion = new FileCodeCompletionResponse();
                    codeCompletion.CompletionOptions = analysisResult.CompletionOptions
                                                       .Select(CodeCompletionResultUtility.FromICompletionDataToFileCodeCompletionResult).ToArray();
                    for (int i = 0, len = codeCompletion.CompletionOptions.Length; i < len; i++)
                    {
                        codeCompletion.CompletionOptions[i].Id = i;
                    }
                    codeCompletion.CompletionWord = analysisResult.CompletionWord;
                    if (analysisResult.BestMatchToCompletionWord != null)
                    {
                        codeCompletion.BestMatchToCompletionWord = codeCompletion.CompletionOptions.FirstOrDefault(x => x.CompletionText == analysisResult.BestMatchToCompletionWord.CompletionText);
                    }
                    // Record text around cursor
                    codeCompletion.TextBeforeCursor = analysisResult.CompletionContextBefore;
                    codeCompletion.TextAfterCursor  = analysisResult.CompletionContextAfter;
                    // Record inputs
                    codeCompletion.Line   = analysisResult.Line;
                    codeCompletion.Column = analysisResult.Column;
                    codeCompletion.Offset = analysisResult.Offset;
                }
                var allErrors = new List <FileParseResult>();
                foreach (var fileModel in analysisRequest.ProjectModel.GetFileDescendants())
                {
                    allErrors.AddRange(fileModel.Parser.ErrorsAndWarnings
                                       .Select(x => new FileParseResult()
                    {
                        FileId   = fileModel.Id,
                        FileName = fileModel.Name,
                        Line     = x.Region.BeginLine,
                        Column   = x.Region.BeginColumn,
                        Type     = x.ErrorType,
                        Message  = x.Message
                    }).ToArray());
                }
                response.ParseResults = allErrors.ToArray();


                /*
                 * StatelessProjectResponse response = new StatelessProjectResponse();
                 * if (analysisResult.CompletionOptions != null)
                 * {
                 *  response.CompletionOptions = analysisResult.CompletionOptions
                 *      .Select(x => new FileCodeCompletionResult()
                 *      {
                 *          CompletionText = x.CompletionText,
                 *          DisplayText = x.DisplayText,
                 *          Description = x.Description,
                 *          OverloadCount = x.OverloadedData.Count(),
                 *          CompletionCategoryDisplayText = (x.CompletionCategory == null ? "" : x.CompletionCategory.DisplayText)
                 *      }).ToArray();
                 *  response.CompletionWord = analysisResult.CompletionWord;
                 *  if (analysisResult.BestMatchToCompletionWord != null)
                 *      response.BestMatchToCompletionWord = response.CompletionOptions.FirstOrDefault(x => x.CompletionText == analysisResult.BestMatchToCompletionWord.CompletionText);
                 * }
                 * var allErrors = new List<FileParseResult>();
                 * foreach (var fileModel in analysisRequest.ProjectModel.GetFileDescendants())
                 * {
                 *  allErrors.AddRange(fileModel.Parser.ErrorsAndWarnings
                 *                         .Select(x => new FileParseResult()
                 *                         {
                 *                             FileId = fileModel.Id,
                 *                             FileName = fileModel.Name,
                 *                             Line = x.Region.BeginLine,
                 *                             Column = x.Region.BeginColumn,
                 *                             Type = x.ErrorType,
                 *                             Message = x.Message
                 *                         }).ToArray());
                 * }
                 * response.Errors = allErrors.ToArray();
                 * response.MsElapsed = analysisResult.TimeElapsed.TotalMilliseconds; // string.Format("{0} ms", analysisResult.TimeElapsed.TotalMilliseconds);
                 */
                response.Status.Success = true;
            }
            catch (Exception ex)
            {
                log.Error(ex.ToString(), ex);
                response.Status.SetError(ex);
            }
            finally
            {
                //response.CodeCompletion.MsElapsed = analysisResult.TimeElapsed.TotalMilliseconds; // string.Format("{0} ms", analysisResult.TimeElapsed.TotalMilliseconds);
                response.Status.MsElapsed = sw.ElapsedMilliseconds;
            }

            return(response);
        }
Exemple #12
0
        //private void ParseFile(ProjectFileViewModel fileViewModelToParse)
        //{
        //    var fileDto = ProjectMVVMConverters.FromViewModelToModel(fileViewModelToParse);

        //    MockWebServiceUtility.ParseFile(fileDto, response =>
        //    {
        //        if (response.Parse == null)
        //            return;

        //        var errors = response.Parse.Errors;
        //        //response.Parse.Errors
        //        if (errors != null)
        //        {
        //            Logger.AppendLine("{0} error(s) detected.", errors.Length);
        //            if (errors.Length > 0)
        //                foreach (var err in errors)
        //                    Logger.AppendLine("{0}: In file {1} ({2}, {3}): {4}", err.Type, err.FileName, err.Line, err.Column, err.Message);
        //        }

        //    });
        //}

        //private static FileOperationResponse DoAutoComplete(FileOperationRequest request)
        //{
        //    return AutocompleteServiceUtil.DoAutoComplete(request);
        //}


        private void AnalyzeProject2(bool ctrlSpace)
        {
            //ctrlSpace = true;
            var sw = Stopwatch.StartNew();

            var projectVm = (ProjectViewModel)DataContext;
            var fileVm    = projectVm.SelectedProjectItem as ProjectFileViewModel;

            if (fileVm == null)
            {
                Logger.AppendLine("A file must be selected");
                return;
            }

            fileVm.CaretIndex = SelectedFileContent.CaretIndex;
            // Synchronize the view's content with the viewmodel (since by default this is only done AFTER the textbox loses focus)
            fileVm.Content = SelectedFileContent.Text;

            // update file content in local data store if not already done
            var projectModelRepo = EndpointHost.AppHost.TryResolve <IProjectModelRepository>();

            projectModelRepo.SaveFileContent(478, fileVm.ProjectId, fileVm.Id, fileVm.Content);


            var fileRequest = new FileOperationRequest()
            {
                UserId       = 478, //projectVm..UserId,
                ProjectId    = projectVm.ProjectId,
                FileId       = fileVm.Id,
                CompleteCode = new FileCodeCompletionRequest()
                {
                    AutoComplete = true,
                    Offset       = fileVm.CaretIndex,
                    LineNumber   = fileVm.CaretLine,
                    ColumnNumber = fileVm.CaretColumn,
                    CtrlSpace    = ctrlSpace
                },
                Parse = new FileParseRequest()
            };


            var fileResponse = AutocompleteServiceUtil.DoAutoComplete(fileRequest);

#if false
            var projectDto = ProjectMVVMConverters.FromViewModelToModel(projectVm);

            var projectModel = ProjectModelConverters.FromDtoToModel(projectDto);

            var analysisRequest = new ProjectAnalysisRequest()
            {
                ProjectModel             = projectModel,
                CodeCompletionParameters = new ProjectAnalysisCodeCompletionParameters()
                {
                    CtrlSpace = ctrlSpace,
                    FileId    = fileVm.Id,
                    Offset    = fileVm.CaretIndex
                                //Line = request.CompleteCode.LineNumber,
                                //Column = request.CompleteCode.ColumnNumber,
                                //CtrlSpace = true // always true for now
                }
            };

            ProjectAnalysisResult analysisResult = NRefactoryUtils.RunFullProjectAnalysis(analysisRequest);

            //StatelessProjectResponse response = MockWebServiceUtility.Server_HandleStatelessCodeCompletionRequest(request);

            FileOperationResponse response = new FileOperationResponse();
            // Convert analysis result model to file operation response DTO
            if (analysisResult.CompletionOptions != null)
            {
                response.CodeCompletion = new FileCodeCompletionResponse();
                response.CodeCompletion.CompletionOptions = analysisResult.CompletionOptions
                                                            .Select(ProjectModelConverters.FromICompletionDataToFileCodeCompletionResult).ToArray();
                for (int i = 0, len = response.CodeCompletion.CompletionOptions.Length; i < len; i++)
                {
                    response.CodeCompletion.CompletionOptions[i].Id = i;
                }
                response.CodeCompletion.CompletionWord = analysisResult.CompletionWord;
                if (analysisResult.BestMatchToCompletionWord != null)
                {
                    response.CodeCompletion.BestMatchToCompletionWord = response.CodeCompletion.CompletionOptions.FirstOrDefault(x => x.CompletionText == analysisResult.BestMatchToCompletionWord.CompletionText);
                }
            }
            var allErrors = new List <FileParseResult>();
            foreach (var fileModel in analysisRequest.ProjectModel.GetFileDescendants())
            {
                allErrors.AddRange(fileModel.Parser.ErrorsAndWarnings
                                   .Select(x => new FileParseResult()
                {
                    FileId   = fileModel.Id,
                    FileName = fileModel.Name,
                    Line     = x.Region.BeginLine,
                    Column   = x.Region.BeginColumn,
                    Type     = x.ErrorType,
                    Message  = x.Message
                }).ToArray());
            }
            response.ParseResults = allErrors.ToArray();
#endif

            //var jsonResponse = JsonConvert.SerializeObject(fileResponse, Formatting.Indented);
            //Logger.AppendLine(jsonResponse);

            // Summarize results...
            Logger.AppendLine("=========================================================");
            Logger.AppendLine("Project analysis completed in {0} ms", sw.ElapsedMilliseconds);

            if (fileResponse.CodeCompletion == null)
            {
                Logger.AppendLine("No Completion Results.");
                Logger.SetCodeCompletionOptions(null, null);
            }
            else
            {
                var codeCompletion = fileResponse.CodeCompletion;

                Logger.SetCodeCompletionOptions(codeCompletion.CompletionOptions, codeCompletion.BestMatchToCompletionWord);

                Logger.AppendLine("Completion Results...");
                Logger.AppendLine("  Input:  Line:{0}  Col:{1}  Offset:{2}", codeCompletion.Line, codeCompletion.Column, codeCompletion.Offset);
                Logger.AppendLine("  Context: \"{0}\" <cursor> \"{1}\"", codeCompletion.TextBeforeCursor, codeCompletion.TextAfterCursor);
                Logger.AppendLine("  {0} code completion option(s) generated.", codeCompletion.CompletionOptions.Length);

                // Try to find closest matching completion result
                if (string.IsNullOrWhiteSpace(codeCompletion.CompletionWord))
                {
                    Logger.AppendLine("  No code completion word detected.");
                }
                else
                {
                    if (codeCompletion.BestMatchToCompletionWord != null)
                    {
                        Logger.AppendLine("  Detected code completion word, \"{0}\", most closely matches completion option \"{1}\".",
                                          codeCompletion.CompletionWord, codeCompletion.BestMatchToCompletionWord.CompletionText);
                    }
                    else
                    {
                        Logger.AppendLine("  Detected code completion word: {0}", codeCompletion.CompletionWord);
                    }
                }
            }


            if (fileResponse.ParseResults != null)
            {
                Logger.AppendLine("{0} error(s) detected.", fileResponse.ParseResults.Length);
                if (fileResponse.ParseResults.Length > 0)
                {
                    foreach (var err in fileResponse.ParseResults)
                    {
                        Logger.AppendLine("{0}: In file {1} ({2}, {3}): {4}", err.Type, err.FileName, err.Line, err.Column, err.Message);
                    }
                }
            }
        }
        //// todo: eliminate this method later
        //private static void AugmentProjectModelWithAlgorithmBase(ProjectModel model)
        //{
        //    model.Children.Add(QcAlgorithmFileModel.Value);
        //}

        public static ProjectAnalysisResult RunFullProjectAnalysis(ProjectAnalysisRequest projectAnalysisRequest)
        {
            Stopwatch sw = Stopwatch.StartNew();

            ProjectAnalysisResult projectAnalysisResult = new ProjectAnalysisResult();
            ProjectModel          projectModel          = projectAnalysisRequest.ProjectModel;

            // todo: Ask Jared why QCAlgorithm is a partial class and why it's not included in "common"

#if false
            // ************************************************************************************
            // NOTE:  In order to get this project building cleanly, with minimal dependencies
            // before checking into Github, I've removed all hard QuantConnect dependencies,
            // including the QCAlgorithm.cs embedded resource and the assembly references to
            // QuantConnect.Algorithm.Interface

            // Augment the project model with the QCAgorithm base class
            // projectModel.Children.Add(QcAlgorithmFileModel.Value);

            // ************************************************************************************
#endif

            // Set up the project (if not already done)
            if (projectModel.ProjectContent == null)
            {
                projectModel.ProjectContent = new CSharpProjectContent();
                projectModel.ProjectContent = projectModel.ProjectContent.AddAssemblyReferences(QCReferences.Value);
            }

            // For each new file, we need to integrate it into the project content
            var fileModelsInProject = projectModel.GetFileDescendants().ToArray();
            foreach (var fileModelInProject in fileModelsInProject)
            {
                IntegrateFileModel(projectModel, fileModelInProject);
            }

            // We can return now if no code completion was requested
            if (projectAnalysisRequest.CodeCompletionParameters == null)
            {
                projectAnalysisResult.TimeElapsed = sw.Elapsed;
                return(projectAnalysisResult);
            }

            // Now it's time to give attention specifically to the matter of resolving the code completion
            // options.  This, of course, requires a deeper analysis of the specified file...

            var codeCompletionParams = projectAnalysisRequest.CodeCompletionParameters;

            // Locate the file in the project
            ProjectFileModel fileModel = projectModel.FindFile(codeCompletionParams.FileId);
            if (fileModel == null)
            {
                throw new Exception("Specified file does not exist in this project");
            }


            // Create a TypeSystem.ICompilation that allows resolving within the project.
            var compilation = projectModel.ProjectContent.CreateCompilation();

            #region Resolve text cursor/caret location

            // The text cursor position is crucial to creating a properly-scoped type resolution context
            // so as to get relevant code completion suggestions.
            int              textCursorOffset   = 0;
            TextLocation     textCursorLocation = new TextLocation(1, 1);
            ReadOnlyDocument doc = new ReadOnlyDocument(fileModel.Content);
            try
            {
                // if line and column aren't set, we'll assume that the cursor offset/index is set
                if (codeCompletionParams.Line == 0 && codeCompletionParams.Column == 0)
                {
                    textCursorOffset = codeCompletionParams.Offset;
                    if (textCursorOffset < 0)
                    {
                        textCursorOffset = 0;
                    }
                    textCursorLocation = doc.GetLocation(textCursorOffset);
                }
                // if either line or column are invalid (i.e. <= 0), then we'll use offset 0 instead
                else if (codeCompletionParams.Line <= 0 || codeCompletionParams.Column <= 0)
                {
                    textCursorOffset = 0;
                }
                else
                {
                    textCursorLocation          = new TextLocation(codeCompletionParams.Line, codeCompletionParams.Column);
                    textCursorOffset            = doc.GetOffset(textCursorLocation);
                    codeCompletionParams.Offset = textCursorOffset;
                }
            }
            catch (Exception)
            {
                textCursorOffset   = 0;
                textCursorLocation = new TextLocation(1, 1);
            }
            finally
            {
                projectAnalysisResult.Line   = textCursorLocation.Line;
                projectAnalysisResult.Column = textCursorLocation.Column;
                projectAnalysisResult.Offset = textCursorOffset;
            }

            #endregion

            #region Create and Refine the type resolution context as much as possible based upon the cursor position

            var typeResolveContext = new CSharpTypeResolveContext(compilation.MainAssembly);
            // Constrain the resolve context by using scope
            typeResolveContext = typeResolveContext
                                 .WithUsingScope(fileModel.UnresolvedFile.GetUsingScope(textCursorLocation)
                                                 .Resolve(compilation));

            var curDef = fileModel.UnresolvedFile.GetInnermostTypeDefinition(textCursorLocation);
            if (curDef != null)
            {
                var resolvedDef = curDef.Resolve(typeResolveContext).GetDefinition();
                typeResolveContext = typeResolveContext.WithCurrentTypeDefinition(resolvedDef);
                var curMember = resolvedDef.Members.FirstOrDefault(m => m.Region.Begin <= textCursorLocation && textCursorLocation < m.BodyRegion.End);
                if (curMember != null)
                {
                    typeResolveContext = typeResolveContext.WithCurrentMember(curMember);
                }
            }

            #endregion

            // The purpose of the rest of these steps is a little fuzzy in my mind...
            // I'm still trying to understand them fully and if/why they're all needed.
            // It seems there is some redundancy here...

            var completionContext = new DefaultCompletionContextProvider(doc, fileModel.UnresolvedFile);

            #region Add Preprocessor Symbols??
            completionContext.AddSymbol("TEST");
            foreach (var sym in fileModel.SyntaxTree.ConditionalSymbols)
            {
                completionContext.AddSymbol(sym);
            }
            #endregion

            var completionDataFactory = new CodeCompletionDataFactory(new CSharpResolver(typeResolveContext));

            var completionEngine = new CSharpCompletionEngine(doc, completionContext, completionDataFactory, projectModel.ProjectContent, typeResolveContext);
            completionEngine.EolMarker        = Environment.NewLine;
            completionEngine.FormattingPolicy = FormattingOptionsFactory.CreateMono();
            projectModel.CompletionEngine     = completionEngine;

            // Attach contextual info to analysis result
            GetDocumentContext(projectAnalysisResult, textCursorOffset, doc);

            // Finally, generate completion data!
            var completionOptions = completionEngine.GetCompletionData(textCursorOffset, projectAnalysisRequest.CodeCompletionParameters.CtrlSpace).ToArray();

            projectAnalysisResult.CompletionOptions       = completionOptions.OrderBy(x => x.CompletionText).ToArray();
            projectAnalysisResult.AutoCompleteEmptyMatch  = completionEngine.AutoCompleteEmptyMatch;
            projectAnalysisResult.AutoSelect              = completionEngine.AutoSelect;
            projectAnalysisResult.DefaultCompletionString = completionEngine.DefaultCompletionString;

            int startPos, wordLength;
            if (completionEngine.TryGetCompletionWord(textCursorOffset, out startPos, out wordLength))
            {
                //Debug.WriteLine("TryGetCompletionWord :: startpos:{0}  wordlength:{1}", startPos, wordLength);
                string completionWord = projectAnalysisResult.CompletionWord = doc.GetText(startPos, wordLength);

                if (!string.IsNullOrWhiteSpace(completionWord))
                {
                    var bestMatch = projectAnalysisResult.CompletionOptions
                                    .FirstOrDefault(x => x.CompletionText.CompareTo(completionWord) >= 0);
                    projectAnalysisResult.BestMatchToCompletionWord = bestMatch;
                    //if (bestMatch != null)
                    //projectAnalysisResult.BestMatchToCompletionWord = bestMatch.CompletionText;
                }
            }

            projectAnalysisResult.TimeElapsed = sw.Elapsed;

            return(projectAnalysisResult);
        }
Exemple #14
0
        public static ProjectAnalysisResult RunFullProjectAnalysis(ProjectAnalysisRequest projectAnalysisRequest) // ProjectModel projectModel, int fileId, int line, int column)
        {
            Stopwatch sw = Stopwatch.StartNew();

            ProjectAnalysisResult projectAnalysisResult = new ProjectAnalysisResult();
            ProjectModel          projectModel          = projectAnalysisRequest.ProjectModel;


            // Set up the project (if not already done)
            if (projectModel.ProjectContent == null)
            {
                projectModel.ProjectContent = new CSharpProjectContent();
                projectModel.ProjectContent = projectModel.ProjectContent.AddAssemblyReferences(QCReferences.Value);
            }

            // For each new file, we need to integrate it into the project content
            var fileModelsInProject = projectModel.GetFileDescendants().ToArray();

            foreach (var fileModelInProject in fileModelsInProject)
            {
                IntegrateFileModel(projectModel, fileModelInProject);
            }

            // We can return now if no code completion was requested
            if (projectAnalysisRequest.CodeCompletionParameters == null)
            {
                projectAnalysisResult.TimeElapsed = sw.Elapsed;
                return(projectAnalysisResult);
            }

            // Now it's time to give attention specifically to the matter of resolving the code completion
            // options.  This, of course, requires a deeper analysis of the specified file...

            var codeCompletionParams = projectAnalysisRequest.CodeCompletionParameters;

            // Locate the file in the project
            ProjectFileModel fileModel = projectModel.FindFile(codeCompletionParams.FileId);

            if (fileModel == null)
            {
                throw new Exception("Specified file does not exist in this project");
            }


            // Create a TypeSystem.ICompilation that allows resolving within the project.
            var compilation = projectModel.ProjectContent.CreateCompilation();

            #region Resolve text cursor/caret location

            // The text cursor position is crucial to creating a properly-scoped type resolution context
            // so as to get relevant code completion suggestions.
            int              textCursorOffset;
            TextLocation     textCursorLocation;
            ReadOnlyDocument doc = new ReadOnlyDocument(fileModel.Content);
            if (codeCompletionParams.Line == 0 && codeCompletionParams.Column == 0)
            {
                textCursorOffset            = codeCompletionParams.Offset;
                textCursorLocation          = doc.GetLocation(textCursorOffset);
                codeCompletionParams.Line   = textCursorLocation.Line;
                codeCompletionParams.Column = textCursorLocation.Column;
            }
            else
            {
                textCursorLocation          = new TextLocation(codeCompletionParams.Line, codeCompletionParams.Column);
                textCursorOffset            = doc.GetOffset(textCursorLocation);
                codeCompletionParams.Offset = textCursorOffset;
            }

            #endregion

            #region Create and Refine the type resolution context as much as possible based upon the cursor position

            var typeResolveContext = new CSharpTypeResolveContext(compilation.MainAssembly);
            // Constrain the resolve context by using scope
            typeResolveContext = typeResolveContext
                                 .WithUsingScope(fileModel.UnresolvedFile.GetUsingScope(textCursorLocation)
                                                 .Resolve(compilation));

            var curDef = fileModel.UnresolvedFile.GetInnermostTypeDefinition(textCursorLocation);
            if (curDef != null)
            {
                var resolvedDef = curDef.Resolve(typeResolveContext).GetDefinition();
                typeResolveContext = typeResolveContext.WithCurrentTypeDefinition(resolvedDef);
                var curMember = resolvedDef.Members.FirstOrDefault(m => m.Region.Begin <= textCursorLocation && textCursorLocation < m.BodyRegion.End);
                if (curMember != null)
                {
                    typeResolveContext = typeResolveContext.WithCurrentMember(curMember);
                }
            }

            #endregion

            // The purpose of the rest of these steps is a little fuzzy in my mind...
            // I'm still trying to understand them fully and if/why they're all needed.
            // It seems there is some redundancy here...

            var completionContext = new DefaultCompletionContextProvider(doc, fileModel.UnresolvedFile);

            #region Add Preprocessor Symbols??
            completionContext.AddSymbol("TEST");
            foreach (var sym in fileModel.SyntaxTree.ConditionalSymbols)
            {
                completionContext.AddSymbol(sym);
            }
            #endregion

            var completionDataFactory = new TestCompletionDataFactory(new CSharpResolver(typeResolveContext));

            var completionEngine = new CSharpCompletionEngine(doc, completionContext, completionDataFactory, projectModel.ProjectContent, typeResolveContext);
            completionEngine.EolMarker        = Environment.NewLine;
            completionEngine.FormattingPolicy = FormattingOptionsFactory.CreateMono();
            projectModel.CompletionEngine     = completionEngine;

            #region Debugging Aid
            // Resolve content around text cursor
            int numberOfCharactersAroundCursorToResolve = 20;
            int firstCharOffset = textCursorOffset - numberOfCharactersAroundCursorToResolve / 2;
            if (firstCharOffset < 0)
            {
                firstCharOffset = 0;
            }
            if (doc.TextLength < firstCharOffset + numberOfCharactersAroundCursorToResolve)
            {
                numberOfCharactersAroundCursorToResolve = doc.TextLength - firstCharOffset;
            }
            string surroundingText = doc.GetText(firstCharOffset, numberOfCharactersAroundCursorToResolve);
            Debug.WriteLine("Text around cursor: [{0}]", surroundingText);
            #endregion

            // Finally, generate completion data!
            var completionOptions = completionEngine.GetCompletionData(textCursorOffset, projectAnalysisRequest.CodeCompletionParameters.CtrlSpace).ToArray();
            projectAnalysisResult.CompletionOptions       = completionEngine.GetCompletionData(textCursorOffset, projectAnalysisRequest.CodeCompletionParameters.CtrlSpace).ToArray();
            projectAnalysisResult.AutoCompleteEmptyMatch  = completionEngine.AutoCompleteEmptyMatch;
            projectAnalysisResult.AutoSelect              = completionEngine.AutoSelect;
            projectAnalysisResult.DefaultCompletionString = completionEngine.DefaultCompletionString;

            int startPos, wordLength;
            if (completionEngine.TryGetCompletionWord(textCursorOffset, out startPos, out wordLength))
            {
                Debug.WriteLine("TryGetCompletionWord :: startpos:{0}  wordlength:{1}", startPos, wordLength);
                projectAnalysisResult.CompletionWord = doc.GetText(startPos, wordLength);
            }

            projectAnalysisResult.TimeElapsed = sw.Elapsed;

            return(projectAnalysisResult);
        }
Exemple #15
0
        public override async Task <CommandResult> ExecuteAsync(ProjectOrSolution projectOrSolution, CancellationToken cancellationToken = default)
        {
            AssemblyResolver.Register();

            var codeAnalyzerOptions = new CodeAnalyzerOptions(
                ignoreAnalyzerReferences: Options.IgnoreAnalyzerReferences,
                ignoreCompilerDiagnostics: Options.IgnoreCompilerDiagnostics,
                reportNotConfigurable: Options.ReportNotConfigurable,
                reportSuppressedDiagnostics: Options.ReportSuppressedDiagnostics,
                logAnalyzerExecutionTime: Options.ExecutionTime,
                severityLevel: SeverityLevel,
                supportedDiagnosticIds: Options.SupportedDiagnostics,
                ignoredDiagnosticIds: Options.IgnoredDiagnostics,
                projectNames: Options.Projects,
                ignoredProjectNames: Options.IgnoredProjects,
                language: Language);

            IEnumerable <AnalyzerAssembly> analyzerAssemblies = Options.AnalyzerAssemblies
                                                                .SelectMany(path => AnalyzerAssemblyLoader.LoadFrom(path, loadFixers: false).Select(info => info.AnalyzerAssembly));

            CultureInfo culture = (Options.Culture != null) ? CultureInfo.GetCultureInfo(Options.Culture) : null;

            var codeAnalyzer = new CodeAnalyzer(
                analyzerAssemblies: analyzerAssemblies,
                formatProvider: culture,
                options: codeAnalyzerOptions);

            if (projectOrSolution.IsProject)
            {
                Project project = projectOrSolution.AsProject();

                WriteLine($"Analyze '{project.Name}'", ConsoleColor.Cyan, Verbosity.Minimal);

                Stopwatch stopwatch = Stopwatch.StartNew();

                ProjectAnalysisResult result = await codeAnalyzer.AnalyzeProjectAsync(project, cancellationToken);

                stopwatch.Stop();

                WriteLine($"Done analyzing project '{project.FilePath}' in {stopwatch.Elapsed:mm\\:ss\\.ff}", Verbosity.Minimal);

                if (Options.Output != null &&
                    result.Diagnostics.Any())
                {
                    DiagnosticXmlSerializer.Serialize(result, project, Options.Output, culture);
                }
            }
            else
            {
                Solution solution = projectOrSolution.AsSolution();

                ImmutableArray <ProjectAnalysisResult> results = await codeAnalyzer.AnalyzeSolutionAsync(solution, cancellationToken);

                if (Options.Output != null &&
                    results.Any(f => f.Diagnostics.Any()))
                {
                    DiagnosticXmlSerializer.Serialize(results, solution, Options.Output, culture);
                }
            }

            return(CommandResult.Success);
        }