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;
 }
Beispiel #4
0
 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))
 {
 }
Beispiel #7
0
 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;
 }
Beispiel #9
0
        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;
 }
Beispiel #11
0
 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);
            }
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
 public HelperCodeGenerator(LocationTagged<string> signature, bool headerComplete)
 {
     Signature = signature;
     HeaderComplete = headerComplete;
 }
Beispiel #17
0
        public CSharpCodeWriter WriteLocationTaggedString(LocationTagged<string> value)
        {
            WriteStringLiteral(value.Value);
            WriteParameterSeparator();
            Write(value.Location.AbsoluteIndex.ToString(CultureInfo.InvariantCulture));

            return this;
        }
Beispiel #18
0
 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);
            }
        }
Beispiel #20
0
 public DynamicAttributeBlockCodeGenerator(LocationTagged <string> prefix, SourceLocation valueStart)
 {
     Prefix     = prefix;
     ValueStart = valueStart;
 }
Beispiel #21
0
 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);
            }
        }