Skip to content

Commit

Permalink
Ensure that we suppress compilation diagnostics reported in generated…
Browse files Browse the repository at this point in the history
… code when the analyzer is configured to analyze generated code, but not report diagnostics on generated code.

Fixes dotnet#11217
  • Loading branch information
mavasani committed May 10, 2016
1 parent 39840b4 commit 0da303d
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,25 @@ partial class PartialType
VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
}

[Fact, WorkItem(11217, "https://github.com/dotnet/roslyn/issues/11217")]
public void TestGeneratedCodeAnalyzerNoReportDiagnostics()
{
string source1 = @"
class TypeInUserFile { }
";
string source2 = @"
class TypeInGeneratedFile { }
";
var tree1 = CSharpSyntaxTree.ParseText(source1, path: "SourceFileRegular.cs");
var tree2 = CSharpSyntaxTree.ParseText(source2, path: "SourceFileRegular.Designer.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree1, tree2 }, new MetadataReference[] { SystemRef });
compilation.VerifyDiagnostics();

var analyzers = new DiagnosticAnalyzer[] { new GeneratedCodeAnalyzer2() };
compilation.VerifyAnalyzerDiagnostics(analyzers,
expected: Diagnostic("GeneratedCodeAnalyzer2Warning", "TypeInUserFile").WithArguments("TypeInUserFile").WithLocation(2, 7));
}

internal class OwningSymbolTestAnalyzer : DiagnosticAnalyzer
{
public static readonly DiagnosticDescriptor ExpressionDescriptor = new DiagnosticDescriptor(
Expand Down
65 changes: 33 additions & 32 deletions src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.Semantics;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

Expand Down Expand Up @@ -327,7 +326,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
}

var symbol = symbolDeclaredEvent.Symbol;
var addDiagnostic = GetAddDiagnostic(symbol, symbolDeclaredEvent.DeclaringSyntaxReferences, analyzer, getTopMostNodeForAnalysis, isGeneratedCodeSymbol);
var addDiagnostic = GetAddDiagnostic(symbol, symbolDeclaredEvent.DeclaringSyntaxReferences, analyzer, getTopMostNodeForAnalysis);

foreach (var symbolAction in symbolActions)
{
Expand Down Expand Up @@ -398,7 +397,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
return;
}

var addDiagnostic = GetAddDiagnostic(semanticModel.SyntaxTree, analyzer, isSyntaxDiagnostic: false, isGeneratedCode: isGeneratedCode);
var addDiagnostic = GetAddDiagnostic(semanticModel.SyntaxTree, analyzer, isSyntaxDiagnostic: false);

foreach (var semanticModelAction in semanticModelActions)
{
Expand Down Expand Up @@ -462,7 +461,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
return;
}

var addDiagnostic = GetAddDiagnostic(tree, analyzer, isSyntaxDiagnostic: true, isGeneratedCode: isGeneratedCode);
var addDiagnostic = GetAddDiagnostic(tree, analyzer, isSyntaxDiagnostic: true);

foreach (var syntaxTreeAction in syntaxTreeActions)
{
Expand Down Expand Up @@ -556,7 +555,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
ExecuteBlockActionsCore<CodeBlockStartAnalyzerAction<TLanguageKindEnum>, CodeBlockAnalyzerAction, SyntaxNodeAnalyzerAction<TLanguageKindEnum>, SyntaxNodeAnalyzerStateData, SyntaxNode, TLanguageKindEnum>(
codeBlockStartActions, codeBlockActions, codeBlockEndActions, analyzer,
declaredNode, declaredSymbol, executableCodeBlocks, (codeBlocks) => codeBlocks.SelectMany(cb => cb.DescendantNodesAndSelf()),
semanticModel, getKind, analyzerStateOpt?.CodeBlockAnalysisState, isGeneratedCode);
semanticModel, getKind, analyzerStateOpt?.CodeBlockAnalysisState);
}
}
finally
Expand Down Expand Up @@ -595,7 +594,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
ExecuteBlockActionsCore<OperationBlockStartAnalyzerAction, OperationBlockAnalyzerAction, OperationAnalyzerAction, OperationAnalyzerStateData, IOperation, int>(
operationBlockStartActions, operationBlockActions, operationBlockEndActions, analyzer,
declaredNode, declaredSymbol, operationBlocks, (blocks) => operations, semanticModel,
null, analyzerStateOpt?.OperationBlockAnalysisState, isGeneratedCode);
null, analyzerStateOpt?.OperationBlockAnalysisState);
}
}
finally
Expand All @@ -615,8 +614,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
Func<ImmutableArray<TNode>, IEnumerable<TNode>> getNodesToAnalyze,
SemanticModel semanticModel,
Func<SyntaxNode, TLanguageKindEnum> getKind,
AnalysisState.BlockAnalyzerStateData<TBlockAction, TNodeStateData> analyzerStateOpt,
bool isGeneratedCode)
AnalysisState.BlockAnalyzerStateData<TBlockAction, TNodeStateData> analyzerStateOpt)
where TLanguageKindEnum : struct
where TBlockStartAction : AnalyzerAction
where TBlockAction : AnalyzerAction
Expand Down Expand Up @@ -654,7 +652,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
blockEndActions.AddAll(endActions);
}

