private void ValidateBinding( TagHelperBinding bindingResult, string tagName, MarkupTagBlockSyntax tagBlock) { // Ensure that all descriptors associated with this tag have appropriate TagStructures. Cannot have // multiple descriptors that expect different TagStructures (other than TagStructure.Unspecified). TagHelperDescriptor baseDescriptor = null; TagStructure? baseStructure = null; foreach (var descriptor in bindingResult.Descriptors) { var boundRules = bindingResult.GetBoundRules(descriptor); foreach (var rule in boundRules) { if (rule.TagStructure != TagStructure.Unspecified) { // Can't have a set of TagHelpers that expect different structures. if (baseStructure.HasValue && baseStructure != rule.TagStructure) { _errorSink.OnError( RazorDiagnosticFactory.CreateTagHelper_InconsistentTagStructure( new SourceSpan(tagBlock.GetSourceLocation(_source), tagBlock.FullWidth), baseDescriptor.DisplayName, descriptor.DisplayName, tagName)); } baseDescriptor = descriptor; baseStructure = rule.TagStructure; } } } }
private static SourceLocation GetTagDeclarationErrorStart(MarkupTagBlockSyntax tagBlock, RazorSourceDocument source) { var advanceBy = IsEndTag(tagBlock) ? "</" : "<"; return(SourceLocationTracker.Advance(tagBlock.GetSourceLocation(source), advanceBy)); }
private bool TryRewriteTagHelperEnd(MarkupTagBlockSyntax tagBlock, out MarkupTagHelperEndTagSyntax rewritten) { rewritten = null; var tagName = tagBlock.GetTagName(); // Could not determine tag name, it can't be a TagHelper, continue on and track the element. if (tagName == null) { return(false); } var tracker = CurrentTagHelperTracker; var tagNameScope = tracker?.TagName ?? string.Empty; if (!IsPotentialTagHelper(tagName, tagBlock)) { return(false); } // Validate that our end tag matches the currently scoped tag, if not we may need to error. if (tagNameScope.Equals(tagName, StringComparison.OrdinalIgnoreCase)) { // If there are additional end tags required before we can build our block it means we're in a // situation like this: <myth req="..."><myth></myth></myth> where we're at the inside </myth>. if (tracker.OpenMatchingTags > 0) { tracker.OpenMatchingTags--; return(false); } ValidateTagSyntax(tagName, tagBlock); _trackerStack.Pop(); } else { var tagHelperBinding = _tagHelperBinder.GetBinding( tagName, attributes: Array.Empty <KeyValuePair <string, string> >(), parentTagName: CurrentParentTagName, parentIsTagHelper: CurrentParentIsTagHelper); // If there are not TagHelperDescriptors associated with the end tag block that also have no // required attributes then it means we can't be a TagHelper, bail out. if (tagHelperBinding == null) { return(false); } foreach (var descriptor in tagHelperBinding.Descriptors) { var boundRules = tagHelperBinding.GetBoundRules(descriptor); var invalidRule = boundRules.FirstOrDefault(rule => rule.TagStructure == TagStructure.WithoutEndTag); if (invalidRule != null) { // End tag TagHelper that states it shouldn't have an end tag. _errorSink.OnError( RazorDiagnosticFactory.CreateParsing_TagHelperMustNotHaveAnEndTag( new SourceSpan(SourceLocationTracker.Advance(tagBlock.GetSourceLocation(_source), "</"), tagName.Length), tagName, descriptor.DisplayName, invalidRule.TagStructure)); return(false); } } } rewritten = SyntaxFactory.MarkupTagHelperEndTag(tagBlock.Children); return(true); }