protected virtual Func <bool> EndTerminatedDirective(string directive, BlockType blockType, SpanCodeGenerator codeGenerator, bool allowMarkup)
        {
            return(() =>
            {
                SourceLocation blockStart = CurrentLocation;
                Context.CurrentBlock.Type = blockType;
                AssertDirective(directive);
                AcceptAndMoveNext();

                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
                Span.CodeGenerator = SpanCodeGenerator.Null;
                Output(SpanKind.MetaCode);

                using (PushSpanConfig(StatementBlockSpanConfiguration(codeGenerator)))
                {
                    AutoCompleteEditHandler editHandler = new AutoCompleteEditHandler(Language.TokenizeString);
                    Span.EditHandler = editHandler;

                    if (!EndTerminatedDirectiveBody(directive, blockStart, allowMarkup))
                    {
                        editHandler.AutoCompleteString = String.Concat(SyntaxConstants.VB.EndKeyword, " ", directive);
                        return false;
                    }
                    return true;
                }
            });
        }
Beispiel #2
0
        protected virtual void FunctionsDirective()
        {
            // Set the block type
            Context.CurrentBlock.Type = BlockType.Functions;

            // Verify we're on "functions" and accept
            AssertDirective(SyntaxConstants.CSharp.FunctionsKeyword);
            Block block = new Block(CurrentSymbol);

            AcceptAndMoveNext();

            AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: false));

            if (!At(CSharpSymbolType.LeftBrace))
            {
                Context.OnError(CurrentLocation,
                                RazorResources.ParseError_Expected_X,
                                Language.GetSample(CSharpSymbolType.LeftBrace));
                CompleteBlock();
                Output(SpanKind.MetaCode);
                return;
            }
            else
            {
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
            }

            // Capture start point and continue
            SourceLocation blockStart = CurrentLocation;

            AcceptAndMoveNext();

            // Output what we've seen and continue
            Output(SpanKind.MetaCode);

            AutoCompleteEditHandler editHandler = new AutoCompleteEditHandler(Language.TokenizeString);

            Span.EditHandler = editHandler;

            Balance(BalancingModes.NoErrorOnFailure, CSharpSymbolType.LeftBrace, CSharpSymbolType.RightBrace, blockStart);
            Span.CodeGenerator = new TypeMemberCodeGenerator();
            if (!At(CSharpSymbolType.RightBrace))
            {
                editHandler.AutoCompleteString = "}";
                Context.OnError(block.Start, RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, block.Name, "}", "{");
                CompleteBlock();
                Output(SpanKind.Code);
            }
            else
            {
                Output(SpanKind.Code);
                Assert(CSharpSymbolType.RightBrace);
                Span.CodeGenerator = SpanCodeGenerator.Null;
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
                AcceptAndMoveNext();
                CompleteBlock();
                Output(SpanKind.MetaCode);
            }
        }
Beispiel #3
0
 public virtual string GetAutoCompleteString()
 {
     if (_lastAutoCompleteSpan != null)
     {
         AutoCompleteEditHandler editHandler = _lastAutoCompleteSpan.EditHandler as AutoCompleteEditHandler;
         if (editHandler != null)
         {
             return(editHandler.AutoCompleteString);
         }
     }
     return(null);
 }