var addDiagnostic = GetAddDiagnostic(semanticModel.SyntaxTree, declaredNode.FullSpan, analyzer, isSyntaxDiagnostic: false, isGeneratedCode: isGeneratedCode);
var addDiagnostic = GetAddDiagnostic(semanticModel.SyntaxTree, declaredNode.FullSpan, analyzer, isSyntaxDiagnostic: false);

try
{
Expand Down Expand Up @@ -831,7 +829,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
{
if (TryStartAnalyzingSyntaxRefence(declaredSymbol, declarationIndex, analyzer, analysisScope, analysisStateOpt, out analyzerStateOpt))
{
ExecuteSyntaxNodeActionsCore(nodesToAnalyze, nodeActionsByKind, analyzer, declaredSymbol, model, getKind, filterSpan, analyzerStateOpt, isGeneratedCode);
ExecuteSyntaxNodeActionsCore(nodesToAnalyze, nodeActionsByKind, analyzer, declaredSymbol, model, getKind, filterSpan, analyzerStateOpt);
}
}
finally
Expand All @@ -848,11 +846,10 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
SemanticModel model,
Func<SyntaxNode, TLanguageKindEnum> getKind,
TextSpan filterSpan,
SyntaxNodeAnalyzerStateData analyzerStateOpt,
bool isGeneratedCode)
SyntaxNodeAnalyzerStateData analyzerStateOpt)
where TLanguageKindEnum : struct
{
var addDiagnostic = GetAddDiagnostic(model.SyntaxTree, filterSpan, analyzer, isSyntaxDiagnostic: false, isGeneratedCode: isGeneratedCode);
var addDiagnostic = GetAddDiagnostic(model.SyntaxTree, filterSpan, analyzer, isSyntaxDiagnostic: false);
ExecuteSyntaxNodeActions(nodesToAnalyze, nodeActionsByKind, containingSymbol, model, getKind, addDiagnostic, analyzerStateOpt);
}

Expand Down Expand Up @@ -957,7 +954,7 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
{
if (TryStartAnalyzingOperationReference(declaredSymbol, declarationIndex, analyzer, analysisScope, analysisStateOpt, out analyzerStateOpt))
{
ExecuteOperationActionsCore(operationsToAnalyze, operationActionsByKind, analyzer, declaredSymbol, model, filterSpan, analyzerStateOpt, isGeneratedCode);
ExecuteOperationActionsCore(operationsToAnalyze, operationActionsByKind, analyzer, declaredSymbol, model, filterSpan, analyzerStateOpt);
}
}
finally
Expand All @@ -973,10 +970,9 @@ private void ExecuteCompilationActionsCore(ImmutableArray<CompilationAnalyzerAct
ISymbol containingSymbol,
SemanticModel model,
TextSpan filterSpan,
OperationAnalyzerStateData analyzerStateOpt,
bool isGeneratedCode)
OperationAnalyzerStateData analyzerStateOpt)
{
var addDiagnostic = GetAddDiagnostic(model.SyntaxTree, filterSpan, analyzer, isSyntaxDiagnostic: false, isGeneratedCode: isGeneratedCode);
var addDiagnostic = GetAddDiagnostic(model.SyntaxTree, filterSpan, analyzer, isSyntaxDiagnostic: false);
ExecuteOperationActions(operationsToAnalyze, operationActionsByKind, containingSymbol, model, addDiagnostic, analyzerStateOpt);
}

