private Token ConvertOperatorOverloadSymbol()
        {
            Token token = null;

            Symbol symbol = this.symbols.Peek(1);
            if (symbol != null)
            {
                if (symbol.SymbolType == SymbolType.GreaterThan)
                {
                    Symbol next = this.symbols.Peek(2);
                    if (next != null && next.SymbolType == SymbolType.GreaterThan)
                    {
                        // This could be a right-shift-equals.
                        next = this.symbols.Peek(3);
                        if (next != null && next.SymbolType == SymbolType.Equals)
                        {
                            // This is a right-shift-equals.
                            this.symbols.Combine(1, 3, ">>=", SymbolType.RightShiftEquals);
                        }
                        else
                        {
                            // This is a right-shift.
                            this.symbols.Combine(1, 2, ">>", SymbolType.RightShift);
                        }
                    }

                    symbol = this.symbols.Peek(1);
                    token = new LiteralToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated);
                    this.symbols.Advance();
                }
                else
                {
                    token = new LiteralToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated);
                    this.symbols.Advance();
                }
            }

            return token;
        }
Example #2
0
        /// <summary>
        /// Reads a generic token from the document.
        /// </summary>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="startIndex">The first index of the generic.</param>
        /// <param name="lastIndex">Returns the last index of the generic.</param>
        /// <returns>Returns the generic token, or null if the symbol manager is not sitting on a generic.</returns>
        /// <remarks>This should only be called by GetGenericToken.</remarks>
        private GenericTypeToken GetGenericTokenAux(bool unsafeCode, int startIndex, out int lastIndex)
        {
            Param.Ignore(unsafeCode);
            Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex");

            lastIndex = -1;

            // The reference to the generic token.
            var genericTokenProxy = new CodeUnitProxy(this.document);

            // Get the first symbol. This should be an unknown word type.
            Symbol firstSymbol = this.symbols.Peek(startIndex);
            CsLanguageService.Debug.Assert(firstSymbol != null && firstSymbol.SymbolType == SymbolType.Other, "Expected a text symbol");

            // This will hold the generic type if we create one.
            GenericTypeToken generic = null;

            // Create a token for the name.
            var name = new LiteralToken(this.document, firstSymbol.Text, firstSymbol.Location, this.symbols.Generated);

            // Get the argument list. This will return null if this is not a generic.
            if (this.GetGenericArgumentList(genericTokenProxy, unsafeCode, name, startIndex + 1, out lastIndex))
            {
                generic = new GenericTypeToken(genericTokenProxy);
            }

            return generic;
        }
        /// <summary>
        /// Gets the next query clause variable.
        /// </summary>
        /// <param name="parentProxy">Represents the parent of the variable.</param>
        /// <param name="unsafeCode">Indicates whether the code is within an unsafe block.</param>
        /// <param name="allowTypelessVariable">Indicates whether to allow a variable with no type defined.</param>
        /// <param name="onlyTypelessVariable">Indicates whether to only get a typeless variable.</param>
        private void GetQueryVariable(CodeUnitProxy parentProxy, bool unsafeCode, bool allowTypelessVariable, bool onlyTypelessVariable)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.Ignore(unsafeCode);
            Param.Ignore(allowTypelessVariable);
            Param.Ignore(onlyTypelessVariable);

            this.AdvanceToNextCodeSymbol(parentProxy);

            // Get the type token representing either the type or the identifier.
            TypeToken type = this.GetTypeToken(null, unsafeCode, true, false);
            if (type == null)
            {
                throw this.CreateSyntaxException();
            }

            if (onlyTypelessVariable)
            {
                // The token is not a type, just an identifier. Detach the child token and ignore the TypeToken.
                CsLanguageService.Debug.Assert(type.Children.Count == 1, "This operation only makes sense when the type token contains a single child.");
                
                Token token = type.FindFirstChildToken();
                CsLanguageService.Debug.Assert(token != null, "The child token of the type token should be a token.");

                token.Detach();
                parentProxy.Children.Add(token);
            }
            else
            {
                // Look ahead to the next symbol to see what it is.
                Symbol symbol = this.PeekToNextCodeSymbol();
                if (symbol == null || symbol.SymbolType != SymbolType.Other)
                {
                    // This variable has no type, only an identifier.
                    if (!allowTypelessVariable)
                    {
                        throw this.CreateSyntaxException();
                    }

                    // The token is not a type, just an identifier.
                    CsLanguageService.Debug.Assert(type.Children.Count == 1, "This operation only makes sense when the type token contains a single child.");

                    Token token = type.FindFirstChildToken();
                    CsLanguageService.Debug.Assert(token != null, "The child token of the type token should be a token.");

                    token.Detach();
                    parentProxy.Children.Add(token);
                }
                else
                {
                    // There is a type so add the type token.
                    parentProxy.Children.Add(type);

                    // Move past any whitespace between the type and identifier.
                    this.AdvanceToNextCodeSymbol(parentProxy);

                    // Create and add the identifier token.
                    var identifier = new LiteralToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated);
                    parentProxy.Children.Add(identifier);

                    this.symbols.Advance();
                }
            }
        }
        /// <summary>
        /// Reads an expression starting with an unknown word.
        /// </summary>
        /// <param name="parentProxy">Proxy object for the parent item.</param>
        /// <returns>Returns the expression.</returns>
        private LiteralExpression GetConditionalPreprocessorConstantExpression(CodeUnitProxy parentProxy)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");

            this.AdvanceToNextConditionalDirectiveCodeSymbol(parentProxy);
            var expressionProxy = new CodeUnitProxy(this.document);

            // Get the first symbol.
            Symbol symbol = this.symbols.Peek(1);
            CsLanguageService.Debug.Assert(symbol != null && symbol.SymbolType == SymbolType.Other, "Expected a text symbol");

            // Convert the symbol to a token.
            this.symbols.Advance();

            var literalToken = new LiteralToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated);
            expressionProxy.Children.Add(literalToken);

            // Create a literal expression from this token.
            var literalExpression = new LiteralExpression(expressionProxy, literalToken);
            parentProxy.Children.Add(literalExpression);

            return literalExpression;
        }