private void CheckGenericSpacing(DocumentRoot root, GenericType generic) { if (generic.ChildTokens.Count > 0) { for (Node<CsToken> node = generic.ChildTokens.First; node != null; node = node.Next) { OperatorSymbol symbol; if (base.Cancel) { return; } if (node.Value.CsTokenClass == CsTokenClass.GenericType) { this.CheckGenericSpacing(root, node.Value as GenericType); } if (!node.Value.Generated) { switch (node.Value.CsTokenType) { case CsTokenType.OpenParenthesis: this.CheckOpenParen(root, generic.ChildTokens, node); goto Label_0169; case CsTokenType.CloseParenthesis: this.CheckCloseParen(root, generic.ChildTokens, node); goto Label_0169; case CsTokenType.OpenCurlyBracket: case CsTokenType.CloseCurlyBracket: case CsTokenType.BaseColon: case CsTokenType.WhereColon: case CsTokenType.AttributeColon: case CsTokenType.LabelColon: case CsTokenType.Other: case CsTokenType.EndOfLine: goto Label_0169; case CsTokenType.OpenSquareBracket: this.CheckOpenSquareBracket(root, node); goto Label_0169; case CsTokenType.CloseSquareBracket: this.CheckCloseSquareBracket(root, generic.ChildTokens, node); goto Label_0169; case CsTokenType.OpenGenericBracket: this.CheckGenericTokenOpenBracket(root, node); goto Label_0169; case CsTokenType.CloseGenericBracket: this.CheckGenericTokenCloseBracket(root, node); goto Label_0169; case CsTokenType.OperatorSymbol: goto Label_013B; case CsTokenType.Comma: this.CheckSemicolonAndComma(root, node); goto Label_0169; case CsTokenType.WhiteSpace: this.CheckWhitespace(root, node); goto Label_0169; case CsTokenType.PreprocessorDirective: goto Label_012C; } } goto Label_0169; Label_012C: this.CheckPreprocessorSpacing(root, node.Value); goto Label_0169; Label_013B: symbol = node.Value as OperatorSymbol; if ((symbol.SymbolType == OperatorType.MemberAccess) || (symbol.SymbolType == OperatorType.QualifiedAlias)) { this.CheckMemberAccessSymbol(root, generic.ChildTokens, node); } Label_0169:; } } }
/// <summary> /// Reads a generic token from the document. /// </summary> /// <param name="genericTokenReference">A reference to the generic token.</param> /// <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 GenericType GetGenericTokenAux(Reference<ICodePart> genericTokenReference, bool unsafeCode, int startIndex, out int lastIndex) { Param.AssertNotNull(genericTokenReference, "genericTokenReference"); Param.Ignore(unsafeCode); Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex"); lastIndex = -1; // Get the first symbol. This should be an unknown word type. Symbol firstSymbol = this.symbols.Peek(startIndex); Debug.Assert(firstSymbol != null && firstSymbol.SymbolType == SymbolType.Other, "Expected a text symbol"); // This will hold the generic type if we create one. GenericType generic = null; // Create a token for the name. CsToken name = new CsToken(firstSymbol.Text, CsTokenType.Other, firstSymbol.Location, genericTokenReference, this.symbols.Generated); // Get the argument list. This will return null if this is not a generic. MasterList<CsToken> genericArgumentTokens = this.GetGenericArgumentList( genericTokenReference, unsafeCode, name, startIndex + 1, out lastIndex); if (genericArgumentTokens != null) { generic = new GenericType( genericArgumentTokens, CsToken.JoinLocations(firstSymbol.Location, genericArgumentTokens.Last), genericTokenReference, this.symbols.Generated); var genericTypeReference = new Reference<ICodePart>(generic); foreach (CsToken token in genericArgumentTokens) { token.ParentRef = genericTypeReference; } } return generic; }
/// <summary> /// Gets the base name and generic symbols for a type token. /// </summary> /// <param name="typeTokenReference">A reference to the type token.</param> /// <param name="typeTokens">The list of tokens in the type.</param> /// <param name="startIndex">The start index within the symbol list.</param> /// <param name="generic">Returns a value indicating whether the type is generic.</param> /// <param name="unsafeCode">Indicates whether the type is within a block of unsafe code.</param> private void GetTypeTokenBaseName( Reference<ICodePart> typeTokenReference, ref MasterList<CsToken> typeTokens, ref int startIndex, out GenericType generic, bool unsafeCode) { Param.AssertNotNull(typeTokenReference, "typeTokenReference"); Param.AssertNotNull(typeTokens, "typeTokens"); Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex"); Param.Ignore(unsafeCode); generic = null; Symbol symbol = this.symbols.Peek(startIndex); // First get the full name of the type. int index = -1; while (true) { // Add any whitespace. while (symbol != null && (symbol.SymbolType == SymbolType.WhiteSpace || symbol.SymbolType == SymbolType.EndOfLine || symbol.SymbolType == SymbolType.SingleLineComment || symbol.SymbolType == SymbolType.MultiLineComment || symbol.SymbolType == SymbolType.PreprocessorDirective)) { typeTokens.Add(this.ConvertSymbol(symbol, TokenTypeFromSymbolType(symbol.SymbolType), typeTokenReference)); symbol = this.symbols.Peek(++startIndex); } // Add the next word. The type of the next word must either be an unknown // word type, which will be the name of the next item in the type, or else // it must be the 'this' keyword. This is used when implementing an explicit // interface member which is an indexer. if (symbol.SymbolType == SymbolType.Other || symbol.SymbolType == SymbolType.This) { typeTokens.Add(new CsToken(symbol.Text, CsTokenType.Other, symbol.Location, typeTokenReference, this.symbols.Generated)); } else { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } ++startIndex; // Look at the type of the next non-whitespace character. index = this.GetNextCodeSymbolIndex(startIndex); if (index == -1) { break; } // If the next character is an opening generic bracket, get the generic. symbol = this.symbols.Peek(index); if (symbol.SymbolType == SymbolType.LessThan) { int end; MasterList<CsToken> genericTypeTokens = this.GetGenericArgumentList( typeTokenReference, unsafeCode, null, startIndex, out end); if (genericTypeTokens != null) { // Add the tokens from this generic into our token list. typeTokens.AddRange(genericTypeTokens); // Create a new GenericTypeToken which represents this generic type. CodeLocation genericTypeLocation = CsToken.JoinLocations(typeTokens.First, typeTokens.Last); generic = new GenericType(typeTokens, genericTypeLocation, typeTokenReference, this.symbols.Generated); Reference<ICodePart> genericReference = new Reference<ICodePart>(generic); foreach (CsToken token in typeTokens) { token.ParentRef = genericReference; } // Reset the token list and add this generic token as the first item in the list. typeTokens = new MasterList<CsToken>(); typeTokens.Add(generic); // Advance the symbol index. startIndex = end + 1; // Look at the type of the next non-whitespace character. index = this.GetNextCodeSymbolIndex(startIndex); if (index == -1) { break; } } } // If the next character is not a dot or a qualified alias, break now. symbol = this.symbols.Peek(index); if (symbol.SymbolType != SymbolType.Dot && symbol.SymbolType != SymbolType.QualifiedAlias) { break; } // Add any whitspace. symbol = this.symbols.Peek(startIndex); while (symbol != null && (symbol.SymbolType == SymbolType.WhiteSpace || symbol.SymbolType == SymbolType.EndOfLine || symbol.SymbolType == SymbolType.SingleLineComment || symbol.SymbolType == SymbolType.MultiLineComment || symbol.SymbolType == SymbolType.PreprocessorDirective)) { typeTokens.Add(this.ConvertSymbol(symbol, TokenTypeFromSymbolType(symbol.SymbolType), typeTokenReference)); symbol = this.symbols.Peek(++startIndex); } // Add the dot or qualified alias. if (symbol.SymbolType == SymbolType.Dot) { typeTokens.Add(new OperatorSymbol( symbol.Text, OperatorCategory.Reference, OperatorType.MemberAccess, symbol.Location, typeTokenReference, this.symbols.Generated)); } else { Debug.Assert(symbol.SymbolType == SymbolType.QualifiedAlias, "Expected a qualified alias keyword"); typeTokens.Add(new OperatorSymbol( symbol.Text, OperatorCategory.Reference, OperatorType.QualifiedAlias, symbol.Location, typeTokenReference, this.symbols.Generated)); } // Get the next symbol. symbol = this.symbols.Peek(++startIndex); } }
private void GetTypeTokenBaseName(ref MasterList<CsToken> typeTokens, ref int startIndex, out GenericType generic, bool unsafeCode) { generic = null; Symbol symbol = this.symbols.Peek(startIndex); int count = -1; Label_0045: while ((symbol != null) && ((((symbol.SymbolType == SymbolType.WhiteSpace) || (symbol.SymbolType == SymbolType.EndOfLine)) || ((symbol.SymbolType == SymbolType.SingleLineComment) || (symbol.SymbolType == SymbolType.MultiLineComment))) || (symbol.SymbolType == SymbolType.PreprocessorDirective))) { int num3; typeTokens.Add(this.ConvertSymbol(symbol, TokenTypeFromSymbolType(symbol.SymbolType))); startIndex = num3 = startIndex + 1; symbol = this.symbols.Peek(num3); } if ((symbol.SymbolType != SymbolType.Other) && (symbol.SymbolType != SymbolType.This)) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } typeTokens.Add(new CsToken(symbol.Text, CsTokenType.Other, symbol.Location, this.symbols.Generated)); startIndex++; count = this.GetNextCodeSymbolIndex(startIndex); if (count != -1) { if (this.symbols.Peek(count).SymbolType == SymbolType.LessThan) { int num2; MasterList<CsToken> items = this.GetGenericArgumentList(unsafeCode, null, startIndex, out num2); if (items != null) { typeTokens.AddRange(items); CodeLocation location = CodeLocation.Join<CsToken>(typeTokens.First, typeTokens.Last); generic = new GenericType(typeTokens, location, this.symbols.Generated); typeTokens = new MasterList<CsToken>(); typeTokens.Add(generic); startIndex = num2 + 1; count = this.GetNextCodeSymbolIndex(startIndex); if (count == -1) { return; } } } symbol = this.symbols.Peek(count); if ((symbol.SymbolType == SymbolType.Dot) || (symbol.SymbolType == SymbolType.QualifiedAlias)) { int num5; symbol = this.symbols.Peek(startIndex); while ((symbol != null) && ((((symbol.SymbolType == SymbolType.WhiteSpace) || (symbol.SymbolType == SymbolType.EndOfLine)) || ((symbol.SymbolType == SymbolType.SingleLineComment) || (symbol.SymbolType == SymbolType.MultiLineComment))) || (symbol.SymbolType == SymbolType.PreprocessorDirective))) { int num4; typeTokens.Add(this.ConvertSymbol(symbol, TokenTypeFromSymbolType(symbol.SymbolType))); startIndex = num4 = startIndex + 1; symbol = this.symbols.Peek(num4); } if (symbol.SymbolType == SymbolType.Dot) { typeTokens.Add(new OperatorSymbol(symbol.Text, OperatorCategory.Reference, OperatorType.MemberAccess, symbol.Location, this.symbols.Generated)); } else { typeTokens.Add(new OperatorSymbol(symbol.Text, OperatorCategory.Reference, OperatorType.QualifiedAlias, symbol.Location, this.symbols.Generated)); } startIndex = num5 = startIndex + 1; symbol = this.symbols.Peek(num5); goto Label_0045; } } }
private GenericType GetGenericTokenAux(bool unsafeCode, int startIndex, out int lastIndex) { lastIndex = -1; Symbol symbol = this.symbols.Peek(startIndex); GenericType type = null; CsToken name = new CsToken(symbol.Text, CsTokenType.Other, symbol.Location, this.symbols.Generated); MasterList<CsToken> childTokens = this.GetGenericArgumentList(unsafeCode, name, startIndex + 1, out lastIndex); if (childTokens != null) { type = new GenericType(childTokens, CodeLocation.Join<CsToken>(symbol.Location, childTokens.Last), this.symbols.Generated); } return type; }
private void CheckGenericSpacing(GenericType generic) { Param.AssertNotNull(generic, "generic"); // Make sure it contains at least one token. if (generic.ChildTokens.Count > 0) { for (Node<CsToken> tokenNode = generic.ChildTokens.First; tokenNode != null; tokenNode = tokenNode.Next) { if (this.Cancel) { break; } // Check whether this token is a generic and if so parse the tokens within // the generic statement. if (tokenNode.Value.CsTokenClass == CsTokenClass.GenericType) { this.CheckGenericSpacing(tokenNode.Value as GenericType); } if (!tokenNode.Value.Generated) { switch (tokenNode.Value.CsTokenType) { case CsTokenType.Comma: this.CheckSemicolonAndComma(tokenNode); break; case CsTokenType.OpenParenthesis: this.CheckOpenParen(generic.ChildTokens, tokenNode); break; case CsTokenType.CloseParenthesis: this.CheckCloseParen(generic.ChildTokens, tokenNode); break; case CsTokenType.OpenSquareBracket: this.CheckOpenSquareBracket(tokenNode); break; case CsTokenType.CloseSquareBracket: this.CheckCloseSquareBracket(generic.ChildTokens, tokenNode); break; case CsTokenType.WhiteSpace: this.CheckWhitespace(tokenNode); break; case CsTokenType.OpenGenericBracket: this.CheckGenericTokenOpenBracket(tokenNode); break; case CsTokenType.CloseGenericBracket: this.CheckGenericTokenCloseBracket(tokenNode); break; case CsTokenType.PreprocessorDirective: this.CheckPreprocessorSpacing(tokenNode.Value); break; case CsTokenType.OperatorSymbol: OperatorSymbol symbol = tokenNode.Value as OperatorSymbol; if (symbol.SymbolType == OperatorType.MemberAccess || symbol.SymbolType == OperatorType.QualifiedAlias) { this.CheckMemberAccessSymbol(generic.ChildTokens, tokenNode); } else { goto default; } break; case CsTokenType.Other: case CsTokenType.EndOfLine: case CsTokenType.In: case CsTokenType.Out: // Ignore these. break; default: // There shouldn't be anything else within a generic type token. Debug.Fail("Unexpected token type."); break; } } } } }