Expand Down Expand Up @@ -1217,9 +1213,9 @@ private bool IsSupportedDiagnostic(DiagnosticAnalyzer analyzer, Diagnostic diagn
return _analyzerManager.IsSupportedDiagnostic(analyzer, diagnostic, _isCompilerAnalyzer, this);
}

private Action<Diagnostic> GetAddDiagnostic(ISymbol contextSymbol, ImmutableArray<SyntaxReference> cachedDeclaringReferences, DiagnosticAnalyzer analyzer, Func<ISymbol, SyntaxReference, Compilation, SyntaxNode> getTopMostNodeForAnalysis, bool isGeneratedCodeSymbol)
private Action<Diagnostic> GetAddDiagnostic(ISymbol contextSymbol, ImmutableArray<SyntaxReference> cachedDeclaringReferences, DiagnosticAnalyzer analyzer, Func<ISymbol, SyntaxReference, Compilation, SyntaxNode> getTopMostNodeForAnalysis)
{
return GetAddDiagnostic(contextSymbol, cachedDeclaringReferences, _compilation, analyzer, isGeneratedCodeSymbol, _addNonCategorizedDiagnosticOpt,
return GetAddDiagnostic(contextSymbol, cachedDeclaringReferences, _compilation, analyzer, _addNonCategorizedDiagnosticOpt,
_addCategorizedLocalDiagnosticOpt, _addCategorizedNonLocalDiagnosticOpt, getTopMostNodeForAnalysis, _shouldSuppressGeneratedCodeDiagnostic, _cancellationToken);
}

Expand All @@ -1228,7 +1224,6 @@ private Action<Diagnostic> GetAddDiagnostic(ISymbol contextSymbol, ImmutableArra
ImmutableArray<SyntaxReference> cachedDeclaringReferences,
Compilation compilation,
DiagnosticAnalyzer analyzer,
bool isGeneratedCodeSymbol,
Action<Diagnostic> addNonCategorizedDiagnosticOpt,
Action<Diagnostic, DiagnosticAnalyzer, bool> addCategorizedLocalDiagnosticOpt,
Action<Diagnostic, DiagnosticAnalyzer> addCategorizedNonLocalDiagnosticOpt,
Expand All @@ -1238,7 +1233,7 @@ private Action<Diagnostic> GetAddDiagnostic(ISymbol contextSymbol, ImmutableArra
{
return diagnostic =>
{
if (isGeneratedCodeSymbol && shouldSuppressGeneratedCodeDiagnostic(diagnostic, analyzer, compilation, cancellationToken))
if (shouldSuppressGeneratedCodeDiagnostic(diagnostic, analyzer, compilation, cancellationToken))
{
return;
}
Expand Down Expand Up @@ -1275,27 +1270,34 @@ private Action<Diagnostic> GetAddDiagnostic(ISymbol contextSymbol, ImmutableArra

private Action<Diagnostic> GetAddCompilationDiagnostic(DiagnosticAnalyzer analyzer)
{
if (_addCategorizedNonLocalDiagnosticOpt == null)
{
return _addNonCategorizedDiagnosticOpt;
}

return diagnostic =>
{
if (_shouldSuppressGeneratedCodeDiagnostic(diagnostic, analyzer, _compilation, _cancellationToken))
{
return;
}
if (_addCategorizedNonLocalDiagnosticOpt == null)
{
Debug.Assert(_addNonCategorizedDiagnosticOpt != null);
_addNonCategorizedDiagnosticOpt(diagnostic);
return;
}
_addCategorizedNonLocalDiagnosticOpt(diagnostic, analyzer);
};
}

private Action<Diagnostic> GetAddDiagnostic(SyntaxTree tree, DiagnosticAnalyzer analyzer, bool isSyntaxDiagnostic, bool isGeneratedCode)
private Action<Diagnostic> GetAddDiagnostic(SyntaxTree tree, DiagnosticAnalyzer analyzer, bool isSyntaxDiagnostic)
{
return GetAddDiagnostic(tree, null, _compilation, analyzer, isSyntaxDiagnostic, isGeneratedCode,
return GetAddDiagnostic(tree, null, _compilation, analyzer, isSyntaxDiagnostic,
_addNonCategorizedDiagnosticOpt, _addCategorizedLocalDiagnosticOpt, _addCategorizedNonLocalDiagnosticOpt,
_shouldSuppressGeneratedCodeDiagnostic, _cancellationToken);
}

private Action<Diagnostic> GetAddDiagnostic(SyntaxTree tree, TextSpan? span, DiagnosticAnalyzer analyzer, bool isSyntaxDiagnostic, bool isGeneratedCode)
private Action<Diagnostic> GetAddDiagnostic(SyntaxTree tree, TextSpan? span, DiagnosticAnalyzer analyzer, bool isSyntaxDiagnostic)
{
return GetAddDiagnostic(tree, span, _compilation, analyzer, false, isGeneratedCode,
return GetAddDiagnostic(tree, span, _compilation, analyzer, false,
_addNonCategorizedDiagnosticOpt, _addCategorizedLocalDiagnosticOpt, _addCategorizedNonLocalDiagnosticOpt,
_shouldSuppressGeneratedCodeDiagnostic, _cancellationToken);
}
Expand All @@ -1306,7 +1308,6 @@ private Action<Diagnostic> GetAddDiagnostic(SyntaxTree tree, TextSpan? span, Dia
Compilation compilation,
DiagnosticAnalyzer analyzer,
bool isSyntaxDiagnostic,
bool isGeneratedCode,
Action<Diagnostic> addNonCategorizedDiagnosticOpt,
Action<Diagnostic, DiagnosticAnalyzer, bool> addCategorizedLocalDiagnosticOpt,
Action<Diagnostic, DiagnosticAnalyzer> addCategorizedNonLocalDiagnosticOpt,
Expand All @@ -1315,7 +1316,7 @@ private Action<Diagnostic> GetAddDiagnostic(SyntaxTree tree, TextSpan? span, Dia
{
return diagnostic =>
{
if (isGeneratedCode && shouldSuppressGeneratedCodeDiagnostic(diagnostic, analyzer, compilation, cancellationToken))
if (shouldSuppressGeneratedCodeDiagnostic(diagnostic, analyzer, compilation, cancellationToken))
{
return;
}
Expand Down
34 changes: 34 additions & 0 deletions src/Test/Utilities/Desktop/CommonDiagnosticAnalyzers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,40 @@ private void ReportDiagnosticsCore(Action<Diagnostic> addDiagnostic, Location lo
}
}

[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public class GeneratedCodeAnalyzer2 : DiagnosticAnalyzer
{
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
"GeneratedCodeAnalyzer2Warning",
"Title",
"GeneratedCodeAnalyzer2Message for '{0}'",
"Category",
DiagnosticSeverity.Warning,
true);

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
// Analyze but don't report diagnostics on generated code.
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);

context.RegisterCompilationStartAction(compilationStartContext =>
{
var namedTypes = new HashSet<ISymbol>();
compilationStartContext.RegisterSymbolAction(symbolContext => namedTypes.Add(symbolContext.Symbol), SymbolKind.NamedType);
compilationStartContext.RegisterCompilationEndAction(compilationEndContext =>
{
foreach (var namedType in namedTypes)
{
var diagnostic = Diagnostic.Create(Rule, namedType.Locations[0], namedType.Name);
compilationEndContext.ReportDiagnostic(diagnostic);
}
});
});
}
}

[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public class SharedStateAnalyzer : DiagnosticAnalyzer
{
Expand Down

0 comments on commit 0da303d

Please sign in to comment.