Beispiel #4
0
        private void ParseDirectiveBlock(RazorDirectiveDescriptor descriptor, Action <SourceLocation> parseChildren)
        {
            if (EndOfFile)
            {
                Context.OnError(
                    CurrentLocation,
                    $"Unexpected end of file following directive {descriptor.Name}. Expected '{{'",
                    CurrentSymbol.Content.Length);
            }
            else if (!At(CSharpSymbolType.LeftBrace))
            {
                Context.OnError(
                    CurrentLocation,
                    $"Unexpected literal '{CurrentSymbol.Content.Length}' following directive {descriptor.Name}. Expected '{{'",
                    CurrentSymbol.Content.Length);
            }
            else
            {
                var editHandler = new AutoCompleteEditHandler(Language.TokenizeString, autoCompleteAtEndOfSpan: true);
                Span.EditHandler = editHandler;
                var startingBraceLocation = CurrentLocation;
                AcceptAndMoveNext();
                Span.ChunkGenerator = SpanChunkGenerator.Null;
                Output(SpanKind.MetaCode, AcceptedCharacters.None);

                parseChildren(startingBraceLocation);

                Span.ChunkGenerator = SpanChunkGenerator.Null;
                if (!Optional(CSharpSymbolType.RightBrace))
                {
                    editHandler.AutoCompleteString = "}";
                    Context.OnError(
                        startingBraceLocation,
                        // TODO: This is RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF
                        string.Format(
                            "The {0} block is missing a closing \"{1}\" character.  Make sure you have a matching \"{1}\" character for all the \"{2}\" characters within this block, and that none of the \"{1}\" characters are being interpreted as markup.",
                            descriptor.Name,
                            Language.GetSample(CSharpSymbolType.RightBrace),
                            Language.GetSample(CSharpSymbolType.LeftBrace)),
                        length: 1 /* } */);
                }
                else
                {
                    Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
                }
                CompleteBlock(insertMarkerIfNecessary: false, captureWhitespaceToEndOfLine: true);
                Span.ChunkGenerator = SpanChunkGenerator.Null;
                Output(SpanKind.MetaCode, AcceptedCharacters.None);
            }
        }
        private void VerbatimBlock()
        {
            Assert(CSharpSymbolType.LeftBrace);
            var block = new Block(RazorResources.BlockName_Code, CurrentLocation);

            AcceptAndMoveNext();

            // Set up the "{" span and output
            Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
            Span.ChunkGenerator = SpanChunkGenerator.Null;
            Output(SpanKind.MetaCode);

            // Set up auto-complete and parse the code block
            var editHandler = new AutoCompleteEditHandler(Language.TokenizeString);

            Span.EditHandler = editHandler;
            CodeBlock(false, block);

            Span.ChunkGenerator = new StatementChunkGenerator();
            AddMarkerSymbolIfNecessary();
            if (!At(CSharpSymbolType.RightBrace))
            {
                editHandler.AutoCompleteString = "}";
            }
            Output(SpanKind.Code);

            if (Optional(CSharpSymbolType.RightBrace))
            {
                // Set up the "}" span
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
                Span.ChunkGenerator = SpanChunkGenerator.Null;
            }

            if (!IsNested)
            {
                EnsureCurrent();
                if (At(CSharpSymbolType.NewLine) ||
                    (At(CSharpSymbolType.WhiteSpace) && NextIs(CSharpSymbolType.NewLine)))
                {
                    Context.NullGenerateWhitespaceAndNewLine = true;
                }
            }

            Output(SpanKind.MetaCode);
        }
Beispiel #6
0
        private void VerbatimBlock()
        {
            Assert(CSharpSymbolType.LeftBrace);
            Block block = new Block(RazorResources.BlockName_Code, CurrentLocation);

            AcceptAndMoveNext();

            // Set up the "{" span and output
            Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
            Span.CodeGenerator = SpanCodeGenerator.Null;
            Output(SpanKind.MetaCode);

            // Set up auto-complete and parse the code block
            AutoCompleteEditHandler editHandler = new AutoCompleteEditHandler(
                Language.TokenizeString
                );

            Span.EditHandler = editHandler;
            CodeBlock(false, block);

            Span.CodeGenerator = new StatementCodeGenerator();
            AddMarkerSymbolIfNecessary();
            if (!At(CSharpSymbolType.RightBrace))
            {
                editHandler.AutoCompleteString = "}";
            }
            Output(SpanKind.Code);

            if (Optional(CSharpSymbolType.RightBrace))
            {
                // Set up the "}" span
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
                Span.CodeGenerator = SpanCodeGenerator.Null;
            }

            if (!At(CSharpSymbolType.WhiteSpace) && !At(CSharpSymbolType.NewLine))
            {
                PutCurrentBack();
            }

            CompleteBlock(insertMarkerIfNecessary: false);
            Output(SpanKind.MetaCode);
        }
