Exemplo n.º 1
0
 private void Dispose(bool disposing)
 {
     if (disposing)
     {
         if (null != systemState)
         {
             systemState.Dispose();
             systemState = null;
         }
     }
     GC.SuppressFinalize(this);
 }
Exemplo n.º 2
0
        private void SearchForCodeBlocks(IVsTextLines buffer)
        {
            // We don't want any change in the buffer while we are parsing,
            // so we have to lock it.
            ErrorHandler.ThrowOnFailure(buffer.LockBufferEx((uint)BufferLockFlags.BLF_READ));
            try {
                // Find the total number of lines in the buffer.
                int totalLines;
                ErrorHandler.ThrowOnFailure(buffer.GetLineCount(out totalLines));
                // Set the initial values for the variables used during the parsing.
                SimpleParserState state     = SimpleParserState.WaitForExternalSource;
                TextSpanAndCookie blockSpan = new TextSpanAndCookie();

                // Parse all the lines in the buffer
                for (int line = 0; line < totalLines; ++line)
                {
                    // Get the text of the current line.
                    int lineLen;
                    ErrorHandler.ThrowOnFailure(buffer.GetLengthOfLine(line, out lineLen));
                    if (0 == lineLen)
                    {
                        // The line is empty, no point in parsing it.
                        continue;
                    }
                    string lineText;
                    ErrorHandler.ThrowOnFailure(buffer.GetLineText(line, 0, line, lineLen, out lineText));

                    // Create the tokenizer.
                    CompilerContext context = new CompilerContext("", new QuietCompilerSink());
                    using (SystemState systemState = new SystemState()) {
                        tokenizer = new Tokenizer(lineText.ToCharArray(), true, systemState, context);

                        Token  token = null;
                        string commentText;

                        // Read all the token looking for the code blocks inside a Snippet Statements
                        // nested in an External Source statement. Note that the standard FoxPro
                        // parser does not return such statements and this is the reason for this
                        // parser.
                        while (!tokenizer.IsEndOfFile)
                        {
                            token = tokenizer.Next();

                            // This parser is strange in that it is only interested in comments:
                            // an external code statement is in the form
                            //     #ExternalSource("PathOfTheOriginalFile", originalLineNumber)
                            //     ... (some code) ...
                            //     #End ExternalSource
                            // and a snippet statement is
                            //     # Snippet Statement
                            //     ... (some code) ...
                            //     #End Snippet Statement
                            // So if we want to find the text region inside a snippet nested
                            // inside an external source, we are only interested in the comment tokens.

                            if (TokenKind.Comment != token.Kind)
                            {
                                continue;
                            }

                            // The comments are line comments, so the comment's text is everything that
                            // is after the beginning of the comment.
                            commentText = CleanCommentStart(lineText.Substring(tokenizer.StartLocation.Column));
                            if (string.IsNullOrEmpty(commentText))
                            {
                                continue;
                            }

                            switch (state)
                            {
                            case SimpleParserState.WaitForExternalSource:
                                // This function returns a non zero value only if the comment text
                                // is a valid external source statment.
                                blockSpan.ulHTMLCookie = ParseExternalSource(commentText);
                                if (0 != blockSpan.ulHTMLCookie)
                                {
                                    // The CodeDOM provider is adding 1 to the line number, but in this
                                    // case the number is actualy the HTML editor's cookie, so we have to
                                    // restore the original value.
                                    blockSpan.ulHTMLCookie -= 1;
                                    state = SimpleParserState.WaitForSnippet;
                                }
                                break;

                            case SimpleParserState.WaitForSnippet:
                                // Check if this comment is the beginning of a snippet block.
                                if (IsBeginSnippet(commentText))
                                {
                                    // This is the beginning of a snippet block, so
                                    // the actual code will start at the beginning of the
                                    // next line.
                                    blockSpan.CodeSpan.iStartLine = line + 1;
                                    // Set the default for the start index.
                                    blockSpan.CodeSpan.iStartIndex = 0;

                                    // Now we have to find the end of the snippet section
                                    // to complete the span of the code.
                                    state = SimpleParserState.WaitForEndSnippet;
                                }
                                else if (IsEndExternalSource(commentText))
                                {
                                    // This was and external block not related to the HTML editor.
                                    // Reset the text span and wait for the next external source.
                                    blockSpan = new TextSpanAndCookie();
                                    state     = SimpleParserState.WaitForExternalSource;
                                }
                                break;

                            case SimpleParserState.WaitForEndSnippet:
                                if (IsEndSnippet(commentText))
                                {
                                    // The code block ends at the end of the line before
                                    // this token.
                                    // Update the data about the code span and add the
                                    // block to the list of the blocks found.
                                    blockSpan.CodeSpan.iEndLine = line - 1;
                                    ErrorHandler.ThrowOnFailure(
                                        buffer.GetLengthOfLine(line - 1, out blockSpan.CodeSpan.iEndIndex));
                                    blocks.Add(blockSpan);

                                    blockSpan = new TextSpanAndCookie();
                                    state     = SimpleParserState.WaitForEndExternal;
                                }
                                break;

                            case SimpleParserState.WaitForEndExternal:
                                // We expect only one snippet block inside the external source
                                // section, so here we skip everything between the end of the first
                                // snippet block and the end of the external code section.
                                if (IsEndExternalSource(commentText))
                                {
                                    state = SimpleParserState.WaitForExternalSource;
                                }
                                break;
                            }
                        }
                    }
                }
            } finally {
                // Make sure that the buffer is always unlocked when we exit this function.
                buffer.UnlockBufferEx((uint)BufferLockFlags.BLF_READ);
            }
        }