Ejemplo n.º 1
0
        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());
        }
Ejemplo n.º 2
0
        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);
            }
        }