public override object VisitMethod(IMethodSymbol methodSymbol)
            {
                if (!methodSymbol.Equals(methodSymbol.ConstructedFrom))
                {
                    WriteType(SymbolKeyType.ConstructedMethod);
                    ConstructedMethodSymbolKey.Create(methodSymbol, this);
                }
                else
                {
                    switch (methodSymbol.MethodKind)
                    {
                    case MethodKind.ReducedExtension:
                        WriteType(SymbolKeyType.ReducedExtensionMethod);
                        ReducedExtensionMethodSymbolKey.Create(methodSymbol, this);
                        break;

                    case MethodKind.AnonymousFunction:
                        WriteType(SymbolKeyType.AnonymousFunctionOrDelegate);
                        AnonymousFunctionOrDelegateSymbolKey.Create(methodSymbol, this);
                        break;

                    case MethodKind.LocalFunction:
                        WriteType(SymbolKeyType.BodyLevel);
                        BodyLevelSymbolKey.Create(methodSymbol, this);
                        break;

                    default:
                        WriteType(SymbolKeyType.Method);
                        MethodSymbolKey.Create(methodSymbol, this);
                        break;
                    }
                }

                return(null);
            }
Beispiel #2
0
            private SymbolKeyResolution ReadWorker(SymbolKeyType type)
            {
                switch (type)
                {
                case SymbolKeyType.Alias: return(AliasSymbolKey.Resolve(this));

                case SymbolKeyType.BodyLevel: return(BodyLevelSymbolKey.Resolve(this));

                case SymbolKeyType.ConstructedMethod: return(ConstructedMethodSymbolKey.Resolve(this));

                case SymbolKeyType.NamedType: return(NamedTypeSymbolKey.Resolve(this));

                case SymbolKeyType.ErrorType: return(ErrorTypeSymbolKey.Resolve(this));

                case SymbolKeyType.Field: return(FieldSymbolKey.Resolve(this));

                case SymbolKeyType.DynamicType: return(DynamicTypeSymbolKey.Resolve(this));

                case SymbolKeyType.Method: return(MethodSymbolKey.Resolve(this));

                case SymbolKeyType.Namespace: return(NamespaceSymbolKey.Resolve(this));

                case SymbolKeyType.PointerType: return(PointerTypeSymbolKey.Resolve(this));

                case SymbolKeyType.Parameter: return(ParameterSymbolKey.Resolve(this));

                case SymbolKeyType.Property: return(PropertySymbolKey.Resolve(this));

                case SymbolKeyType.ArrayType: return(ArrayTypeSymbolKey.Resolve(this));

                case SymbolKeyType.Assembly: return(AssemblySymbolKey.Resolve(this));

                case SymbolKeyType.TupleType: return(TupleTypeSymbolKey.Resolve(this));

                case SymbolKeyType.Module: return(ModuleSymbolKey.Resolve(this));

                case SymbolKeyType.Event: return(EventSymbolKey.Resolve(this));

                case SymbolKeyType.ReducedExtensionMethod: return(ReducedExtensionMethodSymbolKey.Resolve(this));

                case SymbolKeyType.TypeParameter: return(TypeParameterSymbolKey.Resolve(this));

                case SymbolKeyType.AnonymousType: return(AnonymousTypeSymbolKey.Resolve(this));

                case SymbolKeyType.AnonymousFunctionOrDelegate: return(AnonymousFunctionOrDelegateSymbolKey.Resolve(this));

                case SymbolKeyType.TypeParameterOrdinal: return(TypeParameterOrdinalSymbolKey.Resolve(this));
                }

                throw new NotImplementedException();
            }
