public static void Create(ISymbol symbol, SymbolKeyWriter visitor) { var containingSymbol = symbol.ContainingSymbol; while (!containingSymbol.DeclaringSyntaxReferences.Any()) { containingSymbol = containingSymbol.ContainingSymbol; } var kind = symbol.Kind; var localName = symbol.Name; Contract.ThrowIfNull( visitor.Compilation, message: $"visitor cannot be created with a null compilation and visit a {nameof(BodyLevelSymbolKey)}."); var ordinal = 0; foreach (var possibleSymbol in EnumerateSymbols(visitor.Compilation, containingSymbol, kind, localName, visitor.CancellationToken)) { if (possibleSymbol.Item1.Equals(symbol)) { ordinal = possibleSymbol.Item2; break; } } visitor.WriteString(localName); visitor.WriteSymbolKey(containingSymbol); visitor.WriteInteger(ordinal); visitor.WriteInteger((int)kind); }
public static void Create(ISymbol symbol, SymbolKeyWriter visitor) { var containingSymbol = symbol.ContainingSymbol; while (!containingSymbol.DeclaringSyntaxReferences.Any()) { containingSymbol = containingSymbol.ContainingSymbol; } var kind = symbol.Kind; var localName = symbol.Name; Contract.ThrowIfNull( visitor.Compilation, message: $"visitor cannot be created with a null compilation and visit a {nameof(BodyLevelSymbolKey)}."); var ordinal = 0; foreach (var possibleSymbol in EnumerateSymbols(visitor.Compilation, containingSymbol, kind, localName, visitor.CancellationToken)) { if (possibleSymbol.Item1.Equals(symbol)) { ordinal = possibleSymbol.Item2; break; } } visitor.WriteString(localName); visitor.WriteSymbolKey(containingSymbol); visitor.WriteInteger(ordinal); visitor.WriteInteger((int)kind); }
public static void Create(ISymbol symbol, SymbolKeyWriter visitor) { var containingSymbol = symbol.ContainingSymbol; while (!containingSymbol.DeclaringSyntaxReferences.Any()) { containingSymbol = containingSymbol.ContainingSymbol; } var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; var kind = symbol.Kind; var localName = symbol.Name; var ordinal = 0; foreach (var possibleSymbol in EnumerateSymbols(compilation, containingSymbol, kind, localName, visitor.CancellationToken)) { if (possibleSymbol.symbol.Equals(symbol)) { ordinal = possibleSymbol.ordinal; break; } } visitor.WriteString(localName); visitor.WriteSymbolKey(containingSymbol); visitor.WriteInteger(ordinal); visitor.WriteInteger((int)kind); }
// The containing symbol can be one of many things. // 1) Null when this is the global namespace for a compilation. // 2) The SymbolId for an assembly symbol if this is the global namespace for an // assembly. // 3) The SymbolId for a module symbol if this is the global namespace for a module. // 4) The SymbolId for the containing namespace symbol if this is not a global // namespace. public sealed override void Create(INamespaceSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteString(symbol.MetadataName); if (symbol.ContainingNamespace != null) { visitor.WriteInteger(0); visitor.WriteSymbolKey(symbol.ContainingNamespace); } else { // A global namespace can either belong to a module or to a compilation. Debug.Assert(symbol.IsGlobalNamespace); switch (symbol.NamespaceKind) { case NamespaceKind.Module: visitor.WriteInteger(1); visitor.WriteSymbolKey(symbol.ContainingModule); break; case NamespaceKind.Assembly: visitor.WriteInteger(2); visitor.WriteSymbolKey(symbol.ContainingAssembly); break; case NamespaceKind.Compilation: visitor.WriteInteger(3); visitor.WriteSymbolKey(null); break; default: throw new NotImplementedException(); } } }
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteString(symbol.Name); switch (symbol.ContainingSymbol) { case INamedTypeSymbol parentType: visitor.WriteInteger(0); visitor.WriteSymbolKey(parentType); break; case INamespaceSymbol parentNamespace: visitor.WriteInteger(1); visitor.WriteStringArray(GetContainingNamespaceNamesInReverse(parentNamespace)); break; default: visitor.WriteInteger(2); break; } visitor.WriteInteger(symbol.Arity); if (!symbol.Equals(symbol.ConstructedFrom)) { visitor.WriteSymbolKeyArray(symbol.TypeArguments); } else { visitor.WriteSymbolKeyArray(ImmutableArray <ITypeSymbol> .Empty); } }
public static void Create( ITypeParameterSymbol symbol, int methodIndex, SymbolKeyWriter visitor ) { Contract.ThrowIfFalse(symbol.TypeParameterKind == TypeParameterKind.Method); visitor.WriteInteger(methodIndex); visitor.WriteInteger(symbol.Ordinal); }
public static void Create(ISymbol symbol, SymbolKeyWriter visitor) { // Store the body level symbol in two forms. The first, a highly precise form that should find explicit // symbols for the case of resolving a symbol key back in the *same* solution snapshot it was created // from. The second, in a more query-oriented form that can allow the symbol to be found in some cases // even if the solution changed (which is a supported use case for SymbolKey). // // The first way just stores the location of the symbol, which we can then validate during resolution // maps back to the same symbol kind/name. // // The second determines the sequence of symbols of the same kind and same name in the file and keeps // track of our index in that sequence. That way, if trivial edits happen, or symbols with different // names/types are added/removed, we can still find what is likely to be this symbol after the edit. var kind = symbol.Kind; var localName = symbol.Name; visitor.WriteString(localName); visitor.WriteInteger((int)kind); // write out the locations for precision Contract.ThrowIfTrue(symbol.DeclaringSyntaxReferences.IsEmpty && symbol.Locations.IsEmpty); var locations = symbol.Locations.Concat( symbol.DeclaringSyntaxReferences.SelectAsArray(r => r.GetSyntax(visitor.CancellationToken).GetLocation())); visitor.WriteLocationArray(locations); // and the ordinal for resilience visitor.WriteInteger(GetOrdinal()); return; int GetOrdinal() { var syntaxTree = locations[0].SourceTree; var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; // Ensure that the tree we're looking at is actually in this compilation. It may not be in the // compilation in the case of work done with a speculative model. if (Contains(compilation.SyntaxTrees, syntaxTree)) { var semanticModel = compilation.GetSemanticModel(syntaxTree); foreach (var possibleSymbol in EnumerateSymbols(semanticModel, kind, localName, visitor.CancellationToken)) { if (possibleSymbol.symbol.Equals(symbol)) { return(possibleSymbol.ordinal); } } } return(int.MaxValue); } }
public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor) { Debug.Assert(symbol.Equals(symbol.ConstructedFrom)); visitor.WriteString(symbol.MetadataName); visitor.WriteSymbolKey(symbol.ContainingSymbol); visitor.WriteInteger(symbol.Arity); visitor.WriteBoolean(symbol.PartialDefinitionPart != null); visitor.WriteRefKindArray(symbol.Parameters); // Mark that we're writing out the signature of a method. This way if we hit a // method type parameter in our parameter-list or return type, we won't recurse // into it, but will instead only write out the type parameter ordinal. This // happens with cases like Foo<T>(T t); visitor.PushMethod(symbol); visitor.WriteParameterTypesArray(symbol.OriginalDefinition.Parameters); if (symbol.MethodKind == MethodKind.Conversion) { visitor.WriteSymbolKey(symbol.ReturnType); } else { visitor.WriteSymbolKey(null); } // Done writing the signature of this method. Remove it from the set of methods // we're writing signatures for. visitor.PopMethod(symbol); }
public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor) { Debug.Assert(symbol.Equals(symbol.ConstructedFrom)); visitor.WriteString(symbol.MetadataName); visitor.WriteSymbolKey(symbol.ContainingSymbol); visitor.WriteInteger(symbol.Arity); visitor.WriteBoolean(symbol.PartialDefinitionPart != null); visitor.WriteRefKindArray(symbol.Parameters); // Mark that we're writing out the signature of a method. This way if we hit a // method type parameter in our parameter-list or return type, we won't recurse // into it, but will instead only write out the type parameter ordinal. This // happens with cases like Foo<T>(T t); Debug.Assert(!visitor.WritingSignature); visitor.WritingSignature = true; visitor.WriteParameterTypesArray(symbol.OriginalDefinition.Parameters); if (symbol.MethodKind == MethodKind.Conversion) { visitor.WriteSymbolKey(symbol.ReturnType); } else { visitor.WriteSymbolKey(null); } // Done writing the signature. Go back to normal mode. Debug.Assert(visitor.WritingSignature); visitor.WritingSignature = false; }
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteString(symbol.MetadataName); visitor.WriteSymbolKey(symbol.ContainingSymbol); visitor.WriteInteger(symbol.Arity); visitor.WriteInteger((int)symbol.TypeKind); visitor.WriteBoolean(symbol.IsUnboundGenericType); if (!symbol.Equals(symbol.ConstructedFrom) && !symbol.IsUnboundGenericType) { visitor.WriteSymbolKeyArray(symbol.TypeArguments); } else { visitor.WriteSymbolKeyArray(default(ImmutableArray<ITypeSymbol>)); } }
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteString(symbol.MetadataName); visitor.WriteSymbolKey(symbol.ContainingSymbol); visitor.WriteInteger(symbol.Arity); visitor.WriteInteger((int)symbol.TypeKind); visitor.WriteBoolean(symbol.IsUnboundGenericType); if (!symbol.Equals(symbol.ConstructedFrom) && !symbol.IsUnboundGenericType) { visitor.WriteSymbolKeyArray(symbol.TypeArguments); } else { visitor.WriteSymbolKeyArray(default(ImmutableArray <ITypeSymbol>)); } }
public static void Create(ISymbol symbol, SymbolKeyWriter visitor) { var containingSymbol = symbol.ContainingSymbol; while (containingSymbol.DeclaringSyntaxReferences.IsDefaultOrEmpty) { containingSymbol = containingSymbol.ContainingSymbol; } var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; var kind = symbol.Kind; var localName = symbol.Name; // Use two mechanisms to try to find the symbol across compilations. First, we use a whitespace // insensitive system where we keep track of the list of all locals in the container and we just store // our index in it. // // The above works for cases where the symbol has a real declaration and can be found by walking the // declarations of the container. However, not all symbols can be found that way. For example, error // locals in VB can't be found using GetDeclaredSymbol. For those, we store the actual local span and // use GetSymbolInfo to find it. var ordinal = GetOrdinal(); visitor.WriteString(localName); visitor.WriteSymbolKey(containingSymbol); visitor.WriteInteger(ordinal); visitor.WriteLocation(symbol.Locations[0]); visitor.WriteInteger((int)kind); return; int GetOrdinal() { foreach (var possibleSymbol in EnumerateSymbols(compilation, containingSymbol, kind, localName, visitor.CancellationToken)) { if (possibleSymbol.symbol.Equals(symbol)) { return(possibleSymbol.ordinal); } } return(int.MaxValue); } }
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteString(symbol.Name); visitor.WriteSymbolKey(symbol.ContainingSymbol as INamespaceOrTypeSymbol); visitor.WriteInteger(symbol.Arity); if (!symbol.Equals(symbol.ConstructedFrom)) { visitor.WriteSymbolKeyArray(symbol.TypeArguments); } else { visitor.WriteSymbolKeyArray(default(ImmutableArray<ITypeSymbol>)); } }
public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteString(symbol.Name); visitor.WriteSymbolKey(symbol.ContainingSymbol as INamespaceOrTypeSymbol); visitor.WriteInteger(symbol.Arity); if (!symbol.Equals(symbol.ConstructedFrom)) { visitor.WriteSymbolKeyArray(symbol.TypeArguments); } else { visitor.WriteSymbolKeyArray(default(ImmutableArray <ITypeSymbol>)); } }
public static void Create(IFunctionPointerTypeSymbol symbol, SymbolKeyWriter visitor) { var callingConvention = symbol.Signature.CallingConvention; visitor.WriteInteger((int)callingConvention); if (callingConvention == SignatureCallingConvention.Unmanaged) { visitor.WriteSymbolKeyArray(symbol.Signature.UnmanagedCallingConventionTypes); } visitor.WriteRefKind(symbol.Signature.RefKind); visitor.WriteSymbolKey(symbol.Signature.ReturnType); visitor.WriteRefKindArray(symbol.Signature.Parameters); visitor.WriteParameterTypesArray(symbol.Signature.Parameters); }
public sealed override void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteSymbolKey(symbol.ContainingSymbol); visitor.WriteString(symbol.Name); visitor.WriteInteger(symbol.Arity); visitor.WriteString(symbol.IsFileLocal ? symbol.DeclaringSyntaxReferences[0].SyntaxTree.FilePath : null); visitor.WriteBoolean(symbol.IsUnboundGenericType); if (!symbol.Equals(symbol.ConstructedFrom) && !symbol.IsUnboundGenericType) { visitor.WriteSymbolKeyArray(symbol.TypeArguments); } else { visitor.WriteSymbolKeyArray(ImmutableArray <ITypeSymbol> .Empty); } }
public static void Create(IArrayTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteSymbolKey(symbol.ElementType); visitor.WriteInteger(symbol.Rank); }
public static void Create(ITypeParameterSymbol symbol, SymbolKeyWriter visitor) { Debug.Assert(visitor.WritingSignature); Debug.Assert(symbol.TypeParameterKind == TypeParameterKind.Method); visitor.WriteInteger(symbol.Ordinal); }
public static void Create(ITypeParameterSymbol symbol, SymbolKeyWriter visitor) { Debug.Assert(visitor.WritingSignature); Debug.Assert(symbol.TypeParameterKind == TypeParameterKind.Method); visitor.WriteInteger(symbol.Ordinal); }
public static void Create(IArrayTypeSymbol symbol, SymbolKeyWriter visitor) { visitor.WriteSymbolKey(symbol.ElementType); visitor.WriteInteger(symbol.Rank); }