private bool IsDiagnosticSuppressed(string id, ISymbol symbol, out SuppressMessageInfo info) { Debug.Assert(id != null); Debug.Assert(symbol != null); if (symbol.Kind == SymbolKind.Namespace) { // Suppressions associated with namespace symbols only apply to namespace declarations themselves // and any syntax nodes immediately contained therein, not to nodes attached to any other symbols. // Diagnostics those nodes will be filtered by location, not by associated symbol. info = default(SuppressMessageInfo); return(false); } if (symbol.Kind == SymbolKind.Method) { ISymbol associated = ((IMethodSymbol)symbol).AssociatedSymbol; if (associated != null && (IsDiagnosticLocallySuppressed(id, associated, out info) || IsDiagnosticGloballySuppressed(id, associated, out info))) { return(true); } } if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info)) { return(true); } // Check for suppression on parent symbol ISymbol parent = symbol.ContainingSymbol; return(parent != null && IsDiagnosticSuppressed(id, parent, out info)); }
private static void AddOrUpdate(SuppressMessageInfo info, IDictionary <string, SuppressMessageInfo> builder) { // TODO: How should we deal with multiple SuppressMessage attributes, with different suppression info/states? // For now, we just pick the last attribute, if not suppressed. if (!builder.TryGetValue(info.Id, out SuppressMessageInfo currentInfo)) { builder[info.Id] = info; } }
private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info, ISymbol symbolOpt = null) { if (symbolOpt != null && IsDiagnosticSuppressed(diagnostic.Id, symbolOpt, out info)) { return(true); } return(IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, out info)); }
public bool HasGlobalSymbolSuppression(ISymbol symbol, string id, out SuppressMessageInfo info) { Debug.Assert(symbol != null); if (_globalSymbolSuppressions.TryGetValue(symbol, out Dictionary <string, SuppressMessageInfo> suppressions) && suppressions.TryGetValue(id, out info)) { return(true); } info = default(SuppressMessageInfo); return(false); }
private bool IsDiagnosticLocallySuppressed( string id, ISymbol symbol, out SuppressMessageInfo info ) { var suppressions = _localSuppressionsBySymbol.GetOrAdd( symbol, this.DecodeLocalSuppressMessageAttributes ); return(suppressions.TryGetValue(id, out info)); }
public void AddGlobalSymbolSuppression(ISymbol symbol, SuppressMessageInfo info) { Dictionary<string, SuppressMessageInfo> suppressions; if (_globalSymbolSuppressions.TryGetValue(symbol, out suppressions)) { AddOrUpdate(info, suppressions); } else { suppressions = new Dictionary<string, SuppressMessageInfo>() {{ info.Id, info }}; _globalSymbolSuppressions.Add(symbol, suppressions); } }
public bool HasGlobalSymbolSuppression(ISymbol symbol, string id, out SuppressMessageInfo info) { Debug.Assert(symbol != null); Dictionary<string, SuppressMessageInfo> suppressions; if (_globalSymbolSuppressions.TryGetValue(symbol, out suppressions) && suppressions.TryGetValue(id, out info)) { return true; } info = default(SuppressMessageInfo); return false; }
public void AddGlobalSymbolSuppression(ISymbol symbol, SuppressMessageInfo info) { if (_globalSymbolSuppressions.TryGetValue(symbol, out Dictionary <string, SuppressMessageInfo> suppressions)) { AddOrUpdate(info, suppressions); } else { suppressions = new Dictionary <string, SuppressMessageInfo>() { { info.Id, info } }; _globalSymbolSuppressions.Add(symbol, suppressions); } }
private bool IsDiagnosticSuppressed(string id, Location location, out SuppressMessageInfo info) { Debug.Assert(id != null); Debug.Assert(location != null); info = default(SuppressMessageInfo); if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, info: out info)) { return(true); } // Walk up the syntax tree checking for suppression by any declared symbols encountered if (location.IsInSource) { SemanticModel model = _compilation.GetSemanticModel(location.SourceTree); bool inImmediatelyContainingSymbol = true; for (SyntaxNode node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true); node != null; node = node.Parent) { ImmutableArray <ISymbol> declaredSymbols = model.GetDeclaredSymbolsForNode(node); Debug.Assert(declaredSymbols != null); foreach (ISymbol symbol in declaredSymbols) { if (symbol.Kind == SymbolKind.Namespace) { // Special case: Only suppress syntax diagnostics in namespace declarations if the namespace is the closest containing symbol. // In other words, only apply suppression to the immediately containing namespace declaration and not to its children or parents. return(inImmediatelyContainingSymbol && IsDiagnosticGloballySuppressed(id, symbol, out info)); } else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info)) { return(true); } inImmediatelyContainingSymbol = false; } } } return(false); }
private bool IsDiagnosticGloballySuppressed( string id, ISymbol?symbolOpt, bool isImmediatelyContainingSymbol, out SuppressMessageInfo info ) { var globalSuppressions = this.DecodeGlobalSuppressMessageAttributes(); return(globalSuppressions.HasCompilationWideSuppression(id, out info) || symbolOpt != null && globalSuppressions.HasGlobalSymbolSuppression( symbolOpt, id, isImmediatelyContainingSymbol, out info )); }
private static bool TryDecodeSuppressMessageAttributeData( AttributeData attribute, out SuppressMessageInfo info ) { info = default(SuppressMessageInfo); // We need at least the Category and Id to decode the diagnostic to suppress. // The only SuppressMessageAttribute constructor requires those two parameters. if (attribute.CommonConstructorArguments.Length < 2) { return(false); } // Ignore the category parameter because it does not identify the diagnostic // and category information can be obtained from diagnostics themselves. info.Id = attribute.CommonConstructorArguments[1].ValueInternal as string; if (info.Id == null) { return(false); } // Allow an optional human-readable descriptive name on the end of an Id. // See http://msdn.microsoft.com/en-us/library/ms244717.aspx var separatorIndex = info.Id.IndexOf(':'); if (separatorIndex != -1) { info.Id = info.Id.Remove(separatorIndex); } info.Scope = attribute.DecodeNamedArgument <string>("Scope", SpecialType.System_String); info.Target = attribute.DecodeNamedArgument <string>( "Target", SpecialType.System_String ); info.MessageId = attribute.DecodeNamedArgument <string>( "MessageId", SpecialType.System_String ); info.Attribute = attribute; return(true); }
public bool HasGlobalSymbolSuppression( ISymbol symbol, string id, bool isImmediatelyContainingSymbol, out SuppressMessageInfo info ) { Debug.Assert(symbol != null); Dictionary <string, SuppressMessageInfo>?suppressions; if ( _globalSymbolSuppressions.TryGetValue(symbol, out suppressions) && suppressions.TryGetValue(id, out info) ) { if (symbol.Kind != SymbolKind.Namespace) { return(true); } if (TryGetTargetScope(info, out TargetScope targetScope)) { switch (targetScope) { case TargetScope.Namespace: // Special case: Only suppress syntax diagnostics in namespace declarations if the namespace is the closest containing symbol. // In other words, only apply suppression to the immediately containing namespace declaration and not to its children or parents. return(isImmediatelyContainingSymbol); case TargetScope.NamespaceAndDescendants: return(true); } } } info = default(SuppressMessageInfo); return(false); }
private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info) => IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, out info);
public void AddCompilationWideSuppression(SuppressMessageInfo info) { AddOrUpdate(info, _compilationWideSuppressions); }
private static void AddOrUpdate(SuppressMessageInfo info, IDictionary<string, SuppressMessageInfo> builder) { // TODO: How should we deal with multiple SuppressMessage attributes, with different suppression info/states? // For now, we just pick the last attribute, if not suppressed. SuppressMessageInfo currentInfo; if (!builder.TryGetValue(info.Id, out currentInfo)) { builder[info.Id] = info; } }
private bool IsDiagnosticLocallySuppressed(string id, ISymbol symbol, out SuppressMessageInfo info) { var suppressions = _localSuppressionsBySymbol.GetOrAdd(symbol, this.DecodeLocalSuppressMessageAttributes); return suppressions.TryGetValue(id, out info); }
private bool IsDiagnosticGloballySuppressed(string id, ISymbol symbolOpt, out SuppressMessageInfo info) { this.DecodeGlobalSuppressMessageAttributes(); return _lazyGlobalSuppressions.HasCompilationWideSuppression(id, out info) || symbolOpt != null && _lazyGlobalSuppressions.HasGlobalSymbolSuppression(symbolOpt, id, out info); }
private bool IsDiagnosticSuppressed(string id, Location location, out SuppressMessageInfo info) { Debug.Assert(id != null); Debug.Assert(location != null); info = default(SuppressMessageInfo); if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, info: out info)) { return true; } // Walk up the syntax tree checking for suppression by any declared symbols encountered if (location.IsInSource) { var model = _compilation.GetSemanticModel(location.SourceTree); bool inImmediatelyContainingSymbol = true; for (var node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true); node != null; node = node.Parent) { var declaredSymbols = model.GetDeclaredSymbolsForNode(node); Debug.Assert(declaredSymbols != null); foreach (var symbol in declaredSymbols) { if (symbol.Kind == SymbolKind.Namespace) { // Special case: Only suppress syntax diagnostics in namespace declarations if the namespace is the closest containing symbol. // In other words, only apply suppression to the immediately containing namespace declaration and not to its children or parents. return inImmediatelyContainingSymbol && IsDiagnosticGloballySuppressed(id, symbol, out info); } else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info)) { return true; } inImmediatelyContainingSymbol = false; } } } return false; }
private bool IsDiagnosticSuppressed(string id, Location location, Func <Compilation, SyntaxTree, SemanticModel> getSemanticModel, out SuppressMessageInfo info) { Debug.Assert(id != null); Debug.Assert(location != null); info = default(SuppressMessageInfo); if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, isImmediatelyContainingSymbol: false, info: out info)) { return(true); } // Walk up the syntax tree checking for suppression by any declared symbols encountered if (location.IsInSource) { var model = getSemanticModel(_compilation, location.SourceTree); bool inImmediatelyContainingSymbol = true; for (var node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true); node != null; node = node.Parent) { var declaredSymbols = model.GetDeclaredSymbolsForNode(node); Debug.Assert(declaredSymbols != null); foreach (var symbol in declaredSymbols) { if (symbol.Kind == SymbolKind.Namespace) { return(hasNamespaceSuppression((INamespaceSymbol)symbol, inImmediatelyContainingSymbol)); } else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, inImmediatelyContainingSymbol, out info)) { return(true); } } if (!declaredSymbols.IsEmpty) { inImmediatelyContainingSymbol = false; } } } return(false); bool hasNamespaceSuppression(INamespaceSymbol namespaceSymbol, bool inImmediatelyContainingSymbol) { do { if (IsDiagnosticGloballySuppressed(id, namespaceSymbol, inImmediatelyContainingSymbol, out _)) { return(true); } namespaceSymbol = namespaceSymbol.ContainingNamespace; inImmediatelyContainingSymbol = false; }while (namespaceSymbol != null); return(false); } }
public bool HasCompilationWideSuppression(string id, out SuppressMessageInfo info) { return(_compilationWideSuppressions.TryGetValue(id, out info)); }
public void AddCompilationWideSuppression(SuppressMessageInfo info) { AddOrUpdate(info, _compilationWideSuppressions); }
private static bool TryGetTargetScope(SuppressMessageInfo info, out TargetScope scope) => s_suppressMessageScopeTypes.TryGetValue(info.Scope ?? string.Empty, out scope);
private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info) { info = default; if (diagnostic.CustomTags.Contains(WellKnownDiagnosticTags.Compiler)) { // SuppressMessage attributes do not apply to compiler diagnostics. return(false); } var id = diagnostic.Id; var location = diagnostic.Location; if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, isImmediatelyContainingSymbol: false, info: out info)) { return(true); } // Walk up the syntax tree checking for suppression by any declared symbols encountered if (location.IsInSource) { var model = _compilation.GetSemanticModel(location.SourceTree); bool inImmediatelyContainingSymbol = true; for (var node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true); node != null; node = node.Parent) { var declaredSymbols = model.GetDeclaredSymbolsForNode(node); Debug.Assert(declaredSymbols != null); foreach (var symbol in declaredSymbols) { if (symbol.Kind == SymbolKind.Namespace) { return(hasNamespaceSuppression((INamespaceSymbol)symbol, inImmediatelyContainingSymbol)); } else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, inImmediatelyContainingSymbol, out info)) { return(true); } } if (!declaredSymbols.IsEmpty) { inImmediatelyContainingSymbol = false; } } } return(false); bool hasNamespaceSuppression(INamespaceSymbol namespaceSymbol, bool inImmediatelyContainingSymbol) { do { if (IsDiagnosticGloballySuppressed(id, namespaceSymbol, inImmediatelyContainingSymbol, out _)) { return(true); } namespaceSymbol = namespaceSymbol.ContainingNamespace; inImmediatelyContainingSymbol = false; }while (namespaceSymbol != null); return(false); } }
private static bool IsDiagnosticSuppressed(Diagnostic diagnostic, Compilation compilation, out SuppressMessageInfo info) { var suppressMessageState = AnalyzerDriver.GetOrCreateCachedCompilationData(compilation).SuppressMessageAttributeState; return(suppressMessageState.IsDiagnosticSuppressed(diagnostic, out info)); }
private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info, ISymbol symbolOpt = null) { if (symbolOpt != null && IsDiagnosticSuppressed(diagnostic.Id, symbolOpt, out info)) { return true; } return IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, out info); }
private bool IsDiagnosticSuppressed(Diagnostic diagnostic, Func <Compilation, SyntaxTree, SemanticModel> getSemanticModel, out SuppressMessageInfo info) => IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, getSemanticModel, out info);
public bool HasCompilationWideSuppression(string id, out SuppressMessageInfo info) { return _compilationWideSuppressions.TryGetValue(id, out info); }
private bool IsDiagnosticSuppressed(string id, ISymbol symbol, out SuppressMessageInfo info) { Debug.Assert(id != null); Debug.Assert(symbol != null); if (symbol.Kind == SymbolKind.Namespace) { // Suppressions associated with namespace symbols only apply to namespace declarations themselves // and any syntax nodes immediately contained therein, not to nodes attached to any other symbols. // Diagnostics those nodes will be filtered by location, not by associated symbol. info = default(SuppressMessageInfo); return false; } if (symbol.Kind == SymbolKind.Method) { var associated = ((IMethodSymbol)symbol).AssociatedSymbol; if (associated != null && (IsDiagnosticLocallySuppressed(id, associated, out info) || IsDiagnosticGloballySuppressed(id, associated, out info))) { return true; } } if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info)) { return true; } // Check for suppression on parent symbol var parent = symbol.ContainingSymbol; return parent != null && IsDiagnosticSuppressed(id, parent, out info); }
private bool IsDiagnosticGloballySuppressed(string id, ISymbol symbolOpt, out SuppressMessageInfo info) { this.DecodeGlobalSuppressMessageAttributes(); return(_lazyGlobalSuppressions.HasCompilationWideSuppression(id, out info) || symbolOpt != null && _lazyGlobalSuppressions.HasGlobalSymbolSuppression(symbolOpt, id, out info)); }
private static bool TryDecodeSuppressMessageAttributeData(AttributeData attribute, out SuppressMessageInfo info) { info = default(SuppressMessageInfo); // We need at least the Category and Id to decode the diagnostic to suppress. // The only SuppressMessageAttribute constructor requires those two parameters. if (attribute.CommonConstructorArguments.Length < 2) { return false; } // Ignore the category parameter because it does not identify the diagnostic // and category information can be obtained from diagnostics themselves. info.Id = attribute.CommonConstructorArguments[1].Value as string; if (info.Id == null) { return false; } // Allow an optional human-readable descriptive name on the end of an Id. // See http://msdn.microsoft.com/en-us/library/ms244717.aspx var separatorIndex = info.Id.IndexOf(':'); if (separatorIndex != -1) { info.Id = info.Id.Remove(separatorIndex); } info.Scope = attribute.DecodeNamedArgument<string>("Scope", SpecialType.System_String); info.Target = attribute.DecodeNamedArgument<string>("Target", SpecialType.System_String); info.MessageId = attribute.DecodeNamedArgument<string>("MessageId", SpecialType.System_String); return true; }
private static bool IsDiagnosticSuppressed(Diagnostic diagnostic, Compilation compilation, out SuppressMessageInfo info) { var suppressMessageState = AnalyzerDriver.GetOrCreateCachedCompilationData(compilation).SuppressMessageAttributeState; return suppressMessageState.IsDiagnosticSuppressed(diagnostic, out info); }