private static bool ShouldFilterHtmlDiagnosticBasedOnErrorCode(OmniSharpVSDiagnostic diagnostic, SourceText sourceText, RazorSyntaxTree syntaxTree, ILogger logger)
        {
            if (!diagnostic.Code.HasValue)
            {
                return(false);
            }

            return(diagnostic.Code.Value.String switch
            {
                CSSErrorCodes.MissingOpeningBrace => IsCSharpInStyleBlock(diagnostic, sourceText, syntaxTree, logger),
                CSSErrorCodes.MissingSelectorAfterCombinator => IsCSharpInStyleBlock(diagnostic, sourceText, syntaxTree, logger),
                CSSErrorCodes.MissingSelectorBeforeCombinatorCode => IsCSharpInStyleBlock(diagnostic, sourceText, syntaxTree, logger),
                HtmlErrorCodes.UnexpectedEndTagErrorCode => IsHtmlWithBangAndMatchingTags(diagnostic, sourceText, syntaxTree, logger),
                HtmlErrorCodes.InvalidNestingErrorCode => IsAnyFilteredInvalidNestingError(diagnostic, sourceText, syntaxTree, logger),
                HtmlErrorCodes.MissingEndTagErrorCode => FileKinds.IsComponent(syntaxTree.Options.FileKind), // Redundant with RZ9980 in Components
                HtmlErrorCodes.TooFewElementsErrorCode => IsAnyFilteredTooFewElementsError(diagnostic, sourceText, syntaxTree, logger),
                _ => false,
            });
        private static bool InCSharpLiteral(OmniSharpVSDiagnostic d, SourceText sourceText, RazorSyntaxTree syntaxTree)
        {
            if (d.Range is null)
            {
                return(false);
            }

            var owner = syntaxTree.GetOwner(sourceText, d.Range.End);

            if (owner is null)
            {
                return(false);
            }

            var isCSharp = owner.Kind is SyntaxKind.CSharpExpressionLiteral or SyntaxKind.CSharpStatementLiteral or SyntaxKind.CSharpEphemeralTextLiteral;

            return(isCSharp);
        }
        private static bool AppliesToTagHelperTagName(
            OmniSharpVSDiagnostic diagnostic,
            SourceText sourceText,
            RazorSyntaxTree syntaxTree,
            ILogger logger)
        {
            // Goal of this method is to filter diagnostics that touch TagHelper tag names. Reason being is TagHelpers can output anything. Meaning
            // If you have a TagHelper like:
            //
            // <Input>
            // </Input>
            //
            // HTML would see this as an error because the input element can't have a body; however, a TagHelper could respect this in a totally valid
            // way.

            if (diagnostic.Range is null)
            {
                return(false);
            }

            var owner = syntaxTree.GetOwner(sourceText, diagnostic.Range.End, logger);

            var startOrEndTag = owner?.FirstAncestorOrSelf <RazorSyntaxNode>(n => n is MarkupTagHelperStartTagSyntax || n is MarkupTagHelperEndTagSyntax);

            if (startOrEndTag is null)
            {
                return(false);
            }

            var tagName      = startOrEndTag is MarkupTagHelperStartTagSyntax startTag ? startTag.Name : ((MarkupTagHelperEndTagSyntax)startOrEndTag).Name;
            var tagNameRange = tagName.GetRange(syntaxTree.Source);

            if (!tagNameRange.IntersectsOrTouches(diagnostic.Range))
            {
                // The diagnostic doesn't touch the tag name
                return(false);
            }

            // Diagnostic is touching the start or end tag name range
            return(true);
        }