Beispiel #7
0
        protected virtual void SectionDirective()
        {
            bool nested        = Context.IsWithin(BlockType.Section);
            bool errorReported = false;

            // Set the block and span type
            Context.CurrentBlock.Type = BlockType.Section;

            // Verify we're on "section" and accept
            AssertDirective(SyntaxConstants.CSharp.SectionKeyword);
            AcceptAndMoveNext();

            if (nested)
            {
                Context.OnError(CurrentLocation, String.Format(CultureInfo.CurrentCulture, RazorResources.ParseError_Sections_Cannot_Be_Nested, RazorResources.SectionExample_CS));
                errorReported = true;
            }

            IEnumerable <CSharpSymbol> ws = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));

            // Get the section name
            string sectionName = String.Empty;

            if (!Required(CSharpSymbolType.Identifier,
                          errorIfNotFound: true,
                          errorBase: RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start))
            {
                if (!errorReported)
                {
                    errorReported = true;
                }

                PutCurrentBack();
                PutBack(ws);
                AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
            }
            else
            {
                Accept(ws);
                sectionName = CurrentSymbol.Content;
                AcceptAndMoveNext();
            }
            Context.CurrentBlock.CodeGenerator = new SectionCodeGenerator(sectionName);

            SourceLocation errorLocation = CurrentLocation;

            ws = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));

            // Get the starting brace
            bool sawStartingBrace = At(CSharpSymbolType.LeftBrace);

            if (!sawStartingBrace)
            {
                if (!errorReported)
                {
                    errorReported = true;
                    Context.OnError(errorLocation, RazorResources.ParseError_MissingOpenBraceAfterSection);
                }

                PutCurrentBack();
                PutBack(ws);
                AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
                Optional(CSharpSymbolType.NewLine);
                Output(SpanKind.MetaCode);
                CompleteBlock();
                return;
            }
            else
            {
                Accept(ws);
            }

            // Set up edit handler
            AutoCompleteEditHandler editHandler = new AutoCompleteEditHandler(Language.TokenizeString)
            {
                AutoCompleteAtEndOfSpan = true
            };

            Span.EditHandler = editHandler;
            Span.Accept(CurrentSymbol);

            // Output Metacode then switch to section parser
            Output(SpanKind.MetaCode);
            SectionBlock("{", "}", caseSensitive: true);

            Span.CodeGenerator = SpanCodeGenerator.Null;
            // Check for the terminating "}"
            if (!Optional(CSharpSymbolType.RightBrace))
            {
                editHandler.AutoCompleteString = "}";
                Context.OnError(CurrentLocation,
                                RazorResources.ParseError_Expected_X,
                                Language.GetSample(CSharpSymbolType.RightBrace));
            }
            else
            {
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
            }
            CompleteBlock(insertMarkerIfNecessary: false, captureWhitespaceToEndOfLine: true);
            Output(SpanKind.MetaCode);
            return;
        }
