Ejemplo n.º 1
0
        /// <summary>
        /// Adds a collection of <paramref name="symbols"/> used by the specified <paramref name="package"/> to
        /// the registry. This operations filters out all symbols with no locations, and de-duplicates the
        /// symbols and locations.
        /// </summary>
        /// <param name="package">The package to assign the symbols to.</param>
        /// <param name="symbols">The collection of symbols to add.</param>
        public void AddPackageSymbols(IPackageWithExecutableLoaded package, IEnumerable <ReferencedSymbol> symbols)
        {
            if (!_items.ContainsKey(package))
            {
                AddPackage(package);
            }

            if (!_items.TryGetValue(package, out var locations))
            {
                locations = new Dictionary <ISymbol, HashSet <ReferenceLocation> >(_comparer);

                _items[package] = locations;
            }

            foreach (var symbol in symbols)
            {
                if (!symbol.Locations.Any())
                {
                    continue;
                }

                if (!locations.ContainsKey(symbol.Definition))
                {
                    locations.Add(symbol.Definition, new HashSet <ReferenceLocation>());
                }

                foreach (var location in symbol.Locations)
                {
                    locations[symbol.Definition].Add(location);
                }
            }
        }
        public IMetricResult?Compute(Project project, Compilation compilation, IPackageWithExecutableLoaded package, Registry registry)
        {
            var count = package.GetUniqueDependenciesCount();

            if (count == 0)
            {
                return(null);
            }

            return(new TransitiveCountMetricResult(count));
        }
Ejemplo n.º 3
0
        /// <inheritdoc />
        public IMetricResult?Compute(Project project, Compilation compilation, IPackageWithExecutableLoaded package, Registry registry)
        {
            var usageCount = registry.GetUsedTypeCount(package);

            if (usageCount == 0)
            {
                return(null);
            }

            var percentage = (float)usageCount / package.GetExecutable().ExportedTypesCount * 100;

            return(new UsageMetricResult(percentage));
        }
Ejemplo n.º 4
0
        /// <inheritdoc />
        public IMetricResult?Compute(Project project, Compilation compilation, IPackageWithExecutableLoaded package, Registry registry)
        {
            var uniqueLocationsIds = registry.GetReferenceLocationsAcrossSymbols(package)
                                     .Select(r => r.Document.Id)
                                     .ToList();

            if (uniqueLocationsIds.Count < 1)
            {
                return(null);
            }

            var useCount   = project.DocumentIds.Intersect(uniqueLocationsIds).Count();
            var totalCount = project.DocumentIds.Count;

            var percentage = (float)useCount / totalCount * 100;

            return(new ScatteringMetricResult(percentage));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Computes the metrics of the package.
        /// </summary>
        /// <param name="project">The project being inspected.</param>
        /// <param name="compilation">The Roslyn compilation of the project source-files.</param>
        /// <param name="package">The package being analyzed.</param>
        /// <param name="metrics">A collection of metrics to compute.</param>
        /// <param name="registry">The registry of information collected from the Roslyn compilation.</param>
        private static PackageInspectionResult ComputeMetrics(Project project, Compilation compilation, IPackageWithExecutableLoaded package, IList <IMetric> metrics, Registry registry)
        {
            var results = new List <IMetricResult?>();

            foreach (var metric in metrics)
            {
                results.Add(metric.Compute(project, compilation, package, registry));
            }

            return(new PackageInspectionResult(package, results));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Finds any references to members (methods, properties, fields, events) of the type.
        /// </summary>
        /// <param name="solution">The solution the project being inspected is part of.</param>
        /// <param name="documents">A collection of documents (source-files) in the project.</param>
        /// <param name="package">The package being inspected.</param>
        /// <param name="registry">The registry of information collected from the Roslyn compilation.</param>
        /// <param name="compilationType">The corresponding Roslyn type of a publicly exported type in a referenced executable.</param>
        /// <param name="lookup">A lookup table of member accesses symbols.</param>
        /// <param name="ct">A cancellation token.</param>
        private static async Task AddMemberReferences(Solution solution, IImmutableSet <Document> documents, IPackageWithExecutableLoaded package, Registry registry, ISymbol compilationType, IReadOnlyDictionary <INamespaceSymbol, ICollection <ISymbol> > lookup, CancellationToken ct)
        {
            if (lookup.TryGetValue(compilationType.ContainingNamespace, out var members))
            {
                foreach (var member in members)
                {
                    var refs = await SymbolFinder.FindReferencesAsync(member, solution, documents, ct);

                    if (refs is null)
                    {
                        continue;
                    }

                    registry.AddPackageSymbols(package, refs);
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Finds any references to the constructor or the type itself when inherited from.
        /// </summary>
        /// <param name="solution">The solution the project being inspected is part of.</param>
        /// <param name="documents">A collection of documents (source-files) in the project.</param>
        /// <param name="package">The package being inspected.</param>
        /// <param name="registry">The registry of information collected from the Roslyn compilation.</param>
        /// <param name="compilationType">The corresponding Roslyn type of a publicly exported type in a referenced executable.</param>
        /// <param name="ct">A cancellation token.</param>
        /// <returns></returns>
        private static async Task <bool> AddConstructorReferences(Solution solution, IImmutableSet <Document> documents, IPackageWithExecutableLoaded package, Registry registry, ISymbol compilationType, CancellationToken ct)
        {
            var refs = await SymbolFinder.FindReferencesAsync(compilationType, solution, documents, ct);

            if (refs is null)
            {
                return(false);
            }

            registry.AddPackageSymbols(package, refs);

            return(true);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Adds a <paramref name="package"/> to the registry.
 /// </summary>
 /// <param name="package">The package to group usage of members by.</param>
 public void AddPackage(IPackageWithExecutableLoaded package)
 {
     _items.Add(package, new Dictionary <ISymbol, HashSet <ReferenceLocation> >(_comparer));
 }