/// <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); } }
/// <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); Reference<ICodePart> genericTypeReference = new Reference<ICodePart>(generic); foreach (CsToken token in genericArgumentTokens) { token.ParentRef = genericTypeReference; } } return generic; }
public TypeResolver(GenericType typeTokenReference, INamesResolver namesInfoHolder) : this(typeTokenReference.Text, namesInfoHolder) { }