Example #1
0
        public void Execute_ErrorsForRazorBlockFileScopedSinglyOccurringDirectives()
        {
            // Arrange
            var directive = DirectiveDescriptor.CreateRazorBlockDirective("custom", b => b.Usage = DirectiveUsage.FileScopedSinglyOccurring);
            var phase     = new DefaultRazorIntermediateNodeLoweringPhase();
            var engine    = RazorProjectEngine.CreateEmpty(b =>
            {
                b.Phases.Add(phase);
                b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
                b.AddDirective(directive);
            });
            var options      = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
            var importSource = TestRazorSourceDocument.Create("@custom { }", filePath: "import.cshtml");
            var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");

            codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
            codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });
            var expectedDiagnostic = RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported("custom");

            // Act
            phase.Execute(codeDocument);

            // Assert
            var documentNode = codeDocument.GetDocumentIntermediateNode();
            var directives   = documentNode.Children.OfType <DirectiveIntermediateNode>();

            Assert.Empty(directives);
            var diagnostic = Assert.Single(documentNode.GetAllDiagnostics());

            Assert.Equal(expectedDiagnostic, diagnostic);
        }
Example #2
0
        private IEnumerable <RazorDiagnostic> Validate()
        {
            if (string.IsNullOrWhiteSpace(Name))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeNameNullOrWhitespace();

                yield return(diagnostic);
            }
            else
            {
                var name = Name;
                var isDirectiveAttribute = this.IsDirectiveAttribute();
                if (isDirectiveAttribute && name.StartsWith("@", StringComparison.Ordinal))
                {
                    name = name.Substring(1);
                }
                else if (isDirectiveAttribute)
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRequiredDirectiveAttributeName(GetDisplayName(), Name);

                    yield return(diagnostic);
                }

                foreach (var character in name)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeName(Name, character);

                        yield return(diagnostic);
                    }
                }
            }
        }
Example #3
0
        private HashSet <RazorDiagnostic> Validate()
        {
            HashSet <RazorDiagnostic> diagnostics = null;

            if (string.IsNullOrWhiteSpace(Name))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChildNullOrWhitespace(_parent.GetDisplayName());

                diagnostics ??= new();
                diagnostics.Add(diagnostic);
            }
            else if (Name != TagHelperMatchingConventions.ElementCatchAllName)
            {
                foreach (var character in Name)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.IsInvalidNonWhitespaceHtmlCharacters(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChild(_parent.GetDisplayName(), Name, character);
                        diagnostics ??= new();
                        diagnostics.Add(diagnostic);
                    }
                }
            }

            return(diagnostics);
        }