Beispiel #3
0
            protected override int ReadWorker(SymbolKeyType type)
            {
                switch (type)
                {
                case SymbolKeyType.Alias: return(AliasSymbolKey.GetHashCode(this));

                case SymbolKeyType.BodyLevel: return(BodyLevelSymbolKey.GetHashCode(this));

                case SymbolKeyType.ConstructedMethod: return(ConstructedMethodSymbolKey.GetHashCode(this));

                case SymbolKeyType.NamedType: return(NamedTypeSymbolKey.GetHashCode(this));

                case SymbolKeyType.ErrorType: return(ErrorTypeSymbolKey.GetHashCode(this));

                case SymbolKeyType.Field: return(FieldSymbolKey.GetHashCode(this));

                case SymbolKeyType.DynamicType: return(DynamicTypeSymbolKey.GetHashCode(this));

                case SymbolKeyType.Method: return(MethodSymbolKey.GetHashCode(this));

                case SymbolKeyType.Namespace: return(NamespaceSymbolKey.GetHashCode(this));

                case SymbolKeyType.PointerType: return(PointerTypeSymbolKey.GetHashCode(this));

                case SymbolKeyType.Parameter: return(ParameterSymbolKey.GetHashCode(this));

                case SymbolKeyType.Property: return(PropertySymbolKey.GetHashCode(this));

                case SymbolKeyType.ArrayType: return(ArrayTypeSymbolKey.GetHashCode(this));

                case SymbolKeyType.Assembly: return(AssemblySymbolKey.GetHashCode(this));

                case SymbolKeyType.TupleType: return(TupleTypeSymbolKey.GetHashCode(this));

                case SymbolKeyType.Module: return(ModuleSymbolKey.GetHashCode(this));

                case SymbolKeyType.Event: return(EventSymbolKey.GetHashCode(this));

                case SymbolKeyType.ReducedExtensionMethod: return(ReducedExtensionMethodSymbolKey.GetHashCode(this));

                case SymbolKeyType.TypeParameter: return(TypeParameterSymbolKey.GetHashCode(this));

                case SymbolKeyType.TypeParameterOrdinal: return(TypeParameterOrdinalSymbolKey.GetHashCode(this));
                }

                throw new NotImplementedException();
            }
Beispiel #4
0
        public static bool CanCreate(ISymbol symbol, CancellationToken cancellationToken)
        {
            if (BodyLevelSymbolKey.IsBodyLevelSymbol(symbol))
            {
                var locations = BodyLevelSymbolKey.GetBodyLevelSourceLocations(symbol, cancellationToken);
                if (locations.Length == 0)
                {
                    return(false);
                }

                // 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.
                var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation;
                return(compilation.SyntaxTrees.Contains(locations.First().SourceTree));
            }

            return(true);
        }
 public override object VisitRangeVariable(IRangeVariableSymbol rangeVariableSymbol)
 {
     WriteType(SymbolKeyType.BodyLevel);
     BodyLevelSymbolKey.Create(rangeVariableSymbol, this);
     return(null);
 }
 public override object VisitLocal(ILocalSymbol localSymbol)
 {
     WriteType(SymbolKeyType.BodyLevel);
     BodyLevelSymbolKey.Create(localSymbol, this);
     return(null);
 }
            internal void WriteSymbolKey(ISymbol?symbol)
            {
                WriteSpace();

                if (symbol == null)
                {
                    WriteType(SymbolKeyType.Null);
                    return;
                }

                int id;
                var shouldWriteOrdinal = ShouldWriteTypeParameterOrdinal(symbol, out _);

                if (!shouldWriteOrdinal)
                {
                    if (_symbolToId.TryGetValue(symbol, out id))
                    {
                        StartKey();
                        WriteType(SymbolKeyType.Reference);
                        WriteInteger(id);
                        EndKey();
                        return;
                    }
                }

                id = _nextId;
                _nextId++;

                StartKey();
                if (IsBodyLevelSymbol(symbol))
                {
                    WriteType(SymbolKeyType.BodyLevel);
                    BodyLevelSymbolKey.Create(symbol, this);
                }
                else
                {
                    symbol.Accept(this);
                }

                if (!shouldWriteOrdinal)
                {
                    // Note: it is possible in some situations to hit the same symbol
                    // multiple times.  For example, if you have:
                    //
                    //      Goo<Z>(List<Z> list)
                    //
                    // If we start with the symbol for "list" then we'll see the following
                    // chain of symbols hit:
                    //
                    //      List<Z>
                    //          Z
                    //              Goo<Z>(List<Z>)
                    //                  List<Z>
                    //
                    // The recursion is prevented because when we hit 'Goo' we mark that
                    // we're writing out a signature.  And, in signature mode we only write
                    // out the ordinal for 'Z' without recursing.  However, even though
                    // we prevent the recursion, we still hit List<Z> twice.  After writing
                    // the innermost one out, we'll give it a reference ID.  When we
                    // then hit the outermost one, we want to just reuse that one.
                    if (_symbolToId.TryGetValue(symbol, out var existingId))
                    {
                        // While we recursed, we already hit this symbol.  Use its ID as our
                        // ID.
                        id = existingId;
                    }
                    else
                    {
                        // Haven't hit this symbol before, write out its fresh ID.
                        _symbolToId.Add(symbol, id);
                    }
                }

                // Now write out the ID for this symbol so that any future hits of it can
                // write out a reference to it instead.
                WriteInteger(id);

                EndKey();
            }