Beispiel #8
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);
        }
        protected virtual bool HelperDirective()
        {
            if (Context.IsWithin(BlockType.Helper))
            {
                Context.OnError(CurrentLocation, RazorResources.ParseError_Helpers_Cannot_Be_Nested);
            }

            Context.CurrentBlock.Type = BlockType.Helper;
            SourceLocation blockStart = CurrentLocation;

            AssertDirective(SyntaxConstants.VB.HelperKeyword);
            AcceptAndMoveNext();

            VBSymbolType firstAfterKeyword = VBSymbolType.Unknown;

            if (CurrentSymbol != null)
            {
                firstAfterKeyword = CurrentSymbol.Type;
            }

            VBSymbol remainingWs = null;

            if (At(VBSymbolType.NewLine))
            {
                // Accept a _single_ new line, we'll be aborting later.
                AcceptAndMoveNext();
            }
            else
            {
                remainingWs = AcceptSingleWhiteSpaceCharacter();
            }
            if (firstAfterKeyword == VBSymbolType.WhiteSpace || firstAfterKeyword == VBSymbolType.NewLine)
            {
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
            }
            Output(SpanKind.MetaCode);
            if (firstAfterKeyword != VBSymbolType.WhiteSpace)
            {
                string error;
                if (At(VBSymbolType.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);

                // Bail out.
                PutCurrentBack();
                Output(SpanKind.Code);
                return(false);
            }

            if (remainingWs != null)
            {
                Accept(remainingWs);
            }

            bool errorReported = !Required(VBSymbolType.Identifier, RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start);

            AcceptWhile(VBSymbolType.WhiteSpace);

            SourceLocation parensStart    = CurrentLocation;
            bool           headerComplete = false;

            if (!Optional(VBSymbolType.LeftParenthesis))
            {
                if (!errorReported)
                {
                    errorReported = true;
                    Context.OnError(CurrentLocation,
                                    RazorResources.ParseError_MissingCharAfterHelperName,
                                    VBSymbol.GetSample(VBSymbolType.LeftParenthesis));
                }
            }
            else if (!Balance(BalancingModes.NoErrorOnFailure, VBSymbolType.LeftParenthesis, VBSymbolType.RightParenthesis, parensStart))
            {
                Context.OnError(parensStart, RazorResources.ParseError_UnterminatedHelperParameterList);
            }
            else
            {
                Expected(VBSymbolType.RightParenthesis);
                headerComplete = true;
            }

            AddMarkerSymbolIfNecessary();
            Context.CurrentBlock.CodeGenerator = new HelperCodeGenerator(
                Span.GetContent(),
                headerComplete);
            AutoCompleteEditHandler editHandler = new AutoCompleteEditHandler(Language.TokenizeString);

            Span.EditHandler = editHandler;
            Output(SpanKind.Code);

            if (headerComplete)
            {
                bool old = IsNested;
                IsNested = true;
                using (Context.StartBlock(BlockType.Statement))
                {
                    using (PushSpanConfig(StatementBlockSpanConfiguration(new StatementCodeGenerator())))
                    {
                        try
                        {
                            if (!EndTerminatedDirectiveBody(SyntaxConstants.VB.HelperKeyword, blockStart, allowAllTransitions: true))
                            {
                                if (Context.LastAcceptedCharacters != AcceptedCharacters.Any)
                                {
                                    AddMarkerSymbolIfNecessary();
                                }

                                editHandler.AutoCompleteString = SyntaxConstants.VB.EndHelperKeyword;
                                return(false);
                            }
                            else
                            {
                                return(true);
                            }
                        }
                        finally
                        {
                            Output(SpanKind.Code);
                            IsNested = old;
                        }
                    }
                }
            }
            else
            {
                Output(SpanKind.Code);
            }
            PutCurrentBack();
            return(false);
        }
        protected virtual bool SectionDirective()
        {
            SourceLocation start = CurrentLocation;

            AssertDirective(SyntaxConstants.VB.SectionKeyword);
            AcceptAndMoveNext();

            if (Context.IsWithin(BlockType.Section))
            {
                Context.OnError(CurrentLocation, RazorResources.ParseError_Sections_Cannot_Be_Nested, RazorResources.SectionExample_VB);
            }

            if (At(VBSymbolType.NewLine))
            {
                AcceptAndMoveNext();
            }
            else
            {
                AcceptVBSpaces();
            }
            string sectionName = null;

            if (!At(VBSymbolType.Identifier))
            {
                Context.OnError(CurrentLocation,
                                RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start,
                                GetCurrentSymbolDisplay());
            }
            else
            {
                sectionName = CurrentSymbol.Content;
                AcceptAndMoveNext();
            }
            Context.CurrentBlock.Type          = BlockType.Section;
            Context.CurrentBlock.CodeGenerator = new SectionCodeGenerator(sectionName ?? String.Empty);

            AutoCompleteEditHandler editHandler = new AutoCompleteEditHandler(Language.TokenizeString);

            Span.EditHandler = editHandler;

            PutCurrentBack();

            Output(SpanKind.MetaCode);

            // Parse the section
            OtherParserBlock(null, SyntaxConstants.VB.EndSectionKeyword);

            Span.CodeGenerator = SpanCodeGenerator.Null;
            bool complete = false;

            if (!At(VBKeyword.End))
            {
                Context.OnError(start,
                                RazorResources.ParseError_BlockNotTerminated,
                                SyntaxConstants.VB.SectionKeyword,
                                SyntaxConstants.VB.EndSectionKeyword);
                editHandler.AutoCompleteString = SyntaxConstants.VB.EndSectionKeyword;
            }
            else
            {
                AcceptAndMoveNext();
                AcceptWhile(VBSymbolType.WhiteSpace);
                if (!At(SyntaxConstants.VB.SectionKeyword))
                {
                    Context.OnError(start,
                                    RazorResources.ParseError_BlockNotTerminated,
                                    SyntaxConstants.VB.SectionKeyword,
                                    SyntaxConstants.VB.EndSectionKeyword);
                }
                else
                {
                    AcceptAndMoveNext();
                    Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
                    complete = true;
                }
            }
            PutCurrentBack();
            Output(SpanKind.MetaCode);
            return(complete);
        }
        public void GetHashCode_ReturnsSameValue_WhenEqual(
            AutoCompleteEditHandler leftObject,
            AutoCompleteEditHandler rightObject)
        {
            // Arrange & Act
            var leftResult = leftObject.GetHashCode();
            var rightResult = rightObject.GetHashCode();

            // Assert
            Assert.Equal(leftResult, rightResult);
        }
        public void Equals_False_WhenExpected(AutoCompleteEditHandler leftObject, object rightObject)
        {
            // Arrange & Act
            var result = leftObject.Equals(rightObject);

            // Assert
            Assert.False(result);
        }
Beispiel #13
0
        protected virtual void FunctionsDirective()
        {
            // Set the block type
            Context.CurrentBlock.Type = BlockType.Functions;

            // Verify we're on "functions" and accept
            AssertDirective(SyntaxConstants.CSharp.FunctionsKeyword);
            var block = new Block(CurrentSymbol);
            AcceptAndMoveNext();

            AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: false));

            if (!At(CSharpSymbolType.LeftBrace))
            {
                Context.OnError(
                    CurrentLocation,
                    RazorResources.FormatParseError_Expected_X(Language.GetSample(CSharpSymbolType.LeftBrace)),
                    length: 1 /* { */);
                CompleteBlock();
                Output(SpanKind.MetaCode);
                return;
            }
            else
            {
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
            }

            // Capture start point and continue
            var blockStart = CurrentLocation;
            AcceptAndMoveNext();

            // Output what we've seen and continue
            Output(SpanKind.MetaCode);

            var editHandler = new AutoCompleteEditHandler(Language.TokenizeString);
            Span.EditHandler = editHandler;

            Balance(BalancingModes.NoErrorOnFailure, CSharpSymbolType.LeftBrace, CSharpSymbolType.RightBrace, blockStart);
            Span.ChunkGenerator = new TypeMemberChunkGenerator();
            if (!At(CSharpSymbolType.RightBrace))
            {
                editHandler.AutoCompleteString = "}";
                Context.OnError(
                    blockStart,
                    RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, "}", "{"),
                    length: 1 /* } */);
                CompleteBlock();
                Output(SpanKind.Code);
            }
            else
            {
                Output(SpanKind.Code);
                Assert(CSharpSymbolType.RightBrace);
                Span.ChunkGenerator = SpanChunkGenerator.Null;
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
                AcceptAndMoveNext();
                CompleteBlock();
                Output(SpanKind.MetaCode);
            }
        }
