Ejemplo n.º 1
0
        private void PerformScanBackground(
            )
        {
            var token = _cancellationTokenSource.Token;

            SolutionBindContainer?sbc = null;

            try
            {
                //const int max = 100;
                //for (var cc = 0; cc <= max; cc++)
                //{
                //    if (token.IsCancellationRequested)
                //    {
                //        return;
                //    }

                //    Thread.Sleep(100);

                //    Progress = ((float)cc) / max;
                //}

                if (_buildStatusContainer.BuildIsInProgress)
                {
                    _outputPane !.OutputStringThreadSafe($"Dpdt scanning is cancelled due to build/cleanup is in progress{Environment.NewLine}");
                    return;
                }

                _outputPane !.OutputStringThreadSafe($"Dpdt scanning is started{Environment.NewLine}");

                var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));

                var workspace = (Workspace)componentModel.GetService <VisualStudioWorkspace>();

                if (workspace == null)
                {
                    return;
                }

                if (!workspace.CurrentSolution.Projects.Any())
                {
                    return;
                }

                sbc = new SolutionBindContainer();
                var index        = -1;
                var projectCount = workspace.CurrentSolution.Projects.Count();
                foreach (var project in workspace.CurrentSolution.Projects)
                {
                    Progress = ((float)(++index)) / projectCount;

                    if (token.IsCancellationRequested)
                    {
                        _outputPane !.OutputStringThreadSafe($"  Dpdt scanning is cancelled{Environment.NewLine}");
                        break;
                    }

                    if (_buildStatusContainer.BuildIsInProgress)
                    {
                        _outputPane !.OutputStringThreadSafe($"  Dpdt scanning is cancelled due to build/cleanup is in progress{Environment.NewLine}");
                        break;
                    }

                    if (project == null)
                    {
                        continue;
                    }

                    if (!project.SupportsCompilation)
                    {
                        continue;
                    }

                    if (project.Language != "C#")
                    {
                        continue;
                    }

                    var letsgo = false;
                    foreach (var reference in project.AnalyzerReferences)
                    {
                        //surrogate marker for nuget Dpdt.Injector has installed to the project
                        if (reference.Display == "DpdtInject.Generator")
                        {
                            letsgo = true;

                            break;
                        }
                    }

                    if (!letsgo)
                    {
                        _outputPane !.OutputStringThreadSafe($"  {project.Name}: Project skipped due to absense of Dpdt package installed{Environment.NewLine}");
                        continue;
                    }

                    var swt = Stopwatch.StartNew();

                    Compilation?compilation = null;
                    ThreadHelper.JoinableTaskFactory.Run(
                        async() =>
                    {
                        try
                        {
                            compilation = await project.GetCompilationAsync(token);
                        }
                        catch (OperationCanceledException ope)
                        {
                            //ok
                        }
                        catch (Exception excp)
                        {
                            LogVS(excp);
                        }
                    });

                    //first check for cancellation...
                    if (token.IsCancellationRequested)
                    {
                        _outputPane !.OutputStringThreadSafe($"  Dpdt scanning is cancelled{Environment.NewLine}");

                        break;
                    }

                    //..next for compilation errors, because both will result with compilation == null
                    if (compilation == null)
                    {
                        continue;
                    }

                    _outputPane !.OutputStringThreadSafe($"    {project.Name}: compilation taken {swt.Elapsed}{Environment.NewLine}");

                    var diag = compilation.GetDiagnostics();

                    var errors = diag.Where(j => j.Severity == DiagnosticSeverity.Error).ToList();
                    if (errors.Count > 0)
                    {
                        var errorMessage = string.Join(
                            Environment.NewLine,
                            errors.Select(j => j.ToString())
                            );

                        //DpdtPackage.ShowMessageBox(
                        //    "Error has been found",
                        //    errorMessage
                        //    );

                        _outputPane !.OutputStringThreadSafe($"     {project.Name}: compilation error {Environment.NewLine}");
                        _outputPane !.OutputStringThreadSafe("     " + errorMessage);
                        _outputPane !.OutputStringThreadSafe(Environment.NewLine);

                        //do not skip this project analysis, it may be partially fine
                        //continue;
                    }

                    swt.Restart();

                    var meta = new BuiltinMeta();
                    if (!meta.TryExtract(compilation, out var projectXml))
                    {
                        continue;
                    }
                    sbc.Append(projectXml !);

                    _outputPane !.OutputStringThreadSafe($"    {project.Name}: Binding extraction taken {swt.Elapsed}{Environment.NewLine}");
                    _outputPane !.OutputStringThreadSafe($"    {project.Name}: Found {projectXml.TotalBindingCount} binding{Environment.NewLine}");

                    if (token.IsCancellationRequested)
                    {
                        _outputPane !.OutputStringThreadSafe($"  Dpdt scanning is cancelled{Environment.NewLine}");

                        break;
                    }
                }
            }
            catch (Exception excp)
            {
                LogVS(excp);
                _outputPane !.OutputStringThreadSafe($"  Dpdt scanning failed: {excp.Message}{Environment.NewLine}");
                _outputPane !.OutputStringThreadSafe($"  Dpdt scanning failed: {excp.StackTrace}{Environment.NewLine}");
            }
            finally
            {
                if (sbc != null)
                {
                    this.SolutionBindContainer = sbc;
                }

                _outputPane !.OutputStringThreadSafe($"Dpdt scanning is finished{Environment.NewLine}");

                // CodeLenses usually only live as long as the document is open so we just refresh all the connected ones.
                //they will show actual status
                CodeLensConnectionHandler.RefreshAllCodeLensDataPointsAsync()
                .FileAndForget(nameof(PerformScanBackground))
                ;
                BindingListViewModel.RefreshAction?.Invoke();

                Progress   = 1f;
                IsFinished = true;
            }
        }
Ejemplo n.º 2
0
        private void DoGenerateXml(
            ITypeInfoContainer typeInfoContainer,
            IReadOnlyList <ClusterMethodBindings> clusterMethodBindings
            )
        {
            if (typeInfoContainer is null)
            {
                throw new ArgumentNullException(nameof(typeInfoContainer));
            }

            if (clusterMethodBindings is null)
            {
                throw new ArgumentNullException(nameof(clusterMethodBindings));
            }

            #region create xml representation

            var clusterXmls = new List <ClusterBindContainerXml>();
            foreach (var clusterMethodBinding in clusterMethodBindings)
            {
                var clusterType    = clusterMethodBinding.ClusterType;
                var clusterTypeXml = clusterType.ToXml();

                var methodBindXmls = new List <MethodBindContainerXml>();
                foreach (var methodBinding in clusterMethodBinding.MethodBindings)
                {
                    var methodDeclaration = methodBinding.Item1;

                    var methodDeclarationXml = new MethodDeclarationInfoXml(
                        methodDeclaration.ToXml(),
                        methodDeclaration.Identifier.Text
                        );

                    var methodBindXml = new MethodBindContainerXml(
                        clusterTypeXml,
                        methodDeclarationXml,
                        methodBinding.Item2.ConvertAll(
                            bc => new BindingXml(
                                bc.UniqueUnstableIdentifier.ToString(),
                                bc.TargetRepresentation,
                                bc.BindFromTypes.ConvertAll(s => s.ToXml()).ToArray(),
                                bc.BindToType.ToXml(),
                                bc.ConstructorArguments.ToXml(),
                                bc.Scope.ToString(),
                                (int)bc.Scope,
                                bc.IsConditional,
                                bc.IsConventional,
                                bc.ExpressionNode.ToXml()
                                )
                            ).ToArray()
                        );
                    methodBindXmls.Add(methodBindXml);
                }

                var clusterXml = new ClusterBindContainerXml(
                    clusterTypeXml,
                    methodBindXmls.ToArray()
                    );
                clusterXmls.Add(clusterXml);
            }

            var projectXml = new ProjectBindContainerXml(
                clusterXmls.ToArray()
                );

            #endregion

            var meta = new BuiltinMeta();
            meta.Store(
                typeInfoContainer,
                projectXml
                );
        }