private TSLCompletionState GetCompletionState()

in src/Trinity.VSExtension/TrinityVSExtension/EditorExtension/AutoCompletion/CompletionSource.cs [194:299]


        private TSLCompletionState GetCompletionState(ICompletionSession session)
        {

            /* We decide to parse the current line in this routine,
             * since it will provide real-time token information
             * without which we would have to depend on the lagging
             * and unnecessary global parse results.
             */
            var caretSnapshotPoint = session.TextView.Caret.Position.BufferPosition;
            var tokenSpans = parser.ParseTokens(textBuffer.CurrentSnapshot.GetLineFromPosition(caretSnapshotPoint.Position).Extent);
            var syntaxSpanTypes = parser.GetSyntaxSpanTypes(caretSnapshotPoint);

            bool afterTypes = false;
            bool beforeRAngle = false;
            bool afterLAngle = false;
            bool afterProtocol = false;
            bool afterColon = false;
            bool afterRAngle = false;
            bool afterProtocolTypeSpecifier = false;
            bool afterProtocolDataSpecifier = false;

            bool afterTopLevelFinalBlockTypeToken = false;

            /* Compare the spans in the line with current caret */
            foreach (var tokenSpan in tokenSpans)
            {
                if (tokenSpan.span.End <= caretSnapshotPoint)
                /* caret after token */
                {
                    if (tokenSpan.token == WrappedTokenType.T_COLON)
                        afterColon = true;
                    if (TSLSyntaxDefinition.isTypeToken(tokenSpan.token))
                        afterTypes = true;
                    if (tokenSpan.token == WrappedTokenType.T_TYPE)
                        afterProtocolTypeSpecifier = true;
                    if (tokenSpan.token == WrappedTokenType.T_REQUEST || tokenSpan.token == WrappedTokenType.T_RESPONSE)
                        afterProtocolDataSpecifier = true;
                    if (tokenSpan.token == WrappedTokenType.T_LANGLE)
                        afterLAngle = true;
                    if (tokenSpan.token == WrappedTokenType.T_PROTOCOL)
                        afterProtocol = true;
                    if (tokenSpan.token == WrappedTokenType.T_RANGLE)
                        afterRAngle = true;
                    if (TSLSyntaxDefinition.isTopLevelFinalBlockTypeToken(tokenSpan.token))
                        afterTopLevelFinalBlockTypeToken = true;
                }
                else if (tokenSpan.span.Start >= caretSnapshotPoint)
                {
                    /* caret before token */
                    switch (tokenSpan.token)
                    {
                        case WrappedTokenType.T_RANGLE:
                            beforeRAngle = true;
                            break;
                    }
                }
            }

            /* Note that GetSyntaxSpanTypes might return multiple results,
             * so we define matching priorities here.
             * For example, Comments take the highest priority to capture State so that any completion will be
             * disabled.
             */

            if (syntaxSpanTypes.Contains(TSLSyntaxSpanType.AttributeSet))
                return TSLCompletionState.InAttributeSet;
            else if (syntaxSpanTypes.Contains(TSLSyntaxSpanType.Comments))
                return TSLCompletionState.InComment;

            if (syntaxSpanTypes.Count != 0)
                switch (syntaxSpanTypes.First())
                {
                    case TSLSyntaxSpanType.EnumBlock:
                        return TSLCompletionState.InEnum;
                    case TSLSyntaxSpanType.IncludeBlock:
                        return TSLCompletionState.InInclude;
                    case TSLSyntaxSpanType.ProtocolBlock:
                        if (afterProtocolTypeSpecifier && afterColon)
                            return TSLCompletionState.InProtocol_SpecifyProtocolType;
                        else if (afterProtocolDataSpecifier && afterColon)
                            return TSLCompletionState.InProtocol_SpecifyProtocolData;
                        else
                            return TSLCompletionState.InProtocol_Default;
                    case TSLSyntaxSpanType.ProtocolGroupBlock:
                        if (afterProtocol)
                            return TSLCompletionState.InProtocolGroup_SpecifyProtocol;
                        else
                            return TSLCompletionState.InProtocolGroup_Default;
                    case TSLSyntaxSpanType.StructBlock:
                        if (beforeRAngle && afterLAngle)
                            return TSLCompletionState.InStruct_SpecifyFieldType;
                        else /* The outmost Type token? */ if (!afterTypes)
                            return TSLCompletionState.InStruct_SpecifyFieldTypeOrModifiers;
                        else /* No RAngle, we're in the middle */if (afterLAngle && !afterRAngle)
                            return TSLCompletionState.InStruct_SpecifyFieldType;
                        else
                            return TSLCompletionState.InStruct_SpecifyFieldName;
                    case TSLSyntaxSpanType.TrinitySettingBlock:
                        return TSLCompletionState.InTrinitySetting;
                }

            /* Nothing matched. we say that it's in the top-level. */
            if (afterTopLevelFinalBlockTypeToken)
                return TSLCompletionState.TSL_SpecifyIdentifier;
            return TSLCompletionState.TSL_Default;
        }