Beispiel #14
0
        protected virtual void SectionDirective()
        {
            var nested = Context.IsWithin(BlockType.Section);
            var errorReported = false;

            // Set the block and span type
            Context.CurrentBlock.Type = BlockType.Section;

            // Verify we're on "section" and accept
            AssertDirective(SyntaxConstants.CSharp.SectionKeyword);
            var startLocation = CurrentLocation;
            AcceptAndMoveNext();

            if (nested)
            {
                Context.OnError(
                    startLocation,
                    RazorResources.FormatParseError_Sections_Cannot_Be_Nested(RazorResources.SectionExample_CS),
                    Span.GetContent().Value.Length);
                errorReported = true;
            }

            var whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));

            // Get the section name
            var sectionName = string.Empty;
            if (!Required(CSharpSymbolType.Identifier,
                          errorIfNotFound: true,
                          errorBase: RazorResources.FormatParseError_Unexpected_Character_At_Section_Name_Start))
            {
                if (!errorReported)
                {
                    errorReported = true;
                }

                PutCurrentBack();
                PutBack(whitespace);
                AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
            }
            else
            {
                Accept(whitespace);
                sectionName = CurrentSymbol.Content;
                AcceptAndMoveNext();
            }
            Context.CurrentBlock.ChunkGenerator = new SectionChunkGenerator(sectionName);

            var errorLocation = CurrentLocation;
            whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));

            // Get the starting brace
            var sawStartingBrace = At(CSharpSymbolType.LeftBrace);
            if (!sawStartingBrace)
            {
                if (!errorReported)
                {
                    errorReported = true;
                    Context.OnError(
                        errorLocation,
                        RazorResources.ParseError_MissingOpenBraceAfterSection,
                        length: 1  /* { */);
                }

                PutCurrentBack();
                PutBack(whitespace);
                AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
                Optional(CSharpSymbolType.NewLine);
                Output(SpanKind.MetaCode);
                CompleteBlock();
                return;
            }
            else
            {
                Accept(whitespace);
            }

            var startingBraceLocation = CurrentLocation;

            // Set up edit handler
            var editHandler = new AutoCompleteEditHandler(Language.TokenizeString, autoCompleteAtEndOfSpan: true);

            Span.EditHandler = editHandler;
            Span.Accept(CurrentSymbol);

            // Output Metacode then switch to section parser
            Output(SpanKind.MetaCode);
            SectionBlock("{", "}", caseSensitive: true);

            Span.ChunkGenerator = SpanChunkGenerator.Null;
            // Check for the terminating "}"
            if (!Optional(CSharpSymbolType.RightBrace))
            {
                editHandler.AutoCompleteString = "}";
                Context.OnError(
                    startingBraceLocation,
                    RazorResources.FormatParseError_Expected_EndOfBlock_Before_EOF(
                        SyntaxConstants.CSharp.SectionKeyword,
                        Language.GetSample(CSharpSymbolType.RightBrace),
                        Language.GetSample(CSharpSymbolType.LeftBrace)),
                    length: 1 /* } */);
            }
            else
            {
                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
            }
            CompleteBlock(insertMarkerIfNecessary: false, captureWhitespaceToEndOfLine: true);
            Output(SpanKind.MetaCode);
            return;
        }