1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Text;
7 
8 namespace Internal.TypeSystem
9 {
10     /// <summary>
11     /// Provides a name formatter that is compatible with SigFormat.cpp in the CLR.
12     /// </summary>
13     public partial class ExceptionTypeNameFormatter : TypeNameFormatter
14     {
15         public static ExceptionTypeNameFormatter Instance { get; } = new ExceptionTypeNameFormatter();
16 
AppendName(StringBuilder sb, PointerType type)17         public override void AppendName(StringBuilder sb, PointerType type)
18         {
19             AppendName(sb, type.ParameterType);
20             sb.Append('*');
21         }
22 
AppendName(StringBuilder sb, GenericParameterDesc type)23         public override void AppendName(StringBuilder sb, GenericParameterDesc type)
24         {
25             string prefix = type.Kind == GenericParameterKind.Type ? "!" : "!!";
26             sb.Append(prefix);
27             sb.Append(type.Name);
28         }
29 
AppendName(StringBuilder sb, SignatureTypeVariable type)30         public override void AppendName(StringBuilder sb, SignatureTypeVariable type)
31         {
32             sb.Append("!");
33             sb.Append(type.Index.ToStringInvariant());
34         }
35 
AppendName(StringBuilder sb, SignatureMethodVariable type)36         public override void AppendName(StringBuilder sb, SignatureMethodVariable type)
37         {
38             sb.Append("!!");
39             sb.Append(type.Index.ToStringInvariant());
40         }
41 
AppendName(StringBuilder sb, FunctionPointerType type)42         public override void AppendName(StringBuilder sb, FunctionPointerType type)
43         {
44             MethodSignature signature = type.Signature;
45 
46             AppendName(sb, signature.ReturnType);
47 
48             sb.Append(" (");
49             for (int i = 0; i < signature.Length; i++)
50             {
51                 if (i > 0)
52                     sb.Append(", ");
53                 AppendName(sb, signature[i]);
54             }
55 
56             // TODO: Append '...' for vararg methods
57 
58             sb.Append(')');
59         }
60 
AppendName(StringBuilder sb, ByRefType type)61         public override void AppendName(StringBuilder sb, ByRefType type)
62         {
63             AppendName(sb, type.ParameterType);
64             sb.Append(" ByRef");
65         }
66 
AppendName(StringBuilder sb, ArrayType type)67         public override void AppendName(StringBuilder sb, ArrayType type)
68         {
69             AppendName(sb, type.ElementType);
70             sb.Append('[');
71 
72             // NOTE: We're ignoring difference between SzArray and MdArray rank 1 for SigFormat.cpp compat.
73             sb.Append(',', type.Rank - 1);
74 
75             sb.Append(']');
76         }
77 
AppendNameForInstantiatedType(StringBuilder sb, DefType type)78         protected override void AppendNameForInstantiatedType(StringBuilder sb, DefType type)
79         {
80             AppendName(sb, type.GetTypeDefinition());
81             sb.Append('<');
82 
83             for (int i = 0; i < type.Instantiation.Length; i++)
84             {
85                 if (i > 0)
86                     sb.Append(", ");
87                 AppendName(sb, type.Instantiation[i]);
88             }
89 
90             sb.Append('>');
91         }
92 
AppendNameForNamespaceType(StringBuilder sb, DefType type)93         protected override void AppendNameForNamespaceType(StringBuilder sb, DefType type)
94         {
95             if (type.IsPrimitive)
96             {
97                 sb.Append(GetTypeName(type));
98             }
99             else
100             {
101                 string ns = GetTypeNamespace(type);
102                 if (ns.Length > 0)
103                 {
104                     sb.Append(ns);
105                     sb.Append('.');
106                 }
107                 sb.Append(GetTypeName(type));
108             }
109         }
110 
AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType)111         protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType)
112         {
113             // NOTE: We're ignoring the containing type for compatiblity with SigFormat.cpp
114             sb.Append(GetTypeName(nestedType));
115         }
116     }
117 }
118 
119