public static void ReportLSPViolatingExceptionIfThrown(SyntaxNodeAnalysisContext context, INamedTypeSymbol exceptionType, DiagnosticDescriptor rule) { var throwStatement = context.Node as ThrowStatementSyntax; throwStatement.Expression.DescendantNodesAndTokens() .Where(t => t.IsKind(SyntaxKind.IdentifierName) || t.IsKind(SyntaxKind.IdentifierToken)) .TryFirst() .Match() .Some().Where(t => t.IsNode).Do(t => { var identifier = t.AsNode() as IdentifierNameSyntax; var identifierType = context.SemanticModel.GetSymbolInfo(identifier); if (identifierType.Symbol.Equals(exceptionType)) { context.ReportDiagnostic(Diagnostic.Create(rule, identifier.GetLocation())); } }) .Some().Do(t => { var identifier = t.Parent as IdentifierNameSyntax; var identiferType = context.SemanticModel.GetTypeInfo(identifier).Type; if (identiferType.Equals(exceptionType)) { context.ReportDiagnostic(Diagnostic.Create(rule, identifier.GetLocation())); } }) .None().Do(() => { }) .Exec(); }
public static Diagnostic CreateDiagnostic( this ISymbol symbol, DiagnosticDescriptor rule, params object[] args) { return symbol.Locations.CreateDiagnostic(rule, args); }
public DiagnosticResult(DiagnosticDescriptor descriptor) : this() { this.Id = descriptor.Id; this.Severity = descriptor.DefaultSeverity; this.MessageFormat = descriptor.MessageFormat; }
public DiagnosticItem(AnalyzerItem analyzerItem, DiagnosticDescriptor descriptor, ReportDiagnostic effectiveSeverity) : base(string.Format("{0}: {1}", descriptor.Id, descriptor.Title)) { _analyzerItem = analyzerItem; _descriptor = descriptor; _effectiveSeverity = effectiveSeverity; }
private static string GenerateDescriptorText(DiagnosticDescriptor descriptor) { StringBuilder builder = new StringBuilder(); builder.Append($"### {descriptor.Id}: {descriptor.Title} ###"); if (!string.IsNullOrWhiteSpace(descriptor.Description.ToString())) { builder .AppendLine() .AppendLine() .Append(descriptor.Description.ToString()); } builder .AppendLine() .AppendLine() .AppendLine($"Category: {descriptor.Category}") .AppendLine() .Append($"Severity: {descriptor.DefaultSeverity}"); if (!string.IsNullOrWhiteSpace(descriptor.HelpLinkUri)) { builder .AppendLine() .AppendLine() .Append($"Help: [{descriptor.HelpLinkUri}]({descriptor.HelpLinkUri})"); } return builder.ToString(); }
protected void TestCodeFix(Document document, TextSpan span, string expected, DiagnosticDescriptor descriptor) { var codeFixes = GetCodeFixes(document, span, descriptor); Assert.That(codeFixes.Length, Is.EqualTo(1)); Verify.CodeAction(codeFixes[0], document, expected); }
public static Diagnostic ToDiagnostics(this RazorError error, string filePath) { if (error == null) { throw new ArgumentNullException(nameof(error)); } if (filePath == null) { throw new ArgumentNullException(nameof(filePath)); } var descriptor = new DiagnosticDescriptor( id: "Razor", title: "Razor parsing error", messageFormat: error.Message.Replace("{", "{{").Replace("}", "}}"), category: "Razor.Parser", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); var location = error.Location; if (location.Equals(SourceLocation.Undefined)) { location = SourceLocation.Zero; } var length = Math.Max(0, error.Length); var textSpan = new TextSpan(location.AbsoluteIndex, length); var linePositionStart = new LinePosition(location.LineIndex, location.CharacterIndex); var linePositionEnd = new LinePosition(location.LineIndex, location.CharacterIndex + length); var linePositionSpan = new LinePositionSpan(linePositionStart, linePositionEnd); return Diagnostic.Create(descriptor, Location.Create(filePath, textSpan, linePositionSpan)); }
private SimpleDiagnostic( DiagnosticDescriptor descriptor, DiagnosticSeverity severity, int warningLevel, Location location, IEnumerable<Location> additionalLocations, object[] messageArgs) { if ((warningLevel == 0 && severity != DiagnosticSeverity.Error) || (warningLevel != 0 && severity == DiagnosticSeverity.Error)) { throw new ArgumentException(nameof(warningLevel)); } if(descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } _descriptor = descriptor; _severity = severity; _warningLevel = warningLevel; _location = location ?? Location.None; _additionalLocations = additionalLocations == null ? SpecializedCollections.EmptyReadOnlyList<Location>() : additionalLocations.ToImmutableArray(); _messageArgs = messageArgs ?? SpecializedCollections.EmptyArray<object>(); }
/// <summary> /// Returns the description as HTML /// </summary> /// <returns>Note: the description should be returned as the HTML that should be rendered i.e. there is no need enclose it in a CDATA section</returns> private static string GetDescriptionAsRawHtml(DiagnosticDescriptor diagnostic) { StringBuilder sb = new StringBuilder(); bool hasDescription = false; string details = diagnostic.Description.ToString(CultureInfo.CurrentCulture); if (!String.IsNullOrWhiteSpace(details)) { sb.AppendLine("<p>" + details + "</p>"); hasDescription = true; } if (!String.IsNullOrWhiteSpace(diagnostic.HelpLinkUri)) { sb.AppendLine("<h2>" + UIResources.RuleGen_MoreDetailsTitle + "</h2>"); sb.AppendLine(String.Format(UIResources.RuleGen_ForMoreDetailsLink, diagnostic.HelpLinkUri)); hasDescription = true; } if (!hasDescription) { return UIResources.RuleGen_NoDescription; } return sb.ToString(); }
private SimpleDiagnostic( DiagnosticDescriptor descriptor, DiagnosticSeverity severity, int warningLevel, Location location, IEnumerable<Location> additionalLocations, object[] messageArgs, ImmutableDictionary<string, string> properties, bool isSuppressed) { if ((warningLevel == 0 && severity != DiagnosticSeverity.Error) || (warningLevel != 0 && severity == DiagnosticSeverity.Error)) { throw new ArgumentException(nameof(warningLevel)); } if (descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } _descriptor = descriptor; _severity = severity; _warningLevel = warningLevel; _location = location ?? Location.None; _additionalLocations = additionalLocations?.ToImmutableArray() ?? SpecializedCollections.EmptyReadOnlyList<Location>(); _messageArgs = messageArgs ?? Array.Empty<object>(); _properties = properties ?? ImmutableDictionary<string, string>.Empty; _isSuppressed = isSuppressed; }
public static Diagnostic CreateDiagnostic( this SyntaxNodeOrToken nodeOrToken, DiagnosticDescriptor rule, params object[] args) { return nodeOrToken.GetLocation().CreateDiagnostic(rule, args); }
public static void AnalyzeFormatInvocation(SyntaxNodeAnalysisContext context, string methodName, string methodOverloadSignature, string methodWithArraySignature, DiagnosticDescriptor rule) { if (context.IsGenerated()) return; var invocationExpression = (InvocationExpressionSyntax)context.Node; var memberExpresion = invocationExpression.Expression as MemberAccessExpressionSyntax; if (memberExpresion?.Name?.ToString() != methodName) return; var memberSymbol = context.SemanticModel.GetSymbolInfo(memberExpresion).Symbol; if (memberSymbol == null) return; if (!memberSymbol.ToString().StartsWith(methodOverloadSignature)) return; var argumentList = invocationExpression.ArgumentList as ArgumentListSyntax; if (argumentList?.Arguments.Count < 2) return; if (!argumentList.Arguments[0]?.Expression?.IsKind(SyntaxKind.StringLiteralExpression) ?? false) return; if (memberSymbol.ToString() == methodWithArraySignature && argumentList.Arguments.Skip(1).Any(a => context.SemanticModel.GetTypeInfo(a.Expression).Type.TypeKind == TypeKind.Array)) return; var formatLiteral = (LiteralExpressionSyntax)argumentList.Arguments[0].Expression; var format = (string)context.SemanticModel.GetConstantValue(formatLiteral).Value; var formatArgs = Enumerable.Range(1, argumentList.Arguments.Count - 1).Select(i => new object()).ToArray(); try { string.Format(format, formatArgs); } catch (FormatException) { return; } var diag = Diagnostic.Create(rule, invocationExpression.GetLocation()); context.ReportDiagnostic(diag); }
public void BeforeCompile(IBeforeCompileContext context) { string keyPath = Environment.GetEnvironmentVariable("NUGET_BUILD_KEY_PATH"); string delaySignString = Environment.GetEnvironmentVariable("NUGET_BUILD_DELAY_SIGN"); if (!string.IsNullOrEmpty(keyPath)) { FileInfo keyFile = new FileInfo(keyPath); if (keyFile.Exists) { bool delaySign = delaySignString != null && StringComparer.OrdinalIgnoreCase.Equals("true", delaySignString); // Console.WriteLine("Signing assembly with: {0} Delay sign: {1}", keyFile.FullName, delaySign ? "true" : "false"); var parms = new CspParameters(); parms.KeyNumber = 2; var provider = new RSACryptoServiceProvider(parms); byte[] array = provider.ExportCspBlob(!provider.PublicOnly); var strongNameProvider = new DesktopStrongNameProvider(); var options = context.Compilation.Options.WithStrongNameProvider(strongNameProvider) .WithCryptoKeyFile(keyFile.FullName) .WithDelaySign(delaySign); // Enfore viral strong naming var specificDiagnosticOptions = new Dictionary<string, ReportDiagnostic>(options.SpecificDiagnosticOptions); specificDiagnosticOptions["CS8002"] = ReportDiagnostic.Error; options = options.WithSpecificDiagnosticOptions(specificDiagnosticOptions); context.Compilation = context.Compilation.WithOptions(options); } else { // The key was not found. Throw a compile error. var descriptor = new DiagnosticDescriptor( id: "SN1001", title: "Missing key file", messageFormat: "Key file '{0}' could not be found", category: "CA1001: \"StrongNaming\"", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); // TODO: what should this reference for the location? var textSpan = new TextSpan(); var position = new LinePosition(0, 0); var span = new LinePositionSpan(position, position); var location = Location.Create(context.ProjectContext.ProjectFilePath, textSpan, span); var diagnsotic = Diagnostic.Create(descriptor, location, keyPath); context.Diagnostics.Add(diagnsotic); } } }
public LockChecks Start(SyntaxNodeAnalysisContext AnalysisContext,DiagnosticDescriptor rule) { this.analysisContext = AnalysisContext; this.usingStatement = (UsingStatementSyntax)analysisContext.Node; this.rule = rule; reportedIssue = false; return this; }
protected void TestCodeFix(string markupCode, string expected, DiagnosticDescriptor descriptor) { Document document; TextSpan span; Assert.That(TestHelpers.TryGetDocumentAndSpanFromMarkup(markupCode, LanguageName, out document, out span), Is.True); TestCodeFix(document, span, expected, descriptor); }
protected new void TestCodeFix(string markupCode, string expected, DiagnosticDescriptor descriptor) { Document document; TextSpan span; TestHelpers.TryGetDocumentAndSpanFromMarkup(markupCode, LanguageName, References.Default, out document, out span); TestCodeFix(document, span, expected, descriptor); }
public DiagnosticItem(AnalyzerItem analyzerItem, DiagnosticDescriptor descriptor, ReportDiagnostic effectiveSeverity, IContextMenuController contextMenuController) : base(string.Format("{0}: {1}", descriptor.Id, descriptor.Title)) { _analyzerItem = analyzerItem; _descriptor = descriptor; _effectiveSeverity = effectiveSeverity; _contextMenuController = contextMenuController; }
/// <summary> /// Analyzes a <see cref="BaseMethodDeclarationSyntax"/> node. If it has a summary it is checked if the text starts with "[firstTextPart]<see cref="[className]"/>[secondTextPart]". /// </summary> /// <param name="context">The <see cref="SyntaxNodeAnalysisContext"/> of this analysis.</param> /// <param name="firstTextPart">The first part of the standard text.</param> /// <param name="secondTextPart">The second part of the standard text.</param> /// <param name="diagnosticDescriptor">The diagnostic to report for violations, or <see langword="null"/> to not report violations.</param> /// <returns>A <see cref="MatchResult"/> describing the result of the analysis.</returns> protected static MatchResult HandleDeclaration(SyntaxNodeAnalysisContext context, string firstTextPart, string secondTextPart, DiagnosticDescriptor diagnosticDescriptor) { var declarationSyntax = context.Node as BaseMethodDeclarationSyntax; if (declarationSyntax == null) { return MatchResult.Unknown; } var documentationStructure = declarationSyntax.GetDocumentationCommentTriviaSyntax(); if (documentationStructure == null) { return MatchResult.Unknown; } var summaryElement = documentationStructure.Content.GetFirstXmlElement(XmlCommentHelper.SummaryXmlTag) as XmlElementSyntax; if (summaryElement == null) { return MatchResult.Unknown; } // Check if the summary content could be a correct standard text if (summaryElement.Content.Count >= 3) { // Standard text has the form <part1><see><part2> var firstTextPartSyntax = summaryElement.Content[0] as XmlTextSyntax; var classReferencePart = summaryElement.Content[1] as XmlEmptyElementSyntax; var secondTextParSyntaxt = summaryElement.Content[2] as XmlTextSyntax; if (firstTextPartSyntax != null && classReferencePart != null && secondTextParSyntaxt != null) { if (TextPartsMatch(firstTextPart, secondTextPart, firstTextPartSyntax, secondTextParSyntaxt)) { if (SeeTagIsCorrect(context, classReferencePart, declarationSyntax)) { // We found a correct standard text return MatchResult.FoundMatch; } else { if (diagnosticDescriptor != null) { context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, classReferencePart.GetLocation())); } return MatchResult.None; } } } } if (diagnosticDescriptor != null) { context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, summaryElement.GetLocation())); } // TODO: be more specific about the type of error when possible return MatchResult.None; }
internal static NRefactoryDiagnosticDiagnostic Create(string id, LocalizableString title, string category, LocalizableString message, LocalizableString description, string helpLink, DiagnosticSeverity severity, DiagnosticSeverity defaultSeverity, bool isEnabledByDefault, int warningLevel, Location location, IEnumerable<Location> additionalLocations, string[] customTags) { var descriptor = new DiagnosticDescriptor(id, title, message, category, defaultSeverity, isEnabledByDefault, description, helpLink); return new NRefactoryDiagnosticDiagnostic(descriptor, severity, warningLevel, location, additionalLocations, messageArgs: null, customTags: customTags); }
internal static SimpleDiagnostic Create(string id, LocalizableString title, string category, LocalizableString message, LocalizableString description, string helpLink, DiagnosticSeverity severity, DiagnosticSeverity defaultSeverity, bool isEnabledByDefault, int warningLevel, Location location, IEnumerable<Location> additionalLocations, IEnumerable<string> customTags) { var descriptor = new DiagnosticDescriptor(id, title, message, category, defaultSeverity, isEnabledByDefault, description, helpLink, customTags.ToImmutableArrayOrEmpty()); return new SimpleDiagnostic(descriptor, severity, warningLevel, location, additionalLocations, messageArgs: null); }
private static void CheckForCondition(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocationNode, SyntaxNode expressionStatementParent, DiagnosticDescriptor descriptor) { if ((!expressionStatementParent?.DescendantNodesAndTokens()?.Any(_ => _.IsKind(SyntaxKind.EqualsToken)) ?? false) && !(invocationNode.DescendantNodes()?.Any(_ => new ContainsInvocationExpressionWalker(_).HasIssue) ?? false)) { context.ReportDiagnostic(Diagnostic.Create(descriptor, invocationNode.GetLocation())); } }
public static IEnumerable<Diagnostic> CreateDiagnostics( this IEnumerable<ISymbol> symbols, DiagnosticDescriptor rule, params object[] args) { foreach (ISymbol symbol in symbols) { yield return symbol.CreateDiagnostic(rule, args); } }
public static IEnumerable<Diagnostic> CreateDiagnostics( this IEnumerable<SyntaxNodeOrToken> nodesOrTokens, DiagnosticDescriptor rule, params object[] args) { foreach (SyntaxNodeOrToken nodeOrToken in nodesOrTokens) { yield return nodeOrToken.CreateDiagnostic(rule, args); } }
internal static SimpleDiagnostic Create( DiagnosticDescriptor descriptor, DiagnosticSeverity severity, int warningLevel, Location location, IEnumerable<Location> additionalLocations, object[] messageArgs) { return new SimpleDiagnostic(descriptor, severity, warningLevel, location, additionalLocations, messageArgs); }
public static IEnumerable<Diagnostic> CreateDiagnostics( this IEnumerable<SyntaxToken> tokens, DiagnosticDescriptor rule, params object[] args) { foreach (var token in tokens) { yield return token.CreateDiagnostic(rule, args); } }
public static IEnumerable<Diagnostic> CreateDiagnostics( this IEnumerable<SyntaxNode> nodes, DiagnosticDescriptor rule, params object[] args) { foreach (var node in nodes) { yield return node.CreateDiagnostic(rule, args); } }
public async Task TestClassVirtualInheritedMembersAsync(bool compilerWarning, string memberName, string memberData) { var testCode = $@"using System; public class ParentClass {{ /// <summary> /// Some documentation. /// </summary> public virtual {memberData} }} public class ChildClass : ParentClass {{ public override {memberData} }} "; var fixedCode = $@"using System; public class ParentClass {{ /// <summary> /// Some documentation. /// </summary> public virtual {memberData} }} public class ChildClass : ParentClass {{ /// <inheritdoc/> public override {memberData} }} "; if (compilerWarning) { this.descriptor = CS1591; } DiagnosticResult[] expected = { this.CSharpDiagnostic(this.descriptor).WithArguments("ParentClass").WithLocation(2, 14), this.CSharpDiagnostic(this.descriptor).WithArguments("ChildClass").WithLocation(10, 14), this.CSharpDiagnostic(this.descriptor).WithArguments(memberName).WithLocation(12, 40), }; DiagnosticResult[] expectedFixed = { this.CSharpDiagnostic(this.descriptor).WithArguments("ParentClass").WithLocation(2, 14), this.CSharpDiagnostic(this.descriptor).WithArguments("ChildClass").WithLocation(10, 14), }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(fixedCode, expectedFixed, CancellationToken.None).ConfigureAwait(false); await this.VerifyCSharpFixAsync(testCode, fixedCode, numberOfFixAllIterations: 2, cancellationToken: CancellationToken.None).ConfigureAwait(false); }
protected BaseAnalyzer(bool appliesToItem) { this.appliesToItem = appliesToItem; // ReSharper disable DoNotCallOverridableMethodsInConstructor ruleForField = CreateRuleFor("Field"); ruleForProperty = CreateRuleFor("Property"); ruleForMethodReturnValue = CreateRuleFor("Method"); ruleForParameter = CreateRuleFor("Parameter"); // ReSharper restore DoNotCallOverridableMethodsInConstructor }
public async Task ReloadScript_WithInvalidCompilationAndMissingMethod_ReportsResults() { // Create the compilation exception we expect to throw during the reload var descriptor = new DiagnosticDescriptor(DotNetConstants.MissingFunctionEntryPointCompilationCode, "Test compilation exception", "Test compilation error", "AzureFunctions", DiagnosticSeverity.Error, true); var exception = new CompilationErrorException("Test compilation exception", ImmutableArray.Create(Diagnostic.Create(descriptor, Location.None))); // Create the invoker dependencies and setup the appropriate method to throw the exception RunDependencies dependencies = CreateDependencies(); dependencies.Compilation.Setup(c => c.GetEntryPointSignature(It.IsAny<IFunctionEntryPointResolver>())) .Throws(exception); dependencies.Compilation.Setup(c => c.EmitAndLoad(It.IsAny<CancellationToken>())) .Returns(typeof(object).Assembly); string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(rootFunctionsFolder); // Create a dummy file to represent our function string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx"); File.WriteAllText(filePath, string.Empty); var metadata = new FunctionMetadata { ScriptFile = filePath, Name = Guid.NewGuid().ToString(), ScriptType = ScriptType.CSharp }; metadata.Bindings.Add(new BindingMetadata() { Name = "Test", Type = "ManualTrigger" }); var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<Script.Binding.FunctionBinding>(), new Collection<FunctionBinding>(), dependencies.EntrypointResolver.Object, new FunctionAssemblyLoader(string.Empty), dependencies.CompilationServiceFactory.Object, dependencies.TraceWriterFactory.Object); // Update the file to trigger a reload File.WriteAllText(filePath, string.Empty); await TestHelpers.Await(() => { return dependencies.TraceWriter.Traces.Any(t => t.Message.Contains("Compilation failed.")) && dependencies.TraceWriter.Traces.Any(t => t.Message.Contains(DotNetConstants.MissingFunctionEntryPointCompilationCode)); }); dependencies.TraceWriter.Traces.Clear(); CompilationErrorException resultException = await Assert.ThrowsAsync<CompilationErrorException>(() => invoker.GetFunctionTargetAsync()); await TestHelpers.Await(() => { return dependencies.TraceWriter.Traces.Any(t => t.Message.Contains("Function compilation error")) && dependencies.TraceWriter.Traces.Any(t => t.Message.Contains(DotNetConstants.MissingFunctionEntryPointCompilationCode)); }); }
internal static SimpleDiagnostic Create( DiagnosticDescriptor descriptor, DiagnosticSeverity severity, int warningLevel, Location location, IEnumerable<Location> additionalLocations, object[] messageArgs, ImmutableDictionary<string, string> properties, bool isSuppressed = false) { return new SimpleDiagnostic(descriptor, severity, warningLevel, location, additionalLocations, messageArgs, properties, isSuppressed); }
internal CodeDiagnosticDescriptor(Microsoft.CodeAnalysis.DiagnosticDescriptor descriptor, string[] languages, Type codeIssueType) { if (descriptor == null) { throw new ArgumentNullException("descriptor"); } if (languages == null) { throw new ArgumentNullException("languages"); } if (codeIssueType == null) { throw new ArgumentNullException("codeIssueType"); } Name = descriptor.Title.ToString() ?? "unnamed"; Languages = languages; this.descriptor = descriptor; this.diagnosticAnalyzerType = codeIssueType; }
private void WriteRules() { if (_descriptors.Count > 0) { _writer.WriteArrayStart("rules"); foreach (var pair in _descriptors.ToSortedList()) { DiagnosticDescriptor descriptor = pair.Value; _writer.WriteObjectStart(); // rule _writer.Write("id", descriptor.Id); string?shortDescription = descriptor.Title.ToString(_culture); if (!RoslynString.IsNullOrEmpty(shortDescription)) { _writer.WriteObjectStart("shortDescription"); _writer.Write("text", shortDescription); _writer.WriteObjectEnd(); } string?fullDescription = descriptor.Description.ToString(_culture); if (!RoslynString.IsNullOrEmpty(fullDescription)) { _writer.WriteObjectStart("fullDescription"); _writer.Write("text", fullDescription); _writer.WriteObjectEnd(); } WriteDefaultConfiguration(descriptor); if (!string.IsNullOrEmpty(descriptor.HelpLinkUri)) { _writer.Write("helpUri", descriptor.HelpLinkUri); } if (!string.IsNullOrEmpty(descriptor.Category) || descriptor.CustomTags.Any()) { _writer.WriteObjectStart("properties"); if (!string.IsNullOrEmpty(descriptor.Category)) { _writer.Write("category", descriptor.Category); } if (descriptor.CustomTags.Any()) { _writer.WriteArrayStart("tags"); foreach (string tag in descriptor.CustomTags) { _writer.Write(tag); } _writer.WriteArrayEnd(); // tags } _writer.WriteObjectEnd(); // properties } _writer.WriteObjectEnd(); // rule } _writer.WriteArrayEnd(); // rules } }