private static void AnalyzeCompilation(CompilationAnalysisContext context) { if (AssemblyHasPublicTypes(context.Compilation.Assembly)) { INamedTypeSymbol comVisibleAttributeSymbol = WellKnownTypes.ComVisibleAttribute(context.Compilation); if (comVisibleAttributeSymbol == null) { return; } AttributeData attributeInstance = context.Compilation.Assembly.GetAttributes().FirstOrDefault(a => a.AttributeClass.Equals(comVisibleAttributeSymbol)); if (attributeInstance != null) { if (attributeInstance.ConstructorArguments.Length > 0 && attributeInstance.ConstructorArguments[0].Kind == TypedConstantKind.Primitive && attributeInstance.ConstructorArguments[0].Value != null & attributeInstance.ConstructorArguments[0].Value.Equals(true)) { // Has the attribute, with the value 'true'. context.ReportDiagnostic(Diagnostic.Create(RuleA, Location.None, context.Compilation.Assembly.Name)); } } else { // No ComVisible attribute at all. context.ReportDiagnostic(Diagnostic.Create(RuleB, Location.None, context.Compilation.Assembly.Name)); } } return; }
private static void AnalyzeCompilation(CompilationAnalysisContext context) { var compilation = context.Compilation; var plugins = compilation.SyntaxTrees .Select(x => x.GetCompilationUnitRoot()) .SelectMany(x => x.FindSyntax<ClassDeclarationSyntax>()) .Where(x => x.IsExportIPlugin()) .ToArray(); var dupe = plugins .GroupBy(x => x.GetGuidMetadataValue()) .Where(x => 1 < x.Count()) .ToArray(); if (!dupe.Any()) return; foreach (var group in dupe) { foreach (var c in group) { var other = group.Except(new[] { c }).ToArray(); context.ReportDiagnostic(Diagnostic.Create( DuplicateGuidRule, c.GetLocation(), string.Join(", ", other.Select(x => x.Identifier)))); } } }
private static void AnalyzeCompilation(CompilationAnalysisContext context) { var compilation = context.Compilation; var allPlugins = compilation.SyntaxTrees .Select(x => x.GetCompilationUnitRoot()) .SelectMany(x => x.FindSyntax<ClassDeclarationSyntax>()) .Where(x => x.IsPluginClass()) .ToArray(); var plugins = allPlugins.Where(x => x.IsExportIPlugin()).ToArray(); foreach (var p in allPlugins) { var semanticModel = compilation.GetSemanticModel(p.SyntaxTree); var syntax = p.GetGuidMetadataValueSyntax(); if (syntax == null) continue; //GUID な Metadata がない場合はスルー // GUID として解釈できない値か、IPlugin で未定義の GUID が指定されてたらアウト var guidMetadata = syntax.GetGuidMetadata(semanticModel); if (!guidMetadata.HasValue || plugins.All(x => x.GetGuidMetadataValueSyntax()?.GetGuidMetadata(compilation.GetSemanticModel(x.SyntaxTree)) != guidMetadata)) { context.ReportDiagnostic(Diagnostic.Create(InvalidGuidMetadataRule, p.GetLocation())); } } }
private void AnalyzeCompilation(CompilationAnalysisContext context) { if (AssemblyHasPublicTypes(context.Compilation.Assembly)) { var comVisibleAttributeSymbol = WellKnownTypes.ComVisibleAttribute(context.Compilation); if (comVisibleAttributeSymbol == null) { return; } var attributeInstance = context.Compilation.Assembly.GetAttributes().FirstOrDefault(a => a.AttributeClass.Equals(comVisibleAttributeSymbol)); if (attributeInstance != null) { if (attributeInstance.ConstructorArguments.Length > 0 && attributeInstance.ConstructorArguments[0].Kind == TypedConstantKind.Primitive && attributeInstance.ConstructorArguments[0].Value != null & attributeInstance.ConstructorArguments[0].Value.Equals(true)) { // Has the attribute, with the value 'true'. context.ReportDiagnostic(Diagnostic.Create(Rule, Location.None, string.Format(SystemRuntimeAnalyzersResources.CA1017_AttributeTrue, context.Compilation.Assembly.Name))); } } else { // No ComVisible attribute at all. context.ReportDiagnostic(Diagnostic.Create(Rule, Location.None, string.Format(SystemRuntimeAnalyzersResources.CA1017_NoAttribute, context.Compilation.Assembly.Name))); } } return; }
public void HandleCompilation(CompilationAnalysisContext context) { if (Volatile.Read(ref this.documentationAnalysisDisabled)) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, Location.None)); } }
private static void OnCompilation(CompilationAnalysisContext context) { var diags = OnCompilationAsync(context.Compilation).Result; foreach (var d in diags) { context.ReportDiagnostic(d); } }
public void AnalyzeCompilation(CompilationAnalysisContext context) { foreach (var item in _fieldDisposedMap) { if (!item.Value) { context.ReportDiagnostic(item.Key.CreateDiagnostic(Rule)); } } }
private void AnalyzeCompilation(CompilationAnalysisContext context) { Trace.WriteLine("AnalyzeCompilation"); try { INamedTypeSymbol dbContextTypeSymbol; IEnumerable<INamedTypeSymbol> entityTypeSymbols = SymbolHelper.GetAllEntityTypesFromDbContext(context.Compilation, out dbContextTypeSymbol); if (!entityTypeSymbols.Any()) { return; } var allTypeSymbols = context.Compilation.GetSymbolsWithName(s => !s.EndsWith("DbContext"), SymbolFilter.Type).Cast<INamedTypeSymbol>(); var allMemberSymbols = allTypeSymbols.SelectMany(t => t.GetMembers().Where(m => m.Kind == SymbolKind.Property)); Trace.WriteLine("Class count: " + allTypeSymbols.Count()); Trace.WriteLine("Property count: " + allMemberSymbols.Count()); var efRoslynTheorem = new EFRoslynTheorem(); var result = efRoslynTheorem.Solve(entityTypeSymbols); if (result.Status == Status.Unsatisfiable) { var classAssumptions = efRoslynTheorem.ClassAssumptions.ToList(); var propertyAssumptions = efRoslynTheorem.PropertyAssumptions.OrderBy(pa => pa.Rank).ToList(); do { result = TryToRemoveWrongAssumption(efRoslynTheorem, result, classAssumptions, propertyAssumptions); } while (result != null && result.Status != Status.Satisfiable); if (result == null || result.Status != Status.Satisfiable) { var diagnostic2 = Diagnostic.Create(UnsatisfiableRule, dbContextTypeSymbol.Locations[0], dbContextTypeSymbol.Name); Trace.WriteLine("ReportDiagnostic " + diagnostic2.Descriptor.Id); context.ReportDiagnostic(diagnostic2); return; } var cacheId = EFRoslynTheoremCache.Add(context.Compilation, efRoslynTheorem, result); var props = ImmutableDictionary.Create<string, string>(); props = props.Add("CacheId", cacheId); var diagnostic = Diagnostic.Create(SatisfiableRule, dbContextTypeSymbol.Locations[0], props, dbContextTypeSymbol.Name); Trace.WriteLine("ReportDiagnostic " + diagnostic.Descriptor.Id); context.ReportDiagnostic(diagnostic); } } catch (Exception ex) { Trace.WriteLine(ex.ToString()); throw; } }
private void AnalyzeCompilation(CompilationAnalysisContext context) { var globalNamespaces = context.Compilation.GlobalNamespace.GetNamespaceMembers() .Where(item => item.ContainingAssembly == context.Compilation.Assembly); var globalTypes = context.Compilation.GlobalNamespace.GetTypeMembers().Where(item => item.ContainingAssembly == context.Compilation.Assembly && IsExternallyVisible(item)); CheckTypeNames(globalTypes, context.ReportDiagnostic); CheckNamespaceMembers(globalNamespaces, context.Compilation, context.ReportDiagnostic); }
private static void AnalyzeCompilation(CompilationAnalysisContext context) { var compilation = context.Compilation; var isDefined = compilation.SyntaxTrees .Select(x => x.GetCompilationUnitRoot()) .SelectMany(x => x.DescendantNodes().OfType<SimpleBaseTypeSyntax>()) .Any(x => x.ToString() == "IPlugin" || x.ToString() == "Grabacr07.KanColleViewer.Composition.IPlugin") ; if (!isDefined) context.ReportDiagnostic(Diagnostic.Create(RequireIPluginRule, Location.None)); }
private void AnalyzeCompilation(CompilationAnalysisContext context) { INamedTypeSymbol assemblyVersionAttributeSymbol = WellKnownTypes.AssemblyVersionAttribute(context.Compilation); INamedTypeSymbol assemblyComplianceAttributeSymbol = WellKnownTypes.CLSCompliantAttribute(context.Compilation); if (assemblyVersionAttributeSymbol == null && assemblyComplianceAttributeSymbol == null) { return; } bool assemblyVersionAttributeFound = false; bool assemblyComplianceAttributeFound = false; // Check all assembly level attributes for the target attribute foreach (AttributeData attribute in context.Compilation.Assembly.GetAttributes()) { if (attribute.AttributeClass.Equals(assemblyVersionAttributeSymbol)) { // Mark the version attribute as found assemblyVersionAttributeFound = true; } else if (attribute.AttributeClass.Equals(assemblyComplianceAttributeSymbol)) { // Mark the compliance attribute as found assemblyComplianceAttributeFound = true; } } // Check for the case where we do not have the target attribute defined at all in our metadata references. If so, how can they reference it if (assemblyVersionAttributeSymbol == null) { assemblyVersionAttributeFound = false; } if (assemblyComplianceAttributeSymbol == null) { assemblyComplianceAttributeFound = false; } // If there's at least one diagnostic to report, let's report them if (!assemblyComplianceAttributeFound || !assemblyVersionAttributeFound) { if (!assemblyVersionAttributeFound) { context.ReportDiagnostic(Diagnostic.Create(CA1016Rule, Location.None)); } if (!assemblyComplianceAttributeFound) { context.ReportDiagnostic(Diagnostic.Create(CA1014Rule, Location.None)); } } }
private static void AnalyzeCompilation(CompilationAnalysisContext context) { // Get all the suppressed analyzer diagnostic IDs. var suppressedAnalyzerDiagnosticIds = GetSuppressedAnalyzerDiagnosticIds(context.Compilation.Options.SpecificDiagnosticOptions); foreach (var suppressedDiagnosticId in suppressedAnalyzerDiagnosticIds) { // For all such suppressed diagnostic IDs, produce a diagnostic. var diagnostic = Diagnostic.Create(Rule, Location.None, suppressedDiagnosticId); context.ReportDiagnostic(diagnostic); } }
private void OnCompilationEnd(CompilationAnalysisContext context) { lock (_apisToEnsureExist) { if (_apisToEnsureExist.Count != 0) { // If we have not cleared the list of APIs that must exist then we need to give errors about them foreach (var missingAPI in _apisToEnsureExist) { context.ReportDiagnostic(Diagnostic.Create(s_memberMustExistDiagnostic, Location.None, missingAPI)); } } } }
private static void HandleCompilation(CompilationAnalysisContext context) { try { SettingsHelper.GetStyleCopSettings(context.Options, DeserializationFailureBehavior.ThrowException, context.CancellationToken); } catch (JsonException ex) { string details = ex.Message; string completeDescription = string.Format(Description.ToString(CultureInfo.CurrentCulture), details); var completeDescriptor = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.SpecialRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, completeDescription, HelpLink); context.ReportDiagnostic(Diagnostic.Create(completeDescriptor, Location.None)); } }
public void HandleCompilation(CompilationAnalysisContext context) { var compilation = context.Compilation; var globalNamespace = compilation.GlobalNamespace; var ruleDependencyAttributeSymbols = GetRuleDependencyAttributeTypeSymbols(globalNamespace); // if ANTLR 4 isn't referenced, no need to run this analyzer if (ruleDependencyAttributeSymbols.Length == 0) return; IEnumerable<INamedTypeSymbol> typesToCheck = GetAllTypes(compilation.SourceModule.GlobalNamespace); var builder = ImmutableArray.CreateBuilder<Tuple<AttributeData, ISymbol>>(); foreach (var type in typesToCheck) builder.AddRange(GetDependencies(type, ruleDependencyAttributeSymbols)); var dependencies = builder.ToImmutable(); if (dependencies.Length == 0) return; var recognizerDependencies = new Dictionary<INamedTypeSymbol, IList<Tuple<AttributeData, ISymbol>>>(); foreach (var dependency in dependencies) { if (dependency.Item1.AttributeConstructor == null) continue; INamedTypeSymbol recognizerType = GetRecognizerType(dependency.Item1); if (recognizerType == null) continue; IList<Tuple<AttributeData, ISymbol>> list; if (!recognizerDependencies.TryGetValue(recognizerType, out list)) { list = new List<Tuple<AttributeData, ISymbol>>(); recognizerDependencies[recognizerType] = list; } list.Add(dependency); } foreach (var entry in recognizerDependencies) { var diagnostics = CheckDependencies((CSharpCompilation)compilation, entry.Value, entry.Key); foreach (var diagnostic in diagnostics) context.ReportDiagnostic(diagnostic); } }
private void AnalizeCompilation(CompilationAnalysisContext context) { // Find CS0006: Metadata file '{0}' could not be found Diagnostic invalidMetadataDiagnostic = context.Compilation .GetDiagnostics().FirstOrDefault(d => string.Compare(d.Id, "CS0006") == 0); if (invalidMetadataDiagnostic != null) { var argument = invalidMetadataDiagnostic.GetDiagnosticMessageArguments().First().ToString(); if (argument != null && string.Compare(Path.GetExtension(argument), ".dll") == 0) { var diagnostic = Diagnostic.Create(_supportedRule, invalidMetadataDiagnostic.Location, argument, ".dll"); context.ReportDiagnostic(diagnostic); } } }
private void RaiseIssuesFromJSon(CompilationAnalysisContext context) { string jsonFileContent; List <List <JObject> > jsonIssues; LogIfFailure($"- parsing json file {cbdeJsonOutputPath}"); try { jsonFileContent = File.ReadAllText(cbdeJsonOutputPath); jsonIssues = JsonConvert.DeserializeObject <List <List <JObject> > >(jsonFileContent); } catch (Exception exception) { if (exception is JsonException || exception is IOException) { LogIfFailure($"- error parsing json file {cbdeJsonOutputPath}: {exception.ToString()}"); Log(logStringBuilder.ToString()); throw new CbdeException($"Error parsing output from CBDE: {exception.Message}{this.moreDetailsMessage}"); } throw; } // in cbde json output there is enclosing {}, so this is considered as a list of list // with one element in the outer list foreach (var issue in jsonIssues.First()) { LogIfFailure($" * processing token {issue.ToString()}"); try { RaiseIssueFromJToken(issue, context); } catch (Exception e) { if (e is SystemException || e is JsonException) { LogIfFailure($" * error reporting token {cbdeJsonOutputPath}: {e.ToString()}"); Log(logStringBuilder.ToString()); throw new CbdeException($"Error raising issue from CBDE: {e.Message}{this.moreDetailsMessage}"); } throw; } } }
protected void ReadParameters(SonarAnalysisContext context, CompilationAnalysisContext c) { var settings = PropertiesHelper.GetSettings(c.Options); var outPath = context.ProjectConfiguration(c.Options).OutPath; // For backward compatibility with S4MSB <= 5.0 if (outPath == null && c.Options.AdditionalFiles.FirstOrDefault(IsProjectOutFolderPath) is { } projectOutFolderAdditionalFile) { outPath = File.ReadAllLines(projectOutFolderAdditionalFile.Path).First(); } if (settings.Any() && !string.IsNullOrEmpty(outPath)) { IgnoreHeaderComments = PropertiesHelper.ReadIgnoreHeaderCommentsProperty(settings, c.Compilation.Language); AnalyzeGeneratedCode = PropertiesHelper.ReadAnalyzeGeneratedCodeProperty(settings, c.Compilation.Language); OutPath = Path.Combine(outPath, c.Compilation.Language == LanguageNames.CSharp ? "output-cs" : "output-vbnet"); IsAnalyzerEnabled = true; IsTestProject = context.IsTestProject(c.Compilation, c.Options); } }
protected async Task <Mock <Action <Diagnostic> > > Analyze(string source, string path, CancellationToken cancellationToken = default(CancellationToken)) { var additionalTextMock = new Mock <AdditionalText>(); additionalTextMock.Setup(text => text.Path).Returns(path); //The path is read when the diagnostic is reported additionalTextMock.Setup(text => text.GetText(cancellationToken)).Returns(SourceText.From(source)); var diagnosticReportMock = new Mock <Action <Diagnostic> >(MockBehavior.Loose); //Will record the reported diagnostic... diagnosticReportMock.Setup(x => x(It.IsAny <Diagnostic>())) .Callback <Diagnostic>(diagnostic => { if (diagnostic != null) { Logger.LogMessage("Was: \"{0}\"", diagnostic.GetMessage()); } }); var compilation = new CompilationAnalysisContext(null, null, diagnosticReportMock.Object, d => true, cancellationToken); var file = File.CreateText(path); try { await file.WriteAsync(source).ConfigureAwait(false); file.Close(); Analyzer.AnalyzeFile(additionalTextMock.Object, compilation); } finally { file.Dispose(); File.Delete(path); } return(diagnosticReportMock); }
private void FindUnusedReferences(CompilationAnalysisContext context) { Debug.WriteLine($"----------------------------------------"); Debug.WriteLine($"Analyzing {context.Compilation.AssemblyName}..."); HashSet <AssemblyIdentity> compilationReferences = context.Compilation.ExternalReferences .OfType <CompilationReference>() .Select(r => r.Compilation.Assembly.Identity) .ToHashSet(); try { using (var syntaxTreeEnumerator = context.Compilation.SyntaxTrees.GetEnumerator()) { while (compilationReferences.Count > 0 && syntaxTreeEnumerator.MoveNext() && !context.CancellationToken.IsCancellationRequested) { var syntaxTree = syntaxTreeEnumerator.Current; var semanticModel = context.Compilation.GetSemanticModel(syntaxTree); ReferenceDiscarder referenceFinder = new ReferenceDiscarder(compilationReferences, syntaxTree, semanticModel, context.CancellationToken); referenceFinder.DiscardUsedReferencesAsync().GetAwaiter().GetResult(); } } } catch (TaskCanceledException) { // ReferenceDiscarder can throw on cancellation if it occurs during getting the root. } // I've no idea when this happens, but if it does, it means we haven't discarded all the used references. // Thus the results can't be trusted and we shouldn't report any diagnostics. if (context.CancellationToken.IsCancellationRequested) { return; } Debug.WriteLine($"{compilationReferences.Count} unused references"); foreach (var assembly in compilationReferences) { context.ReportDiagnostic(Diagnostic.Create(_rule, null, assembly.Name)); } }
public static void ReportProblems(CompilationAnalysisContext context, SyntaxNode methodDeclaration) { var staticKeyword = methodDeclaration.ChildTokens().FirstOrDefault(x => x.IsKind(SyntaxKind.StaticKeyword)); if (staticKeyword == null || staticKeyword.IsKind(SyntaxKind.None)) { SemanticModel semanticModel = context.Compilation.GetSemanticModel(methodDeclaration.SyntaxTree); if (IsInEntityClass(semanticModel, methodDeclaration)) { var methodName = methodDeclaration.ChildTokens().FirstOrDefault(x => x.IsKind(SyntaxKind.IdentifierToken)); if (methodName != null) { var diagnostic = Diagnostic.Create(Rule, methodName.GetLocation(), methodName); context.ReportDiagnostic(diagnostic); } } } }
public static void ReportProblems( CompilationAnalysisContext context, SemanticModel semanticModel, IEnumerable <ActivityFunctionDefinition> functionDefinitions, IEnumerable <ActivityFunctionCall> functionInvocations) { foreach (var invocation in functionInvocations) { var definition = functionDefinitions.FirstOrDefault(x => x.FunctionName == invocation.FunctionName); if (definition != null && invocation.ReturnTypeNode != null) { if (!IsValidReturnTypeForDefinition(invocation, definition)) { var diagnostic = Diagnostic.Create(Rule, invocation.InvocationExpression.GetLocation(), invocation.FunctionName, definition.ReturnType, invocation.ReturnType); context.ReportDiagnostic(diagnostic); } } } }
private static void OnCompilation(CompilationAnalysisContext context) { if (!TryLoadNUnitTypes(context.Compilation, out NUnitTypes types)) { return; } VisitCategories(types, context.Compilation.Assembly, (category, attribute) => { if (!ProhibitedAssemblyCategories.Contains(category)) { return; } context.ReportDiagnostic(Diagnostic.Create( Diagnostics.NUnitCategory, attribute.ApplicationSyntaxReference.GetSyntax(context.CancellationToken).GetLocation(), $"Assemblies cannot be categorized as any of [{string.Join( ", ", ProhibitedAssemblyCategories )}], but saw '{category}'." )); }); }
private static bool TryCheckNeutralResourcesLanguageAttribute(CompilationAnalysisContext context, out AttributeData attributeData) { INamedTypeSymbol attribute = WellKnownTypes.NeutralResourcesLanguageAttribute(context.Compilation); INamedTypeSymbol @string = WellKnownTypes.String(context.Compilation); Collections.Generic.IEnumerable <AttributeData> attributes = context.Compilation.Assembly.GetAttributes().Where(d => d.AttributeClass?.Equals(attribute) == true); foreach (AttributeData data in attributes) { if (data.ConstructorArguments.Any(c => c.Type?.Equals(@string) == true && !string.IsNullOrWhiteSpace((string)c.Value))) { // found one that already does right thing. attributeData = data; return(true); } } // either we couldn't find one or existing one is wrong. attributeData = attributes.FirstOrDefault(); return(false); }
private void Analyze(CompilationAnalysisContext context) { var attributes = context.Compilation.Assembly.GetAttributes(); Version fileVersion = null; Version informationalVersion = null; foreach (var attr in attributes) { if (attr.AttributeClass != null && attr.AttributeClass.Name == nameof(AssemblyFileVersionAttribute)) { if (!attr.ConstructorArguments.IsEmpty) { fileVersion = new Version((string)attr.ConstructorArguments[0].Value ?? string.Empty); fileVersion = SetRevisionToZeroIfMissing(fileVersion); } } if (attr.AttributeClass != null && attr.AttributeClass.Name == nameof(AssemblyInformationalVersionAttribute)) { if (!attr.ConstructorArguments.IsEmpty) { string strippedVersionSuffix = RemoveVersionSuffix((string)attr.ConstructorArguments[0].Value); string strippedsourceRevisionId = RemoveSourceRevisionId(strippedVersionSuffix); informationalVersion = new Version(strippedsourceRevisionId); informationalVersion = SetRevisionToZeroIfMissing(informationalVersion); } } } if (fileVersion is null || informationalVersion is null) { return; } if (!fileVersion.Equals(informationalVersion)) { Diagnostic diagnostic = Diagnostic.Create(Rule, null, fileVersion, informationalVersion); context.ReportDiagnostic(diagnostic); } }
internal void AnalyzeCompilationEnd(CompilationAnalysisContext context) { foreach (INamedTypeSymbol sourceSymbol in _sourceSymbolsToCheck) { var found = false; foreach (INamedTypeSymbol type in sourceSymbol.GetBaseTypesAndThis()) { if (_typesWithSymbolDeclaredEventInvoked.Contains(type)) { found = true; break; } } if (!found) { Diagnostic diagnostic = Diagnostic.Create(SymbolDeclaredEventRule, sourceSymbol.Locations[0], sourceSymbol.Name, _compilationType.Name, SymbolDeclaredEventName); context.ReportDiagnostic(diagnostic); } } }
private void AnalyzeXaml(CompilationAnalysisContext context) { var additionalFiles = context.Options.AdditionalFiles; var xamlFiles = additionalFiles.Where(file => Path.GetExtension(file.Path) == "xaml"); var stylerOptions = new StylerOptions(); var styleService = new StylerService(stylerOptions); foreach (var xamlFile in xamlFiles) { // Process each XAML file var originalContents = xamlFile.GetText().ToString(); var originalContentsHash = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(originalContents)); var styledContents = styleService.StyleDocument(originalContents); var styledContentsHash = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(originalContents)); if (originalContentsHash != styledContentsHash) { context.ReportDiagnostic(Diagnostic.Create( new DiagnosticDescriptor( "id", "title", "msg format", "category", DiagnosticSeverity.Warning, true ), Location.Create( xamlFile.Path, TextSpan.FromBounds(0, originalContents.Length - 1), new LinePositionSpan( new LinePosition(0, 0), new LinePosition(0, 0) ) ) )); } } }
private void ReportOnConflictingTransparencyAttributes(CompilationAnalysisContext compilationContext, Dictionary <SyntaxNode, AttributeSyntax> nodesWithSecuritySafeCritical, Dictionary <SyntaxNode, AttributeSyntax> nodesWithSecurityCritical) { var assemblySecurityCriticalAttribute = compilationContext.Compilation.Assembly .GetAttributes(KnownType.System_Security_SecurityCriticalAttribute) .FirstOrDefault(); if (assemblySecurityCriticalAttribute != null) { var assemblySecurityLocation = assemblySecurityCriticalAttribute.ApplicationSyntaxReference .GetSyntax().GetLocation(); // All parts declaring the 'SecuritySafeCriticalAttribute' are incorrect since the assembly // itself is marked as 'SecurityCritical'. foreach (var item in nodesWithSecuritySafeCritical) { compilationContext.ReportDiagnosticWhenActive(Diagnostic.Create(rule, item.Value.GetLocation(), additionalLocations: new[] { assemblySecurityLocation })); } } else { foreach (var item in nodesWithSecuritySafeCritical) { var current = item.Key.Parent; while (current != null) { if (nodesWithSecurityCritical.ContainsKey(current)) { compilationContext.ReportDiagnosticWhenActive(Diagnostic.Create(rule, item.Value.GetLocation(), additionalLocations: new[] { nodesWithSecurityCritical[current].GetLocation() })); break; } current = current.Parent; } } } }
public void OnCompilationEnd(CompilationAnalysisContext context) { foreach (var kv in _used.Where(kv => !kv.Value && (kv.Key.Locations.FirstOrDefault()?.IsInSource == true))) { context.CancellationToken.ThrowIfCancellationRequested(); var symbol = kv.Key; // report visible error only if symbol is not local symbol if (!(symbol is ILocalSymbol)) { context.ReportDiagnostic(Diagnostic.Create(s_rule, symbol.Locations[0], symbol.Locations.Skip(1), symbol.Name)); } // where code fix works foreach (var reference in symbol.DeclaringSyntaxReferences) { context.CancellationToken.ThrowIfCancellationRequested(); context.ReportDiagnostic(Diagnostic.Create(s_triggerRule, Location.Create(reference.SyntaxTree, reference.Span))); } } }
private void OnCompilationAction(CompilationAnalysisContext ctx) { foreach (AdditionalText file in ctx.Options .AdditionalFiles .Where(file => { var ext = Path.GetExtension(file.Path); if (0 != String.Compare(ext, ".aspx", StringComparison.OrdinalIgnoreCase)) { return(false); } if (!File.Exists(file.Path)) { return(false); // happens... let's avoid the AD0001 exception } return(true); })) { AnalyzeFile(file, ctx); } }
private static void AnalyzeCompilation(CompilationAnalysisContext context) { var compilation = context.Compilation; var allPlugins = compilation.SyntaxTrees .Select(x => x.GetCompilationUnitRoot()) .SelectMany(x => x.FindSyntax<ClassDeclarationSyntax>()) .Where(x => x.IsPluginClass()) .ToArray(); var plugins = allPlugins.Where(x => x.IsExportIPlugin()).ToArray(); foreach (var p in allPlugins) { var guidVaue = p.GetGuidMetadataValue(); if (guidVaue == null) continue; //GUID な Metadata がない場合はスルー // GUID として解釈できない値か、IPlugin で未定義の GUID が指定されてたらアウト Guid guid; if (!Guid.TryParse(guidVaue, out guid) || plugins.All(x => x.GetGuidMetadataValue().ToUpper() != guidVaue.ToUpper())) context.ReportDiagnostic(Diagnostic.Create(InvalidGuidMetadataRule, p.GetLocation())); } }
public void ReportProblems(CompilationAnalysisContext context, EntityInterface entityInterface) { var childNodes = entityInterface.InterfaceDeclaration.ChildNodes(); foreach (var node in childNodes) { if (node.IsKind(SyntaxKind.MethodDeclaration)) { var returnTypeNode = node.ChildNodes().Where(x => x.IsKind(SyntaxKind.PredefinedType) || x.IsKind(SyntaxKind.IdentifierName) || x.IsKind(SyntaxKind.GenericName)); if (returnTypeNode.Any()) { var returnType = returnTypeNode.First().ToString(); if (!returnType.Equals("void") && !returnType.StartsWith("Task")) { var diagnostic = Diagnostic.Create(Rule, node.GetLocation(), returnType); context.ReportDiagnostic(diagnostic); } } } } }
private void CompilationStart(CompilationAnalysisContext context) { if (configFile != null) { return; // introduced for unit testing, for now } var additionalFiles = context.Options.AdditionalFiles.Where(f => f.Path.ToLower().EndsWith(".namespacer")); if (!additionalFiles.Any()) { context.ReportDiagnostic(Diagnostic.Create(ConfigurationRule, null, "There is no configuration file added to compilation as an AdditionalFile with a '.namespacer' suffix. Consider adding '<AdditionalFiles Include=\".namespacer\" />' to your csproj.")); return; } configFile = ConfigFile.LoadFromFile(additionalFiles.First().Path); if (configFile == null) { context.ReportDiagnostic(Diagnostic.Create(ConfigurationRule, null, $"Configuration file '{additionalFiles.First().Path}' was found, but failed parsing.")); } }
public static void ReportProblems( CompilationAnalysisContext context, SemanticModel semanticModel, IEnumerable <ActivityFunctionDefinition> functionDefinitions, IEnumerable <ActivityFunctionCall> functionInvocations) { foreach (var invocation in functionInvocations) { var definition = functionDefinitions.FirstOrDefault(x => x.FunctionName == invocation.FunctionName); if (definition != null) { if (InvocationInputIsNull(invocation)) { if (DefinitionInputIsNonNullableValueType(definition)) { var diagnostic = Diagnostic.Create(InvalidNullRule, invocation.InputNode.GetLocation(), invocation.FunctionName, definition.InputType.ToString()); context.ReportDiagnostic(diagnostic); } } else { if (DefinitionInputIsNotUsed(definition)) { var diagnostic = Diagnostic.Create(InputNotUsedRule, invocation.InputNode.GetLocation(), invocation.FunctionName); context.ReportDiagnostic(diagnostic); } else if (!IsValidArgumentForDefinition(invocation, definition)) { var diagnostic = Diagnostic.Create(MismatchRule, invocation.InputNode.GetLocation(), invocation.FunctionName, definition.InputType, invocation.InputType); context.ReportDiagnostic(diagnostic); } } } } }
private static void AnalyzeCompilation(CompilationAnalysisContext context) { INamedTypeSymbol assemblyVersionAttributeSymbol = WellKnownTypes.AssemblyVersionAttribute(context.Compilation); INamedTypeSymbol assemblyComplianceAttributeSymbol = WellKnownTypes.CLSCompliantAttribute(context.Compilation); if (assemblyVersionAttributeSymbol == null && assemblyComplianceAttributeSymbol == null) { return; } bool assemblyVersionAttributeFound = false; bool assemblyComplianceAttributeFound = false; // Check all assembly level attributes for the target attribute foreach (AttributeData attribute in context.Compilation.Assembly.GetAttributes()) { if (attribute.AttributeClass.Equals(assemblyVersionAttributeSymbol)) { // Mark the version attribute as found assemblyVersionAttributeFound = true; } else if (attribute.AttributeClass.Equals(assemblyComplianceAttributeSymbol)) { // Mark the compliance attribute as found assemblyComplianceAttributeFound = true; } } if (!assemblyVersionAttributeFound && assemblyVersionAttributeSymbol != null) { context.ReportDiagnostic(Diagnostic.Create(CA1016Rule, Location.None)); } if (!assemblyComplianceAttributeFound && assemblyComplianceAttributeSymbol != null) { context.ReportDiagnostic(Diagnostic.Create(CA1014Rule, Location.None)); } }
/// <summary> /// Performs the analysis. /// </summary> /// <param name="context">The context in which the analysis should be performed.</param> private static void AnalyzeCompilation(CompilationAnalysisContext context) { var compilation = context.Compilation; var types = compilation.GetSymbolsWithName(_ => true, SymbolFilter.Type).OfType <INamedTypeSymbol>().ToArray(); var components = types.Where(type => type.IsComponent(compilation)).ToArray(); var faultEffects = types.Where(type => type.IsFaultEffect(compilation) && !type.HasAttribute <PriorityAttribute>(compilation)).ToArray(); foreach (var component in components) { var effects = faultEffects.Where(faultEffect => faultEffect.BaseType.Equals(component)).ToArray(); var nondeterministic = effects.GroupBy(fault => fault.GetPriority(compilation)).Where(group => group.Count() > 1).ToArray(); foreach (var method in component.GetFaultAffectableMethods(context.Compilation)) { var unprioritizedTypes = nondeterministic .Where(typeGroup => typeGroup.Count(f => f.GetMembers().OfType <IMethodSymbol>().Any(m => m.Overrides(method))) > 1) .SelectMany(typeGroup => typeGroup) .Where(type => type.GetMembers().OfType <IMethodSymbol>().Any(m => m.Overrides(method))) .Select(type => $"'{type.ToDisplayString()}'") .OrderBy(type => type) .ToArray(); if (unprioritizedTypes.Length <= 0) { continue; } if (method.ContainingType.Equals(component)) { _multipleEffectsWithoutPriority.Emit(context, method, method.ToDisplayString(), String.Join(", ", unprioritizedTypes)); } else { _multipleEffectsWithoutPriority.Emit(context, component, method.ToDisplayString(), String.Join(", ", unprioritizedTypes)); } } } }
public static void ReportProblems(CompilationAnalysisContext context, EntityInterface entityInterface) { var interfaceDeclaration = entityInterface.InterfaceDeclaration; var interfaceChildNodes = interfaceDeclaration.ChildNodes(); if (!interfaceChildNodes.Any()) { var diagnostic = Diagnostic.Create(NoMethodsRule, interfaceDeclaration.GetLocation(), interfaceDeclaration); context.ReportDiagnostic(diagnostic); return; } foreach (var node in interfaceChildNodes) { if (!node.IsKind(SyntaxKind.MethodDeclaration)) { var diagnostic = Diagnostic.Create(NotAMethodRule, node.GetLocation(), node); context.ReportDiagnostic(diagnostic); } } }
private void RegisterAnalyzers(CompilationAnalysisContext context) { var methodInvocationAnalyzer = new MethodInvocationAnalyzer(); var orchestratorMethods = orchestratorMethodCollector.GetOrchestratorMethods(); foreach (var methodInformation in orchestratorMethods) { var semanticModel = methodInformation.SemanticModel; var methodDeclaration = methodInformation.Declaration; // | is the non short circuit or; this is important so that each method analyzes the code and reports all needed diagnostics. if (DateTimeAnalyzer.RegisterDiagnostic(context, semanticModel, methodDeclaration) | EnvironmentVariableAnalyzer.RegisterDiagnostic(context, semanticModel, methodDeclaration) | GuidAnalyzer.RegisterDiagnostic(context, semanticModel, methodDeclaration) | IOTypesAnalyzer.RegisterDiagnostic(context, semanticModel, methodDeclaration) | ThreadTaskAnalyzer.RegisterDiagnostic(context, semanticModel, methodDeclaration) | TimerAnalyzer.RegisterDiagnostic(context, semanticModel, methodDeclaration) | CancellationTokenAnalyzer.RegisterDiagnostic(context, methodDeclaration)) { methodInvocationAnalyzer.RegisterDiagnostics(context, methodInformation); } } }
public static void ReportProblems(CompilationAnalysisContext context, EntityInterface entityInterface) { var interfaceChildNodes = entityInterface.InterfaceDeclaration.ChildNodes(); foreach (var node in interfaceChildNodes) { if (node.IsKind(SyntaxKind.MethodDeclaration)) { var parameterList = node.ChildNodes().Where(x => x.IsKind(SyntaxKind.ParameterList)); if (!parameterList.Any()) { return; } var parameters = parameterList.First().ChildNodes().Where(x => x.IsKind(SyntaxKind.Parameter)); if (parameters.Count() > 1) { var diagnostic = Diagnostic.Create(Rule, node.GetLocation(), node); context.ReportDiagnostic(diagnostic); } } } }
private static void HandleCompilation(CompilationAnalysisContext context) { var firstSyntaxTree = context.Compilation.SyntaxTrees.FirstOrDefault(); if (firstSyntaxTree is null) { return; } try { SettingsHelper.GetStyleCopSettings(context.Options, firstSyntaxTree, DeserializationFailureBehavior.ThrowException, context.CancellationToken); } catch (Exception ex) when(ex is JsonParseException || ex is InvalidSettingsException) { string details = ex.Message; string completeDescription = string.Format(Description.ToString(CultureInfo.CurrentCulture), details); var completeDescriptor = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.SpecialRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, completeDescription, HelpLink); context.ReportDiagnostic(Diagnostic.Create(completeDescriptor, Location.None)); } }
internal void CompilationEnd(CompilationAnalysisContext context) { if (_codeFixProviders == null) { // No fixers. return; } if (_codeActionCreateInvocations == null && _codeActionObjectCreations == null) { // No registered fixes. return; } // Analyze all fixers that have FixAll support. foreach (INamedTypeSymbol fixer in _codeFixProviders) { if (OverridesGetFixAllProvider(fixer)) { AnalyzeFixerWithFixAll(fixer, context); } } }
public void CompilationEndAction(CompilationAnalysisContext context) { if (_interfacesWithUnsecureMethods == null || _secureTypes == null) { // No violating types. return; } // Report diagnostic for violating named types. foreach (var secureType in _secureTypes) { foreach (var unsecureInterface in _interfacesWithUnsecureMethods) { if (secureType.AllInterfaces.Contains(unsecureInterface)) { var diagnostic = Diagnostic.Create(Rule, secureType.Locations[0], secureType.Name, SecureTypeInterfaceName, unsecureInterface.Name); context.ReportDiagnostic(diagnostic); break; } } } }
public void CompilationEnd(CompilationAnalysisContext context) { foreach (var symbol in _potentialSymbols) { if (_cannotBeStaticSymbols.Contains(symbol)) { continue; } if (symbol is IMethodSymbol) { context.ReportDiagnostic(s_methodRule, symbol); } else if (symbol is IPropertySymbol) { context.ReportDiagnostic(s_propertyRule, symbol); } else { throw new InvalidOperationException("Symbol is not supported: " + symbol); } } }
private void RaiseIssuesFromResultFile(CompilationAnalysisContext context) { LogIfFailure($"- parsing file {cbdeResultsPath}"); try { var document = XDocument.Load(cbdeResultsPath); foreach (var i in document.Descendants("Issue")) { RaiseIssueFromXElement(i, context); } } catch (Exception exception) { if (exception is XmlException || exception is NullReferenceException) { LogIfFailure($"- error parsing result file {cbdeResultsPath}: {exception}"); Log(logStringBuilder.ToString()); ReportEndOfCbdeExecution(); throw new CbdeException($"Error parsing output from CBDE: {exception.Message}{moreDetailsMessage}"); } ReportEndOfCbdeExecution(); throw; } }
public void Analyze( string targetPath, Action <Diagnostic> reportDiagnostic, CancellationToken cancellationToken = default(CancellationToken)) { // Create a Roslyn representation of the IL by constructing a MetadataReference against // the target path (as if we intended to reference this binary during compilation, instead // of analyzing it). Using this mechanism, we can scan types/members contained in the // binary. We cannot currently retrieve IL from method bodies. PortableExecutableReference reference = MetadataReference.CreateFromFile(targetPath); var compilation = CSharpCompilation.Create("_", references: new[] { reference }); ISymbol target = compilation.GetAssemblyOrModuleSymbol(reference); // For each analysis target, we create a compilation start context, which may result // in symbol action registration. We need to capture and throw these registrations // away for each binary we inspect. var compilationStartAnalysisContext = new RoslynCompilationStartAnalysisContext(compilation, _options, cancellationToken); this.GlobalRoslynAnalysisContext.CompilationStartActions?.Invoke(compilationStartAnalysisContext); var visitor = new RoslynSymbolVisitor(symbol => this.Analyze( symbol, compilation, compilationStartAnalysisContext.SymbolActions, reportDiagnostic, cancellationToken)); visitor.Visit(target); // Having finished analysis, we'll invoke any compilation end actions registered previously. // We also discard the per-compilation symbol actions we collected. var compilationAnalysisContext = new CompilationAnalysisContext(compilation, _options, reportDiagnostic, _isSupportedDiagnostic, cancellationToken); this.GlobalRoslynAnalysisContext.CompilationActions?.Invoke(compilationAnalysisContext); compilationStartAnalysisContext.CompilationEndActions?.Invoke(compilationAnalysisContext); }
public static UseMvcDiagnosticValidator CreateAndInitialize(CompilationAnalysisContext context, ConcurrentBag <StartupComputedAnalysis> analyses) { if (analyses == null) { throw new ArgumentNullException(nameof(analyses)); } var validator = new UseMvcDiagnosticValidator(); foreach (var mvcOptionsAnalysis in analyses.OfType <MvcOptionsAnalysis>()) { // Each analysis of the options is one-per-class (in user code). Find the middleware analysis foreach of the Configure methods // defined by this class and validate. // // Note that this doesn't attempt to handle inheritance scenarios. foreach (var middlewareAnalsysis in analyses.OfType <MiddlewareAnalysis>().Where(m => m.EnclosingType == mvcOptionsAnalysis.EnclosingType)) { foreach (var middlewareItem in middlewareAnalsysis.Middleware) { if ((middlewareItem.UseMethod.Name == "UseMvc" || middlewareItem.UseMethod.Name == "UseMvcWithDefaultRoute") && // Report a diagnostic if it's unclear that the user turned off Endpoint Routing. (mvcOptionsAnalysis.EndpointRoutingEnabled == true || mvcOptionsAnalysis.EndpointRoutingEnabled == null)) { context.ReportDiagnostic(Diagnostic.Create( StartupAnalzyer.UnsupportedUseMvcWithEndpointRouting, middlewareItem.Operation.Syntax.GetLocation(), middlewareItem.UseMethod.Name, mvcOptionsAnalysis.ConfigureServicesMethod.Name)); } } } } return(validator); }
private static bool AnalyzeIdentifierThread(SyntaxNode method, CompilationAnalysisContext context, SemanticModel semanticModel) { var diagnosedIssue = false; foreach (SyntaxNode descendant in method.DescendantNodes()) { if (descendant is IdentifierNameSyntax identifierName) { version = SyntaxNodeUtils.GetDurableVersion(semanticModel); var identifierText = identifierName.Identifier.ValueText; if (identifierText == "Sleep") { var memberAccessExpression = identifierName.Parent; if (SyntaxNodeUtils.TryGetISymbol(semanticModel, memberAccessExpression, out ISymbol memberSymbol)) { if (memberSymbol != null && memberSymbol.ToString().StartsWith("System.Threading.Thread")) { if (TryGetRuleFromVersion(out DiagnosticDescriptor rule)) { var expression = GetAwaitOrInvocationExpression(memberAccessExpression); var diagnostic = Diagnostic.Create(rule, expression.GetLocation(), expression); context.ReportDiagnostic(diagnostic); diagnosedIssue = true; } } } } } } return(diagnosedIssue); }
// Checks the syntax tree analysis part of the user analyzer, returns a bool representing whether the check was successful or not private bool CheckAnalysis(string branch, string kind, List<string> ruleNames, CompilationAnalysisContext context, IMethodSymbol analysisMethodSymbol) { if (branch == "SyntaxNode") { if (kind == "IfStatement") { return CheckIfStatementAnalysis(ruleNames, context, analysisMethodSymbol); } } return false; }
//"main" method, performs the analysis once state has been collected internal protected void ReportCompilationEndDiagnostics(CompilationAnalysisContext context) { //supported main branches for tutorial _branchesDict.Add("RegisterSyntaxNodeAction", "SyntaxNode"); //supported sub-branches for tutorial List<string> allowedKinds = new List<string>(); allowedKinds.Add("IfStatement"); if (_analyzerClassSymbol == null) { return; } //look for and interpret id fields List<string> idNames = CheckIds(); if (idNames.Count > 0) { //look for and interpret rule fields List<string> ruleNames = CheckRules(idNames, context); if (ruleNames.Count > 0) { //look for and interpret SupportedDiagnostics property bool supportedDiagnosticsCorrect = CheckSupportedDiagnostics(ruleNames, context); if (supportedDiagnosticsCorrect) { //gather initialize info CheckInitializeInfo registerInfo = CheckInitialize(context); if (registerInfo == null) { return; } var registerSymbol = registerInfo.RegisterMethod; if (registerSymbol == null) { return; } var registerArgs = registerInfo.RegisterArgs; if (registerArgs == null) { return; } if (registerArgs.Count == 0) { return; } IMethodSymbol analysisMethodSymbol = null; if (registerArgs.Count > 0) { analysisMethodSymbol = (IMethodSymbol)registerArgs[0]; } IFieldSymbol kind = null; if (registerArgs.Count > 1) { kind = (IFieldSymbol)registerArgs[1]; } else { return; } var invocationExpression = registerInfo.InvocationExpr; if (invocationExpression == null) { return; } //interpret initialize info if (_branchesDict.ContainsKey(registerSymbol.Name)) { string kindName = null; if (kind != null) { kindName = kind.Name; } if (kindName == null || allowedKinds.Contains(kindName)) { //look for and interpret analysis methods bool analysisMethodFound = CheckMethods(invocationExpression, context); if (analysisMethodFound) { //check the SyntaxNode, Symbol, Compilation, CodeBlock, etc analysis method(s) bool analysisCorrect = CheckAnalysis(_branchesDict[registerSymbol.Name], kindName, ruleNames, context, analysisMethodSymbol); if (analysisCorrect) { ReportDiagnostic(context, GoToCodeFixRule, _analyzerClassSymbol.Locations[0]); } else { return; } } else { return; } } else { Location loc = null; if (kindName == null) { loc = invocationExpression.ArgumentList.GetLocation(); } else { loc = invocationExpression.ArgumentList.Arguments[1].GetLocation(); } ReportDiagnostic(context, IncorrectKindRule, loc); } } else { return; } } else { return; } } else { return; } } else { ReportDiagnostic(context, MissingIdRule, _analyzerClassSymbol.Locations[0], _analyzerClassSymbol.Name); } }
//reports a diagnostics private static void ReportDiagnostic(CompilationAnalysisContext context, DiagnosticDescriptor rule, Location location, params string[] messageArgs) { Diagnostic diagnostic = Diagnostic.Create(rule, location, messageArgs); context.ReportDiagnostic(diagnostic); }
// Checks the body of initializer, returns the invocation expression and member expression of the register statements, null if failed private InitializeBodyInfo InitializeBody(CompilationAnalysisContext context, SyntaxList<StatementSyntax> statements) { var statement = statements[0] as ExpressionStatementSyntax; if (statement == null) { ReportDiagnostic(context, InvalidStatementRule, statements[0].GetLocation()); return null; } var invocationExpr = statement.Expression as InvocationExpressionSyntax; if (invocationExpr == null) { ReportDiagnostic(context, InvalidStatementRule, statements[0].GetLocation()); return null; } var memberExpr = invocationExpr.Expression as MemberAccessExpressionSyntax; if (memberExpr == null) { ReportDiagnostic(context, InvalidStatementRule, statements[0].GetLocation()); return null; } var memberExprContext = memberExpr.Expression as IdentifierNameSyntax; if (memberExprContext == null) { ReportDiagnostic(context, InvalidStatementRule, statements[0].GetLocation()); return null; } MethodDeclarationSyntax methodDeclaration = statement.Parent.Parent as MethodDeclarationSyntax; ParameterSyntax parameter = methodDeclaration.ParameterList.Parameters[0] as ParameterSyntax; if (memberExprContext.Identifier.Text != parameter.Identifier.ValueText) { ReportDiagnostic(context, InvalidStatementRule, statements[0].GetLocation()); return null; } var memberExprRegister = memberExpr.Name as IdentifierNameSyntax; if (memberExprRegister == null) { ReportDiagnostic(context, InvalidStatementRule, statements[0].GetLocation()); return null; } if (!_branchesDict.ContainsKey(memberExprRegister.Identifier.Text)) { ReportDiagnostic(context, IncorrectRegisterRule, memberExprRegister.GetLocation()); return null; } return new InitializeBodyInfo(invocationExpr, memberExpr); }
// Checks the signature of initialize and returns the block of the method, null if failed private BlockSyntax InitializeOverview(CompilationAnalysisContext context) { ImmutableArray<IParameterSymbol> parameters = _initializeSymbol.Parameters; if (parameters.Count() != 1 || parameters[0].Type != context.Compilation.GetTypeByMetadataName("Microsoft.CodeAnalysis.Diagnostics.AnalysisContext") || _initializeSymbol.DeclaredAccessibility != Accessibility.Public || !_initializeSymbol.IsOverride || !_initializeSymbol.ReturnsVoid) { ReportDiagnostic(context, IncorrectInitSigRule, _initializeSymbol.Locations[0], _initializeSymbol.Name); return null; } //looking at the contents of the initialize method var initializeMethod = _initializeSymbol.DeclaringSyntaxReferences[0].GetSyntax() as MethodDeclarationSyntax; if (initializeMethod == null) { return null; } var codeBlock = initializeMethod.Body as BlockSyntax; if (codeBlock == null) { return null; } return codeBlock; }
// Returns a symbol for the register call, and a list of the arguments private CheckInitializeInfo CheckInitialize(CompilationAnalysisContext context) { //default values for returning IMethodSymbol registerCall = null; List<ISymbol> registerArgs = new List<ISymbol>(); InvocationExpressionSyntax invocExpr = null; if (_initializeSymbol == null) { //the initialize method was not found ReportDiagnostic(context, MissingInitRule, _analyzerClassSymbol.Locations[0], _analyzerClassSymbol.Name); return new CheckInitializeInfo(); } else { //checking method signature var codeBlock = InitializeOverview(context) as BlockSyntax; if (codeBlock == null) { return new CheckInitializeInfo(); } SyntaxList<StatementSyntax> statements = codeBlock.Statements; if (statements.Count == 0) { //no statements inside initiailize ReportDiagnostic(context, MissingRegisterRule, _initializeSymbol.Locations[0], _initializeSymbol.Name); return new CheckInitializeInfo(); } else if (statements.Count > 1) { foreach (var statement in statements) { if (statement.Kind() != SyntaxKind.ExpressionStatement) { ReportDiagnostic(context, InvalidStatementRule, statement.GetLocation()); return new CheckInitializeInfo(); } } foreach (ExpressionStatementSyntax statement in statements) { var expression = statement.Expression as InvocationExpressionSyntax; if (expression == null) { ReportDiagnostic(context, InvalidStatementRule, statement.GetLocation()); return new CheckInitializeInfo(); } var expressionStart = expression.Expression as MemberAccessExpressionSyntax; if (expressionStart == null || expressionStart.Name == null) { ReportDiagnostic(context, InvalidStatementRule, statement.GetLocation()); return new CheckInitializeInfo(); } var preExpressionStart = expressionStart.Expression as IdentifierNameSyntax; if (preExpressionStart == null || preExpressionStart.Identifier == null || preExpressionStart.Identifier.ValueText != _initializeSymbol.Parameters.First().Name) { ReportDiagnostic(context, InvalidStatementRule, statement.GetLocation()); return new CheckInitializeInfo(); } var name = expressionStart.Name.Identifier.Text; if (!_branchesDict.ContainsKey(name)) { ReportDiagnostic(context, InvalidStatementRule, statement.GetLocation()); return new CheckInitializeInfo(); } } //too many statements inside initialize ReportDiagnostic(context, TooManyInitStatementsRule, _initializeSymbol.Locations[0], _initializeSymbol.Name); return new CheckInitializeInfo(); } //only one statement inside initialize else { InitializeBodyInfo bodyResults = InitializeBody(context, statements); if (bodyResults == null) { return new CheckInitializeInfo(); } var invocationExpr = bodyResults.InvocationExpr as InvocationExpressionSyntax; var memberExpr = bodyResults.MemberExpr as MemberAccessExpressionSyntax; invocExpr = invocationExpr; if (context.Compilation.GetSemanticModel(invocationExpr.SyntaxTree).GetSymbolInfo(memberExpr).CandidateSymbols.Count() == 0) { registerCall = context.Compilation.GetSemanticModel(memberExpr.SyntaxTree).GetSymbolInfo(memberExpr).Symbol as IMethodSymbol; } else { registerCall = context.Compilation.GetSemanticModel(memberExpr.SyntaxTree).GetSymbolInfo(memberExpr).CandidateSymbols[0] as IMethodSymbol; } if (registerCall == null) { return new CheckInitializeInfo(registerCall, invocationExpr: invocExpr); } SeparatedSyntaxList<ArgumentSyntax> arguments = invocationExpr.ArgumentList.Arguments; if (arguments == null || arguments.Count == 0) { ReportDiagnostic(context, IncorrectArgumentsRule, invocationExpr.Expression.GetLocation()); return new CheckInitializeInfo(registerCall, invocationExpr: invocExpr); } if (arguments.Count > 0) { IMethodSymbol actionSymbol = context.Compilation.GetSemanticModel(invocationExpr.SyntaxTree).GetSymbolInfo(arguments[0].Expression).Symbol as IMethodSymbol; registerArgs.Add(actionSymbol); if (arguments.Count > 1) { IFieldSymbol kindSymbol = context.Compilation.GetSemanticModel(invocationExpr.SyntaxTree).GetSymbolInfo(arguments[1].Expression).Symbol as IFieldSymbol; if (kindSymbol == null) { return new CheckInitializeInfo(registerCall, registerArgs, invocExpr); } else { registerArgs.Add(kindSymbol); } } else { ReportDiagnostic(context, IncorrectArgumentsRule, invocationExpr.Expression.GetLocation()); } } } } return new CheckInitializeInfo(registerCall, registerArgs, invocExpr); }
// Returns a list of rule names private List<string> CheckRules(List<string> idNames, CompilationAnalysisContext context) { List<string> ruleNames = new List<string>(); List<string> emptyRuleNames = new List<string>(); bool foundARule = false; foreach (IFieldSymbol fieldSymbol in _analyzerFieldSymbols) { if (fieldSymbol.Type != null && fieldSymbol.Type.MetadataName == "DiagnosticDescriptor") { foundARule = true; if (fieldSymbol.DeclaredAccessibility != Accessibility.Internal || !fieldSymbol.IsStatic) { ReportDiagnostic(context, InternalAndStaticErrorRule, fieldSymbol.Locations[0], fieldSymbol.Name); return emptyRuleNames; } var declaratorSyntax = fieldSymbol.DeclaringSyntaxReferences[0].GetSyntax() as VariableDeclaratorSyntax; if (declaratorSyntax == null) { return emptyRuleNames; } var initializer = declaratorSyntax.Initializer as EqualsValueClauseSyntax; if (initializer == null) { return emptyRuleNames; } var objectCreationSyntax = initializer.Value as ObjectCreationExpressionSyntax; if (objectCreationSyntax == null) { return emptyRuleNames; } var ruleArgumentList = objectCreationSyntax.ArgumentList; for (int i = 0; i < ruleArgumentList.Arguments.Count; i++) { var currentArg = ruleArgumentList.Arguments[i]; if (currentArg == null) { return emptyRuleNames; } if (currentArg.NameColon != null) { string currentArgName = currentArg.NameColon.Name.Identifier.Text; var currentArgExpr = currentArg.Expression; var currentArgExprIdentifier = currentArgExpr as IdentifierNameSyntax; if (currentArgName == "isEnabledByDefault") { if (currentArgExprIdentifier != null) { if (currentArgExprIdentifier.Identifier.Text == "") { ReportDiagnostic(context, EnabledByDefaultErrorRule, currentArg.GetLocation()); return emptyRuleNames; } } if (!currentArgExpr.IsKind(SyntaxKind.TrueLiteralExpression)) { ReportDiagnostic(context, EnabledByDefaultErrorRule, currentArgExpr.GetLocation()); return emptyRuleNames; } } else if (currentArgName == "defaultSeverity") { if (currentArgExprIdentifier != null) { if (currentArgExprIdentifier.Identifier.Text == "") { ReportDiagnostic(context, DefaultSeverityErrorRule, currentArg.GetLocation()); return emptyRuleNames; } } var memberAccessExpr = currentArgExpr as MemberAccessExpressionSyntax; if (memberAccessExpr == null) { ReportDiagnostic(context, DefaultSeverityErrorRule, currentArgExpr.GetLocation()); return emptyRuleNames; } var expressionIdentifier = memberAccessExpr.Expression as IdentifierNameSyntax; if (expressionIdentifier == null) { ReportDiagnostic(context, DefaultSeverityErrorRule, currentArgExpr.GetLocation()); return emptyRuleNames; } string expressionText = expressionIdentifier.Identifier.Text; var expressionName = memberAccessExpr.Name as IdentifierNameSyntax; if (expressionName == null) { ReportDiagnostic(context, DefaultSeverityErrorRule, currentArgExpr.GetLocation()); return emptyRuleNames; } string identifierName = memberAccessExpr.Name.Identifier.Text; List<string> severities = new List<string> { "Warning", "Error" }; if (expressionText != "DiagnosticSeverity") { ReportDiagnostic(context, DefaultSeverityErrorRule, currentArgExpr.GetLocation()); return emptyRuleNames; } else if (!severities.Contains(identifierName)) { ReportDiagnostic(context, DefaultSeverityErrorRule, currentArgExpr.GetLocation()); return emptyRuleNames; } } else if (currentArgName == "id") { if (currentArgExprIdentifier != null) { if (currentArgExprIdentifier.Identifier.Text == "") { ReportDiagnostic(context, IdDeclTypeErrorRule, Location.Create(currentArg.SyntaxTree, currentArg.NameColon.ColonToken.TrailingTrivia.FullSpan)); return emptyRuleNames; } } if (currentArgExpr.IsKind(SyntaxKind.StringLiteralExpression)) { ReportDiagnostic(context, IdStringLiteralRule, currentArgExpr.GetLocation()); return emptyRuleNames; } if (!currentArgExpr.IsKind(SyntaxKind.IdentifierName)) { ReportDiagnostic(context, IdDeclTypeErrorRule, currentArgExpr.GetLocation()); return emptyRuleNames; } var ruleName = fieldSymbol.Name as string; if (ruleName == null) { return emptyRuleNames; } bool ruleIdFound = false; foreach (string idName in idNames) { if (idName == currentArgExprIdentifier.Identifier.Text) { ruleNames.Add(ruleName); ruleIdFound = true; } } if (!ruleIdFound) { ReportDiagnostic(context, MissingIdDeclarationRule, currentArgExpr.GetLocation()); return emptyRuleNames; } } else if (currentArgName == "title" || currentArgName == "messageFormat" || currentArgName == "category") { Dictionary<string, string> argDefaults = new Dictionary<string, string>(); argDefaults.Add("title", "Enter a title for this diagnostic"); argDefaults.Add("messageFormat", "Enter a message to be displayed with this diagnostic"); argDefaults.Add("category", "Enter a category for this diagnostic (e.g. Formatting)"); if (currentArgExpr.IsKind(SyntaxKind.StringLiteralExpression)) { if ((currentArgExpr as LiteralExpressionSyntax).Token.ValueText == argDefaults[currentArgName]) { if (currentArgName == "title") { ReportDiagnostic(context, TitleRule, currentArgExpr.GetLocation()); return emptyRuleNames; } else if (currentArgName == "messageFormat") { ReportDiagnostic(context, MessageRule, currentArgExpr.GetLocation()); return emptyRuleNames; } else if (currentArgName == "category") { ReportDiagnostic(context, CategoryRule, currentArgExpr.GetLocation()); return emptyRuleNames; } } } } } } if (ruleArgumentList.Arguments.Count != 6) { return emptyRuleNames; } } } if (foundARule) { return ruleNames; } else { var analyzerClass = _analyzerClassSymbol.DeclaringSyntaxReferences[0].GetSyntax() as ClassDeclarationSyntax; Location idLocation = null; foreach (IFieldSymbol field in _analyzerFieldSymbols) { if (idNames.Contains(field.Name)) { var idField = field.DeclaringSyntaxReferences[0].GetSyntax() as VariableDeclaratorSyntax; idLocation = idField.Identifier.GetLocation(); break; } } ReportDiagnostic(context, MissingRuleRule, idLocation); return emptyRuleNames; } }
//Returns the valueClause of the return statement from SupportedDiagnostics and the return declaration, empty list if failed private SuppDiagReturnSymbolInfo SuppDiagReturnSymbol(CompilationAnalysisContext context, SymbolInfo returnSymbolInfo, Location getAccessorKeywordLocation, PropertyDeclarationSyntax propertyDeclaration) { SuppDiagReturnSymbolInfo result = new SuppDiagReturnSymbolInfo(); ILocalSymbol returnSymbol = null; if (returnSymbolInfo.CandidateSymbols.Count() == 0) { returnSymbol = returnSymbolInfo.Symbol as ILocalSymbol; } else { returnSymbol = returnSymbolInfo.CandidateSymbols[0] as ILocalSymbol; } if (returnSymbol == null) { ReportDiagnostic(context, IncorrectAccessorReturnRule, getAccessorKeywordLocation); return result; } var variableDeclaration = returnSymbol.DeclaringSyntaxReferences[0].GetSyntax() as VariableDeclaratorSyntax; ReturnStatementSyntax returnDeclaration = returnSymbol.DeclaringSyntaxReferences[0].GetSyntax() as ReturnStatementSyntax; if (variableDeclaration == null) { ReportDiagnostic(context, IncorrectAccessorReturnRule, returnSymbol.Locations[0]); return result; } var equalsValueClause = variableDeclaration.Initializer as EqualsValueClauseSyntax; if (equalsValueClause == null) { ReportDiagnostic(context, IncorrectAccessorReturnRule, variableDeclaration.GetLocation()); return result; } var valueClause = equalsValueClause.Value as InvocationExpressionSyntax; if (valueClause == null) { ReportDiagnostic(context, IncorrectAccessorReturnRule, variableDeclaration.GetLocation()); return result; } var valueClauseMemberAccess = valueClause.Expression as MemberAccessExpressionSyntax; if (valueClauseMemberAccess == null) { ReportDiagnostic(context, IncorrectAccessorReturnRule, valueClause.GetLocation()); return result; } var valueClauseExpression = valueClauseMemberAccess.Expression as IdentifierNameSyntax; if (valueClauseExpression == null || valueClauseExpression.Identifier.Text != "ImmutableArray") { ReportDiagnostic(context, IncorrectAccessorReturnRule, valueClause.GetLocation()); return result; } var valueClauseName = valueClauseMemberAccess.Name as IdentifierNameSyntax; if (valueClauseName == null || valueClauseName.Identifier.Text != "Create") { ReportDiagnostic(context, SuppDiagReturnValueRule, valueClauseName.GetLocation(), propertyDeclaration.Identifier.Text); return result; } result.ValueClause = valueClause; result.ReturnDeclaration = returnDeclaration; return result; }
// Checks the return value of the get accessor within SupportedDiagnostics private bool SuppDiagReturnCheck(CompilationAnalysisContext context, InvocationExpressionSyntax valueClause, ReturnStatementSyntax returnDeclarationLocation, List<string> ruleNames, PropertyDeclarationSyntax propertyDeclaration) { if (valueClause == null) { ReportDiagnostic(context, IncorrectAccessorReturnRule, returnDeclarationLocation.ReturnKeyword.GetLocation()); return false; } var valueExpression = valueClause.Expression as MemberAccessExpressionSyntax; if (valueExpression == null) { ReportDiagnostic(context, IncorrectAccessorReturnRule, returnDeclarationLocation.ReturnKeyword.GetLocation()); return false; } var valueExprExpr = valueExpression.Expression as IdentifierNameSyntax; var valueExprName = valueExpression.Name as IdentifierNameSyntax; if (valueExprExpr == null || valueExprExpr.Identifier.Text != "ImmutableArray") { ReportDiagnostic(context, IncorrectAccessorReturnRule, valueExpression.GetLocation(), propertyDeclaration.Identifier.Text); return false; } if (valueExprName == null || valueExprName.Identifier.Text != "Create") { ReportDiagnostic(context, SuppDiagReturnValueRule, valueExpression.GetLocation(), propertyDeclaration.Identifier.Text); return false; } var valueArguments = valueClause.ArgumentList as ArgumentListSyntax; if (valueArguments == null) { ReportDiagnostic(context, SupportedRulesRule, valueExpression.GetLocation(), propertyDeclaration.Identifier.Text); return false; } SeparatedSyntaxList<ArgumentSyntax> valueArgs = valueArguments.Arguments; if (valueArgs.Count == 0) { ReportDiagnostic(context, SupportedRulesRule, valueExpression.GetLocation()); return false; } if (ruleNames.Count != valueArgs.Count) { ReportDiagnostic(context, SupportedRulesRule, valueExpression.GetLocation()); return false; } List<string> newRuleNames = new List<string>(); foreach (string rule in ruleNames) { newRuleNames.Add(rule); } foreach (ArgumentSyntax arg in valueArgs) { bool foundRule = false; foreach (string ruleName in ruleNames) { var argExpression = arg.Expression as IdentifierNameSyntax; if (argExpression != null) { if (argExpression.Identifier.Text == ruleName) { foundRule = true; } } } if (!foundRule) { ReportDiagnostic(context, SupportedRulesRule, valueExpression.GetLocation()); return false; } } return true; }
// Checks the AnalyzeIfStatement of the user's analyzer, returns a bool representing whether the check was successful or not private bool CheckIfStatementAnalysis(List<string> ruleNames, CompilationAnalysisContext context, IMethodSymbol analysisMethodSymbol) { var methodDeclaration = AnalysisGetStatements(analysisMethodSymbol) as MethodDeclarationSyntax; var body = methodDeclaration.Body as BlockSyntax; if (body == null) { return false; } var statements = body.Statements; if (statements == null) { return false; } var contextParameter = methodDeclaration.ParameterList.Parameters[0] as ParameterSyntax; if (contextParameter == null) { return false; } int statementCount = statements.Count; if (statementCount > 0) { SyntaxToken statementIdentifierToken = IfStatementAnalysis1(statements, contextParameter); if (statementIdentifierToken.Text == "") { IfDiagnostic(context, statements[0], IfStatementIncorrectRule, contextParameter.Identifier.Text); return false; } if (statementCount > 1) { SyntaxToken keywordIdentifierToken = IfStatementAnalysis2(statements, statementIdentifierToken); if (keywordIdentifierToken.Text == "") { IfDiagnostic(context, statements[1], IfKeywordIncorrectRule, statementIdentifierToken.Text); return false; } // HasTrailingTrivia if-statement in user analyzer if (statementCount > 2) { var triviaBlock = IfStatementAnalysis3(statements, keywordIdentifierToken) as BlockSyntax; if (triviaBlock == null) { IfDiagnostic(context, statements[2], TrailingTriviaCheckIncorrectRule, keywordIdentifierToken.Text); return false; } SyntaxList<StatementSyntax> triviaBlockStatements = triviaBlock.Statements; if (triviaBlockStatements == null) { IfDiagnostic(context, triviaBlock.Parent as StatementSyntax, TriviaCountMissingRule, keywordIdentifierToken.Text); return false; } if (triviaBlockStatements.Count > 0) { BlockSyntax triviaCountBlock = IfStatementAnalysis8(triviaBlockStatements, keywordIdentifierToken); if (triviaCountBlock == null) { IfDiagnostic(context, triviaBlockStatements[0], TriviaCountIncorrectRule, keywordIdentifierToken.Text); return false; } SyntaxList<StatementSyntax> triviaCountBlockStatements = triviaCountBlock.Statements; if (triviaCountBlockStatements.Count > 0) { SyntaxToken triviaIdentifierToken = IfStatementAnalysis4(triviaCountBlockStatements, keywordIdentifierToken); if (triviaIdentifierToken.Text == "") { IfDiagnostic(context, triviaCountBlockStatements[0], TrailingTriviaVarIncorrectRule, keywordIdentifierToken.Text); return false; } // Kind if-statement in user analyzer if (triviaCountBlockStatements.Count > 1) { BlockSyntax triviaKindCheckBlock = IfStatementAnalysis5(triviaCountBlockStatements, triviaIdentifierToken); if (triviaKindCheckBlock == null) { IfDiagnostic(context, triviaCountBlockStatements[1], TrailingTriviaKindCheckIncorrectRule, triviaIdentifierToken.Text); return false; } SyntaxList<StatementSyntax> triviaKindCheckBlockStatements = triviaKindCheckBlock.Statements; if (triviaKindCheckBlockStatements == null) { IfDiagnostic(context, triviaCountBlockStatements[1], TrailingTriviaKindCheckIncorrectRule, triviaIdentifierToken.Text); return false; } // Whitespace if-statement in user analyzer if (triviaKindCheckBlockStatements.Count > 0) { BlockSyntax triviaCheckBlock = IfStatementAnalysis6(triviaKindCheckBlock.Statements, triviaIdentifierToken); if (triviaCheckBlock == null) { IfDiagnostic(context, triviaKindCheckBlockStatements[0], WhitespaceCheckIncorrectRule, triviaIdentifierToken.Text); return false; } SyntaxList<StatementSyntax> triviaCheckBlockStatements = triviaCheckBlock.Statements; if (triviaCheckBlockStatements == null) { IfDiagnostic(context, triviaKindCheckBlockStatements[0], WhitespaceCheckIncorrectRule, triviaIdentifierToken.Text); return false; } if (triviaCheckBlockStatements.Count > 0) { if (!IfStatementAnalysis7(triviaCheckBlockStatements)) { IfDiagnostic(context, triviaCheckBlockStatements[0], ReturnStatementIncorrectRule, methodDeclaration.Identifier.Text); return false; } if (triviaCheckBlockStatements.Count > 1) { IfDiagnostic(context, triviaCheckBlock.Parent as StatementSyntax, TooManyStatementsRule, "if-block", "1", "return from the method"); return false; } //successfully through if-statement checks } else { IfDiagnostic(context, triviaCheckBlock.Parent as StatementSyntax, ReturnStatementMissingRule, methodDeclaration.Identifier.Text); return false; } if (triviaKindCheckBlockStatements.Count > 1) { IfDiagnostic(context, triviaKindCheckBlock.Parent as StatementSyntax, TooManyStatementsRule, "if-block", "1", "check if the trivia is a single space"); return false; } } else { IfDiagnostic(context, triviaKindCheckBlock.Parent as StatementSyntax, WhitespaceCheckMissingRule, triviaIdentifierToken.Text); return false; } if (triviaCountBlockStatements.Count > 2) { IfDiagnostic(context, triviaCountBlock.Parent as StatementSyntax, TooManyStatementsRule, "if-block", "2", "extract the first trivia of the if-keyword and check its kind"); return false; } } else { ReportDiagnostic(context, TrailingTriviaKindCheckMissingRule, triviaCountBlockStatements[0].GetLocation(), triviaIdentifierToken.Text); return false; } } else { IfDiagnostic(context, triviaCountBlock.Parent as StatementSyntax, TrailingTriviaVarMissingRule, keywordIdentifierToken.Text); return false; } if (triviaBlockStatements.Count > 1) { IfDiagnostic(context, triviaBlock.Parent as StatementSyntax, TooManyStatementsRule, "if-block", "1", "check the number of trailing trivia on the if-keyword"); return false; } } else { IfDiagnostic(context, triviaBlock.Parent as StatementSyntax, TriviaCountMissingRule, keywordIdentifierToken.Text); return false; } //check diagnostic reporting statements if (statementCount > 3) { bool diagnosticReportingCorrect = CheckDiagnosticCreation(context, statementIdentifierToken, keywordIdentifierToken, ruleNames, statements, contextParameter); if (!diagnosticReportingCorrect) { return false; } if (statementCount > 10) { ReportDiagnostic(context, TooManyStatementsRule, methodDeclaration.Identifier.GetLocation(), "method", "10", "walk through the Syntax Tree and check the spacing of the if-statement"); return false; } } else { IfDiagnostic(context, statements[2], OpenParenMissingRule, statementIdentifierToken.Text); return false; } } else { ReportDiagnostic(context, TrailingTriviaCheckMissingRule, statements[1].GetLocation(), keywordIdentifierToken.Text); return false; } } else { ReportDiagnostic(context, IfKeywordMissingRule, statements[0].GetLocation(), statementIdentifierToken.Text); return false; } } else { ReportDiagnostic(context, IfStatementMissingRule, methodDeclaration.Identifier.GetLocation(), contextParameter.Identifier.Text); return false; } return true; }
void Report(CompilationAnalysisContext context, IFieldSymbol field, DiagnosticDescriptor descriptor) { context.ReportDiagnostic(Diagnostic.Create(descriptor, field.Locations.FirstOrDefault())); }
// Returns true if the method called upon registering an action exists and is correct private bool CheckMethods(InvocationExpressionSyntax invocationExpression, CompilationAnalysisContext context) { IMethodSymbol analysisMethod = null; bool analysisMethodFound = false; var argList = invocationExpression.ArgumentList; var calledMethodName = argList.Arguments.First().Expression as IdentifierNameSyntax; foreach (IMethodSymbol currentMethod in _analyzerMethodSymbols) { if (calledMethodName.Identifier.Text == currentMethod.Name) { analysisMethod = currentMethod; analysisMethodFound = true; break; } } if (analysisMethodFound) { MethodDeclarationSyntax analysisMethodSyntax = analysisMethod.DeclaringSyntaxReferences[0].GetSyntax() as MethodDeclarationSyntax; if (analysisMethodSyntax.Modifiers.Count == 0 || analysisMethodSyntax.Modifiers.First().Text != "private" || analysisMethod.DeclaredAccessibility != Accessibility.Private) { ReportDiagnostic(context, IncorrectAnalysisAccessibilityRule, analysisMethodSyntax.Identifier.GetLocation(), analysisMethodSyntax.Identifier.ValueText); return false; } else if (analysisMethodSyntax.ReturnType.IsMissing || !analysisMethod.ReturnsVoid) { ReportDiagnostic(context, IncorrectAnalysisReturnTypeRule, analysisMethodSyntax.Identifier.GetLocation(), analysisMethodSyntax.Identifier.ValueText); return false; } else if (analysisMethod.Parameters.Count() != 1 || analysisMethod.Parameters.First().Type != context.Compilation.GetTypeByMetadataName("Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext")) { ReportDiagnostic(context, IncorrectAnalysisParameterRule, analysisMethodSyntax.ParameterList.GetLocation(), analysisMethodSyntax.Identifier.ValueText); return false; } else { return true; } } else { ReportDiagnostic(context, MissingAnalysisMethodRule, calledMethodName.GetLocation(), calledMethodName.Identifier.Text); return false; } }