public void GetDescriptors_LocatesNestedRemoveTagHelperChunkGenerator() { // Arrange var resolver = new TestTagHelperDescriptorResolver(); var tagHelperDirectiveSpanVisitor = new TagHelperDirectiveSpanVisitor(resolver, new ErrorSink()); var document = new MarkupBlock( new DirectiveBlock( Factory.CodeTransition(), Factory.MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword + " ") .Accepts(AcceptedCharacters.None), Factory.Code("\"something\"").AsRemoveTagHelper("something")) ); var expectedRegistration = new TagHelperDirectiveDescriptor { DirectiveText = "something", DirectiveType = TagHelperDirectiveType.RemoveTagHelper }; // Act tagHelperDirectiveSpanVisitor.GetDescriptors(document); // Assert var directiveDescriptor = Assert.Single(resolver.DirectiveDescriptors); Assert.Equal(expectedRegistration, directiveDescriptor, TagHelperDirectiveDescriptorComparer.Default); }
public override void VisitSpan(Span span) { // We're only interested in spans with an AddOrRemoveTagHelperChunkGenerator. if (span.ChunkGenerator is AddOrRemoveTagHelperChunkGenerator) { var chunkGenerator = (AddOrRemoveTagHelperChunkGenerator)span.ChunkGenerator; var directive = chunkGenerator.RemoveTagHelperDescriptors ? TagHelperDirectiveType.RemoveTagHelper : TagHelperDirectiveType.AddTagHelper; var directiveDescriptor = new TagHelperDirectiveDescriptor( chunkGenerator.LookupText, span.Start, directive); _directiveDescriptors.Add(directiveDescriptor); } else if (span.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator) { var chunkGenerator = (TagHelperPrefixDirectiveChunkGenerator)span.ChunkGenerator; var directiveDescriptor = new TagHelperDirectiveDescriptor( chunkGenerator.Prefix, span.Start, TagHelperDirectiveType.TagHelperPrefix); _directiveDescriptors.Add(directiveDescriptor); } }
public void GetDescriptors_LocatesTagHelperCodeGenerator_CreatesDirectiveDescriptors() { // Arrange var resolver = new TestTagHelperDescriptorResolver(); var tagHelperDirectiveSpanVisitor = new TagHelperDirectiveSpanVisitor(resolver, new ParserErrorSink()); var document = new MarkupBlock( Factory.Code("\"one\"").AsAddTagHelper("one"), Factory.Code("\"two\"").AsRemoveTagHelper("two"), Factory.Code("\"three\"").AsRemoveTagHelper("three"), Factory.Code("\"four\"").AsTagHelperPrefixDirective("four")); var expectedDescriptors = new TagHelperDirectiveDescriptor[] { new TagHelperDirectiveDescriptor("one", TagHelperDirectiveType.AddTagHelper), new TagHelperDirectiveDescriptor("two", TagHelperDirectiveType.RemoveTagHelper), new TagHelperDirectiveDescriptor("three", TagHelperDirectiveType.RemoveTagHelper), new TagHelperDirectiveDescriptor("four", TagHelperDirectiveType.TagHelperPrefix), }; // Act tagHelperDirectiveSpanVisitor.GetDescriptors(document); // Assert Assert.Equal( expectedDescriptors, resolver.DirectiveDescriptors, TagHelperDirectiveDescriptorComparer.Default); }
public void GetDescriptors_LocatesTagHelperPrefixDirectiveCodeGenerator() { // Arrange var resolver = new TestTagHelperDescriptorResolver(); var tagHelperDirectiveSpanVisitor = new TagHelperDirectiveSpanVisitor(resolver, new ParserErrorSink()); var document = new MarkupBlock( new DirectiveBlock( Factory.CodeTransition(), Factory .MetaCode(SyntaxConstants.CSharp.TagHelperPrefixKeyword + " ") .Accepts(AcceptedCharacters.None), Factory.Code("\"something\"").AsTagHelperPrefixDirective("something"))); var expectedDirectiveDescriptor = new TagHelperDirectiveDescriptor("something", TagHelperDirectiveType.TagHelperPrefix); // Act tagHelperDirectiveSpanVisitor.GetDescriptors(document); // Assert var directiveDescriptor = Assert.Single(resolver.DirectiveDescriptors); Assert.Equal( expectedDirectiveDescriptor, directiveDescriptor, TagHelperDirectiveDescriptorComparer.Default); }
private static IEnumerable<TagHelperDirectiveDescriptor> GetTagHelperDirectiveDescriptors( IReadOnlyList<CodeTree> inheritedCodeTrees, IReadOnlyList<Chunk> defaultInheritedChunks) { var descriptors = new List<TagHelperDirectiveDescriptor>(); // For tag helpers, the @removeTagHelper only applies tag helpers that were added prior to it. // Consequently we must visit tag helpers outside-in - furthest _GlobalImport first and nearest one last. // This is different from the behavior of chunk merging where we visit the nearest one first and ignore // chunks that were previously visited. var chunksFromGlobalImports = inheritedCodeTrees .Reverse() .SelectMany(tree => tree.Chunks); var chunksInOrder = defaultInheritedChunks.Concat(chunksFromGlobalImports); foreach (var chunk in chunksInOrder) { // All TagHelperDirectiveDescriptors created here have undefined source locations because the source // that created them is not in the same file. var addTagHelperChunk = chunk as AddTagHelperChunk; if (addTagHelperChunk != null) { var descriptor = new TagHelperDirectiveDescriptor( addTagHelperChunk.LookupText, SourceLocation.Undefined, TagHelperDirectiveType.AddTagHelper); descriptors.Add(descriptor); continue; } var removeTagHelperChunk = chunk as RemoveTagHelperChunk; if (removeTagHelperChunk != null) { var descriptor = new TagHelperDirectiveDescriptor( removeTagHelperChunk.LookupText, SourceLocation.Undefined, TagHelperDirectiveType.RemoveTagHelper); descriptors.Add(descriptor); continue; } var tagHelperPrefixDirectiveChunk = chunk as TagHelperPrefixDirectiveChunk; if (tagHelperPrefixDirectiveChunk != null) { var descriptor = new TagHelperDirectiveDescriptor( tagHelperPrefixDirectiveChunk.Prefix, SourceLocation.Undefined, TagHelperDirectiveType.TagHelperPrefix); descriptors.Add(descriptor); } } return descriptors; }
public void GetDescriptors_CanOverrideResolutionContext() { // Arrange var resolver = new TestTagHelperDescriptorResolver(); var expectedInitialDirectiveDescriptors = new TagHelperDirectiveDescriptor[] { new TagHelperDirectiveDescriptor("one", TagHelperDirectiveType.AddTagHelper), new TagHelperDirectiveDescriptor("two", TagHelperDirectiveType.RemoveTagHelper), new TagHelperDirectiveDescriptor("three", TagHelperDirectiveType.RemoveTagHelper), new TagHelperDirectiveDescriptor("four", TagHelperDirectiveType.TagHelperPrefix), }; var expectedEndDirectiveDescriptors = new TagHelperDirectiveDescriptor[] { new TagHelperDirectiveDescriptor("custom", TagHelperDirectiveType.AddTagHelper) }; var tagHelperDirectiveSpanVisitor = new CustomTagHelperDirectiveSpanVisitor( resolver, (descriptors, errorSink) => { Assert.Equal( expectedInitialDirectiveDescriptors, descriptors, TagHelperDirectiveDescriptorComparer.Default); return(new TagHelperDescriptorResolutionContext(expectedEndDirectiveDescriptors, errorSink)); }); var document = new MarkupBlock( Factory.Code("\"one\"").AsAddTagHelper("one"), Factory.Code("\"two\"").AsRemoveTagHelper("two"), Factory.Code("\"three\"").AsRemoveTagHelper("three"), Factory.Code("\"four\"").AsTagHelperPrefixDirective("four")); // Act tagHelperDirectiveSpanVisitor.GetDescriptors(document); // Assert Assert.Equal(expectedEndDirectiveDescriptors, resolver.DirectiveDescriptors, TagHelperDirectiveDescriptorComparer.Default); }
public void GetTagHelperDescriptors_ReturnsExpectedDirectiveDescriptors( CodeTree[] codeTrees, TagHelperDirectiveDescriptor[] expectedDirectiveDescriptors) { // Arrange var builder = new BlockBuilder { Type = BlockType.Comment }; var block = new Block(builder); IList<TagHelperDirectiveDescriptor> descriptors = null; var resolver = new Mock<ITagHelperDescriptorResolver>(); resolver.Setup(r => r.Resolve(It.IsAny<TagHelperDescriptorResolutionContext>())) .Callback((TagHelperDescriptorResolutionContext context) => { descriptors = context.DirectiveDescriptors; }) .Returns(Enumerable.Empty<TagHelperDescriptor>()) .Verifiable(); var baseParser = new RazorParser( new CSharpCodeParser(), new HtmlMarkupParser(), tagHelperDescriptorResolver: resolver.Object); var parser = new TestableMvcRazorParser(baseParser, codeTrees, defaultInheritedChunks: new Chunk[0]); // Act parser.GetTagHelperDescriptorsPublic(block, errorSink: new ErrorSink()).ToArray(); // Assert Assert.NotNull(descriptors); Assert.Equal(expectedDirectiveDescriptors.Length, descriptors.Count); for (var i = 0; i < expectedDirectiveDescriptors.Length; i++) { var expected = expectedDirectiveDescriptors[i]; var actual = descriptors[i]; Assert.Equal(expected.DirectiveText, actual.DirectiveText, StringComparer.Ordinal); Assert.Equal(SourceLocation.Zero, actual.Location); Assert.Equal(expected.DirectiveType, actual.DirectiveType); } }
public override void VisitSpan(Span span) { // We're only interested in spans with an AddOrRemoveTagHelperChunkGenerator. if (span.ChunkGenerator is AddOrRemoveTagHelperChunkGenerator) { var chunkGenerator = (AddOrRemoveTagHelperChunkGenerator)span.ChunkGenerator; var directive = chunkGenerator.RemoveTagHelperDescriptors ? TagHelperDirectiveType.RemoveTagHelper : TagHelperDirectiveType.AddTagHelper; var textLocation = GetSubTextSourceLocation(span, chunkGenerator.LookupText); var directiveDescriptor = new TagHelperDirectiveDescriptor { DirectiveText = chunkGenerator.LookupText, Location = textLocation, DirectiveType = directive }; _directiveDescriptors.Add(directiveDescriptor); } else if (span.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator) { var chunkGenerator = (TagHelperPrefixDirectiveChunkGenerator)span.ChunkGenerator; var textLocation = GetSubTextSourceLocation(span, chunkGenerator.Prefix); var directiveDescriptor = new TagHelperDirectiveDescriptor { DirectiveText = chunkGenerator.Prefix, Location = textLocation, DirectiveType = TagHelperDirectiveType.TagHelperPrefix }; _directiveDescriptors.Add(directiveDescriptor); } }
private static LookupInfo GetLookupInfo(TagHelperDirectiveDescriptor directiveDescriptor, ErrorSink errorSink) { var lookupText = directiveDescriptor.DirectiveText; var lookupStrings = lookupText?.Split(new[] { ',' }); // Ensure that we have valid lookupStrings to work with. Valid formats are: // "assemblyName" // "typeName, assemblyName" if (lookupStrings == null || lookupStrings.Any(string.IsNullOrWhiteSpace) || lookupStrings.Length != 2) { errorSink.OnError( directiveDescriptor.Location, Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(lookupText)); return null; } return new LookupInfo { TypePattern = lookupStrings[0].Trim(), AssemblyName = lookupStrings[1].Trim() }; }
private static LookupInfo GetLookupInfo( TagHelperDirectiveDescriptor directiveDescriptor, ErrorSink errorSink) { var lookupText = directiveDescriptor.DirectiveText; var lookupStrings = lookupText?.Split(new[] { ',' }); // Ensure that we have valid lookupStrings to work with. The valid format is "typeName, assemblyName" if (lookupStrings == null || lookupStrings.Any(string.IsNullOrWhiteSpace) || lookupStrings.Length != 2) { errorSink.OnError( directiveDescriptor.Location, Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(lookupText), GetErrorLength(lookupText)); return null; } var trimmedAssemblyName = lookupStrings[1].Trim(); // + 1 is for the comma separator in the lookup text. var assemblyNameIndex = lookupStrings[0].Length + 1 + lookupStrings[1].IndexOf(trimmedAssemblyName); var assemblyNamePrefix = directiveDescriptor.DirectiveText.Substring(0, assemblyNameIndex); var assemblyNameLocation = SourceLocation.Advance(directiveDescriptor.Location, assemblyNamePrefix); return new LookupInfo { TypePattern = lookupStrings[0].Trim(), AssemblyName = trimmedAssemblyName, AssemblyNameLocation = assemblyNameLocation, }; }
private static IEnumerable<TagHelperDirectiveDescriptor> GetTagHelperDirectiveDescriptors( IReadOnlyList<ChunkTree> inheritedChunkTrees, IReadOnlyList<Chunk> defaultInheritedChunks) { var descriptors = new List<TagHelperDirectiveDescriptor>(); var inheritedChunks = defaultInheritedChunks.Concat(inheritedChunkTrees.SelectMany(tree => tree.Chunks)); foreach (var chunk in inheritedChunks) { // All TagHelperDirectiveDescriptors created here have undefined source locations because the source // that created them is not in the same file. var addTagHelperChunk = chunk as AddTagHelperChunk; if (addTagHelperChunk != null) { var descriptor = new TagHelperDirectiveDescriptor { DirectiveText = addTagHelperChunk.LookupText, Location = chunk.Start, DirectiveType = TagHelperDirectiveType.AddTagHelper }; descriptors.Add(descriptor); continue; } var removeTagHelperChunk = chunk as RemoveTagHelperChunk; if (removeTagHelperChunk != null) { var descriptor = new TagHelperDirectiveDescriptor { DirectiveText = removeTagHelperChunk.LookupText, Location = chunk.Start, DirectiveType = TagHelperDirectiveType.RemoveTagHelper }; descriptors.Add(descriptor); continue; } var tagHelperPrefixDirectiveChunk = chunk as TagHelperPrefixDirectiveChunk; if (tagHelperPrefixDirectiveChunk != null) { var descriptor = new TagHelperDirectiveDescriptor { DirectiveText = tagHelperPrefixDirectiveChunk.Prefix, Location = chunk.Start, DirectiveType = TagHelperDirectiveType.TagHelperPrefix }; descriptors.Add(descriptor); } } return descriptors; }