Example #4
0
        private HashSet <RazorDiagnostic> Validate()
        {
            HashSet <RazorDiagnostic> diagnostics = null;

            if (string.IsNullOrWhiteSpace(Name))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeParameterNullOrWhitespace(_parent.Name);
                diagnostics ??= new();
                diagnostics.Add(diagnostic);
            }
            else
            {
                foreach (var character in Name)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.IsInvalidNonWhitespaceHtmlCharacters(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeParameterName(
                            _parent.Name,
                            Name,
                            character);

                        diagnostics ??= new();
                        diagnostics.Add(diagnostic);
                    }
                }
            }

            return(diagnostics);
        }
        public void Execute_CombinesErrorsOnRewritingErrors()
        {
            // Arrange
            var engine = RazorEngine.Create(builder =>
            {
                builder.AddTagHelpers(new[]
                {
                    CreateTagHelperDescriptor(
                        tagName: "form",
                        typeName: "TestFormTagHelper",
                        assemblyName: "TestAssembly"),
                    CreateTagHelperDescriptor(
                        tagName: "input",
                        typeName: "TestInputTagHelper",
                        assemblyName: "TestAssembly"),
                });
            });

            var phase = new DefaultRazorTagHelperBinderPhase()
            {
                Engine = engine,
            };

            var content =
                @"
@addTagHelper *, TestAssembly
<form>
    <input value='Hello' type='text' />";
            var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
            var codeDocument   = RazorCodeDocument.Create(sourceDocument);

            var originalTree = RazorSyntaxTree.Parse(sourceDocument);

            var initialError = RazorDiagnostic.Create(
                new RazorDiagnosticDescriptor("RZ9999", () => "Initial test error", RazorDiagnosticSeverity.Error),
                new SourceSpan(SourceLocation.Zero, contentLength: 1));
            var expectedRewritingError = RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
                new SourceSpan(new SourceLocation(Environment.NewLine.Length * 2 + 30, 2, 1), contentLength: 4), "form");

            var erroredOriginalTree = RazorSyntaxTree.Create(originalTree.Root, originalTree.Source, new[] { initialError }, originalTree.Options);

            codeDocument.SetSyntaxTree(erroredOriginalTree);

            // Act
            phase.Execute(codeDocument);

            // Assert
            var outputTree = codeDocument.GetSyntaxTree();

            Assert.Empty(originalTree.Diagnostics);
            Assert.NotSame(erroredOriginalTree, outputTree);
            Assert.Equal(new[] { initialError, expectedRewritingError }, outputTree.Diagnostics);
        }
        private void ImportDirectives(DocumentIntermediateNode document)
        {
            var visitor = new DirectiveVisitor();

            visitor.VisitDocument(document);

            var seenDirectives = new HashSet <DirectiveDescriptor>();

            for (var i = visitor.Directives.Count - 1; i >= 0; i--)
            {
                var reference     = visitor.Directives[i];
                var directive     = (DirectiveIntermediateNode)reference.Node;
                var descriptor    = directive.Directive;
                var seenDirective = !seenDirectives.Add(descriptor);

                if (!directive.IsImported())
                {
                    continue;
                }

                switch (descriptor.Kind)
                {
                case DirectiveKind.SingleLine:
                    if (seenDirective && descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring)
                    {
                        // This directive has been overridden, it should be removed from the document.

                        break;
                    }

                    continue;

                case DirectiveKind.RazorBlock:
                case DirectiveKind.CodeBlock:
                    if (descriptor.Usage == DirectiveUsage.FileScopedSinglyOccurring)
                    {
                        // A block directive cannot be imported.

                        document.Diagnostics.Add(
                            RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported(descriptor.Directive));
                    }
                    break;

                default:
                    throw new InvalidOperationException(Resources.FormatUnexpectedDirectiveKind(typeof(DirectiveKind).FullName));
                }

                // Overridden and invalid imported directives make it to here. They should be removed from the document.

                reference.Remove();
            }
        }
