public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile) { if (namedType.IsTupleType) { trapFile.Write('('); trapFile.BuildList(",", namedType.TupleElements.Select(f => f.Type), (t, tb0) => t.BuildDisplayName(cx, tb0) ); trapFile.Write(")"); return; } if (namedType.IsAnonymousType) { namedType.BuildAnonymousName(cx, trapFile, (cx0, tb0, sub) => sub.BuildDisplayName(cx0, tb0), false); } trapFile.Write(namedType.Name); if (namedType.IsGenericType && namedType.TypeKind != TypeKind.Error && namedType.TypeArguments.Any()) { trapFile.Write('<'); trapFile.BuildList(",", namedType.TypeArguments, (p, tb0) => { if (IsReallyBound(namedType)) { p.BuildDisplayName(cx, tb0); } }); trapFile.Write('>'); } }
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action <Context, TextWriter, ITypeSymbol> subTermAction) { if (named.IsTupleType) { trapFile.Write('('); trapFile.BuildList(",", named.TupleElements, (f, tb0) => { trapFile.Write(f.Name); trapFile.Write(":"); subTermAction(cx, tb0, f.Type); } ); trapFile.Write(")"); return; } if (named.ContainingType != null) { subTermAction(cx, trapFile, named.ContainingType); trapFile.Write('.'); } else if (named.ContainingNamespace != null) { named.ContainingNamespace.BuildNamespace(cx, trapFile); } if (named.IsAnonymousType) { named.BuildAnonymousName(cx, trapFile, subTermAction, true); } else if (named.TypeParameters.IsEmpty) { trapFile.Write(named.Name); } else if (IsReallyUnbound(named)) { trapFile.Write(named.Name); trapFile.Write("`"); trapFile.Write(named.TypeParameters.Length); } else { subTermAction(cx, trapFile, named.ConstructedFrom); trapFile.Write('<'); // Encode the nullability of the type arguments in the label. // Type arguments with different nullability can result in // a constructed type with different nullability of its members and methods, // so we need to create a distinct database entity for it. trapFile.BuildList(",", named.GetAnnotatedTypeArguments(), (ta, tb0) => { subTermAction(cx, tb0, ta.Symbol); trapFile.Write((int)ta.Nullability); }); trapFile.Write('>'); } }
/// <summary> /// Factored out to share logic between `Method` and `UserOperator`. /// </summary> private static void BuildMethodId(Method m, TextWriter trapFile) { m.Symbol.ReturnType.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write(" "); trapFile.WriteSubId(m.ContainingType !); AddExplicitInterfaceQualifierToId(m.Context, trapFile, m.Symbol.ExplicitInterfaceImplementations); trapFile.Write("."); trapFile.Write(m.Symbol.Name); if (m.Symbol.IsGenericMethod) { if (SymbolEqualityComparer.Default.Equals(m.Symbol, m.Symbol.OriginalDefinition)) { trapFile.Write('`'); trapFile.Write(m.Symbol.TypeParameters.Length); } else { trapFile.Write('<'); // Encode the nullability of the type arguments in the label. // Type arguments with different nullability can result in // a constructed method with different nullability of its parameters and return type, // so we need to create a distinct database entity for it. trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { ta.Symbol.BuildOrWriteId(m.Context, tb0, m.Symbol); trapFile.Write((int)ta.Nullability); }); trapFile.Write('>'); } } AddParametersToId(m.Context, trapFile, m.Symbol); switch (m.Symbol.MethodKind) { case MethodKind.PropertyGet: trapFile.Write(";getter"); break; case MethodKind.PropertySet: trapFile.Write(";setter"); break; case MethodKind.EventAdd: trapFile.Write(";adder"); break; case MethodKind.EventRaise: trapFile.Write(";raiser"); break; case MethodKind.EventRemove: trapFile.Write(";remover"); break; default: trapFile.Write(";method"); break; } }
public override void WriteId(TextWriter trapFile) { trapFile.WriteSubId(ContainingType); trapFile.Write('.'); trapFile.Write(symbol.MetadataName); trapFile.Write('('); trapFile.BuildList(",", symbol.Parameters, (p, tb0) => tb0.WriteSubId(Type.Create(Context, p.Type))); trapFile.Write(");indexer"); }
public override void WriteId(TextWriter trapFile) { trapFile.WriteSubId(Location); if (symbol.IsGenericMethod && !IsSourceDeclaration) { trapFile.Write('<'); trapFile.BuildList(",", symbol.TypeArguments, (ta, tb0) => AddSignatureTypeToId(Context, tb0, symbol, ta)); trapFile.Write('>'); } trapFile.Write(";localfunction"); }
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter trapFile, Action <Context, TextWriter, ITypeSymbol> subTermAction, bool includeParamName) { var buildParam = includeParamName ? (prop, tb0) => { tb0.Write(prop.Name); tb0.Write(' '); subTermAction(cx, tb0, prop.Type); } : (Action <IPropertySymbol, TextWriter>)((prop, tb0) => subTermAction(cx, tb0, prop.Type)); int memberCount = type.GetMembers().OfType <IPropertySymbol>().Count(); int hackTypeNumber = memberCount == 1 ? 1 : 0; trapFile.Write("<>__AnonType"); trapFile.Write(hackTypeNumber); trapFile.Write('<'); trapFile.BuildList(",", type.GetMembers().OfType <IPropertySymbol>(), buildParam); trapFile.Write('>'); }
/// <summary> /// Appends a [comma] separated list to a trap builder. /// </summary> /// <typeparam name="T">The type of the list.</typeparam> /// <param name="trapFile">The trap builder to append to.</param> /// <param name="separator">The separator string (e.g. ",")</param> /// <param name="items">The list of items.</param> /// <returns>The original trap builder (fluent interface).</returns> public static TextWriter AppendList <T>(this TextWriter trapFile, string separator, IEnumerable <T> items) where T : IEntity { return(trapFile.BuildList(separator, items, (x, tb0) => { tb0.WriteSubId(x); })); }