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); }
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); }
public ISymbolInternal MapDefinitionOrNamespace(ISymbolInternal symbol) { var adapter = symbol.GetCciAdapter(); return((adapter is Cci.IDefinition definition) ? MapDefinition(definition)?.GetInternalSymbol() : MapNamespace((Cci.INamespace)adapter)?.GetInternalSymbol()); }
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)); }
public ISymbolInternal MapDefinitionOrNamespace(ISymbolInternal symbol) => (symbol is Cci.IDefinition definition) ? (ISymbolInternal)MapDefinition(definition) : (ISymbolInternal)MapNamespace((Cci.INamespace)symbol);
bool ISymbolInternal.Equals(ISymbolInternal other, TypeCompareKind compareKind) => this.Equals((object)other);