public LiteralAttributeChunkGenerator( LocationTagged<string> prefix, LocationTagged<SpanChunkGenerator> valueGenerator) { Prefix = prefix; ValueGenerator = valueGenerator; }
public static void WriteLocationTaggedString(this CodeWriter writer, LocationTagged<string> value) { writer.WriteStartMethodInvoke("Tuple.Create"); writer.WriteStringLiteral(value.Value); writer.WriteParameterSeparator(); writer.WriteSnippet(value.Location.AbsoluteIndex.ToString(CultureInfo.CurrentCulture)); writer.WriteEndMethodInvoke(); }
public AttributeBlockCodeGenerator(string name, LocationTagged <string> prefix, LocationTagged <string> suffix) { Name = name; Prefix = prefix; Suffix = suffix; }
public HelperCodeGenerator(LocationTagged <string> signature, bool headerComplete) { Signature = signature; HeaderComplete = headerComplete; }
public DynamicAttributeBlockCodeGenerator(LocationTagged<string> prefix, SourceLocation valueStart) { Prefix = prefix; ValueStart = valueStart; }
public DynamicAttributeBlockCodeGenerator(LocationTagged<string> prefix, int offset, int line, int col) : this(prefix, new SourceLocation(offset, line, col)) { }
public LiteralAttributeCodeGenerator(LocationTagged <string> prefix, LocationTagged <SpanCodeGenerator> valueGenerator) { Prefix = prefix; ValueGenerator = valueGenerator; }
public AttributeBlockCodeGenerator(string name, LocationTagged<string> prefix, LocationTagged<string> suffix) { Name = name; Prefix = prefix; Suffix = suffix; }
public CSharpCodeWriter WriteLocationTaggedString(LocationTagged<string> value) { WriteStartMethodInvocation("Tuple.Create"); WriteStringLiteral(value.Value); WriteParameterSeparator(); Write(value.Location.AbsoluteIndex.ToString(CultureInfo.CurrentCulture)); WriteEndMethodInvocation(false); return this; }
public LiteralAttributeCodeGenerator(LocationTagged<string> prefix, LocationTagged<string> value) { Prefix = prefix; Value = value; }
public PreprocessedLiteralAttributeCodeGenerator(LocationTagged <string> prefix, LocationTagged <SpanCodeGenerator> valueGenerator) : base(prefix, valueGenerator) { }
private void AttributePrefix( IEnumerable<HtmlSymbol> whitespace, IEnumerable<HtmlSymbol> nameSymbols, IEnumerable<HtmlSymbol> whitespaceAfterAttributeName) { // First, determine if this is a 'data-' attribute (since those can't use conditional attributes) var name = nameSymbols.GetContent(Span.Start); var attributeCanBeConditional = !name.Value.StartsWith("data-", StringComparison.OrdinalIgnoreCase); // Accept the whitespace and name Accept(whitespace); Accept(nameSymbols); // Since this is not a minimized attribute, the whitespace after attribute name belongs to this attribute. Accept(whitespaceAfterAttributeName); Assert(HtmlSymbolType.Equals); // We should be at "=" AcceptAndMoveNext(); var whitespaceAfterEquals = ReadWhile(sym => sym.Type == HtmlSymbolType.WhiteSpace || sym.Type == HtmlSymbolType.NewLine); var quote = HtmlSymbolType.Unknown; if (At(HtmlSymbolType.SingleQuote) || At(HtmlSymbolType.DoubleQuote)) { // Found a quote, the whitespace belongs to this attribute. Accept(whitespaceAfterEquals); quote = CurrentSymbol.Type; AcceptAndMoveNext(); } else if (whitespaceAfterEquals.Any()) { // No quotes found after the whitespace. Put it back so that it can be parsed later. PutCurrentBack(); PutBack(whitespaceAfterEquals); } // We now have the prefix: (i.e. ' foo="') var prefix = Span.GetContent(); if (attributeCanBeConditional) { Span.ChunkGenerator = SpanChunkGenerator.Null; // The block chunk generator will render the prefix Output(SpanKind.Markup); // Read the attribute value only if the value is quoted // or if there is no whitespace between '=' and the unquoted value. if (quote != HtmlSymbolType.Unknown || !whitespaceAfterEquals.Any()) { // Read the attribute value. while (!EndOfFile && !IsEndOfAttributeValue(quote, CurrentSymbol)) { AttributeValue(quote); } } // Capture the suffix var suffix = new LocationTagged<string>(string.Empty, CurrentLocation); if (quote != HtmlSymbolType.Unknown && At(quote)) { suffix = CurrentSymbol.GetContent(); AcceptAndMoveNext(); } if (Span.Symbols.Count > 0) { // Again, block chunk generator will render the suffix Span.ChunkGenerator = SpanChunkGenerator.Null; Output(SpanKind.Markup); } // Create the block chunk generator Context.CurrentBlock.ChunkGenerator = new AttributeBlockChunkGenerator( name, prefix, suffix); } else { // Output the attribute name, the equals and optional quote. Ex: foo=" Output(SpanKind.Markup); if (quote == HtmlSymbolType.Unknown && whitespaceAfterEquals.Any()) { return; } // Not a "conditional" attribute, so just read the value SkipToAndParseCode(sym => IsEndOfAttributeValue(quote, sym)); // Output the attribute value (will include everything in-between the attribute's quotes). Output(SpanKind.Markup); if (quote != HtmlSymbolType.Unknown) { Optional(quote); } Output(SpanKind.Markup); } }
public PreprocessedLiteralAttributeCodeGenerator (LocationTagged<string> prefix, LocationTagged<SpanCodeGenerator> valueGenerator) : base (prefix, valueGenerator) { }
private void AttributePrefix(IEnumerable<HtmlSymbol> whitespace, IEnumerable<HtmlSymbol> nameSymbols) { // First, determine if this is a 'data-' attribute (since those can't use conditional attributes) LocationTagged<string> name = nameSymbols.GetContent(Span.Start); bool attributeCanBeConditional = !name.Value.StartsWith("data-", StringComparison.OrdinalIgnoreCase); // Accept the whitespace and name Accept(whitespace); Accept(nameSymbols); Assert(HtmlSymbolType.Equals); // We should be at "=" AcceptAndMoveNext(); HtmlSymbolType quote = HtmlSymbolType.Unknown; if (At(HtmlSymbolType.SingleQuote) || At(HtmlSymbolType.DoubleQuote)) { quote = CurrentSymbol.Type; AcceptAndMoveNext(); } // We now have the prefix: (i.e. ' foo="') LocationTagged<string> prefix = Span.GetContent(); if (attributeCanBeConditional) { Span.CodeGenerator = SpanCodeGenerator.Null; // The block code generator will render the prefix Output(SpanKind.Markup); // Read the values while (!EndOfFile && !IsEndOfAttributeValue(quote, CurrentSymbol)) { AttributeValue(quote); } // Capture the suffix LocationTagged<string> suffix = new LocationTagged<string>(String.Empty, CurrentLocation); if (quote != HtmlSymbolType.Unknown && At(quote)) { suffix = CurrentSymbol.GetContent(); AcceptAndMoveNext(); } if (Span.Symbols.Count > 0) { Span.CodeGenerator = SpanCodeGenerator.Null; // Again, block code generator will render the suffix Output(SpanKind.Markup); } // Create the block code generator Context.CurrentBlock.CodeGenerator = new AttributeBlockCodeGenerator( name, prefix, suffix); } else { // Not a "conditional" attribute, so just read the value SkipToAndParseCode(sym => IsEndOfAttributeValue(quote, sym)); if (quote != HtmlSymbolType.Unknown) { Optional(quote); } Output(SpanKind.Markup); } }
protected virtual void HelperDirective() { bool nested = Context.IsWithin(BlockType.Helper); // Set the block and span type Context.CurrentBlock.Type = BlockType.Helper; // Verify we're on "helper" and accept AssertDirective(SyntaxConstants.CSharp.HelperKeyword); Block block = new Block(CurrentSymbol.Content.ToString().ToLowerInvariant(), CurrentLocation); AcceptAndMoveNext(); if (nested) { Context.OnError(CurrentLocation, RazorResources.ParseError_Helpers_Cannot_Be_Nested); } // Accept a single whitespace character if present, if not, we should stop now if (!At(CSharpSymbolType.WhiteSpace)) { string error; if (At(CSharpSymbolType.NewLine)) { error = RazorResources.ErrorComponent_Newline; } else if (EndOfFile) { error = RazorResources.ErrorComponent_EndOfFile; } else { error = String.Format(CultureInfo.CurrentCulture, RazorResources.ErrorComponent_Character, CurrentSymbol.Content); } Context.OnError( CurrentLocation, RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start, error); PutCurrentBack(); Output(SpanKind.MetaCode); return; } CSharpSymbol remainingWs = AcceptSingleWhiteSpaceCharacter(); // Output metacode and continue Output(SpanKind.MetaCode); if (remainingWs != null) { Accept(remainingWs); } AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); // Don't accept newlines. // Expecting an identifier (helper name) bool errorReported = !Required(CSharpSymbolType.Identifier, errorIfNotFound: true, errorBase: RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start); if (!errorReported) { Assert(CSharpSymbolType.Identifier); AcceptAndMoveNext(); } AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); // Expecting parameter list start: "(" SourceLocation bracketErrorPos = CurrentLocation; if (!Optional(CSharpSymbolType.LeftParenthesis)) { if (!errorReported) { errorReported = true; Context.OnError( CurrentLocation, RazorResources.ParseError_MissingCharAfterHelperName, "("); } } else { SourceLocation bracketStart = CurrentLocation; if (!Balance(BalancingModes.NoErrorOnFailure, CSharpSymbolType.LeftParenthesis, CSharpSymbolType.RightParenthesis, bracketStart)) { errorReported = true; Context.OnError( bracketErrorPos, RazorResources.ParseError_UnterminatedHelperParameterList); } Optional(CSharpSymbolType.RightParenthesis); } int bookmark = CurrentLocation.AbsoluteIndex; IEnumerable <CSharpSymbol> ws = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: true)); // Expecting a "{" SourceLocation errorLocation = CurrentLocation; bool headerComplete = At(CSharpSymbolType.LeftBrace); if (headerComplete) { Accept(ws); AcceptAndMoveNext(); } else { Context.Source.Position = bookmark; NextToken(); AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: true)); if (!errorReported) { Context.OnError( errorLocation, RazorResources.ParseError_MissingCharAfterHelperParameters, Language.GetSample(CSharpSymbolType.LeftBrace)); } } // Grab the signature and build the code generator AddMarkerSymbolIfNecessary(); LocationTagged <string> signature = Span.GetContent(); HelperCodeGenerator blockGen = new HelperCodeGenerator(signature, headerComplete); Context.CurrentBlock.CodeGenerator = blockGen; // The block will generate appropriate code, Span.CodeGenerator = SpanCodeGenerator.Null; if (!headerComplete) { CompleteBlock(); Output(SpanKind.Code); return; } else { Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; Output(SpanKind.Code); } // We're valid, so parse the nested block AutoCompleteEditHandler bodyEditHandler = new AutoCompleteEditHandler(Language.TokenizeString); using (PushSpanConfig(DefaultSpanConfig)) { using (Context.StartBlock(BlockType.Statement)) { Span.EditHandler = bodyEditHandler; CodeBlock(false, block); CompleteBlock(insertMarkerIfNecessary: true); Output(SpanKind.Code); } } Initialize(Span); EnsureCurrent(); Span.CodeGenerator = SpanCodeGenerator.Null; // The block will generate the footer code. if (!Optional(CSharpSymbolType.RightBrace)) { // The } is missing, so set the initial signature span to use it as an autocomplete string bodyEditHandler.AutoCompleteString = "}"; // Need to be able to accept anything to properly handle the autocomplete bodyEditHandler.AcceptedCharacters = AcceptedCharacters.Any; } else { blockGen.Footer = Span.GetContent(); Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; } CompleteBlock(); Output(SpanKind.Code); }
public HelperCodeGenerator(LocationTagged<string> signature, bool headerComplete) { Signature = signature; HeaderComplete = headerComplete; }
public CSharpCodeWriter WriteLocationTaggedString(LocationTagged<string> value) { WriteStringLiteral(value.Value); WriteParameterSeparator(); Write(value.Location.AbsoluteIndex.ToString(CultureInfo.InvariantCulture)); return this; }
public DynamicAttributeBlockCodeGenerator(LocationTagged <string> prefix, int offset, int line, int col) : this(prefix, new SourceLocation(offset, line, col)) { }
private void AttributePrefix(IEnumerable <HtmlSymbol> whitespace, IEnumerable <HtmlSymbol> nameSymbols) { // First, determine if this is a 'data-' attribute (since those can't use conditional attributes) LocationTagged <string> name = nameSymbols.GetContent(Span.Start); bool attributeCanBeConditional = !name.Value.StartsWith("data-", StringComparison.OrdinalIgnoreCase); // Accept the whitespace and name Accept(whitespace); Accept(nameSymbols); Assert(HtmlSymbolType.Equals); // We should be at "=" AcceptAndMoveNext(); HtmlSymbolType quote = HtmlSymbolType.Unknown; if (At(HtmlSymbolType.SingleQuote) || At(HtmlSymbolType.DoubleQuote)) { quote = CurrentSymbol.Type; AcceptAndMoveNext(); } // We now have the prefix: (i.e. ' foo="') LocationTagged <string> prefix = Span.GetContent(); if (attributeCanBeConditional) { Span.CodeGenerator = SpanCodeGenerator.Null; // The block code generator will render the prefix Output(SpanKind.Markup); // Read the values while (!EndOfFile && !IsEndOfAttributeValue(quote, CurrentSymbol)) { AttributeValue(quote); } // Capture the suffix LocationTagged <string> suffix = new LocationTagged <string>(String.Empty, CurrentLocation); if (quote != HtmlSymbolType.Unknown && At(quote)) { suffix = CurrentSymbol.GetContent(); AcceptAndMoveNext(); } if (Span.Symbols.Count > 0) { Span.CodeGenerator = SpanCodeGenerator.Null; // Again, block code generator will render the suffix Output(SpanKind.Markup); } // Create the block code generator Context.CurrentBlock.CodeGenerator = new AttributeBlockCodeGenerator( name, prefix, suffix); } else { // Not a "conditional" attribute, so just read the value SkipToAndParseCode(sym => IsEndOfAttributeValue(quote, sym)); if (quote != HtmlSymbolType.Unknown) { Optional(quote); } Output(SpanKind.Markup); } }
public DynamicAttributeBlockCodeGenerator(LocationTagged <string> prefix, SourceLocation valueStart) { Prefix = prefix; ValueStart = valueStart; }
public LiteralAttributeCodeGenerator(LocationTagged <string> prefix, LocationTagged <string> value) { Prefix = prefix; Value = value; }
private void AttributePrefix( IEnumerable <HtmlSymbol> whitespace, IEnumerable <HtmlSymbol> nameSymbols, IEnumerable <HtmlSymbol> whitespaceAfterAttributeName) { // First, determine if this is a 'data-' attribute (since those can't use conditional attributes) var name = nameSymbols.GetContent(Span.Start); var attributeCanBeConditional = !name.Value.StartsWith("data-", StringComparison.OrdinalIgnoreCase); // Accept the whitespace and name Accept(whitespace); Accept(nameSymbols); // Since this is not a minimized attribute, the whitespace after attribute name belongs to this attribute. Accept(whitespaceAfterAttributeName); Assert(HtmlSymbolType.Equals); // We should be at "=" AcceptAndMoveNext(); var whitespaceAfterEquals = ReadWhile(sym => sym.Type == HtmlSymbolType.WhiteSpace || sym.Type == HtmlSymbolType.NewLine); var quote = HtmlSymbolType.Unknown; if (At(HtmlSymbolType.SingleQuote) || At(HtmlSymbolType.DoubleQuote)) { // Found a quote, the whitespace belongs to this attribute. Accept(whitespaceAfterEquals); quote = CurrentSymbol.Type; AcceptAndMoveNext(); } else if (whitespaceAfterEquals.Any()) { // No quotes found after the whitespace. Put it back so that it can be parsed later. PutCurrentBack(); PutBack(whitespaceAfterEquals); } // We now have the prefix: (i.e. ' foo="') var prefix = Span.GetContent(); if (attributeCanBeConditional) { Span.ChunkGenerator = SpanChunkGenerator.Null; // The block chunk generator will render the prefix Output(SpanKind.Markup); // Read the attribute value only if the value is quoted // or if there is no whitespace between '=' and the unquoted value. if (quote != HtmlSymbolType.Unknown || !whitespaceAfterEquals.Any()) { // Read the attribute value. while (!EndOfFile && !IsEndOfAttributeValue(quote, CurrentSymbol)) { AttributeValue(quote); } } // Capture the suffix var suffix = new LocationTagged <string>(string.Empty, CurrentLocation); if (quote != HtmlSymbolType.Unknown && At(quote)) { suffix = CurrentSymbol.GetContent(); AcceptAndMoveNext(); } if (Span.Symbols.Count > 0) { // Again, block chunk generator will render the suffix Span.ChunkGenerator = SpanChunkGenerator.Null; Output(SpanKind.Markup); } // Create the block chunk generator Context.CurrentBlock.ChunkGenerator = new AttributeBlockChunkGenerator( name, prefix, suffix); } else { // Output the attribute name, the equals and optional quote. Ex: foo=" Output(SpanKind.Markup); if (quote == HtmlSymbolType.Unknown && whitespaceAfterEquals.Any()) { return; } // Not a "conditional" attribute, so just read the value SkipToAndParseCode(sym => IsEndOfAttributeValue(quote, sym)); // Output the attribute value (will include everything in-between the attribute's quotes). Output(SpanKind.Markup); if (quote != HtmlSymbolType.Unknown) { Optional(quote); } Output(SpanKind.Markup); } }