Esempio n. 1
0
        /* Function: TryToGetLineComment
         * If the iterator is on a line that starts with a line comment symbol, this function moves the iterator past the entire
         * comment and returns true.  If the comment is a candidate for documentation it will also return it as a
         * <PossibleDocumentationComment>.  If the line does not start with a line comment symbol it will return false and
         * leave the iterator where it is.
         */
        protected bool TryToGetLineComment(ref LineIterator lineIterator, string commentSymbol,
                                           out PossibleDocumentationComment comment)
        {
            TokenIterator firstToken = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace);

            if (firstToken.MatchesAcrossTokens(commentSymbol) == false)
            {
                comment = null;
                return(false);
            }

            comment       = new PossibleDocumentationComment();
            comment.Start = lineIterator;
            lineIterator.Next();

            // Since we're definitely returning a comment we can mark the comment symbols as we go rather than waiting until
            // the end.
            firstToken.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, commentSymbol.Length);

            while (lineIterator.IsInBounds)
            {
                firstToken = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace);

                if (firstToken.MatchesAcrossTokens(commentSymbol) == false)
                {
                    break;
                }

                firstToken.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, commentSymbol.Length);
                lineIterator.Next();
            }

            comment.End = lineIterator;
            return(true);
        }
Esempio n. 2
0
        /* Function: TryToSkipSubstitutionIdentifier
         * If the iterator is on a valid substitution identifier, advances it past it, returns it, and returns true.
         * Otherwise the iterator will be left alone and it will return false.
         */
        protected bool TryToSkipSubstitutionIdentifier(ref TokenIterator iterator, out string identifier)
        {
            if (iterator.Character != '$' && iterator.Character != '@')
            {
                identifier = null;
                return(false);
            }

            TokenIterator lookahead = iterator;

            lookahead.Next();

            // Locale substitutions
            if (lookahead.MatchesAcrossTokens("Locale{"))
            {
                identifier = null;
                return(false);
            }

            while (lookahead.IsInBounds &&
                   (lookahead.FundamentalType == FundamentalType.Text ||
                    lookahead.Character == '.' ||
                    lookahead.Character == '_'))
            {
                lookahead.Next();
            }

            identifier = iterator.TextBetween(lookahead);
            iterator   = lookahead;
            return(true);
        }
Esempio n. 3
0
        /* Function: IsOnOpeningBlockCommentSymbol
         *
         * Returns whether  the iterator is on an opening block comment symbol.  This handles --[[ comments as well as forms with
         * equals signs such as --[==[.
         */
        protected bool IsOnOpeningBlockCommentSymbol(TokenIterator iterator)
        {
            if (iterator.MatchesAcrossTokens("--[") == false)
            {
                return(false);
            }

            TokenIterator lookahead = iterator;

            lookahead.Next(3);

            while (lookahead.Character == '=')
            {
                lookahead.Next();
            }

            if (lookahead.Character == '[')
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 4
0
        /* Function: TryToGetPDLineComment
         *
         * If the line iterator is on a line comment, return it and all connected line comments as a
         * <PossibleDocumentationComment> and mark the symbols as <CommentParsingType.CommentSymbol>.  Returns
         * null otherwise.
         *
         * This function takes a separate comment symbol for the first line and all remaining lines, allowing you to detect
         * Javadoc line comments that start with ## and the remaining lines use #.  Both symbols can be the same if this isn't
         * required.  If openingMustBeAlone is set, no symbol can appear immediately after the first line symbol for this
         * function to succeed.  This allows you to specifically detect something like ## without also matching #######.
         */
        protected PossibleDocumentationComment TryToGetPDLineComment(LineIterator lineIterator,
                                                                     string firstSymbol, string remainderSymbol,
                                                                     bool openingMustBeAlone)
        {
            TokenIterator firstToken = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace);

            if (firstToken.MatchesAcrossTokens(firstSymbol) == false)
            {
                return(null);
            }

            if (openingMustBeAlone)
            {
                TokenIterator nextToken = firstToken;
                nextToken.NextByCharacters(firstSymbol.Length);
                if (nextToken.FundamentalType == FundamentalType.Symbol)
                {
                    return(null);
                }
            }

            PossibleDocumentationComment comment = new PossibleDocumentationComment();

            comment.Start = lineIterator;
            lineIterator.Next();

            // Since we're definitely returning a comment (barring the operation being cancelled) we can mark the comment
            // symbols as we go rather than waiting until the end.
            firstToken.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, firstSymbol.Length);

            while (lineIterator.IsInBounds)
            {
                firstToken = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace);

                if (firstToken.MatchesAcrossTokens(remainderSymbol) == false)
                {
                    break;
                }

                firstToken.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, remainderSymbol.Length);
                lineIterator.Next();
            }

            comment.End = lineIterator;
            return(comment);
        }
