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; }
/// <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; }