Example #7
0
        private HashSet <RazorDiagnostic> Validate()
        {
            HashSet <RazorDiagnostic> diagnostics = null;

            if (string.IsNullOrWhiteSpace(TagName))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedTagNameNullOrWhitespace();

                diagnostics ??= new();
                diagnostics.Add(diagnostic);
            }
            else if (TagName != TagHelperMatchingConventions.ElementCatchAllName)
            {
                foreach (var character in TagName)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.IsInvalidNonWhitespaceHtmlCharacters(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedTagName(TagName, character);

                        diagnostics ??= new();
                        diagnostics.Add(diagnostic);
                    }
                }
            }

            if (ParentTag != null)
            {
                if (string.IsNullOrWhiteSpace(ParentTag))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedParentTagNameNullOrWhitespace();

                    diagnostics ??= new();
                    diagnostics.Add(diagnostic);
                }
                else
                {
                    foreach (var character in ParentTag)
                    {
                        if (char.IsWhiteSpace(character) || HtmlConventions.IsInvalidNonWhitespaceHtmlCharacters(character))
                        {
                            var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedParentTagName(ParentTag, character);

                            diagnostics ??= new();
                            diagnostics.Add(diagnostic);
                        }
                    }
                }
            }

            return(diagnostics);
        }
            public override SyntaxNode Visit(SyntaxNode node)
            {
                try
                {
                    return(base.Visit(node));
                }
                catch (InsufficientExecutionStackException)
                {
                    // We're very close to reaching the stack limit. Let's not go any deeper.
                    // It's okay to not show nested section errors in deeply nested cases instead of crashing.
                    _diagnostics.Add(RazorDiagnosticFactory.CreateRewriter_InsufficientStack(SourceSpan.Undefined));

                    return(node);
                }
            }
            public override void VisitDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
            {
                if (_nestedLevel > 0)
                {
                    var directiveStart = block.Children.First(child => !child.IsBlock && ((Span)child).Kind == SpanKindInternal.Transition).Start;
                    var errorLength    = /* @ */ 1 + SectionDirective.Directive.Directive.Length;
                    var error          = RazorDiagnosticFactory.CreateParsing_SectionsCannotBeNested(new SourceSpan(directiveStart, errorLength));
                    chunkGenerator.Diagnostics.Add(error);
                }

                _nestedLevel++;

                VisitDefault(block);

                _nestedLevel--;
            }
            public override SyntaxNode VisitRazorDirective(RazorDirectiveSyntax node)
            {
                if (_nestedLevel > 0)
                {
                    var directiveStart = node.Transition.GetSourceLocation(_syntaxTree.Source);
                    var errorLength    = /* @ */ 1 + SectionDirective.Directive.Directive.Length;
                    var error          = RazorDiagnosticFactory.CreateParsing_SectionsCannotBeNested(new SourceSpan(directiveStart, errorLength));
                    node = node.AppendDiagnostic(error);
                }
                _nestedLevel++;
                var result = base.VisitRazorDirective(node);

                _nestedLevel--;

                return(result);
            }
        private IEnumerable <RazorDiagnostic> Validate()
        {
            if (string.IsNullOrWhiteSpace(TagName))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedTagNameNullOrWhitespace();

                yield return(diagnostic);
            }
            else if (TagName != TagHelperMatchingConventions.ElementCatchAllName)
            {
                foreach (var character in TagName)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedTagName(TagName, character);

                        yield return(diagnostic);
                    }
                }
            }

            if (ParentTag != null)
            {
                if (string.IsNullOrWhiteSpace(ParentTag))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedParentTagNameNullOrWhitespace();

                    yield return(diagnostic);
                }
                else
                {
                    foreach (var character in ParentTag)
                    {
                        if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                        {
                            var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedParentTagName(ParentTag, character);

                            yield return(diagnostic);
                        }
                    }
                }
            }
        }
Example #12
0
        private HashSet <RazorDiagnostic> Validate()
        {
            HashSet <RazorDiagnostic> diagnostics = null;

            if (string.IsNullOrWhiteSpace(Name))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeNameNullOrWhitespace();

                diagnostics ??= new();
                diagnostics.Add(diagnostic);
            }
            else
            {
                var name = new StringSegment(Name);
                var isDirectiveAttribute = this.IsDirectiveAttribute();
                if (isDirectiveAttribute && name.StartsWith("@", StringComparison.Ordinal))
                {
                    name = name.Subsegment(1);
                }
                else if (isDirectiveAttribute)
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRequiredDirectiveAttributeName(GetDisplayName(), Name);

                    diagnostics ??= new();
                    diagnostics.Add(diagnostic);
                }

                for (var i = 0; i < name.Length; i++)
                {
                    var character = name[i];
                    if (char.IsWhiteSpace(character) || HtmlConventions.IsInvalidNonWhitespaceHtmlCharacters(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeName(Name, character);

                        diagnostics ??= new();
                        diagnostics.Add(diagnostic);
                    }
                }
            }

            return(diagnostics);
        }
        private IEnumerable <RazorDiagnostic> Validate()
        {
            if (string.IsNullOrWhiteSpace(Name))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeNameNullOrWhitespace();

                yield return(diagnostic);
            }
            else
            {
                foreach (var character in Name)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidTargetedAttributeName(Name, character);

                        yield return(diagnostic);
                    }
                }
            }
        }
Example #14
0
        private IEnumerable <RazorDiagnostic> Validate()
        {
            if (string.IsNullOrWhiteSpace(Name))
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChildNullOrWhitespace(_parent.GetDisplayName());

                yield return(diagnostic);
            }
            else if (Name != TagHelperMatchingConventions.ElementCatchAllName)
            {
                foreach (var character in Name)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChild(_parent.GetDisplayName(), Name, character);

                        yield return(diagnostic);
                    }
                }
            }
        }
        public void Execute_CanHandleSingleLengthTagHelperPrefix()
        {
            // Arrange
            var engine = RazorEngine.Create(builder =>
            {
                builder.AddTagHelpers(new TagHelperDescriptor[0]);
            });

            var phase = new DefaultRazorTagHelperBinderPhase()
            {
                Engine = engine,
            };
            var expectedDiagnostics = new[]
            {
                RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
                    new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1)),
                RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue(
                    new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1), "tagHelperPrefix", '\"', "\""),
            };

            var content =
                @"
