private static string GetMangledAndEscapedName(INamedTypeReference namedType) { var pooled = PooledStringBuilder.GetInstance(); StringBuilder mangledName = pooled.Builder; const string needsEscaping = "\\[]*.+,& "; foreach (var ch in namedType.Name) { if (needsEscaping.IndexOf(ch) >= 0) { mangledName.Append('\\'); } mangledName.Append(ch); } if (namedType.MangleName && namedType.GenericParameterCount > 0) { mangledName.Append(MetadataHelpers.GetAritySuffix(namedType.GenericParameterCount)); } return(pooled.ToStringAndFree()); }
private void AddNameAndTypeArgumentsOrParameters(INamedTypeSymbol symbol) { if (symbol.IsAnonymousType) { AddAnonymousTypeName(symbol); return; } else if (symbol.IsTupleType && !ShouldDisplayAsValueTuple(symbol)) { AddTupleTypeName(symbol); return; } string symbolName = null; // It would be nice to handle VB NoPia symbols too, but it's not worth the effort. NamedTypeSymbol underlyingTypeSymbol = (symbol as Symbols.PublicModel.NamedTypeSymbol)?.UnderlyingNamedTypeSymbol; var illegalGenericInstantiationSymbol = underlyingTypeSymbol as NoPiaIllegalGenericInstantiationSymbol; if ((object)illegalGenericInstantiationSymbol != null) { symbol = illegalGenericInstantiationSymbol.UnderlyingSymbol.GetPublicSymbol(); } else { var ambiguousCanonicalTypeSymbol = underlyingTypeSymbol as NoPiaAmbiguousCanonicalTypeSymbol; if ((object)ambiguousCanonicalTypeSymbol != null) { symbol = ambiguousCanonicalTypeSymbol.FirstCandidate.GetPublicSymbol(); } else { var missingCanonicalTypeSymbol = underlyingTypeSymbol as NoPiaMissingCanonicalTypeSymbol; if ((object)missingCanonicalTypeSymbol != null) { symbolName = missingCanonicalTypeSymbol.FullTypeName; } } } var partKind = GetPartKind(symbol); if (symbolName == null) { symbolName = symbol.Name; } if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName) && partKind == SymbolDisplayPartKind.ErrorTypeName && string.IsNullOrEmpty(symbolName)) { builder.Add(CreatePart(partKind, symbol, "?")); } else { symbolName = RemoveAttributeSufficeIfNecessary(symbol, symbolName); builder.Add(CreatePart(partKind, symbol, symbolName)); } if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes)) { // Only the compiler can set the internal option and the compiler doesn't use other implementations of INamedTypeSymbol. if (underlyingTypeSymbol?.MangleName == true) { Debug.Assert(symbol.Arity > 0); builder.Add(CreatePart(InternalSymbolDisplayPartKind.Arity, null, MetadataHelpers.GetAritySuffix(symbol.Arity))); } } else if (symbol.Arity > 0 && format.GenericsOptions.IncludesOption(SymbolDisplayGenericsOptions.IncludeTypeParameters)) { // It would be nice to handle VB symbols too, but it's not worth the effort. if (underlyingTypeSymbol is UnsupportedMetadataTypeSymbol || underlyingTypeSymbol is MissingMetadataTypeSymbol || symbol.IsUnboundGenericType) { AddPunctuation(SyntaxKind.LessThanToken); for (int i = 0; i < symbol.Arity - 1; i++) { AddPunctuation(SyntaxKind.CommaToken); } AddPunctuation(SyntaxKind.GreaterThanToken); } else { ImmutableArray <ImmutableArray <CustomModifier> > modifiers = GetTypeArgumentsModifiers(underlyingTypeSymbol); AddTypeArguments(symbol, modifiers); AddDelegateParameters(symbol); // TODO: do we want to skip these if we're being visited as a containing type? AddTypeParameterConstraints(symbol.TypeArguments); } } else { AddDelegateParameters(symbol); } // Only the compiler can set the internal option and the compiler doesn't use other implementations of INamedTypeSymbol. if (underlyingTypeSymbol?.OriginalDefinition is MissingMetadataTypeSymbol && format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.FlagMissingMetadataTypes)) { //add it as punctuation - it's just for testing AddPunctuation(SyntaxKind.OpenBracketToken); builder.Add(CreatePart(InternalSymbolDisplayPartKind.Other, symbol, "missing")); AddPunctuation(SyntaxKind.CloseBracketToken); } }
private void AddNameAndTypeArgumentsOrParameters(INamedTypeSymbol symbol) { if (symbol.IsAnonymousType) { AddAnonymousTypeName(symbol); return; } else if (symbol.IsTupleType) { // If top level tuple uses non-default names, there is no way to preserve them // unless we use tuple syntax for the type. So, we give them priority. if (!format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseValueTuple)) { if (HasNonDefaultTupleElements(symbol) || CanUseTupleTypeName(symbol)) { AddTupleTypeName(symbol); return; } } // Fall back to displaying the underlying type. symbol = symbol.TupleUnderlyingType; } string symbolName = null; // It would be nice to handle VB NoPia symbols too, but it's not worth the effort. var illegalGenericInstantiationSymbol = symbol as NoPiaIllegalGenericInstantiationSymbol; if ((object)illegalGenericInstantiationSymbol != null) { symbol = illegalGenericInstantiationSymbol.UnderlyingSymbol; } else { var ambiguousCanonicalTypeSymbol = symbol as NoPiaAmbiguousCanonicalTypeSymbol; if ((object)ambiguousCanonicalTypeSymbol != null) { symbol = ambiguousCanonicalTypeSymbol.FirstCandidate; } else { var missingCanonicalTypeSymbol = symbol as NoPiaMissingCanonicalTypeSymbol; if ((object)missingCanonicalTypeSymbol != null) { symbolName = missingCanonicalTypeSymbol.FullTypeName; } } } var partKind = GetPartKind(symbol); if (symbolName == null) { symbolName = symbol.Name; } if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName) && partKind == SymbolDisplayPartKind.ErrorTypeName && string.IsNullOrEmpty(symbolName)) { builder.Add(CreatePart(partKind, symbol, "?")); } else { symbolName = RemoveAttributeSufficeIfNecessary(symbol, symbolName); builder.Add(CreatePart(partKind, symbol, symbolName)); } if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes)) { // Only the compiler can set the internal option and the compiler doesn't use other implementations of INamedTypeSymbol. if (((NamedTypeSymbol)symbol).MangleName) { Debug.Assert(symbol.Arity > 0); builder.Add(CreatePart(InternalSymbolDisplayPartKind.Arity, null, MetadataHelpers.GetAritySuffix(symbol.Arity))); } } else if (symbol.Arity > 0 && format.GenericsOptions.IncludesOption(SymbolDisplayGenericsOptions.IncludeTypeParameters)) { // It would be nice to handle VB symbols too, but it's not worth the effort. if (symbol is UnsupportedMetadataTypeSymbol || symbol is MissingMetadataTypeSymbol || symbol.IsUnboundGenericType) { AddPunctuation(SyntaxKind.LessThanToken); for (int i = 0; i < symbol.Arity - 1; i++) { AddPunctuation(SyntaxKind.CommaToken); } AddPunctuation(SyntaxKind.GreaterThanToken); } else { var modifiers = default(ImmutableArray <ImmutableArray <CustomModifier> >); if (this.format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers)) { var namedType = symbol as NamedTypeSymbol; if ((object)namedType != null) { modifiers = namedType.TypeArgumentsNoUseSiteDiagnostics.SelectAsArray(a => a.CustomModifiers); } } AddTypeArguments(symbol, modifiers); AddDelegateParameters(symbol); // TODO: do we want to skip these if we're being visited as a containing type? AddTypeParameterConstraints(symbol.TypeArguments); } } else { AddDelegateParameters(symbol); } // Only the compiler can set the internal option and the compiler doesn't use other implementations of INamedTypeSymbol. if (symbol.OriginalDefinition is MissingMetadataTypeSymbol && format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.FlagMissingMetadataTypes)) { //add it as punctuation - it's just for testing AddPunctuation(SyntaxKind.OpenBracketToken); builder.Add(CreatePart(InternalSymbolDisplayPartKind.Other, symbol, "missing")); AddPunctuation(SyntaxKind.CloseBracketToken); } }