static ErrorFacts() { ImmutableHashSet <string> .Builder builder = ImmutableHashSet.CreateBuilder <string>(); builder.Add(getId(ErrorCode.WRN_NullReferenceAssignment)); builder.Add(getId(ErrorCode.WRN_NullReferenceReceiver)); builder.Add(getId(ErrorCode.WRN_NullReferenceReturn)); builder.Add(getId(ErrorCode.WRN_NullReferenceArgument)); builder.Add(getId(ErrorCode.WRN_NullReferenceIterationVariable)); builder.Add(getId(ErrorCode.WRN_UninitializedNonNullableField)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInAssignment)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgument)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate)); builder.Add(getId(ErrorCode.WRN_NullAsNonNullable)); builder.Add(getId(ErrorCode.WRN_NullableValueTypeMayBeNull)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint)); builder.Add(getId(ErrorCode.WRN_ThrowPossibleNull)); builder.Add(getId(ErrorCode.WRN_UnboxPossibleNull)); builder.Add(getId(ErrorCode.WRN_DefaultExpressionMayIntroduceNullT)); builder.Add(getId(ErrorCode.WRN_NullLiteralMayIntroduceNullT)); builder.Add(getId(ErrorCode.WRN_ConditionalAccessMayReturnNull)); builder.Add(getId(ErrorCode.WRN_AsOperatorMayReturnNull)); builder.Add(getId(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull)); builder.Add(getId(ErrorCode.WRN_ConvertingNullableToNonNullable)); NullableFlowAnalysisWarnings = builder.ToImmutable(); string getId(ErrorCode errorCode) { return(MessageProvider.Instance.GetIdForErrorCode((int)errorCode)); } }
public State(INamedTypeSymbol bindingFlagsConstants, INamedTypeSymbol bindingFlags, ImmutableArray <SourceSpan> bindingFlagsConstantsRoots) { BindingFlagsConstants = bindingFlagsConstants; BindingFlags = bindingFlags; BindingFlagsConstantsRoots = bindingFlagsConstantsRoots; { var bfcns = ImmutableHashSet.CreateBuilder <string>(); foreach (var member in bindingFlagsConstants.GetMembers()) { bfcns.Add(member.Name); } BindingFlagsConstantsNames = bfcns.ToImmutable(); } { var bfns = ImmutableHashSet.CreateBuilder <string>(); foreach (var member in bindingFlags.GetMembers()) { bfns.Add(member.Name); } BindingFlagsNames = bfns.ToImmutable(); } }
private static BlockSyntax RewriteBody( IImmutableDictionary <ISymbol, PrivateField> privateFields, BlockSyntax body, IImmutableDictionary <SyntaxNode, ISymbol> references, out ISet <SyntaxNode> rewrittenNodes) { var symbolsToRewrite = references.Values.ToImmutableHashSet(); var localDeclaration = SyntaxFactory.LocalDeclarationStatement( SyntaxFactory.VariableDeclaration( SyntaxFactory.PredefinedType( SyntaxFactory.Token(SyntaxKind.IntKeyword)).WithTrailingTrivia(SyntaxFactory.Space), SyntaxFactory.SeparatedList(symbolsToRewrite.Select( s => SyntaxFactory.VariableDeclarator(privateFields[s].UniqueName))))); var rewrittenNodesBuilder = ImmutableHashSet.CreateBuilder <SyntaxNode>(); var newBody = body.ReplaceSyntax( references.Keys, (original, partiallyRewritten) => { rewrittenNodesBuilder.Add(original); return(SyntaxFactory.IdentifierName(privateFields[references[original]].UniqueName)); }, null, null, null, null); var newStatements = newBody.Statements.Insert(0, localDeclaration); newBody = newBody.WithStatements(newStatements); rewrittenNodes = rewrittenNodesBuilder.ToImmutable(); return(newBody); }
public void ToImmutableHashSet() { ImmutableHashSet <int> .Builder builder = ImmutableHashSet.CreateBuilder <int>(); builder.Add(1); builder.Add(2); builder.Add(3); var set = builder.ToImmutableSortedSet(); Assert.True(builder.Contains(1)); Assert.True(builder.Contains(2)); Assert.True(builder.Contains(3)); builder.Remove(3); Assert.False(builder.Contains(3)); Assert.True(set.Contains(3)); builder.Clear(); Assert.True(builder.ToImmutableHashSet().IsEmpty); Assert.False(set.IsEmpty); ImmutableHashSet <int> .Builder nullBuilder = null; AssertExtensions.Throws <ArgumentNullException>("builder", () => nullBuilder.ToImmutableHashSet()); }
static GlobalFlowStateAnalysisValueSet GetNegateValueFromParents(ImmutableHashSet <GlobalFlowStateAnalysisValueSet> parents) { Debug.Assert(parents.Count > 0); var analysisValuesBuilder = ImmutableHashSet.CreateBuilder <IAbstractAnalysisValue>(); var parentsBuilder = ImmutableHashSet.CreateBuilder <GlobalFlowStateAnalysisValueSet>(); var height = 0; foreach (var parent in parents) { if (parent.AnalysisValues.Count == 1 && parent.Height == 0) { analysisValuesBuilder.Add(parent.AnalysisValues.Single().GetNegatedValue()); } else { var negatedParent = parent.GetNegatedValue(); parentsBuilder.Add(negatedParent); height = Math.Max(height, negatedParent.Height + 1); } } return(new GlobalFlowStateAnalysisValueSet(analysisValuesBuilder.ToImmutable(), parentsBuilder.ToImmutable(), height, GlobalFlowStateAnalysisValueSetKind.Known)); }
private ImmutableHashSet <string> GetWhitelist( ImmutableArray <AdditionalText> additionalFiles ) { ImmutableHashSet <string> .Builder whitelistedClasses = ImmutableHashSet.CreateBuilder <string>(); AdditionalText whitelistFile = additionalFiles.FirstOrDefault( file => Path.GetFileName(file.Path) == WhitelistFileName ); if (whitelistFile == null) { return(whitelistedClasses.ToImmutableHashSet()); } SourceText whitelistText = whitelistFile.GetText(); foreach (TextLine line in whitelistText.Lines) { whitelistedClasses.Add(line.ToString().Trim()); } return(whitelistedClasses.ToImmutableHashSet()); }
private static async Task<(ImmutableHashSet<string> remoteRootPaths, ImmutableHashSet<string> externalPaths)> GetLocalPathsOfRemoteRootsAsync(CollaborationSession session) { var roots = await session.ListRootsAsync(CancellationToken.None).ConfigureAwait(false); var localPathsOfRemoteRoots = roots.Select(root => session.ConvertSharedUriToLocalPath(root)).ToImmutableArray(); var remoteRootPaths = ImmutableHashSet.CreateBuilder<string>(); var externalPaths = ImmutableHashSet.CreateBuilder<string>(); foreach (var localRoot in localPathsOfRemoteRoots) { // The local root is something like tmp\\xxx\\<workspace name> // The external root should be tmp\\xxx\\~external, so replace the workspace name with ~external. #pragma warning disable CS8602 // Dereference of a possibly null reference. (Can localRoot be null here?) var splitRoot = localRoot.TrimEnd('\\').Split('\\'); #pragma warning restore CS8602 // Dereference of a possibly null reference. splitRoot[splitRoot.Length - 1] = "~external"; var externalPath = string.Join("\\", splitRoot) + "\\"; remoteRootPaths.Add(localRoot); externalPaths.Add(externalPath); } return (remoteRootPaths.ToImmutable(), externalPaths.ToImmutable()); }
private static bool TryAddMatches( ImmutableHashSet <string> values, int minRequiredLength, int maxRequiredLength, ref ImmutableHashSet <string> .Builder matches) { var success = false; foreach (string value2 in values) { if (value2.Length < minRequiredLength || value2.Length > maxRequiredLength) { continue; } if ((matches ??= ImmutableHashSet.CreateBuilder(WordList.DefaultComparer)).Add(value2)) { success = true; } } return(success); }
static ErrorFacts() { ImmutableHashSet <string> .Builder nullableWarnings = ImmutableHashSet.CreateBuilder <string>(); nullableWarnings.Add(GetId(ErrorCode.WRN_NullReferenceAssignment)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullReferenceReceiver)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullReferenceReturn)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullReferenceArgument)); nullableWarnings.Add(GetId(ErrorCode.WRN_UninitializedNonNullableField)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInAssignment)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInArgument)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput)); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate) ); nullableWarnings.Add(GetId(ErrorCode.WRN_NullAsNonNullable)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullableValueTypeMayBeNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint)); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint) ); nullableWarnings.Add(GetId(ErrorCode.WRN_ThrowPossibleNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_UnboxPossibleNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNullWithWhen)); nullableWarnings.Add(GetId(ErrorCode.WRN_ConvertingNullableToNonNullable)); nullableWarnings.Add( GetId(ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment) ); nullableWarnings.Add(GetId(ErrorCode.WRN_ParameterConditionallyDisallowsNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_ShouldNotReturn)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInTypeOnOverride)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride)); nullableWarnings.Add(GetId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial)); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInTypeOnImplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnImplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnImplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInTypeOnExplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnExplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase) ); nullableWarnings.Add( GetId(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList) ); nullableWarnings.Add( GetId(ErrorCode.WRN_NullabilityMismatchInConstraintsOnPartialImplementation) ); nullableWarnings.Add(GetId(ErrorCode.WRN_NullReferenceInitializer)); nullableWarnings.Add(GetId(ErrorCode.WRN_ShouldNotReturn)); nullableWarnings.Add(GetId(ErrorCode.WRN_DoesNotReturnMismatch)); nullableWarnings.Add( GetId( ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation ) ); nullableWarnings.Add( GetId( ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnImplicitImplementation ) ); nullableWarnings.Add( GetId(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride) ); nullableWarnings.Add( GetId(ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnExplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnImplicitImplementation) ); nullableWarnings.Add( GetId(ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnOverride) ); nullableWarnings.Add(GetId(ErrorCode.WRN_MemberNotNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_MemberNotNullBadMember)); nullableWarnings.Add(GetId(ErrorCode.WRN_MemberNotNullWhen)); nullableWarnings.Add(GetId(ErrorCode.WRN_ParameterDisallowsNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_ParameterNotNullIfNotNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_ReturnNotNullIfNotNull)); NullableWarnings = nullableWarnings.ToImmutable(); }
/// <summary> /// Triggered when the file picker button is clicked /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void UIButtonFilePick_Click(object sender, RoutedEventArgs e) { // Pick image file var imageFiles = await GetFilesPickedAsync(); if (imageFiles == null || imageFiles.Count == 0) { return; } await UIParameterDialog.ShowAsync(); UIResultPanel.Items.Clear(); m_imageToProcessTotal = imageFiles.Count; UIProgressMaxValue.Text = m_imageToProcessTotal.ToString(); m_hashTags = ImmutableHashSet.CreateBuilder(new TagEqualityComparer()); // Disable UI UIOptionPanel.IsEnabled = false; UIButtonFilePick.IsEnabled = false; UIHashTagBrowser.IsEnabled = false; UIClearFilterButton.IsEnabled = false; NotifyUser("", NotifyType.ClearMessage); // Start our stopwatch to measure the time it takes to process all of this m_perfWatch.Restart(); m_e2eRunTime = (float)m_perfWatch.ElapsedTicks / Stopwatch.Frequency * 1000f; m_imageProcessedCount = 0; UIFilterPanel.Visibility = Visibility.Collapsed; UIProgressPanel.Visibility = Visibility.Visible; UIExecutionProgressRing.Visibility = Visibility.Visible; UIExecutionProgressRing.IsActive = true; // Process each image selected foreach (var file in imageFiles) { // Take a lock for using a binding if one is available, or wait if not await m_bindingLock.WaitAsync(); // Display a staging content in our UI ResultItemUserControl resultItem = new ResultItemUserControl(); UIResultPanel.Items.Add(resultItem); // Start a task that will Load the frame, display it in the UI, binf it and schedule // execution of the skill against that binding // (fire and forget) var bindingTask = Task.Run(async() => { ConceptTaggerBinding binding = null; // Execute concept tag skill try { // Load the VideoFrame from the image file var frame = await LoadVideoFrameFromFileAsync(file); if (frame == null) { throw new Exception($"Error reading image file: {file.Path}"); } if (!m_bindingQueue.TryDequeue(out binding)) { throw new Exception("Could not access binding"); } var baseTime = (float)m_perfWatch.ElapsedTicks / Stopwatch.Frequency * 1000f; // Bind input image await binding.SetInputImageAsync(frame); // Record bind time for display resultItem.BindTime = (float)m_perfWatch.ElapsedTicks / Stopwatch.Frequency * 1000f - baseTime; // Display image and results await Dispatcher.RunAsync( CoreDispatcherPriority.Normal, async() => { await resultItem.UpdateResultItemImageAsync(frame.SoftwareBitmap); }); // Evaluate binding (fire and forget) var evalTask = Task.Run(() => EvaluateBinding(binding, resultItem)); } catch (Exception ex) { NotifyUser(ex.Message, NotifyType.ErrorMessage); if (binding != null) { m_bindingQueue.Enqueue(binding); } m_bindingLock.Release(); m_imageToProcessTotal--; await UIProgressMaxValue.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => UIProgressMaxValue.Text = m_imageToProcessTotal.ToString()); } }); } // Enable UI UIOptionPanel.IsEnabled = true; UIButtonFilePick.IsEnabled = true; UIHashTagBrowser.IsEnabled = true; UIClearFilterButton.IsEnabled = true; UIFilterPanel.Visibility = Visibility.Visible; UIExecutionProgressRing.Visibility = Visibility.Collapsed; UIExecutionProgressRing.IsActive = false; }
private ImmutableHashSet <INamedTypeSymbol> GetUsedNamedTypes(INamedTypeSymbol namedType, Compilation compilation, CancellationToken cancellationToken, ref bool hasAccessToTypeFromWorkspaceAssemblies) { var builder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>(); foreach (var decl in namedType.DeclaringSyntaxReferences) { var syntax = decl.GetSyntax(cancellationToken); // GetSyntax for VB returns the StatementSyntax instead of BlockSyntax node. syntax = syntax.FirstAncestorOrSelf <SyntaxNode>(node => IsNamedTypeDeclarationBlock(node), ascendOutOfTrivia: false) ?? syntax; var semanticModel = compilation.GetSemanticModel(syntax.SyntaxTree); var nodesToProcess = new Queue <(SyntaxNode node, bool inExecutableCode)>(); nodesToProcess.Enqueue((node: syntax, inExecutableCode: false)); do { (SyntaxNode node, bool inExecutableCode)nodeToProcess = nodesToProcess.Dequeue(); var node = nodeToProcess.node; var inExecutableCode = nodeToProcess.inExecutableCode; if (!inExecutableCode && !ReferenceEquals(node, syntax) && IsNamedTypeDeclarationBlock(node)) { // Skip type member declarations. continue; } if (node is TTypeSyntax typeSyntax) { var typeInfo = semanticModel.GetTypeInfo(typeSyntax, cancellationToken); AddUsedNamedTypeCore(typeInfo.Type, builder, ref hasAccessToTypeFromWorkspaceAssemblies); } if (!inExecutableCode) { var operationBlock = semanticModel.GetOperation(node, cancellationToken); if (operationBlock != null) { // Add used types within executable code in the operation tree. inExecutableCode = true; foreach (var operation in operationBlock.DescendantsAndSelf()) { AddUsedNamedTypeCore(operation.Type, builder, ref hasAccessToTypeFromWorkspaceAssemblies); // Handle static member accesses specially as there is no operation for static type off which the member is accessed. if (operation is IMemberReferenceOperation memberReference && memberReference.Member.IsStatic) { AddUsedNamedTypeCore(memberReference.Member.ContainingType, builder, ref hasAccessToTypeFromWorkspaceAssemblies); } else if (operation is IInvocationOperation invocation && (invocation.TargetMethod.IsStatic || invocation.TargetMethod.IsExtensionMethod)) { AddUsedNamedTypeCore(invocation.TargetMethod.ContainingType, builder, ref hasAccessToTypeFromWorkspaceAssemblies); } } } } foreach (var child in node.ChildNodes()) { nodesToProcess.Enqueue((child, inExecutableCode)); } } while (nodesToProcess.Count != 0);
void countUnaryOperator(IOperation operation, UnaryOperatorKind operatorKind) { countOperator(operation); distinctUnaryOperatorKindsBuilder ??= ImmutableHashSet.CreateBuilder <UnaryOperatorKind>(); distinctUnaryOperatorKindsBuilder.Add(operatorKind); }
void countOperator(IOperation operation) { operatorUsageCounts++; distinctOperatorKindsBuilder ??= ImmutableHashSet.CreateBuilder <OperationKind>(); distinctOperatorKindsBuilder.Add(operation.Kind); }
internal static async Task <NamedTypeMetricData> ComputeAsync(INamedTypeSymbol namedType, SemanticModelProvider semanticModelProvider, CancellationToken cancellationToken) { var coupledTypesBuilder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>(); ImmutableArray <SyntaxReference> declarations = namedType.DeclaringSyntaxReferences; (int cyclomaticComplexity, ComputationalComplexityMetrics computationalComplexityMetrics) = await MetricsHelper.ComputeCoupledTypesAndComplexityExcludingMemberDeclsAsync(declarations, namedType, coupledTypesBuilder, semanticModelProvider, cancellationToken).ConfigureAwait(false); // Compat: Filter out nested types as they are children of most closest containing namespace. var members = namedType.GetMembers().Where(m => m.Kind != SymbolKind.NamedType); #if LEGACY_CODE_METRICS_MODE // Legacy mode skips metrics for field/property/event symbols, and explicitly includes accessors as methods. members = members.Where(m => m.Kind != SymbolKind.Field && m.Kind != SymbolKind.Property && m.Kind != SymbolKind.Event); #else // Filter out accessors as they are children of their associated symbols, for which we generate a separate node. members = members.Where(m => m.Kind != SymbolKind.Method || ((IMethodSymbol)m).AssociatedSymbol == null); #endif ImmutableArray <CodeAnalysisMetricData> children = await ComputeAsync(members, semanticModelProvider, cancellationToken).ConfigureAwait(false); // Heuristic to prevent simple fields (no initializer or simple initializer) from skewing the complexity. ImmutableHashSet <IFieldSymbol> filteredFieldsForComplexity = getFilteredFieldsForComplexity(); int effectiveChildrenCountForComplexity = 0; int singleEffectiveChildMaintainabilityIndex = -1; foreach (CodeAnalysisMetricData child in children) { MetricsHelper.AddCoupledNamedTypes(coupledTypesBuilder, child.CoupledNamedTypes); if (child.Symbol.Kind != SymbolKind.Field || filteredFieldsForComplexity.Contains((IFieldSymbol)child.Symbol)) { singleEffectiveChildMaintainabilityIndex = effectiveChildrenCountForComplexity == 0 && computationalComplexityMetrics.IsDefault ? child.MaintainabilityIndex : -1; effectiveChildrenCountForComplexity++; cyclomaticComplexity += child.CyclomaticComplexity; computationalComplexityMetrics = computationalComplexityMetrics.Union(child.ComputationalComplexityMetrics); } } if (cyclomaticComplexity == 0 && !namedType.IsStatic) { // Empty named type, account for implicit constructor. cyclomaticComplexity = 1; } int depthOfInheritance = CalculateDepthOfInheritance(namedType); long linesOfCode = await MetricsHelper.GetLinesOfCodeAsync(declarations, namedType, semanticModelProvider, cancellationToken).ConfigureAwait(false); int maintainabilityIndex = singleEffectiveChildMaintainabilityIndex != -1 ? singleEffectiveChildMaintainabilityIndex : CalculateMaintainabilityIndex(computationalComplexityMetrics, cyclomaticComplexity, effectiveChildrenCountForComplexity); MetricsHelper.RemoveContainingTypes(namedType, coupledTypesBuilder); return(new NamedTypeMetricData(namedType, maintainabilityIndex, computationalComplexityMetrics, coupledTypesBuilder.ToImmutable(), linesOfCode, cyclomaticComplexity, depthOfInheritance, children)); ImmutableHashSet <IFieldSymbol> getFilteredFieldsForComplexity() { ImmutableHashSet <IFieldSymbol> .Builder?builderOpt = null; var orderedFieldDatas = children.Where(c => c.Symbol.Kind == SymbolKind.Field).OrderBy(c => c.MaintainabilityIndex); var indexThreshold = 99; foreach (CodeAnalysisMetricData fieldData in orderedFieldDatas) { if (fieldData.MaintainabilityIndex > indexThreshold) { break; } builderOpt ??= ImmutableHashSet.CreateBuilder <IFieldSymbol>(); builderOpt.Add((IFieldSymbol)fieldData.Symbol); indexThreshold -= 4; } return(builderOpt?.ToImmutable() ?? ImmutableHashSet <IFieldSymbol> .Empty); } }
protected override void InitializeWorker(CompilationStartAnalysisContext context) { #region "Get All the WellKnown Types and Members" var iformatProviderType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIFormatProvider); var cultureInfoType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemGlobalizationCultureInfo); if (iformatProviderType == null || cultureInfoType == null) { return; } var objectType = context.Compilation.GetSpecialType(SpecialType.System_Object); var stringType = context.Compilation.GetSpecialType(SpecialType.System_String); if (objectType == null || stringType == null) { return; } var charType = context.Compilation.GetSpecialType(SpecialType.System_Char); var boolType = context.Compilation.GetSpecialType(SpecialType.System_Boolean); var guidType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemGuid); var builder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>(); builder.AddIfNotNull(charType); builder.AddIfNotNull(boolType); builder.AddIfNotNull(stringType); builder.AddIfNotNull(guidType); var invariantToStringTypes = builder.ToImmutableHashSet(); var dateTimeType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDateTime); var dateTimeOffsetType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDateTimeOffset); var timeSpanType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTimeSpan); var stringFormatMembers = stringType.GetMembers("Format").OfType <IMethodSymbol>(); var stringFormatMemberWithStringAndObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos( GetParameterInfo(stringType), GetParameterInfo(objectType)); var stringFormatMemberWithStringObjectAndObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos( GetParameterInfo(stringType), GetParameterInfo(objectType), GetParameterInfo(objectType)); var stringFormatMemberWithStringObjectObjectAndObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos( GetParameterInfo(stringType), GetParameterInfo(objectType), GetParameterInfo(objectType), GetParameterInfo(objectType)); var stringFormatMemberWithStringAndParamsObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos( GetParameterInfo(stringType), GetParameterInfo(objectType, isArray: true, arrayRank: 1, isParams: true)); var stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos( GetParameterInfo(iformatProviderType), GetParameterInfo(stringType), GetParameterInfo(objectType, isArray: true, arrayRank: 1, isParams: true)); var currentCultureProperty = cultureInfoType.GetMembers("CurrentCulture").OfType <IPropertySymbol>().FirstOrDefault(); var invariantCultureProperty = cultureInfoType.GetMembers("InvariantCulture").OfType <IPropertySymbol>().FirstOrDefault(); var currentUICultureProperty = cultureInfoType.GetMembers("CurrentUICulture").OfType <IPropertySymbol>().FirstOrDefault(); var installedUICultureProperty = cultureInfoType.GetMembers("InstalledUICulture").OfType <IPropertySymbol>().FirstOrDefault(); var threadType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingThread); var currentThreadCurrentUICultureProperty = threadType?.GetMembers("CurrentUICulture").OfType <IPropertySymbol>().FirstOrDefault(); var activatorType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemActivator); var resourceManagerType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemResourcesResourceManager); var computerInfoType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualBasicDevicesComputerInfo); var installedUICulturePropertyOfComputerInfoType = computerInfoType?.GetMembers("InstalledUICulture").OfType <IPropertySymbol>().FirstOrDefault(); var obsoleteAttributeType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemObsoleteAttribute); #endregion context.RegisterOperationAction(oaContext => { var invocationExpression = (IInvocationOperation)oaContext.Operation; var targetMethod = invocationExpression.TargetMethod; #region "Exceptions" if (targetMethod.IsGenericMethod || targetMethod.ContainingType.IsErrorType() || (activatorType != null && activatorType.Equals(targetMethod.ContainingType)) || (resourceManagerType != null && resourceManagerType.Equals(targetMethod.ContainingType)) || IsValidToStringCall(invocationExpression, invariantToStringTypes, dateTimeType, dateTimeOffsetType, timeSpanType)) { return; } #endregion #region "IFormatProviderAlternateStringRule Only" if (stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter != null && (targetMethod.Equals(stringFormatMemberWithStringAndObjectParameter) || targetMethod.Equals(stringFormatMemberWithStringObjectAndObjectParameter) || targetMethod.Equals(stringFormatMemberWithStringObjectObjectAndObjectParameter) || targetMethod.Equals(stringFormatMemberWithStringAndParamsObjectParameter))) { // Sample message for IFormatProviderAlternateStringRule: Because the behavior of string.Format(string, object) could vary based on the current user's locale settings, // replace this call in IFormatProviderStringTest.M() with a call to string.Format(IFormatProvider, string, params object[]). oaContext.ReportDiagnostic( invocationExpression.Syntax.CreateDiagnostic( IFormatProviderAlternateStringRule, targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat))); return; } #endregion #region "IFormatProviderAlternateStringRule & IFormatProviderAlternateRule" IEnumerable <IMethodSymbol> methodsWithSameNameAsTargetMethod = targetMethod.ContainingType.GetMembers(targetMethod.Name).OfType <IMethodSymbol>().WhereMethodDoesNotContainAttribute(obsoleteAttributeType).ToList(); if (methodsWithSameNameAsTargetMethod.HasMoreThan(1)) { var correctOverloads = methodsWithSameNameAsTargetMethod.GetMethodOverloadsWithDesiredParameterAtLeadingOrTrailing(targetMethod, iformatProviderType).ToList(); // If there are two matching overloads, one with CultureInfo as the first parameter and one with CultureInfo as the last parameter, // report the diagnostic on the overload with CultureInfo as the last parameter, to match the behavior of FxCop. var correctOverload = correctOverloads.FirstOrDefault(overload => overload.Parameters.Last().Type.Equals(iformatProviderType)) ?? correctOverloads.FirstOrDefault(); // Sample message for IFormatProviderAlternateRule: Because the behavior of Convert.ToInt64(string) could vary based on the current user's locale settings, // replace this call in IFormatProviderStringTest.TestMethod() with a call to Convert.ToInt64(string, IFormatProvider). if (correctOverload != null) { oaContext.ReportDiagnostic( invocationExpression.Syntax.CreateDiagnostic( targetMethod.ReturnType.Equals(stringType) ? IFormatProviderAlternateStringRule : IFormatProviderAlternateRule, targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), correctOverload.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat))); } } #endregion #region "UICultureStringRule & UICultureRule" IEnumerable <int> IformatProviderParameterIndices = GetIndexesOfParameterType(targetMethod, iformatProviderType); foreach (var index in IformatProviderParameterIndices) { var argument = invocationExpression.Arguments[index]; if (argument != null && currentUICultureProperty != null && installedUICultureProperty != null && currentThreadCurrentUICultureProperty != null) { var semanticModel = argument.SemanticModel; var symbol = semanticModel.GetSymbolInfo(argument.Value.Syntax, oaContext.CancellationToken).Symbol; if (symbol != null && (symbol.Equals(currentUICultureProperty) || symbol.Equals(installedUICultureProperty) || symbol.Equals(currentThreadCurrentUICultureProperty) || (installedUICulturePropertyOfComputerInfoType != null && symbol.Equals(installedUICulturePropertyOfComputerInfoType)))) { // Sample message // 1. UICultureStringRule - 'TestClass.TestMethod()' passes 'Thread.CurrentUICulture' as the 'IFormatProvider' parameter to 'TestClass.CalleeMethod(string, IFormatProvider)'. // This property returns a culture that is inappropriate for formatting methods. // 2. UICultureRule -'TestClass.TestMethod()' passes 'CultureInfo.CurrentUICulture' as the 'IFormatProvider' parameter to 'TestClass.Callee(IFormatProvider, string)'. // This property returns a culture that is inappropriate for formatting methods. oaContext.ReportDiagnostic( invocationExpression.Syntax.CreateDiagnostic( targetMethod.ReturnType.Equals(stringType) ? UICultureStringRule : UICultureRule, oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), symbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat))); } } } #endregion }, OperationKind.Invocation); }
protected override ComposablePartDefinition?CreatePart(Type partType, bool typeExplicitlyRequested) { Requires.NotNull(partType, nameof(partType)); var partTypeInfo = partType.GetTypeInfo(); if (!typeExplicitlyRequested) { bool isPublic = partType.IsNested ? partTypeInfo.IsNestedPublic : partTypeInfo.IsPublic; if (!this.IsNonPublicSupported && !isPublic) { // Skip non-public types. return(null); } } var declaredProperties = partTypeInfo.GetProperties(BindingFlags.Instance | this.PublicVsNonPublicFlags); var exportingProperties = from member in declaredProperties from export in member.GetAttributes <ExportAttribute>() where member.GetMethod != null // MEFv2 quietly omits exporting properties with no getter select new KeyValuePair <MemberInfo, ExportAttribute>(member, export); var exportedTypes = from export in partTypeInfo.GetAttributes <ExportAttribute>() select new KeyValuePair <MemberInfo, ExportAttribute>(partTypeInfo, export); var exportsByMember = (from export in exportingProperties.Concat(exportedTypes) group export.Value by export.Key into exportsByType select exportsByType).Select(g => new KeyValuePair <MemberInfo, ExportAttribute[]>(g.Key, g.ToArray())).ToArray(); if (exportsByMember.Length == 0) { return(null); } // Check for PartNotDiscoverable only after we've established it's an interesting part. // This optimizes for the fact that most types have no exports, in which case it's not a discoverable // part anyway. Checking for the PartNotDiscoverableAttribute first, which is rarely defined, // doesn't usually pay for itself in terms of short-circuiting. But it does add an extra // attribute to look for that we don't need to find for all the types that have no export attributes either. if (!typeExplicitlyRequested && partTypeInfo.IsAttributeDefined <PartNotDiscoverableAttribute>()) { return(null); } foreach (var exportingMember in exportsByMember) { this.ThrowOnInvalidExportingMember(exportingMember.Key); } TypeRef partTypeRef = TypeRef.Get(partType, this.Resolver); Type? partTypeAsGenericTypeDefinition = partTypeInfo.IsGenericType ? partType.GetGenericTypeDefinition() : null; string?sharingBoundary = null; var sharedAttribute = partTypeInfo.GetFirstAttribute <SharedAttribute>(); if (sharedAttribute != null) { sharingBoundary = sharedAttribute.SharingBoundary ?? string.Empty; } CreationPolicy partCreationPolicy = sharingBoundary != null ? CreationPolicy.Shared : CreationPolicy.NonShared; var allExportsMetadata = ImmutableDictionary.CreateRange(PartCreationPolicyConstraint.GetExportMetadata(partCreationPolicy)); var exportsOnType = ImmutableList.CreateBuilder <ExportDefinition>(); var exportsOnMembers = ImmutableDictionary.CreateBuilder <MemberRef, IReadOnlyCollection <ExportDefinition> >(); var imports = ImmutableList.CreateBuilder <ImportDefinitionBinding>(); foreach (var export in exportsByMember) { var member = export.Key; var memberExportMetadata = allExportsMetadata.AddRange(this.GetExportMetadata(member)); if (member is TypeInfo) { foreach (var exportAttribute in export.Value) { Type exportedType = exportAttribute.ContractType ?? partTypeAsGenericTypeDefinition ?? partType; ExportDefinition exportDefinition = CreateExportDefinition(memberExportMetadata, exportAttribute, exportedType); exportsOnType.Add(exportDefinition); } } else // property { var property = (PropertyInfo)member; Verify.Operation(!partTypeInfo.IsGenericTypeDefinition, Strings.ExportsOnMembersNotAllowedWhenDeclaringTypeGeneric); var exportDefinitions = ImmutableList.CreateBuilder <ExportDefinition>(); foreach (var exportAttribute in export.Value) { Type exportedType = exportAttribute.ContractType ?? property.PropertyType; ExportDefinition exportDefinition = CreateExportDefinition(memberExportMetadata, exportAttribute, exportedType); exportDefinitions.Add(exportDefinition); } exportsOnMembers.Add(MemberRef.Get(member, this.Resolver), exportDefinitions.ToImmutable()); } } foreach (var member in declaredProperties) { var importAttribute = member.GetFirstAttribute <ImportAttribute>(); var importManyAttribute = member.GetFirstAttribute <ImportManyAttribute>(); Requires.Argument(!(importAttribute != null && importManyAttribute != null), "partType", Strings.MemberContainsBothImportAndImportMany, member.Name); var importConstraints = GetImportConstraints(member); ImportDefinition?importDefinition; if (this.TryCreateImportDefinition(ReflectionHelpers.GetMemberType(member), member, importConstraints, out importDefinition)) { var importDefinitionBinding = new ImportDefinitionBinding( importDefinition, TypeRef.Get(partType, this.Resolver), MemberRef.Get(member, this.Resolver), TypeRef.Get(member.PropertyType, this.Resolver), TypeRef.Get(GetImportingSiteTypeWithoutCollection(importDefinition, member.PropertyType), this.Resolver)); imports.Add(importDefinitionBinding); } } MethodInfo?onImportsSatisfied = null; foreach (var method in partTypeInfo.GetMethods(this.PublicVsNonPublicFlags | BindingFlags.Instance)) { if (method.IsAttributeDefined <OnImportsSatisfiedAttribute>()) { Verify.Operation(method.GetParameters().Length == 0, Strings.OnImportsSatisfiedTakeNoParameters); Verify.Operation(onImportsSatisfied == null, Strings.OnlyOneOnImportsSatisfiedMethodIsSupported); onImportsSatisfied = method; } } var importingConstructorParameters = ImmutableList.CreateBuilder <ImportDefinitionBinding>(); var importingCtor = GetImportingConstructor <ImportingConstructorAttribute>(partType, publicOnly: !this.IsNonPublicSupported); Verify.Operation(importingCtor != null, Strings.NoImportingConstructorFound); foreach (var parameter in importingCtor.GetParameters()) { var import = this.CreateImport(parameter, GetImportConstraints(parameter)); if (import.ImportDefinition.Cardinality == ImportCardinality.ZeroOrMore) { Verify.Operation(PartDiscovery.IsImportManyCollectionTypeCreateable(import), Strings.CollectionMustBePublicAndPublicCtorWhenUsingImportingCtor); } importingConstructorParameters.Add(import); } var partMetadata = ImmutableDictionary.CreateBuilder <string, object?>(); foreach (var partMetadataAttribute in partTypeInfo.GetAttributes <PartMetadataAttribute>()) { partMetadata[partMetadataAttribute.Name] = partMetadataAttribute.Value; } var assemblyNamesForMetadataAttributes = ImmutableHashSet.CreateBuilder <AssemblyName>(ByValueEquality.AssemblyName); foreach (var export in exportsByMember) { GetAssemblyNamesFromMetadataAttributes <MetadataAttributeAttribute>(export.Key, assemblyNamesForMetadataAttributes); } return(new ComposablePartDefinition( TypeRef.Get(partType, this.Resolver), partMetadata.ToImmutable(), exportsOnType.ToImmutable(), exportsOnMembers.ToImmutable(), imports.ToImmutable(), sharingBoundary, MethodRef.Get(onImportsSatisfied, this.Resolver), MethodRef.Get(importingCtor, this.Resolver), importingConstructorParameters.ToImmutable(), partCreationPolicy, assemblyNamesForMetadataAttributes)); }
public override IEnumerable <KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> > > GetOutgoingInputs( BasicBlock block, ImmutableHashSet <ValueTag> output) { var domTree = block.Graph.GetAnalysisResult <DominatorTree>(); var preds = block.Graph.GetAnalysisResult <BasicBlockPredecessors>(); // Materialization is always propagated forward. var results = new List <KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> > >(); foreach (var pair in base.GetOutgoingInputs(block, output)) { // Don't materialize values in blocks that are not dominated by the block // that defines those values---those blocks can't use the value, so // materializing values there doesn't make any sense. var matVals = pair.Value .Where(val => domTree.IsDominatedBy( pair.Key, block.Graph.GetValueParent(val))) .ToImmutableHashSet(); results.Add(new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >(pair.Key, matVals)); // An edge from a block to another block that dominates said block indicates // that we've encountered a loop. We absolutely don't want materialization // to happen *inside* a loop. To avoid it, we'll propagate materialization // information to all predecessors of the block. foreach (var targetPred in preds.GetPredecessorsOf(pair.Key)) { results.Add(new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >(pair.Key, matVals)); } } // Propagate materialization backward for basic block parameters. foreach (var pred in preds.GetPredecessorsOf(block)) { foreach (var branch in block.Graph.GetBasicBlock(pred).Flow.Branches) { if (branch.Target != block.Tag) { continue; } var imported = ImmutableHashSet.CreateBuilder <ValueTag>(); foreach (var pair in branch.ZipArgumentsWithParameters(block.Graph)) { if (!output.Contains(pair.Key) || !pair.Value.IsValue) { continue; } imported.Add(pair.Value.ValueOrNull); } if (imported.Count > 0) { results.Add( new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >( pred, imported.ToImmutable())); } } } // Propagate materialized basic block parameters all the way back to the // parameters' definitions. foreach (var value in output) { if (block.Graph.ContainsBlockParameter(value)) { results.Add( new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >( block.Graph.GetValueParent(value), ImmutableHashSet.Create(value))); } } return(results); }
/// <summary> /// Gets the set of assemblies that a generated assembly must be granted the ability to skip visiblity checks for /// in order to access the specified type. /// </summary> /// <param name="typeInfo">The type which may be internal.</param> /// <returns>The set of names of assemblies to skip visibility checks for.</returns> internal static ImmutableHashSet <AssemblyName> GetSkipVisibilityChecksRequirements(TypeInfo typeInfo) { Requires.NotNull(typeInfo, nameof(typeInfo)); var visitedTypes = new HashSet <TypeInfo>(); ImmutableHashSet <AssemblyName> .Builder assembliesDeclaringInternalTypes = ImmutableHashSet.CreateBuilder <AssemblyName>(AssemblyNameEqualityComparer.Instance); CheckForNonPublicTypes(typeInfo, assembliesDeclaringInternalTypes, visitedTypes); // Enumerate members on the interface that we're going to need to implement. foreach (MethodInfo methodInfo in typeInfo.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy)) { CheckForNonPublicTypes(methodInfo.ReturnType.GetTypeInfo(), assembliesDeclaringInternalTypes, visitedTypes); foreach (ParameterInfo parameter in methodInfo.GetParameters()) { CheckForNonPublicTypes(parameter.ParameterType.GetTypeInfo(), assembliesDeclaringInternalTypes, visitedTypes); } } return(assembliesDeclaringInternalTypes.ToImmutable()); }
public static CompositionConfiguration Create(ComposableCatalog catalog) { Requires.NotNull(catalog, nameof(catalog)); // We consider all the parts in the catalog, plus the specially synthesized ones // that should always be applied. var customizedCatalog = catalog.AddParts(AlwaysBundledParts); // Construct our part builders, initialized with all their imports satisfied. // We explicitly use reference equality because ComposablePartDefinition.Equals is too slow, and unnecessary for this. var partBuilders = new Dictionary <ComposablePartDefinition, PartBuilder>(ReferenceEquality <ComposablePartDefinition> .Default); foreach (ComposablePartDefinition partDefinition in customizedCatalog.Parts) { var satisfyingImports = partDefinition.Imports.ToImmutableDictionary(i => i, i => customizedCatalog.GetExports(i.ImportDefinition)); partBuilders.Add(partDefinition, new PartBuilder(partDefinition, satisfyingImports)); } // Create a lookup table that gets all immediate importers for each part. foreach (PartBuilder partBuilder in partBuilders.Values) { // We want to understand who imports each part so we can properly propagate sharing boundaries // for MEFv1 attributed parts. ExportFactory's that create sharing boundaries are an exception // because if a part has a factory that creates new sharing boundaries, the requirement for // that sharing boundary of the child scope shouldn't be interpreted as a requirement for that // same boundary by the parent part. // However, if the ExportFactory does not create sharing boundaries, it does in fact need all // the same sharing boundaries as the parts it constructs. var importedPartsExcludingFactoriesWithSharingBoundaries = (from entry in partBuilder.SatisfyingExports where !entry.Key.IsExportFactory || entry.Key.ImportDefinition.ExportFactorySharingBoundaries.Count == 0 from export in entry.Value select export.PartDefinition).Distinct(ReferenceEquality <ComposablePartDefinition> .Default); foreach (var importedPartDefinition in importedPartsExcludingFactoriesWithSharingBoundaries) { var importedPartBuilder = partBuilders[importedPartDefinition]; importedPartBuilder.ReportImportingPart(partBuilder); } } // Propagate sharing boundaries defined on parts to all importers (transitive closure). foreach (PartBuilder partBuilder in partBuilders.Values) { partBuilder.ApplySharingBoundary(); } var sharingBoundaryOverrides = ComputeInferredSharingBoundaries(partBuilders.Values); // Build up our set of composed parts. var partsBuilder = ImmutableHashSet.CreateBuilder <ComposedPart>(); foreach (var partBuilder in partBuilders.Values) { var composedPart = new ComposedPart(partBuilder.PartDefinition, partBuilder.SatisfyingExports, partBuilder.RequiredSharingBoundaries.ToImmutableHashSet()); partsBuilder.Add(composedPart); } var parts = partsBuilder.ToImmutable(); // Determine which metadata views to use for each applicable import. var metadataViewsAndProviders = GetMetadataViewProvidersMap(customizedCatalog); // Validate configuration. var errors = new List <ComposedPartDiagnostic>(); foreach (var part in parts) { errors.AddRange(part.Validate(metadataViewsAndProviders)); } // Detect loops of all non-shared parts. errors.AddRange(FindLoops(parts)); // If errors are found, re-validate the salvaged parts in case there are parts whose dependencies are affected by the initial errors if (errors.Count > 0) { // Set salvaged parts to current catalog in case there are no errors var salvagedParts = parts; var salvagedPartDefinitions = catalog.Parts; List <ComposedPartDiagnostic> previousErrors = errors; Stack <IReadOnlyCollection <ComposedPartDiagnostic> > stackedErrors = new Stack <IReadOnlyCollection <ComposedPartDiagnostic> >(); // While we still find errors we validate the exports so that we remove all dependency failures while (previousErrors.Count > 0) { stackedErrors.Push(previousErrors); // Get the salvaged parts var invalidParts = previousErrors.SelectMany(error => error.Parts).ToList(); if (invalidParts.Count == 0) { // If we can't identify the faulty parts but we still have errors, we have to just throw. throw new CompositionFailedException(Strings.FailStableComposition, ImmutableStack.Create <IReadOnlyCollection <ComposedPartDiagnostic> >(errors)); } salvagedParts = salvagedParts.Except(invalidParts); var invalidPartDefinitionsSet = new HashSet <ComposablePartDefinition>(invalidParts.Select(p => p.Definition)); salvagedPartDefinitions = salvagedPartDefinitions.Except(invalidPartDefinitionsSet); // Empty the list so that we create a new one only with the new set of errors previousErrors = new List <ComposedPartDiagnostic>(); foreach (var part in salvagedParts) { previousErrors.AddRange(part.RemoveSatisfyingExports(invalidPartDefinitionsSet)); } } var finalCatalog = ComposableCatalog.Create(catalog.Resolver).AddParts(salvagedPartDefinitions); // We want the first found errors to come out of the stack first, so we need to invert the current stack. var compositionErrors = ImmutableStack.CreateRange(stackedErrors); var configuration = new CompositionConfiguration( finalCatalog, salvagedParts, metadataViewsAndProviders, compositionErrors, sharingBoundaryOverrides); return(configuration); } return(new CompositionConfiguration( catalog, parts, metadataViewsAndProviders, ImmutableStack <IReadOnlyCollection <ComposedPartDiagnostic> > .Empty, sharingBoundaryOverrides)); }
public TrackedPropertiesBuilder() { this.trackedPropertiesBuilder = ImmutableHashSet.CreateBuilder <string>(); }
void countOperand(ISymbol symbol) { symbolUsageCounts++; distinctReferencedSymbolsBuilder ??= ImmutableHashSet.CreateBuilder <ISymbol>(); distinctReferencedSymbolsBuilder.Add(symbol); }
private static async Task <RenameLocations> FindLocationsInCurrentProcessAsync( ISymbol symbol, Solution solution, RenameOptionSet optionSet, CancellationToken cancellationToken ) { Contract.ThrowIfNull(symbol); using (Logger.LogBlock(FunctionId.Rename_AllRenameLocations, cancellationToken)) { symbol = await ReferenceProcessing .FindDefinitionSymbolAsync(symbol, solution, cancellationToken) .ConfigureAwait(false); // First, find the direct references just to the symbol being renamed. var originalSymbolResult = await AddLocationsReferenceSymbolsAsync( symbol, solution, cancellationToken ) .ConfigureAwait(false); // Next, find references to overloads, if the user has asked to rename those as well. var overloadsResult = await GetOverloadsAsync( symbol, solution, optionSet, cancellationToken ) .ConfigureAwait(false); // Finally, include strings/comments if that's what the user wants. var(strings, comments) = await ReferenceProcessing .GetRenamableLocationsInStringsAndCommentsAsync( symbol, solution, originalSymbolResult.Locations, optionSet.RenameInStrings, optionSet.RenameInComments, cancellationToken ) .ConfigureAwait(false); var mergedLocations = ImmutableHashSet.CreateBuilder <RenameLocation>(); using var _1 = ArrayBuilder <ISymbol> .GetInstance(out var mergedReferencedSymbols); using var _2 = ArrayBuilder <ReferenceLocation> .GetInstance( out var mergedImplicitLocations ); mergedLocations.AddRange(strings.NullToEmpty()); mergedLocations.AddRange(comments.NullToEmpty()); var renameMethodGroupReferences = optionSet.RenameOverloads || !GetOverloadedSymbols(symbol).Any(); foreach (var result in overloadsResult.Concat(originalSymbolResult)) { mergedLocations.AddRange( renameMethodGroupReferences ? result.Locations : result.Locations.Where( x => x.CandidateReason != CandidateReason.MemberGroup ) ); mergedImplicitLocations.AddRange(result.ImplicitLocations); mergedReferencedSymbols.AddRange(result.ReferencedSymbols); } return(new RenameLocations( symbol, solution, optionSet, new SearchResult( mergedLocations.ToImmutable(), mergedImplicitLocations.ToImmutable(), mergedReferencedSymbols.ToImmutable() ) )); } }
public static ComputationalComplexityMetrics Compute(IOperation operationBlock) { bool hasSymbolInitializer = false; long executableLinesOfCode = 0; long operatorUsageCounts = 0; long symbolUsageCounts = 0; long constantUsageCounts = 0; ImmutableHashSet <OperationKind> .Builder? distinctOperatorKindsBuilder = null; ImmutableHashSet <BinaryOperatorKind> .Builder?distinctBinaryOperatorKindsBuilder = null; ImmutableHashSet <UnaryOperatorKind> .Builder? distinctUnaryOperatorKindsBuilder = null; ImmutableHashSet <CaseKind> .Builder? distinctCaseKindsBuilder = null; ImmutableHashSet <ISymbol> .Builder? distinctReferencedSymbolsBuilder = null; ImmutableHashSet <object> .Builder? distinctReferencedConstantsBuilder = null; // Explicit user applied attribute. if (operationBlock.Kind == OperationKind.None && hasAnyExplicitExpression(operationBlock)) { executableLinesOfCode += 1; } foreach (var operation in operationBlock.Descendants()) { executableLinesOfCode += getExecutableLinesOfCode(operation, ref hasSymbolInitializer); if (operation.IsImplicit) { continue; } #if LEGACY_CODE_METRICS_MODE // Legacy mode does not account for code within lambdas/local functions for code metrics. if (operation.IsWithinLambdaOrLocalFunction(out _)) { continue; } #endif if (operation.ConstantValue.HasValue) { constantUsageCounts++; distinctReferencedConstantsBuilder ??= ImmutableHashSet.CreateBuilder <object>(); distinctReferencedConstantsBuilder.Add(operation.ConstantValue.Value ?? s_nullConstantPlaceholder); continue; } switch (operation.Kind) { // Symbol references. case OperationKind.LocalReference: countOperand(((ILocalReferenceOperation)operation).Local); continue; case OperationKind.ParameterReference: countOperand(((IParameterReferenceOperation)operation).Parameter); continue; case OperationKind.FieldReference: case OperationKind.MethodReference: case OperationKind.PropertyReference: case OperationKind.EventReference: countOperator(operation); countOperand(((IMemberReferenceOperation)operation).Member); continue; // Symbol initializers. case OperationKind.FieldInitializer: foreach (var field in ((IFieldInitializerOperation)operation).InitializedFields) { countOperator(operation); countOperand(field); } continue; case OperationKind.PropertyInitializer: foreach (var property in ((IPropertyInitializerOperation)operation).InitializedProperties) { countOperator(operation); countOperand(property); } continue; case OperationKind.ParameterInitializer: countOperator(operation); countOperand(((IParameterInitializerOperation)operation).Parameter); continue; case OperationKind.VariableInitializer: countOperator(operation); // We count the operand in the variable declarator. continue; case OperationKind.VariableDeclarator: var variableDeclarator = (IVariableDeclaratorOperation)operation; if (variableDeclarator.GetVariableInitializer() != null) { countOperand(variableDeclarator.Symbol); } continue; // Invocations and Object creations. case OperationKind.Invocation: countOperator(operation); var invocation = (IInvocationOperation)operation; if (!invocation.TargetMethod.ReturnsVoid) { countOperand(invocation.TargetMethod); } continue; case OperationKind.ObjectCreation: countOperator(operation); countOperand(((IObjectCreationOperation)operation).Constructor); continue; case OperationKind.DelegateCreation: case OperationKind.AnonymousObjectCreation: case OperationKind.TypeParameterObjectCreation: case OperationKind.DynamicObjectCreation: case OperationKind.DynamicInvocation: countOperator(operation); continue; // Operators with special operator kinds. case OperationKind.BinaryOperator: countBinaryOperator(operation, ((IBinaryOperation)operation).OperatorKind); continue; case OperationKind.CompoundAssignment: countBinaryOperator(operation, ((ICompoundAssignmentOperation)operation).OperatorKind); continue; case OperationKind.TupleBinaryOperator: countBinaryOperator(operation, ((ITupleBinaryOperation)operation).OperatorKind); continue; case OperationKind.UnaryOperator: countUnaryOperator(operation, ((IUnaryOperation)operation).OperatorKind); continue; case OperationKind.CaseClause: var caseClauseOperation = (ICaseClauseOperation)operation; distinctCaseKindsBuilder ??= ImmutableHashSet.CreateBuilder <CaseKind>(); distinctCaseKindsBuilder.Add(caseClauseOperation.CaseKind); if (caseClauseOperation.CaseKind == CaseKind.Relational) { countBinaryOperator(operation, ((IRelationalCaseClauseOperation)operation).Relation); } else { countOperator(operation); } continue; // Other common operators. case OperationKind.Increment: case OperationKind.Decrement: case OperationKind.SimpleAssignment: case OperationKind.DeconstructionAssignment: case OperationKind.EventAssignment: case OperationKind.Coalesce: case OperationKind.ConditionalAccess: case OperationKind.Conversion: case OperationKind.ArrayElementReference: case OperationKind.Await: case OperationKind.NameOf: case OperationKind.SizeOf: case OperationKind.TypeOf: case OperationKind.AddressOf: case OperationKind.MemberInitializer: case OperationKind.IsType: case OperationKind.IsPattern: case OperationKind.Parenthesized: countOperator(operation); continue; // Following are considered operators for now, but we may want to revisit. case OperationKind.ArrayCreation: case OperationKind.ArrayInitializer: case OperationKind.DynamicMemberReference: case OperationKind.DynamicIndexerAccess: case OperationKind.Tuple: case OperationKind.Lock: case OperationKind.Using: case OperationKind.Throw: case OperationKind.RaiseEvent: case OperationKind.InterpolatedString: countOperator(operation); continue; // Return value. case OperationKind.Return: case OperationKind.YieldBreak: case OperationKind.YieldReturn: if (((IReturnOperation)operation).ReturnedValue != null) { countOperator(operation); } continue; } } return(Create( executableLinesOfCode, operatorUsageCounts, symbolUsageCounts, constantUsageCounts, hasSymbolInitializer, distinctOperatorKindsBuilder != null ? distinctOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <OperationKind> .Empty, distinctBinaryOperatorKindsBuilder != null ? distinctBinaryOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <BinaryOperatorKind> .Empty, distinctUnaryOperatorKindsBuilder != null ? distinctUnaryOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <UnaryOperatorKind> .Empty, distinctCaseKindsBuilder != null ? distinctCaseKindsBuilder.ToImmutable() : ImmutableHashSet <CaseKind> .Empty, distinctReferencedSymbolsBuilder != null ? distinctReferencedSymbolsBuilder.ToImmutable() : ImmutableHashSet <ISymbol> .Empty, distinctReferencedConstantsBuilder != null ? distinctReferencedConstantsBuilder.ToImmutable() : ImmutableHashSet <object> .Empty));
private Tuple <ITargetBlock <Type>, Task <DiscoveredParts> > CreateDiscoveryBlockChain(bool typeExplicitlyRequested, IProgress <DiscoveryProgress>?progress, CancellationToken cancellationToken) { string status = Strings.ScanningMEFAssemblies; int typesScanned = 0; var transformBlock = new TransformBlock <Type, object?>( type => { try { return(this.CreatePart(type, typeExplicitlyRequested)); } catch (Exception ex) { return(new PartDiscoveryException(string.Format(CultureInfo.CurrentCulture, Strings.FailureWhileScanningType, type.FullName), ex) { AssemblyPath = type.GetTypeInfo().Assembly.Location, ScannedType = type }); } }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Debugger.IsAttached ? 1 : Environment.ProcessorCount, CancellationToken = cancellationToken, MaxMessagesPerTask = 10, BoundedCapacity = 100, }); var parts = ImmutableHashSet.CreateBuilder <ComposablePartDefinition>(); var errors = ImmutableList.CreateBuilder <PartDiscoveryException>(); var aggregatingBlock = new ActionBlock <object?>(partOrException => { var part = partOrException as ComposablePartDefinition; var error = partOrException as PartDiscoveryException; Debug.Assert(partOrException is Exception == partOrException is PartDiscoveryException, "Wrong exception type returned."); if (part != null) { parts.Add(part); } else if (error != null) { errors.Add(error); } progress.ReportNullSafe(new DiscoveryProgress(++typesScanned, 0, status)); }); transformBlock.LinkTo(aggregatingBlock, new DataflowLinkOptions { PropagateCompletion = true }); var tcs = new TaskCompletionSource <DiscoveredParts>(); Task.Run(async delegate { try { await aggregatingBlock.Completion.ConfigureAwait(false); tcs.SetResult(new DiscoveredParts(parts.ToImmutable(), errors.ToImmutable())); } catch (Exception ex) { tcs.SetException(ex); } }); return(Tuple.Create <ITargetBlock <Type>, Task <DiscoveredParts> >(transformBlock, tcs.Task)); }
private static TaintedDataConfig Create(Compilation compilation) { WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); using PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SourceInfo> > > sourceSymbolMapBuilder = PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SourceInfo> > > .GetInstance(); using PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > sanitizerSymbolMapBuilder = PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > .GetInstance(); using PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SinkInfo> > > sinkSymbolMapBuilder = PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SinkInfo> > > .GetInstance(); // For tainted data rules with the same set of sources, we'll reuse the same TaintedDataSymbolMap<SourceInfo> instance. // Same for sanitizers. using PooledDictionary <ImmutableHashSet <SourceInfo>, Lazy <TaintedDataSymbolMap <SourceInfo> > > sourcesToSymbolMap = PooledDictionary <ImmutableHashSet <SourceInfo>, Lazy <TaintedDataSymbolMap <SourceInfo> > > .GetInstance(); using PooledDictionary <ImmutableHashSet <SanitizerInfo>, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > sanitizersToSymbolMap = PooledDictionary <ImmutableHashSet <SanitizerInfo>, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > .GetInstance(); // Build a mapping of (sourceSet, sanitizerSet) -> (sinkKinds, sinkSet), so we'll reuse the same TaintedDataSymbolMap<SinkInfo> instance. using PooledDictionary <(ImmutableHashSet <SourceInfo> SourceInfos, ImmutableHashSet <SanitizerInfo> SanitizerInfos), (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)> sourceSanitizersToSinks = PooledDictionary <(ImmutableHashSet <SourceInfo> SourceInfos, ImmutableHashSet <SanitizerInfo> SanitizerInfos), (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)> .GetInstance(); // Using LazyThreadSafetyMode.ExecutionAndPublication to avoid instantiating multiple times. foreach (SinkKind sinkKind in Enum.GetValues(typeof(SinkKind))) { ImmutableHashSet <SourceInfo> sources = GetSourceInfos(sinkKind); if (!sourcesToSymbolMap.TryGetValue(sources, out Lazy <TaintedDataSymbolMap <SourceInfo> > lazySourceSymbolMap)) { lazySourceSymbolMap = new Lazy <TaintedDataSymbolMap <SourceInfo> >( () => { return(new TaintedDataSymbolMap <SourceInfo>(wellKnownTypeProvider, sources)); }, LazyThreadSafetyMode.ExecutionAndPublication); sourcesToSymbolMap.Add(sources, lazySourceSymbolMap); } sourceSymbolMapBuilder.Add(sinkKind, lazySourceSymbolMap); ImmutableHashSet <SanitizerInfo> sanitizers = GetSanitizerInfos(sinkKind); if (!sanitizersToSymbolMap.TryGetValue(sanitizers, out Lazy <TaintedDataSymbolMap <SanitizerInfo> > lazySanitizerSymbolMap)) { lazySanitizerSymbolMap = new Lazy <TaintedDataSymbolMap <SanitizerInfo> >( () => { return(new TaintedDataSymbolMap <SanitizerInfo>(wellKnownTypeProvider, sanitizers)); }, LazyThreadSafetyMode.ExecutionAndPublication); sanitizersToSymbolMap.Add(sanitizers, lazySanitizerSymbolMap); } sanitizerSymbolMapBuilder.Add(sinkKind, lazySanitizerSymbolMap); ImmutableHashSet <SinkInfo> sinks = GetSinkInfos(sinkKind); if (!sourceSanitizersToSinks.TryGetValue((sources, sanitizers), out (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)sinksPair)) { sinksPair = (ImmutableHashSet.CreateBuilder <SinkKind>(), ImmutableHashSet.CreateBuilder <SinkInfo>()); sourceSanitizersToSinks.Add((sources, sanitizers), sinksPair); } sinksPair.SinkKinds.Add(sinkKind); sinksPair.SinkInfos.UnionWith(sinks); } foreach (KeyValuePair <(ImmutableHashSet <SourceInfo> SourceInfos, ImmutableHashSet <SanitizerInfo> SanitizerInfos), (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)> kvp in sourceSanitizersToSinks) { ImmutableHashSet <SinkInfo> sinks = kvp.Value.SinkInfos.ToImmutable(); Lazy <TaintedDataSymbolMap <SinkInfo> > lazySinkSymbolMap = new Lazy <TaintedDataSymbolMap <SinkInfo> >( () => { return(new TaintedDataSymbolMap <SinkInfo>(wellKnownTypeProvider, sinks)); }, LazyThreadSafetyMode.ExecutionAndPublication); foreach (SinkKind sinkKind in kvp.Value.SinkKinds) { sinkSymbolMapBuilder.Add(sinkKind, lazySinkSymbolMap); } } return(new TaintedDataConfig( wellKnownTypeProvider, sourceSymbolMapBuilder.ToImmutableDictionary(), sanitizerSymbolMapBuilder.ToImmutableDictionary(), sinkSymbolMapBuilder.ToImmutableDictionary())); }
internal static Options Create(string[] args) { string analyzerPath = null; string solutionPath = null; var builder = ImmutableHashSet.CreateBuilder <string>(); var refactoringBuilder = ImmutableHashSet.CreateBuilder <string>(); bool runConcurrent = false; bool reportSuppressedDiagnostics = false; bool applyChanges = false; bool showStats = false; bool showCompilerDiagnostics = false; bool useAll = false; int iterations = 1; bool testDocuments = false; Func <string, bool> testDocumentMatch = _ => true; int testDocumentIterations = 10; string logFileName = null; string profileRoot = null; var usePersistentStorage = false; var analysisScope = BackgroundAnalysisScope.Default; var incrementalAnalyzerNames = ImmutableList.CreateBuilder <string>(); int i = 0; while (i < args.Length) { var arg = args[i++]; string ReadValue() => (i < args.Length) ? args[i++] : throw new InvalidDataException($"Missing value for option {arg}"); switch (arg) { case "/all": useAll = true; break; case "/stats": showStats = true; break; case "/compilerStats": showCompilerDiagnostics = true; break; case "/concurrent": runConcurrent = true; break; case "/editperf": testDocuments = true; break; case var _ when arg.StartsWith("/editperf:"): testDocuments = true; var expression = new Regex(arg.Substring("/editperf:".Length), RegexOptions.Compiled | RegexOptions.IgnoreCase); testDocumentMatch = documentPath => expression.IsMatch(documentPath); break; case var _ when arg.StartsWith("/edititer:"): testDocumentIterations = int.Parse(arg.Substring("/edititer:".Length)); break; case var _ when arg.StartsWith("/iter:"): iterations = int.Parse(arg.Substring("/iter:".Length)); break; case "/suppressed": reportSuppressedDiagnostics = true; break; case "/apply": applyChanges = true; break; case "/a": builder.Add(ReadValue()); break; case "/refactor": refactoringBuilder.Add(ReadValue()); break; case "/log": logFileName = ReadValue(); break; case "/profileroot": profileRoot = ReadValue(); break; case "/persist": usePersistentStorage = true; break; case "/fsa": analysisScope = BackgroundAnalysisScope.FullSolution; break; case "/ia": incrementalAnalyzerNames.Add(ReadValue()); break; default: if (analyzerPath == null) { analyzerPath = arg; } else if (solutionPath == null) { solutionPath = arg; } else { throw new InvalidDataException((arg.StartsWith("/", StringComparison.Ordinal) ? "Unrecognized option " + arg : "Unrecognized parameter " + arg)); } break; } } if (analyzerPath == null) { throw new InvalidDataException("Missing analyzer path"); } if (solutionPath == null) { throw new InvalidDataException("Missing solution path"); } return(new Options( analyzerPath: analyzerPath, solutionPath: solutionPath, analyzerIds: builder.ToImmutableHashSet(), refactoringNodes: refactoringBuilder.ToImmutableHashSet(), runConcurrent: runConcurrent, reportSuppressedDiagnostics: reportSuppressedDiagnostics, applyChanges: applyChanges, showStats: showStats, showCompilerDiagnostics: showCompilerDiagnostics, useAll: useAll, iterations: iterations, testDocuments: testDocuments, testDocumentMatch: testDocumentMatch, testDocumentIterations: testDocumentIterations, logFileName: logFileName, profileRoot: profileRoot, usePersistentStorage: usePersistentStorage, analysisScope: analysisScope, incrementalAnalyzerNames: incrementalAnalyzerNames.ToImmutable())); }
public void DebuggerAttributesValid() { DebuggerAttributes.ValidateDebuggerDisplayReferences(ImmutableHashSet.CreateBuilder <int>()); }
protected override async Task <Solution> GetChangedSolutionAsync(CancellationToken cancellationToken) { var updatedPublicSurfaceAreaText = new List <KeyValuePair <DocumentId, SourceText> >(); foreach (KeyValuePair <Project, ImmutableArray <Diagnostic> > pair in _diagnosticsToFix) { Project project = pair.Key; ImmutableArray <Diagnostic> diagnostics = pair.Value; TextDocument publicSurfaceAreaAdditionalDocument = GetPublicSurfaceAreaDocument(project); if (publicSurfaceAreaAdditionalDocument == null) { continue; } SourceText sourceText = await publicSurfaceAreaAdditionalDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); IEnumerable <IGrouping <SyntaxTree, Diagnostic> > groupedDiagnostics = diagnostics .Where(d => d.Location.IsInSource) .GroupBy(d => d.Location.SourceTree); var newSymbolNames = new List <string>(); var symbolNamesToRemoveBuilder = ImmutableHashSet.CreateBuilder <string>(); foreach (IGrouping <SyntaxTree, Diagnostic> grouping in groupedDiagnostics) { Document document = project.GetDocument(grouping.Key); if (document == null) { continue; } SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); foreach (Diagnostic diagnostic in grouping) { string publicSurfaceAreaSymbolName = diagnostic.Properties[DeclarePublicAPIAnalyzer.PublicApiNamePropertyBagKey]; newSymbolNames.Add(publicSurfaceAreaSymbolName); string siblingNamesToRemove = diagnostic.Properties[DeclarePublicAPIAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagKey]; if (siblingNamesToRemove.Length > 0) { var namesToRemove = siblingNamesToRemove.Split(DeclarePublicAPIAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagValueSeparator.ToCharArray()); foreach (var nameToRemove in namesToRemove) { symbolNamesToRemoveBuilder.Add(nameToRemove); } } } } var symbolNamesToRemove = symbolNamesToRemoveBuilder.ToImmutable(); // We shouldn't be attempting to remove any symbol name, while also adding it. Debug.Assert(newSymbolNames.All(newSymbolName => !symbolNamesToRemove.Contains(newSymbolName))); SourceText newSourceText = AddSymbolNamesToSourceText(sourceText, newSymbolNames); newSourceText = RemoveSymbolNamesFromSourceText(newSourceText, symbolNamesToRemove); updatedPublicSurfaceAreaText.Add(new KeyValuePair <DocumentId, SourceText>(publicSurfaceAreaAdditionalDocument.Id, newSourceText)); } Solution newSolution = _solution; foreach (KeyValuePair <DocumentId, SourceText> pair in updatedPublicSurfaceAreaText) { newSolution = newSolution.WithAdditionalDocumentText(pair.Key, pair.Value); } return(newSolution); }
private static void OnCompilationStart(CompilationStartAnalysisContext context) { ImmutableHashSet <IMethodSymbol> .Builder syncMethods = ImmutableHashSet.CreateBuilder <IMethodSymbol>(); ImmutableHashSet <IMethodSymbol> .Builder asyncMethods = ImmutableHashSet.CreateBuilder <IMethodSymbol>(); INamedTypeSymbol? namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemLinqEnumerable); IEnumerable <IMethodSymbol>?methods = namedType?.GetMembers(Count).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(syncMethods, methods); methods = namedType?.GetMembers(LongCount).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(syncMethods, methods); namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemLinqQueryable); methods = namedType?.GetMembers(Count).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(syncMethods, methods); methods = namedType?.GetMembers(LongCount).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(syncMethods, methods); namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftEntityFrameworkCoreEntityFrameworkQueryableExtensions); methods = namedType?.GetMembers(CountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(asyncMethods, methods); methods = namedType?.GetMembers(LongCountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(asyncMethods, methods); namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDataEntityQueryableExtensions); methods = namedType?.GetMembers(CountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(asyncMethods, methods); methods = namedType?.GetMembers(LongCountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2); AddIfNotNull(asyncMethods, methods); // Allowed types that should report a CA1836 diagnosis given that there is proven benefit on doing so. ImmutableHashSet <ITypeSymbol> .Builder allowedTypesBuilder = ImmutableHashSet.CreateBuilder <ITypeSymbol>(); namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentBag1); allowedTypesBuilder.AddIfNotNull(namedType); namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentDictionary2); allowedTypesBuilder.AddIfNotNull(namedType); namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentQueue1); allowedTypesBuilder.AddIfNotNull(namedType); namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentStack1); allowedTypesBuilder.AddIfNotNull(namedType); ImmutableHashSet <ITypeSymbol> allowedTypesForCA1836 = allowedTypesBuilder.ToImmutable(); if (syncMethods.Count > 0 || asyncMethods.Count > 0) { context.RegisterOperationAction(operationContext => AnalyzeInvocationOperation( operationContext, syncMethods.ToImmutable(), asyncMethods.ToImmutable(), allowedTypesForCA1836), OperationKind.Invocation); } if (!allowedTypesForCA1836.IsEmpty) { context.RegisterOperationAction(operationContext => AnalyzePropertyReference( operationContext, allowedTypesForCA1836), OperationKind.PropertyReference); }
protected override ImmutableHashSet <T> .Builder Create(int count, MessagePackSerializerOptions options) { return(ImmutableHashSet.CreateBuilder <T>(options.Security.GetEqualityComparer <T>())); }