@tagHelperPrefix """;
            var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
            var codeDocument   = RazorCodeDocument.Create(sourceDocument);
            var originalTree   = RazorSyntaxTree.Parse(sourceDocument);

            codeDocument.SetSyntaxTree(originalTree);

            // Act
            phase.Execute(codeDocument);

            // Assert
            var rewrittenTree  = codeDocument.GetSyntaxTree();
            var directiveValue = rewrittenTree.Root.Children.OfType <Block>().First().Children.Last() as Span;
            var chunkGenerator = Assert.IsType <TagHelperPrefixDirectiveChunkGenerator>(directiveValue.ChunkGenerator);

            Assert.Equal(expectedDiagnostics, chunkGenerator.Diagnostics);
        }
        public void Execute_CanHandleSingleLengthRemoveTagHelperDirective()
        {
            // Arrange
            var projectEngine = RazorProjectEngine.Create(builder =>
            {
                builder.AddTagHelpers(new TagHelperDescriptor[0]);
            });

            var phase = new DefaultRazorTagHelperBinderPhase()
            {
                Engine = projectEngine.Engine,
            };
            var expectedDiagnostics = new[]
            {
                RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
                    new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1)),
                RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
                    new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1), "\"")
            };

            var content =
                @"
@removeTagHelper """;
            var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
            var codeDocument   = RazorCodeDocument.Create(sourceDocument);
            var originalTree   = RazorSyntaxTree.Parse(sourceDocument);

            codeDocument.SetSyntaxTree(originalTree);

            // Act
            phase.Execute(codeDocument);

            // Assert
            var rewrittenTree  = codeDocument.GetSyntaxTree();
            var erroredNode    = rewrittenTree.Root.DescendantNodes().First(n => n.GetSpanContext()?.ChunkGenerator is RemoveTagHelperChunkGenerator);
            var chunkGenerator = Assert.IsType <RemoveTagHelperChunkGenerator>(erroredNode.GetSpanContext().ChunkGenerator);

            Assert.Equal(expectedDiagnostics, chunkGenerator.Diagnostics);
        }
            public override SyntaxNode VisitRazorDirective(RazorDirectiveSyntax node)
            {
                if (node.DirectiveDescriptor?.Directive != SectionDirective.Directive.Directive)
                {
                    // We only want to track the nesting of section directives.
                    return(base.VisitRazorDirective(node));
                }

                _nestedLevel++;
                var result = (RazorDirectiveSyntax)base.VisitRazorDirective(node);

                if (_nestedLevel > 1)
                {
                    var directiveStart = node.Transition.GetSourceLocation(_syntaxTree.Source);
                    var errorLength    = /* @ */ 1 + SectionDirective.Directive.Directive.Length;
                    var error          = RazorDiagnosticFactory.CreateParsing_SectionsCannotBeNested(new SourceSpan(directiveStart, errorLength));
                    result = result.AppendDiagnostic(error);
                }

                _nestedLevel--;

                return(result);
            }