Esempio n. 5
0
 /* Function: TryToSkipLineCommentSymbol
  *
  * If the iterator is on a line comment, moves it past it and returns true.  Otherwise leaves the iterator alone and
  * returns false. This handles the fact that block comments also start with -- and will not move past them.
  */
 protected bool TryToSkipLineCommentSymbol(ref TokenIterator iterator)
 {
     if (iterator.MatchesAcrossTokens("--") &&
         !IsOnOpeningBlockCommentSymbol(iterator))
     {
         iterator.Next(2);
         return(true);
     }
     else
     {
         return(false);
     }
 }
Esempio n. 6
0
        /* Function: TryToSkipBlockComment
         * If the iterator is on the opening symbol of a block comment, skips over it and returns true.  Otherwise leaves the iterator
         * alone and returns false.
         */
        protected bool TryToSkipBlockComment(ref TokenIterator iterator, string openingSymbol, string closingSymbol)
        {
            if (iterator.MatchesAcrossTokens(openingSymbol))
            {
                iterator.NextByCharacters(openingSymbol.Length);

                while (iterator.IsInBounds && !iterator.MatchesAcrossTokens(closingSymbol))
                {
                    iterator.Next();
                }

                if (iterator.IsInBounds)
                {
                    iterator.NextByCharacters(closingSymbol.Length);
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 7
0
        /* Function: TryToSkipOpeningBlockCommentSymbol
         *
         * If the iterator is on an opening block comment symbol, moves it past it and returns true and the closing symbol.  Otherwise
         * leaves the iterator alone and returns false and null.  This handles --[[ comments as well as forms with equals signs such as
         * --[==[.
         */
        protected bool TryToSkipOpeningBlockCommentSymbol(ref TokenIterator iterator, out string closingSymbol)
        {
            if (iterator.MatchesAcrossTokens("--[") == false)
            {
                closingSymbol = null;
                return(false);
            }

            TokenIterator lookahead = iterator;

            lookahead.Next(3);

            int equals = 0;

            while (lookahead.Character == '=')
            {
                lookahead.Next();
                equals++;
            }

            if (lookahead.Character != '[')
            {
                closingSymbol = null;
                return(false);
            }

            lookahead.Next();
            iterator = lookahead;

            if (equals == 0)
            {
                closingSymbol = "]]";
            }
            else
            {
                StringBuilder closingSymbolBuilder = new StringBuilder(2 + equals);
                closingSymbolBuilder.Append(']');
                closingSymbolBuilder.Append('=', equals);
                closingSymbolBuilder.Append(']');
                closingSymbol = closingSymbolBuilder.ToString();
            }

            return(true);
        }
Esempio n. 8
0
        /* Function: TryToSkipLocaleSubstitutionIdentifier
         * If the iterator is on a valid locale substitution identifier, advances it past it, returns it, and returns true.
         * Otherwise the iterator will be left alone and it will return false.
         */
        protected bool TryToSkipLocaleSubstitutionIdentifier(ref TokenIterator iterator, out string identifier, out string localeIdentifier)
        {
            if (iterator.Character != '$' && iterator.Character != '@')
            {
                identifier       = null;
                localeIdentifier = null;
                return(false);
            }

            TokenIterator lookahead = iterator;

            lookahead.Next();

            if (lookahead.MatchesAcrossTokens("Locale{") == false)
            {
                identifier       = null;
                localeIdentifier = null;
                return(false);
            }

            lookahead.NextByCharacters(7);
            TokenIterator startOfLocaleIdentifier = lookahead;

            while (lookahead.IsInBounds && lookahead.Character != '}')
            {
                lookahead.Next();
            }

            if (lookahead.Character != '}')
            {
                identifier       = null;
                localeIdentifier = null;
                return(false);
            }

            localeIdentifier = startOfLocaleIdentifier.TextBetween(lookahead);
            lookahead.Next();

            identifier = iterator.TextBetween(lookahead);

            iterator = lookahead;
            return(true);
        }
Esempio n. 9
0
        /* Function: TryToSkipLineComment
         * If the iterator is on the opening symbol of a line comment, skips over it and returns true.  Otherwise leaves the iterator
         * alone and returns false.
         */
        protected bool TryToSkipLineComment(ref TokenIterator iterator, string symbol)
        {
            if (iterator.MatchesAcrossTokens(symbol))
            {
                iterator.NextByCharacters(symbol.Length);

                while (iterator.IsInBounds && iterator.FundamentalType != FundamentalType.LineBreak)
                {
                    iterator.Next();
                }

                if (iterator.FundamentalType == FundamentalType.LineBreak)
                {
                    iterator.Next();
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 10
0
        // Function: GetPossibleDocumentationComments
        //
        // Goes through the file looking for comments that could possibly contain documentation and returns them as a list.  These
        // comments are not guaranteed to have documentation in them, just to be acceptable candidates for them.  If there are no
        // comments it will return an empty list.
        //
        // All the comments in the returned list will have their comment symbols marked as <CommentParsingType.CommentSymbol>
        // in the tokenizer.  This allows further operations to be done on them in a language independent manner.  If you want to also
        // filter out text boxes and lines, use <Comments.LineFinder>.
        //
        override public List <PossibleDocumentationComment> GetPossibleDocumentationComments(Tokenizer source)
        {
            List <PossibleDocumentationComment> comments = new List <PossibleDocumentationComment>();
            LineIterator lineIterator = source.FirstLine;

            PODLineType podLineType;

            while (lineIterator.IsInBounds)
            {
                TokenIterator tokenIterator = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace);


                // Hash comments

                if (tokenIterator.Character == '#')
                {
                    PossibleDocumentationComment comment = new PossibleDocumentationComment();
                    comment.Start = lineIterator;


                    // First line

                    if (tokenIterator.MatchesAcrossTokens("###"))
                    {
                        comment.Javadoc = false;
                        comment.XML     = true;
                    }
                    else if (tokenIterator.MatchesAcrossTokens("##"))
                    {
                        comment.Javadoc = true;
                        comment.XML     = false;
                    }
                    else                     // just "#"
                    {
                        comment.Javadoc = false;
                        comment.XML     = false;
                    }

                    lineIterator.Next();


                    // Subsequent lines

                    while (lineIterator.IsInBounds)
                    {
                        tokenIterator = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace);

                        if (tokenIterator.Character != '#')
                        {
                            break;
                        }

                        if (tokenIterator.MatchesAcrossTokens("###"))
                        {
                            comment.Javadoc = false;
                            // XML is still possible
                        }
                        else if (tokenIterator.MatchesAcrossTokens("##"))
                        {
                            comment.Javadoc = false;
                            comment.XML     = false;
                        }
                        else                         // just "#"
                        {
                            // Javadoc is still possible
                            comment.XML = false;
                        }

                        lineIterator.Next();
                    }

                    comment.End = lineIterator;
                    comments.Add(comment);


                    // Go back and mark the tokens

                    int firstLineCount, subsequentLineCount;

                    if (comment.XML)
                    {
                        firstLineCount      = 3;
                        subsequentLineCount = 3;
                    }
                    else if (comment.Javadoc)
                    {
                        firstLineCount      = 2;
                        subsequentLineCount = 1;
                    }
                    else                     // plain
                    {
                        firstLineCount      = 1;
                        subsequentLineCount = 1;
                    }

                    LineIterator temp = comment.Start;
                    tokenIterator = temp.FirstToken(LineBoundsMode.ExcludeWhitespace);

                    tokenIterator.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, firstLineCount);
                    temp.Next();

                    while (temp < comment.End)
                    {
                        tokenIterator = temp.FirstToken(LineBoundsMode.ExcludeWhitespace);
                        tokenIterator.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, subsequentLineCount);
                        temp.Next();
                    }


                    // XML can actually appear in Javadoc comments

                    if (comment.Javadoc)
                    {
                        comment.XML = true;
                    }
                }


                // POD comments

                else if (TryToSkipPODLine(ref tokenIterator, out podLineType))
                {
                    TokenIterator podLineStart, podLineEnd;
                    lineIterator.GetBounds(LineBoundsMode.CommentContent, out podLineStart, out podLineEnd);

                    lineIterator.Tokenizer.SetCommentParsingTypeBetween(podLineStart, podLineEnd, CommentParsingType.CommentSymbol);

                    if (podLineType == PODLineType.StartNaturalDocs ||
                        podLineType == PODLineType.StartJavadoc)
                    {
                        PossibleDocumentationComment comment = new PossibleDocumentationComment();
                        comment.Start = lineIterator;

                        if (podLineType == PODLineType.StartJavadoc)
                        {
                            comment.Javadoc = true;
                        }

                        for (;;)
                        {
                            lineIterator.Next();

                            if (lineIterator.IsInBounds == false)
                            {
                                break;
                            }

                            tokenIterator = lineIterator.FirstToken(LineBoundsMode.CommentContent);

                            if (TryToSkipPODLine(ref tokenIterator, out podLineType) == true)
                            {
                                if (podLineType == PODLineType.End)
                                {
                                    lineIterator.GetBounds(LineBoundsMode.CommentContent, out podLineStart, out podLineEnd);
                                    lineIterator.Tokenizer.SetCommentParsingTypeBetween(podLineStart, podLineEnd, CommentParsingType.CommentSymbol);

                                    lineIterator.Next();
                                }

                                break;
                            }
                        }

                        comment.End = lineIterator;
                        comments.Add(comment);
                    }
                    else
                    {
                        lineIterator.Next();
                    }
                }

                else
                {
                    lineIterator.Next();
                }
            }

            return(comments);
        }
Esempio n. 11
0
        /* Function: AppendCellContents
         */
        protected void AppendCellContents(int parameterIndex, int cellIndex, StringBuilder output)
        {
            TokenIterator start = parameterTableSection.Start;

            start.Next(parameterTableTokenIndexes[parameterIndex, cellIndex] - start.TokenIndex);

            TokenIterator end = start;

            end.Next(parameterTableTokenIndexes[parameterIndex, cellIndex + 1] - end.TokenIndex);

            bool hadTrailingWhitespace = end.PreviousPastWhitespace(PreviousPastWhitespaceMode.EndingBounds, start);

            ColumnType type = ColumnOrder[cellIndex];

            // Find the type of the next used cell
            ColumnType?nextType = null;

            for (int nextCellIndex = cellIndex + 1; nextCellIndex < NumberOfColumns; nextCellIndex++)
            {
                if (parameterTableColumnsUsed[nextCellIndex])
                {
                    nextType = ColumnOrder[nextCellIndex];
                    break;
                }
            }

            // Default value separators always get spaces before.
            // Property value separators get them unless they're ":", but watch out for ":=".
            // Type-name separators get them if they're text (SQL's "AS") instead of symbols (Pascal's ":").
            if (type == ColumnType.DefaultValueSeparator ||
                (type == ColumnType.PropertyValueSeparator && (start.Character != ':' || start.MatchesAcrossTokens(":="))) ||
                (type == ColumnType.TypeNameSeparator && start.FundamentalType == FundamentalType.Text))
            {
                output.Append("&nbsp;");
            }

            // We don't want to highlight keywords on the Name cell because identifiers can accidentally be marked as them with
            // basic language support, such as "event" in "wxPaintEvent &event".
            if (type == ColumnType.Name)
            {
                AppendSyntaxHighlightedText(start, end, output, excludeKeywords: true);
            }
            else if (addLinks)
            {
                AppendSyntaxHighlightedTextWithTypeLinks(start, end, output, links, linkTargets, extendTypeSearch: true);
            }
            else
            {
                AppendSyntaxHighlightedText(start, end, output);
            }

            // Default value separators, property value separators, and type/name separators always get spaces after.  Make sure
            // the spaces aren't duplicated by the preceding cells.
            if (type == ColumnType.DefaultValueSeparator ||
                type == ColumnType.PropertyValueSeparator ||
                type == ColumnType.TypeNameSeparator ||
                (hadTrailingWhitespace &&
                 type != ColumnType.DefaultValue &&
                 nextType != ColumnType.DefaultValueSeparator &&
                 nextType != ColumnType.PropertyValueSeparator &&
                 nextType != ColumnType.TypeNameSeparator))
            {
                output.Append("&nbsp;");
            }
        }
Esempio n. 12
0
        /* Function: TryToGetBlockSymbol
         * If the iterator is on the symbol part of a block tag that has one, such as "@param symbol description", extracts the symbol,
         * moves the iterator past it, and returns true.
         */
        protected bool TryToGetBlockSymbol(ref TokenIterator iterator, TokenIterator limit, out string entryText)
        {
            TokenIterator lookahead = iterator;

            // Javadoc recommends documenting template parameters as "@param <T> ...".
            if (lookahead.Character == '<')
            {
                lookahead.Next();

                for (;;)
                {
                    if (lookahead >= limit)
                    {
                        entryText = null;
                        return(false);
                    }
                    else if (lookahead.Character == '>')
                    {
                        lookahead.Next();
                        break;
                    }
                    else
                    {
                        lookahead.Next();
                    }
                }
            }

            else             // not '<'
            {
                for (;;)
                {
                    if (lookahead >= limit)
                    {
                        entryText = null;
                        return(false);
                    }
                    else if (lookahead.FundamentalType == FundamentalType.Text ||
                             lookahead.Character == '_' ||
                             lookahead.Character == '.')
                    {
                        lookahead.Next();
                    }
                    else if (lookahead.MatchesAcrossTokens("::") ||
                             lookahead.MatchesAcrossTokens("->"))
                    {
                        lookahead.NextByCharacters(2);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (lookahead >= limit || lookahead.FundamentalType != FundamentalType.Whitespace)
            {
                entryText = null;
                return(false);
            }

            entryText = iterator.TextBetween(lookahead);
            iterator  = lookahead;
            return(true);
        }
Esempio n. 13
0
        // Group: Support Functions
        // __________________________________________________________________________


        /* Function: TryToGetPDBlockComment
         *
         * If the line iterator is on the starting symbol of a block comment, return it as a <PossibleDocumentationComment>
         * and mark the symbols as <CommentParsingType.CommentSymbol>.  If the iterator is not on the opening comment
         * symbol or there is content after the closing comment symbol making it unsuitable as a documentation comment,
         * returns null.
         *
         * If openingMustBeAlone is set, that means no symbol can appear immediately after the opening symbol for this
         * function to succeed.  This allows you to specifically detect something like /** without also matching /******.
         */
        protected PossibleDocumentationComment TryToGetPDBlockComment(LineIterator lineIterator,
                                                                      string openingSymbol, string closingSymbol,
                                                                      bool openingMustBeAlone)
        {
            TokenIterator firstToken = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace);

            if (firstToken.MatchesAcrossTokens(openingSymbol) == false)
            {
                return(null);
            }

            if (openingMustBeAlone)
            {
                TokenIterator nextToken = firstToken;
                nextToken.NextByCharacters(openingSymbol.Length);
                if (nextToken.FundamentalType == FundamentalType.Symbol)
                {
                    return(null);
                }
            }

            PossibleDocumentationComment comment = new PossibleDocumentationComment();

            comment.Start = lineIterator;

            for (;;)
            {
                if (!lineIterator.IsInBounds)
                {
                    return(null);
                }

                TokenIterator closingSymbolIterator;

                if (lineIterator.FindAcrossTokens(closingSymbol, false, LineBoundsMode.Everything, out closingSymbolIterator) == true)
                {
                    closingSymbolIterator.NextByCharacters(closingSymbol.Length);

                    closingSymbolIterator.NextPastWhitespace();

                    if (closingSymbolIterator.FundamentalType != FundamentalType.LineBreak &&
                        closingSymbolIterator.FundamentalType != FundamentalType.Null)
                    {
                        return(null);
                    }

                    lineIterator.Next();
                    comment.End = lineIterator;
                    break;
                }

                lineIterator.Next();
            }

            // Success.  Mark the symbols before returning.
            firstToken.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, openingSymbol.Length);

            TokenIterator lastToken;

            lineIterator.Previous();
            lineIterator.GetBounds(LineBoundsMode.ExcludeWhitespace, out firstToken, out lastToken);
            lastToken.PreviousByCharacters(closingSymbol.Length);
            lastToken.SetCommentParsingTypeByCharacters(CommentParsingType.CommentSymbol, closingSymbol.Length);

            return(comment);
        }
Esempio n. 14
0
        /* Function: AddToken
         * Adds a single token to the type builder.  You must use <AddBlock()> for blocks.
         */
        public void AddToken(TokenIterator iterator)
        {
            if (iterator.PrototypeParsingType == PrototypeParsingType.OpeningTypeModifier ||
                iterator.PrototypeParsingType == PrototypeParsingType.OpeningParamModifier)
            {
                throw new InvalidOperationException();
            }

            if (iterator.PrototypeParsingType == PrototypeParsingType.Type ||
                iterator.PrototypeParsingType == PrototypeParsingType.TypeModifier ||
                iterator.PrototypeParsingType == PrototypeParsingType.TypeQualifier ||
                iterator.PrototypeParsingType == PrototypeParsingType.ParamModifier ||
                iterator.PrototypeParsingType == PrototypeParsingType.StartOfTuple ||
                iterator.PrototypeParsingType == PrototypeParsingType.EndOfTuple ||
                iterator.PrototypeParsingType == PrototypeParsingType.TupleMemberSeparator ||
                iterator.PrototypeParsingType == PrototypeParsingType.TupleMemberName)
            {
                FundamentalType thisTokenType = (iterator.Character == '_' ? FundamentalType.Text : iterator.FundamentalType);

                // ignore whitespace, we'll create it as necessary
                if (thisTokenType == FundamentalType.Text ||
                    thisTokenType == FundamentalType.Symbol)
                {
                    // Do we need to add a space?
                    if ((thisTokenType == FundamentalType.Text && lastTokenType == FundamentalType.Text &&
                         (iterator.Tokenizer != lastTokenIterator.Tokenizer || iterator.TokenIndex != lastTokenIterator.TokenIndex + 1))
                        ||
                        (thisTokenType == FundamentalType.Text && lastTokenType == FundamentalType.Symbol &&
                         !dontAddSpaceAfterSymbol && (pastFirstText || lastSymbolWasBlock))
                        ||
                        (!lastTokenIterator.IsNull && lastTokenIterator.PrototypeParsingType == PrototypeParsingType.TupleMemberSeparator))
                    {
                        rawText.Append(' ');
                        prototypeParsingTypes.Add(PrototypeParsingType.Null);
                        syntaxHighlightingTypes.Add(SyntaxHighlightingType.Null);
                    }

                    // Special handling for package separators and a few other things
                    if (iterator.FundamentalType == FundamentalType.Symbol)
                    {
                        if (iterator.Character == '.' || iterator.MatchesAcrossTokens("::") ||
                            (iterator.Character == ':' && dontAddSpaceAfterSymbol) ||  // second colon of ::
                            iterator.Character == '%' ||                               // used for MyVar%TYPE or MyTable%ROWTYPE in Oracle's PL/SQL
                            iterator.Character == '"' || iterator.Character == '\'' || // strings in Java annotations like @copyright("me")
                            iterator.Character == '@' ||                               // tags in Java annotations like @copyright
                            iterator.Character == '(')                                 // parens around tuples
                        {
                            dontAddSpaceAfterSymbol = true;
                        }
                        else
                        {
                            dontAddSpaceAfterSymbol = false;
                        }
                    }

                    iterator.AppendTokenTo(rawText);
                    prototypeParsingTypes.Add(iterator.PrototypeParsingType);
                    syntaxHighlightingTypes.Add(iterator.SyntaxHighlightingType);

                    lastTokenIterator  = iterator;
                    lastTokenType      = thisTokenType;
                    lastSymbolWasBlock = false;

                    if (thisTokenType == FundamentalType.Text)
                    {
                        pastFirstText = true;
                    }
                }
            }
        }
Esempio n. 15
0
        /* Function: HasSimilarSpacing
         * Returns whether the spacing of the tokens between the two iterators matches what would have been built by this
         * class if the tokens were passed through it.
         */
        public static bool HasSimilarSpacing(TokenIterator start, TokenIterator end)
        {
            // ::Package::Name* array of const*[]
            // Single spaces only between words, and between words and prior symbols except for leading symbols and package separators

            TokenIterator iterator = start;

            bool            pastFirstText           = false;
            FundamentalType lastTokenType           = FundamentalType.Null;
            bool            dontAddSpaceAfterSymbol = false;
            bool            lastSymbolWasBlock      = false;

            while (iterator < end)
            {
                if (iterator.FundamentalType == FundamentalType.Text ||
                    iterator.Character == '_')
                {
                    if (lastTokenType == FundamentalType.Null ||
                        lastTokenType == FundamentalType.Text ||
                        (lastTokenType == FundamentalType.Symbol && (dontAddSpaceAfterSymbol || (!pastFirstText && !lastSymbolWasBlock))) ||
                        lastTokenType == FundamentalType.Whitespace)
                    {
                        pastFirstText = true;
                        lastTokenType = FundamentalType.Text;

                        if (!TryToSkipModifierBlock(ref iterator))
                        {
                            iterator.Next();
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else if (iterator.FundamentalType == FundamentalType.Symbol)
                {
                    if (iterator.Character == ',')
                    {
                        // Quit early on commas, since it could be x[,,] or (x, y), in which case it's not clear whether there should be
                        // a space without making this logic even more complicated.  Just fail out and build a new one.
                        return(false);
                    }

                    if (lastTokenType == FundamentalType.Null ||
                        lastTokenType == FundamentalType.Text ||
                        lastTokenType == FundamentalType.Symbol)
                    {
                        lastTokenType = FundamentalType.Symbol;

                        if (iterator.MatchesAcrossTokens("::"))
                        {
                            lastSymbolWasBlock      = false;
                            dontAddSpaceAfterSymbol = true;
                            iterator.NextByCharacters(2);
                        }
                        else if (iterator.Character == '.' || iterator.Character == '%' ||
                                 iterator.Character == '"' || iterator.Character == '\'' || iterator.Character == '@' ||
                                 iterator.Character == '(')
                        {
                            lastSymbolWasBlock      = false;
                            dontAddSpaceAfterSymbol = true;
                            iterator.Next();
                        }
                        else if (TryToSkipModifierBlock(ref iterator))
                        {
                            lastSymbolWasBlock      = true;
                            dontAddSpaceAfterSymbol = false;
                            // already moved iterator
                        }
                        else
                        {
                            lastSymbolWasBlock      = false;
                            dontAddSpaceAfterSymbol = false;
                            iterator.Next();
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else if (iterator.FundamentalType == FundamentalType.Whitespace &&
                         iterator.Character == ' ' && iterator.RawTextLength == 1)
                {
                    if ((lastTokenType == FundamentalType.Symbol && !dontAddSpaceAfterSymbol && (pastFirstText || lastSymbolWasBlock)) ||
                        lastTokenType == FundamentalType.Text)
                    {
                        lastTokenType = FundamentalType.Whitespace;
                        iterator.Next();
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 16
0
        /* Function: HasSimilarSpacing
         * Returns whether the spacing of the tokens between the two iterators matches what would have been built by this
         * class if the tokens were passed through it.
         */
        public static bool HasSimilarSpacing(TokenIterator start, TokenIterator end)
        {
            // ::Package::Name* array of const*[]
            // Single spaces only between words, and between words and prior symbols except for leading symbols and package separators

            TokenIterator iterator = start;

            bool            pastFirstText           = false;
            FundamentalType lastTokenType           = FundamentalType.Null;
            bool            dontAddSpaceAfterSymbol = false;
            bool            lastSymbolWasBlock      = false;

            while (iterator < end)
            {
                if (iterator.FundamentalType == FundamentalType.Text ||
                    iterator.Character == '_')
                {
                    if (lastTokenType == FundamentalType.Null ||
                        lastTokenType == FundamentalType.Text ||
                        (lastTokenType == FundamentalType.Symbol && (dontAddSpaceAfterSymbol || (!pastFirstText && !lastSymbolWasBlock))) ||
                        lastTokenType == FundamentalType.Whitespace)
                    {
                        pastFirstText = true;
                        lastTokenType = FundamentalType.Text;

                        if (!TryToSkipModifierBlock(ref iterator))
                        {
                            iterator.Next();
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else if (iterator.FundamentalType == FundamentalType.Symbol)
                {
                    if (lastTokenType == FundamentalType.Null ||
                        lastTokenType == FundamentalType.Text ||
                        lastTokenType == FundamentalType.Symbol)
                    {
                        lastTokenType = FundamentalType.Symbol;

                        if (iterator.MatchesAcrossTokens("::"))
                        {
                            lastSymbolWasBlock      = false;
                            dontAddSpaceAfterSymbol = true;
                            iterator.NextByCharacters(2);
                        }
                        else if (iterator.Character == '.' || iterator.Character == '%')
                        {
                            lastSymbolWasBlock      = false;
                            dontAddSpaceAfterSymbol = true;
                            iterator.Next();
                        }
                        else if (TryToSkipModifierBlock(ref iterator))
                        {
                            lastSymbolWasBlock      = true;
                            dontAddSpaceAfterSymbol = false;
                            // already moved iterator
                        }
                        else
                        {
                            lastSymbolWasBlock      = false;
                            dontAddSpaceAfterSymbol = false;
                            iterator.Next();
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else if (iterator.FundamentalType == FundamentalType.Whitespace &&
                         iterator.Character == ' ' && iterator.RawTextLength == 1)
                {
                    if ((lastTokenType == FundamentalType.Symbol && !dontAddSpaceAfterSymbol && (pastFirstText || lastSymbolWasBlock)) ||
                        lastTokenType == FundamentalType.Text)
                    {
                        lastTokenType = FundamentalType.Whitespace;
                        iterator.Next();
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }