Ejemplo n.º 1
0
        /// <summary>
        /// Processes the provided <paramref name="project"/>, and computes the provided <paramref name="metrics"/>.
        /// </summary>
        /// <param name="parameters">The inspection parameters provided by the user.</param>
        /// <param name="project">The project to inspect.</param>
        /// <param name="metrics">The metrics to compute.</param>
        /// <param name="ct">A cancellation token.</param>
        private async Task <ProjectInspectionResult> ProcessAsync(InspectionParameters parameters, Project project, IList <IMetric> metrics, CancellationToken ct)
        {
            _logger.LogVerbose($"Inspecting project: {project.Name}");

            var compilation = await project.GetCompilationAsync(ct);

            if (compilation is null)
            {
                throw new InspectionException($"Failed to compile project: {project.Name}");
            }

            var registry = new Registry();
            var resolver = new PackageResolver(_logger);
            var results  = new List <PackageInspectionResult>();

            var documents  = project.Documents.ToImmutableHashSet();
            var exclusions = NamespaceExclusionList.CreateFromParameters(parameters, project);

            await resolver.CreatePackageGraph(project, exclusions, ct);

            var memberLookupTable = await GetMemberAccessLookupTable(compilation, exclusions, ct);

            using (var portableExecutableLoadContext = new PortableExecutableLoadContext(project, _logger))
            {
                foreach (var executable in portableExecutableLoadContext.GetExecutables(exclusions))
                {
                    var package = resolver.CreatePackage(executable);

                    registry.AddPackage(package);

                    foreach (var type in executable.ExportedTypes)
                    {
                        var compilationType = GetCompilationType(compilation, type);

                        if (compilationType is null)
                        {
                            continue;
                        }

                        var isAdded = await AddConstructorReferences(project.Solution, documents, package, registry, compilationType, ct);

                        if (isAdded)
                        {
                            await AddMemberReferences(project.Solution, documents, package, registry, compilationType, memberLookupTable, ct);
                        }
                    }

                    results.Add(ComputeMetrics(project, compilation, package, metrics, registry));
                }
            }

            results.AddRange(AddMissingExplicitPackages(resolver, exclusions, results));

            return(ProjectInspectionResult.Ok(project, results));
        }