Example #18
0
        private IEnumerable <RazorDiagnostic> Validate()
        {
            // data-* attributes are explicitly not implemented by user agents and are not intended for use on
            // the server; therefore it's invalid for TagHelpers to bind to them.
            const string DataDashPrefix = "data-";

            if (string.IsNullOrWhiteSpace(Name))
            {
                if (IndexerAttributeNamePrefix == null)
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNullOrWhitespace(
                        _parent.GetDisplayName(),
                        GetDisplayName());

                    yield return(diagnostic);
                }
            }
            else
            {
                if (Name.StartsWith(DataDashPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNameStartsWith(
                        _parent.GetDisplayName(),
                        GetDisplayName(),
                        Name);

                    yield return(diagnostic);
                }

                foreach (var character in Name)
                {
                    if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeName(
                            _parent.GetDisplayName(),
                            GetDisplayName(),
                            Name,
                            character);

                        yield return(diagnostic);
                    }
                }
            }

            if (IndexerAttributeNamePrefix != null)
            {
                if (IndexerAttributeNamePrefix.StartsWith(DataDashPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributePrefixStartsWith(
                        _parent.GetDisplayName(),
                        GetDisplayName(),
                        IndexerAttributeNamePrefix);

                    yield return(diagnostic);
                }
                else if (IndexerAttributeNamePrefix.Length > 0 && string.IsNullOrWhiteSpace(IndexerAttributeNamePrefix))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNullOrWhitespace(
                        _parent.GetDisplayName(),
                        GetDisplayName());

                    yield return(diagnostic);
                }
                else
                {
                    foreach (var character in IndexerAttributeNamePrefix)
                    {
                        if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                        {
                            var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributePrefix(
                                _parent.GetDisplayName(),
                                GetDisplayName(),
                                IndexerAttributeNamePrefix,
                                character);

                            yield return(diagnostic);
                        }
                    }
                }
            }
        }
Example #19
0
        private IEnumerable <RazorDiagnostic> Validate()
        {
            // data-* attributes are explicitly not implemented by user agents and are not intended for use on
            // the server; therefore it's invalid for TagHelpers to bind to them.
            const string DataDashPrefix       = "data-";
            var          isDirectiveAttribute = this.IsDirectiveAttribute();

            if (string.IsNullOrWhiteSpace(Name))
            {
                if (IndexerAttributeNamePrefix == null)
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNullOrWhitespace(
                        _parent.GetDisplayName(),
                        GetDisplayName());

                    yield return(diagnostic);
                }
            }
            else
            {
                if (Name.StartsWith(DataDashPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNameStartsWith(
                        _parent.GetDisplayName(),
                        GetDisplayName(),
                        Name);

                    yield return(diagnostic);
                }

                StringSegment name = Name;
                if (isDirectiveAttribute && name.StartsWith("@", StringComparison.Ordinal))
                {
                    name = name.Subsegment(1);
                }
                else if (isDirectiveAttribute)
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundDirectiveAttributeName(
                        _parent.GetDisplayName(),
                        GetDisplayName(),
                        Name);

                    yield return(diagnostic);
                }

                for (var i = 0; i < name.Length; i++)
                {
                    var character = name[i];
                    if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeName(
                            _parent.GetDisplayName(),
                            GetDisplayName(),
                            name.Value,
                            character);

                        yield return(diagnostic);
                    }
                }
            }

            if (IndexerAttributeNamePrefix != null)
            {
                if (IndexerAttributeNamePrefix.StartsWith(DataDashPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributePrefixStartsWith(
                        _parent.GetDisplayName(),
                        GetDisplayName(),
                        IndexerAttributeNamePrefix);

                    yield return(diagnostic);
                }
                else if (IndexerAttributeNamePrefix.Length > 0 && string.IsNullOrWhiteSpace(IndexerAttributeNamePrefix))
                {
                    var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributeNullOrWhitespace(
                        _parent.GetDisplayName(),
                        GetDisplayName());

                    yield return(diagnostic);
                }
                else
                {
                    StringSegment indexerPrefix = IndexerAttributeNamePrefix;
                    if (isDirectiveAttribute && indexerPrefix.StartsWith("@", StringComparison.Ordinal))
                    {
                        indexerPrefix = indexerPrefix.Subsegment(1);
                    }
                    else if (isDirectiveAttribute)
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundDirectiveAttributePrefix(
                            _parent.GetDisplayName(),
                            GetDisplayName(),
                            indexerPrefix.Value);

                        yield return(diagnostic);
                    }

                    for (var i = 0; i < indexerPrefix.Length; i++)
                    {
                        var character = indexerPrefix[i];
                        if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
                        {
                            var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidBoundAttributePrefix(
                                _parent.GetDisplayName(),
                                GetDisplayName(),
                                indexerPrefix.Value,
                                character);

                            yield return(diagnostic);
                        }
                    }
                }
            }
        }