internal static async System.Threading.Tasks.Task <AssemblyMetricData> ComputeAsync(IAssemblySymbol assembly, SemanticModelProvider semanticModelProvider, CancellationToken cancellationToken) { var coupledTypesBuilder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>(); long linesOfCode = 0; int maintainabilityIndexTotal = 0; int cyclomaticComplexity = 0; int depthOfInheritance = 0; int grandChildCount = 0; ImmutableArray <CodeAnalysisMetricData> children = await ComputeAsync(GetChildSymbols(assembly), semanticModelProvider, cancellationToken).ConfigureAwait(false); foreach (CodeAnalysisMetricData child in children) { MetricsHelper.AddCoupledNamedTypes(coupledTypesBuilder, child.CoupledNamedTypes); linesOfCode += child.SourceLines; cyclomaticComplexity += child.CyclomaticComplexity; depthOfInheritance = Math.Max(child.DepthOfInheritance.GetValueOrDefault(), depthOfInheritance); // Compat: Maintainability index of an assembly is computed based on the values of types, not namespace children. Debug.Assert(child.Symbol.Kind == SymbolKind.Namespace); Debug.Assert(child.Children.Length > 0); Debug.Assert(child.Children.All(grandChild => grandChild.Symbol.Kind == SymbolKind.NamedType)); maintainabilityIndexTotal += (child.MaintainabilityIndex * child.Children.Length); grandChildCount += child.Children.Length; } int maintainabilityIndex = grandChildCount > 0 ? MetricsHelper.GetAverageRoundedMetricValue(maintainabilityIndexTotal, grandChildCount) : 100; return(new AssemblyMetricData(assembly, maintainabilityIndex, coupledTypesBuilder.ToImmutable(), linesOfCode, cyclomaticComplexity, depthOfInheritance, children)); }
internal static async Task <PropertyMetricData> ComputeAsync(IPropertySymbol property, SemanticModelProvider semanticModelProvider, CancellationToken cancellationToken) { var coupledTypesBuilder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>(); ImmutableArray <SyntaxReference> declarations = property.DeclaringSyntaxReferences; long linesOfCode = await MetricsHelper.GetLinesOfCodeAsync(declarations, property, semanticModelProvider, cancellationToken).ConfigureAwait(false); (int cyclomaticComplexity, ComputationalComplexityMetrics computationalComplexityMetrics) = await MetricsHelper.ComputeCoupledTypesAndComplexityExcludingMemberDeclsAsync(declarations, property, coupledTypesBuilder, semanticModelProvider, cancellationToken).ConfigureAwait(false); MetricsHelper.AddCoupledNamedTypes(coupledTypesBuilder, property.Parameters); MetricsHelper.AddCoupledNamedTypes(coupledTypesBuilder, property.Type); ImmutableArray <CodeAnalysisMetricData> children = await ComputeAsync(GetAccessors(property), semanticModelProvider, cancellationToken).ConfigureAwait(false); int maintainabilityIndexTotal = 0; foreach (CodeAnalysisMetricData child in children) { MetricsHelper.AddCoupledNamedTypes(coupledTypesBuilder, child.CoupledNamedTypes); maintainabilityIndexTotal += child.MaintainabilityIndex; cyclomaticComplexity += child.CyclomaticComplexity; computationalComplexityMetrics = computationalComplexityMetrics.Union(child.ComputationalComplexityMetrics); } int?depthOfInheritance = null; int maintainabilityIndex = children.Length > 0 ? MetricsHelper.GetAverageRoundedMetricValue(maintainabilityIndexTotal, children.Length) : 100; MetricsHelper.RemoveContainingTypes(property, coupledTypesBuilder); return(new PropertyMetricData(property, maintainabilityIndex, computationalComplexityMetrics, coupledTypesBuilder.ToImmutable(), linesOfCode, cyclomaticComplexity, depthOfInheritance, children)); }
internal static async Task <NamespaceMetricData> ComputeAsync(INamespaceSymbol @namespace, SemanticModelProvider semanticModelProvider, CancellationToken cancellationToken) { var coupledTypesBuilder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>(); int maintainabilityIndexTotal = 0; int cyclomaticComplexity = 0; int depthOfInheritance = 0; long childrenLinesOfCode = 0; ImmutableArray <CodeAnalysisMetricData> children = await ComputeAsync(GetChildSymbols(@namespace), semanticModelProvider, cancellationToken).ConfigureAwait(false); foreach (CodeAnalysisMetricData child in children) { MetricsHelper.AddCoupledNamedTypes(coupledTypesBuilder, child.CoupledNamedTypes); maintainabilityIndexTotal += child.MaintainabilityIndex; cyclomaticComplexity += child.CyclomaticComplexity; depthOfInheritance = Math.Max(child.DepthOfInheritance.GetValueOrDefault(), depthOfInheritance); // Avoid double counting lines for nested types. if (child.Symbol.ContainingType == null) { childrenLinesOfCode += child.SourceLines; } } long linesOfCode = @namespace.IsImplicitlyDeclared ? childrenLinesOfCode : await MetricsHelper.GetLinesOfCodeAsync(@namespace.DeclaringSyntaxReferences, @namespace, semanticModelProvider, cancellationToken).ConfigureAwait(false); int maintainabilityIndex = children.Length > 0 ? MetricsHelper.GetAverageRoundedMetricValue(maintainabilityIndexTotal, children.Length) : 100; return(new NamespaceMetricData(@namespace, maintainabilityIndex, coupledTypesBuilder.ToImmutable(), linesOfCode, cyclomaticComplexity, depthOfInheritance, children)); }