Exemplo n.º 1
0
            private IReadOnlyDictionary <string, ImmutableArray <ISymbolInternal> > GetAllEmittedMembers(ISymbolInternal symbol)
            {
                var members = ArrayBuilder <ISymbolInternal> .GetInstance();

                if (symbol.Kind == SymbolKind.NamedType)
                {
                    var type = (NamedTypeSymbol)symbol;
                    members.AddRange(type.GetEventsToEmit());
                    members.AddRange(type.GetFieldsToEmit());
                    members.AddRange(type.GetMethodsToEmit());
                    members.AddRange(type.GetTypeMembers());
                    members.AddRange(type.GetPropertiesToEmit());
                }
                else
                {
                    members.AddRange(((NamespaceSymbol)symbol).GetMembers());
                }

                if (_otherSynthesizedMembersOpt != null && _otherSynthesizedMembersOpt.TryGetValue(symbol, out var synthesizedMembers))
                {
                    members.AddRange(synthesizedMembers);
                }

                var result = members.ToDictionary(s => s.MetadataName, StringOrdinalComparer.Instance);

                members.Free();
                return(result);
            }
Exemplo n.º 2
0
        public SymbolChange GetChange(IDefinition def)
        {
            var synthesizedDef = def as ISynthesizedMethodBodyImplementationSymbol;

            if (synthesizedDef != null)
            {
                Debug.Assert(synthesizedDef.Method != null);

                var             generator         = synthesizedDef.Method;
                ISymbolInternal synthesizedSymbol = synthesizedDef;

                var change = GetChange((IDefinition)generator);
                switch (change)
                {
                case SymbolChange.Updated:
                    // The generator has been updated. Some synthesized members should be reused, others updated or added.

                    // The container of the synthesized symbol doesn't exist, we need to add the symbol.
                    // This may happen e.g. for members of a state machine type when a non-iterator method is changed to an iterator.
                    if (!_definitionMap.DefinitionExists((IDefinition)synthesizedSymbol.ContainingType))
                    {
                        return(SymbolChange.Added);
                    }

                    if (!_definitionMap.DefinitionExists(def))
                    {
                        // A method was changed to a method containing a lambda, to an iterator, or to an async method.
                        // The state machine or closure class has been added.
                        return(SymbolChange.Added);
                    }

                    // The existing symbol should be reused when the generator is updated,
                    // not updated since it's form doesn't depend on the content of the generator.
                    // For example, when an iterator method changes all methods that implement IEnumerable
                    // but MoveNext can be reused as they are.
                    if (!synthesizedDef.HasMethodBodyDependency)
                    {
                        return(SymbolChange.None);
                    }

                    // If the type produced from the method body existed before then its members are updated.
                    if (synthesizedSymbol.Kind == SymbolKind.NamedType)
                    {
                        return(SymbolChange.ContainsChanges);
                    }

                    if (synthesizedSymbol.Kind == SymbolKind.Method)
                    {
                        // The method body might have been updated.
                        return(SymbolChange.Updated);
                    }

                    return(SymbolChange.None);

                case SymbolChange.Added:
                    // The method has been added - add the synthesized member as well, unless they already exist.
                    if (!_definitionMap.DefinitionExists(def))
                    {
                        return(SymbolChange.Added);
                    }

                    // If the existing member is a type we need to add new members into it.
                    // An example is a shared static display class - an added method with static lambda will contribute
                    // the lambda and cache fields into the shared display class.
                    if (synthesizedSymbol.Kind == SymbolKind.NamedType)
                    {
                        return(SymbolChange.ContainsChanges);
                    }

                    // Update method.
                    // An example is a constructor a shared display class - an added method with lambda will contribute
                    // cache field initialization code into the constructor.
                    if (synthesizedSymbol.Kind == SymbolKind.Method)
                    {
                        return(SymbolChange.Updated);
                    }

                    // Otherwise, there is nothing to do.
                    // For example, a static lambda display class cache field.
                    return(SymbolChange.None);

                default:
                    // The method had to change, otherwise the synthesized symbol wouldn't be generated
                    throw ExceptionUtilities.UnexpectedValue(change);
                }
            }

            if (def is ISymbolInternal symbol)
            {
                return(GetChange(symbol.GetISymbol()));
            }

            // If the def existed in the previous generation, the def is unchanged
            // (although it may contain changed defs); otherwise, it was added.
            if (_definitionMap.DefinitionExists(def))
            {
                return((def is ITypeDefinition) ? SymbolChange.ContainsChanges : SymbolChange.None);
            }

            return(SymbolChange.Added);
        }
Exemplo n.º 3
0
        public ISymbolInternal MapDefinitionOrNamespace(ISymbolInternal symbol)
        {
            var adapter = symbol.GetCciAdapter();

            return((adapter is Cci.IDefinition definition) ? MapDefinition(definition)?.GetInternalSymbol() : MapNamespace((Cci.INamespace)adapter)?.GetInternalSymbol());
        }
Exemplo n.º 4
0
 internal static SemanticEdit Create(SemanticEditKind kind, ISymbolInternal oldSymbol, ISymbolInternal newSymbol, Func <SyntaxNode, SyntaxNode>?syntaxMap = null, bool preserveLocalVariables = false)
 {
     return(new SemanticEdit(kind, oldSymbol?.GetISymbol(), newSymbol?.GetISymbol(), syntaxMap, preserveLocalVariables));
 }
Exemplo n.º 5
0
 public ISymbolInternal MapDefinitionOrNamespace(ISymbolInternal symbol)
 => (symbol is Cci.IDefinition definition) ? (ISymbolInternal)MapDefinition(definition) : (ISymbolInternal)MapNamespace((Cci.INamespace)symbol);
Exemplo n.º 6
0
 bool ISymbolInternal.Equals(ISymbolInternal other, TypeCompareKind compareKind) => this.Equals((object)other);