Skip to content

Commit c642678

Browse files
Remove ToTypeReference: Implement ParseReflectionName with SRM TypeName.
1 parent 33e497e commit c642678

File tree

13 files changed

+203
-360
lines changed

13 files changed

+203
-360
lines changed

ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,33 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
3333
{
3434
// assign short names to the fake reflection types
3535
using C = Conversion;
36-
using dynamic = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.Dynamic;
37-
using nint = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.NInt;
38-
using nuint = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.NUInt;
39-
using Null = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.Null;
36+
using dynamic = ConversionTest.Dynamic;
37+
using nint = ConversionTest.NInt;
38+
using nuint = ConversionTest.NUInt;
4039

4140
[TestFixture, Parallelizable(ParallelScope.All)]
4241
public unsafe class ConversionTest
4342
{
43+
/// <summary>
44+
/// A reflection class used to represent <c>null</c>.
45+
/// </summary>
46+
public sealed class Null { }
47+
48+
/// <summary>
49+
/// A reflection class used to represent <c>dynamic</c>.
50+
/// </summary>
51+
public sealed class Dynamic { }
52+
53+
/// <summary>
54+
/// A reflection class used to represent <c>nint</c>.
55+
/// </summary>
56+
public sealed class NInt { }
57+
58+
/// <summary>
59+
/// A reflection class used to represent <c>nuint</c>.
60+
/// </summary>
61+
public sealed class NUInt { }
62+
4463
CSharpConversions conversions;
4564
ICompilation compilation;
4665

@@ -53,17 +72,37 @@ public void SetUp()
5372
conversions = new CSharpConversions(compilation);
5473
}
5574

75+
public class ReplaceSpecialTypesVisitor : TypeVisitor
76+
{
77+
public override IType VisitTypeDefinition(ITypeDefinition type)
78+
{
79+
switch (type.FullName)
80+
{
81+
case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.Dynamic":
82+
return SpecialType.Dynamic;
83+
case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.Null":
84+
return SpecialType.NullType;
85+
case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.NInt":
86+
return SpecialType.NInt;
87+
case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.NUInt":
88+
return SpecialType.NUInt;
89+
default:
90+
return base.VisitTypeDefinition(type);
91+
}
92+
}
93+
}
94+
5695
Conversion ImplicitConversion(Type from, Type to)
5796
{
58-
IType from2 = compilation.FindType(from);
59-
IType to2 = compilation.FindType(to);
97+
IType from2 = compilation.FindType(from).AcceptVisitor(new ReplaceSpecialTypesVisitor());
98+
IType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());
6099
return conversions.ImplicitConversion(from2, to2);
61100
}
62101

63102
Conversion ExplicitConversion(Type from, Type to)
64103
{
65-
IType from2 = compilation.FindType(from);
66-
IType to2 = compilation.FindType(to);
104+
IType from2 = compilation.FindType(from).AcceptVisitor(new ReplaceSpecialTypesVisitor());
105+
IType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());
67106
return conversions.ExplicitConversion(from2, to2);
68107
}
69108

@@ -509,9 +548,9 @@ public void UserDefinedImplicitNullableConversion()
509548

510549
bool IntegerLiteralConversion(object value, Type to)
511550
{
512-
IType fromType = compilation.FindType(value.GetType());
551+
IType fromType = compilation.FindType(value.GetType()).AcceptVisitor(new ReplaceSpecialTypesVisitor());
513552
ConstantResolveResult crr = new ConstantResolveResult(fromType, value);
514-
IType to2 = compilation.FindType(to);
553+
IType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());
515554
return conversions.ImplicitConversion(crr, to2).IsValid;
516555
}
517556

@@ -587,18 +626,18 @@ public void ImplicitConstantExpressionConversionNumberInterfaces()
587626

588627
int BetterConversion(Type s, Type t1, Type t2)
589628
{
590-
IType sType = compilation.FindType(s);
591-
IType t1Type = compilation.FindType(t1);
592-
IType t2Type = compilation.FindType(t2);
629+
IType sType = compilation.FindType(s).AcceptVisitor(new ReplaceSpecialTypesVisitor());
630+
IType t1Type = compilation.FindType(t1).AcceptVisitor(new ReplaceSpecialTypesVisitor());
631+
IType t2Type = compilation.FindType(t2).AcceptVisitor(new ReplaceSpecialTypesVisitor());
593632
return conversions.BetterConversion(sType, t1Type, t2Type);
594633
}
595634

596635
int BetterConversion(object value, Type t1, Type t2)
597636
{
598-
IType fromType = compilation.FindType(value.GetType());
637+
IType fromType = compilation.FindType(value.GetType()).AcceptVisitor(new ReplaceSpecialTypesVisitor());
599638
ConstantResolveResult crr = new ConstantResolveResult(fromType, value);
600-
IType t1Type = compilation.FindType(t1);
601-
IType t2Type = compilation.FindType(t2);
639+
IType t1Type = compilation.FindType(t1).AcceptVisitor(new ReplaceSpecialTypesVisitor());
640+
IType t2Type = compilation.FindType(t2).AcceptVisitor(new ReplaceSpecialTypesVisitor());
602641
return conversions.BetterConversion(crr, t1Type, t2Type);
603642
}
604643

ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
using System;
2020
using System.Collections.Generic;
21-
using System.Linq;
2221

2322
using ICSharpCode.Decompiler.CSharp.Resolver;
2423
using ICSharpCode.Decompiler.Semantics;
@@ -31,7 +30,7 @@
3130
namespace ICSharpCode.Decompiler.Tests.Semantics
3231
{
3332
using C = Conversion;
34-
using dynamic = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.Dynamic;
33+
using dynamic = ConversionTest.Dynamic;
3534

3635
[TestFixture, Parallelizable(ParallelScope.All)]
3736
public class ExplicitConversionsTest
@@ -50,8 +49,8 @@ public void SetUp()
5049

5150
Conversion ExplicitConversion(Type from, Type to)
5251
{
53-
IType from2 = compilation.FindType(from);
54-
IType to2 = compilation.FindType(to);
52+
IType from2 = compilation.FindType(from).AcceptVisitor(new ConversionTest.ReplaceSpecialTypesVisitor());
53+
IType to2 = compilation.FindType(to).AcceptVisitor(new ConversionTest.ReplaceSpecialTypesVisitor());
5554
return conversions.ExplicitConversion(from2, to2);
5655
}
5756

ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
using System;
2020
using System.Collections.Generic;
2121
using System.Linq;
22-
using System.Reflection;
2322

2423
using ICSharpCode.Decompiler.TypeSystem;
2524
using ICSharpCode.Decompiler.TypeSystem.Implementation;
@@ -71,90 +70,74 @@ public void TestGetInnerClassInGenericClass2()
7170
}
7271

7372
[Test]
74-
public void TestToTypeReferenceInnerClass()
73+
public void TestFindTypeReflectionNameInnerClass()
7574
{
7675
Assert.That(compilation.FindType(typeof(Environment.SpecialFolder)).ReflectionName, Is.EqualTo("System.Environment+SpecialFolder"));
7776
}
7877

7978
[Test]
80-
public void TestToTypeReferenceUnboundGenericClass()
79+
public void TestFindTypeReflectionNameUnboundGenericClass()
8180
{
8281
Assert.That(compilation.FindType(typeof(Action<>)).ReflectionName, Is.EqualTo("System.Action`1"));
8382
Assert.That(compilation.FindType(typeof(Action<,>)).ReflectionName, Is.EqualTo("System.Action`2"));
8483
}
8584

8685
[Test]
87-
public void TestToTypeReferenceBoundGenericClass()
86+
public void TestFindTypeReflectionNameBoundGenericClass()
8887
{
8988
Assert.That(compilation.FindType(typeof(Action<string>)).ReflectionName, Is.EqualTo("System.Action`1[[System.String]]"));
9089
Assert.That(compilation.FindType(typeof(Action<int, short>)).ReflectionName, Is.EqualTo("System.Action`2[[System.Int32],[System.Int16]]"));
9190
}
9291

9392

9493
[Test]
95-
public void TestToTypeReferenceNullableType()
94+
public void TestFindTypeReflectionNameNullableType()
9695
{
9796
Assert.That(compilation.FindType(typeof(int?)).ReflectionName, Is.EqualTo("System.Nullable`1[[System.Int32]]"));
9897
}
9998

10099
[Test]
101-
public void TestToTypeReferenceInnerClassInUnboundGenericType()
100+
public void TestFindTypeReflectionNameInnerClassInUnboundGenericType()
102101
{
103102
Assert.That(compilation.FindType(typeof(Dictionary<,>.ValueCollection)).ReflectionName, Is.EqualTo("System.Collections.Generic.Dictionary`2+ValueCollection"));
104103
}
105104

106105
[Test]
107-
public void TestToTypeReferenceInnerClassInBoundGenericType()
106+
public void TestFindTypeReflectionNameInnerClassInBoundGenericType()
108107
{
109108
Assert.That(compilation.FindType(typeof(Dictionary<string, int>.KeyCollection)).ReflectionName, Is.EqualTo("System.Collections.Generic.Dictionary`2+KeyCollection[[System.String],[System.Int32]]"));
110109
}
111110

112111
[Test]
113-
public void TestToTypeReferenceArrayType()
112+
public void TestFindTypeReflectionNameArrayType()
114113
{
115114
Assert.That(compilation.FindType(typeof(int[])).ReflectionName, Is.EqualTo(typeof(int[]).FullName));
116115
}
117116

118117
[Test]
119-
public void TestToTypeReferenceMultidimensionalArrayType()
118+
public void TestFindTypeReflectionNameMultidimensionalArrayType()
120119
{
121120
Assert.That(compilation.FindType(typeof(int[,])).ReflectionName, Is.EqualTo(typeof(int[,]).FullName));
122121
}
123122

124123
[Test]
125-
public void TestToTypeReferenceJaggedMultidimensionalArrayType()
124+
public void TestFindTypeReflectionNameJaggedMultidimensionalArrayType()
126125
{
127126
Assert.That(compilation.FindType(typeof(int[,][,,])).ReflectionName, Is.EqualTo(typeof(int[,][,,]).FullName));
128127
}
129128

130129
[Test]
131-
public void TestToTypeReferencePointerType()
130+
public void TestFindTypeReflectionNamePointerType()
132131
{
133132
Assert.That(compilation.FindType(typeof(int*)).ReflectionName, Is.EqualTo(typeof(int*).FullName));
134133
}
135134

136135
[Test]
137-
public void TestToTypeReferenceByReferenceType()
136+
public void TestFindTypeReflectionNameByReferenceType()
138137
{
139138
Assert.That(compilation.FindType(typeof(int).MakeByRefType()).ReflectionName, Is.EqualTo(typeof(int).MakeByRefType().FullName));
140139
}
141140

142-
[Test]
143-
public void TestToTypeReferenceGenericType()
144-
{
145-
MethodInfo convertAllInfo = typeof(List<>).GetMethod("ConvertAll");
146-
ITypeReference parameterType = convertAllInfo.GetParameters()[0].ParameterType.ToTypeReference(); // Converter[[`0],[``0]]
147-
// cannot resolve generic types without knowing the parent entity:
148-
IType resolvedWithoutEntity = parameterType.Resolve(new SimpleTypeResolveContext(compilation));
149-
Assert.That(resolvedWithoutEntity.ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]"));
150-
Assert.That(((ITypeParameter)((ParameterizedType)resolvedWithoutEntity).GetTypeArgument(0)).Owner, Is.Null);
151-
// now try with parent entity:
152-
IMethod convertAll = compilation.FindType(typeof(List<>)).GetMethods(m => m.Name == "ConvertAll").Single();
153-
IType resolvedWithEntity = parameterType.Resolve(new SimpleTypeResolveContext(convertAll));
154-
Assert.That(resolvedWithEntity.ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]"));
155-
Assert.That(((ITypeParameter)((ParameterizedType)resolvedWithEntity).GetTypeArgument(0)).Owner, Is.SameAs(convertAll.DeclaringTypeDefinition));
156-
}
157-
158141
[Test]
159142
public void ParseReflectionName()
160143
{
@@ -204,21 +187,21 @@ public void ParseInvalidReflectionName1()
204187
public void ParseInvalidReflectionName2()
205188
{
206189
var context = new SimpleTypeResolveContext(compilation.MainModule);
207-
Assert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName("`", context));
190+
Assert.That(ReflectionHelper.ParseReflectionName("`", context).ReflectionName, Is.EqualTo("`"));
208191
}
209192

210193
[Test]
211194
public void ParseInvalidReflectionName3()
212195
{
213196
var context = new SimpleTypeResolveContext(compilation.MainModule);
214-
Assert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName("``", context));
197+
Assert.That(ReflectionHelper.ParseReflectionName("``", context).ReflectionName, Is.EqualTo("``"));
215198
}
216199

217200
[Test]
218201
public void ParseInvalidReflectionName4()
219202
{
220203
var context = new SimpleTypeResolveContext(compilation.MainModule);
221-
Assert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName("System.Action`A", context));
204+
Assert.That(ReflectionHelper.ParseReflectionName("System.Action`A", context).ReflectionName, Is.EqualTo("System.Action`A"));
222205
}
223206

224207
[Test]
@@ -232,7 +215,7 @@ public void ParseInvalidReflectionName5()
232215
public void ParseInvalidReflectionName5b()
233216
{
234217
var context = new SimpleTypeResolveContext(compilation.MainModule);
235-
Assert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName("System.Environment+`", context));
218+
Assert.That(ReflectionHelper.ParseReflectionName("System.Environment+`", context).ReflectionName, Is.EqualTo("System.Environment+`"));
236219
}
237220

238221
[Test]
@@ -246,7 +229,7 @@ public void ParseInvalidReflectionName6()
246229
public void ParseInvalidReflectionName7()
247230
{
248231
var context = new SimpleTypeResolveContext(compilation.MainModule);
249-
Assert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName("System.Int32[`]", context));
232+
Assert.That(ReflectionHelper.ParseReflectionName("System.Int32[`]", context).ReflectionName, Is.EqualTo("System.Int32"));
250233
}
251234

252235
[Test]

ICSharpCode.Decompiler/CSharp/Syntax/AstType.cs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1717
// DEALINGS IN THE SOFTWARE.
1818

19-
using System;
2019
using System.Collections.Generic;
2120

2221
using ICSharpCode.Decompiler.CSharp.Resolver;
2322
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
24-
using ICSharpCode.Decompiler.TypeSystem;
2523

2624
namespace ICSharpCode.Decompiler.CSharp.Syntax
2725
{
@@ -60,11 +58,6 @@ protected internal override bool DoMatch(AstNode other, PatternMatching.Match ma
6058
{
6159
return other == null || other.IsNull;
6260
}
63-
64-
public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
65-
{
66-
return SpecialType.UnknownType;
67-
}
6861
}
6962
#endregion
7063

@@ -102,11 +95,6 @@ public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
10295
return visitor.VisitPatternPlaceholder(this, child, data);
10396
}
10497

105-
public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
106-
{
107-
throw new NotSupportedException();
108-
}
109-
11098
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
11199
{
112100
return child.DoMatch(other, match);
@@ -137,34 +125,6 @@ public bool IsVar()
137125
return st != null && st.Identifier == "var" && st.TypeArguments.Count == 0;
138126
}
139127

140-
/// <summary>
141-
/// Create an ITypeReference for this AstType.
142-
/// Uses the context (ancestors of this node) to determine the correct <see cref="NameLookupMode"/>.
143-
/// </summary>
144-
/// <remarks>
145-
/// The resulting type reference will read the context information from the
146-
/// <see cref="ITypeResolveContext"/>:
147-
/// For resolving type parameters, the CurrentTypeDefinition/CurrentMember is used.
148-
/// For resolving simple names, the current namespace and usings from the CurrentUsingScope
149-
/// (on CSharpTypeResolveContext only) is used.
150-
/// </remarks>
151-
public ITypeReference ToTypeReference(InterningProvider interningProvider = null)
152-
{
153-
return ToTypeReference(GetNameLookupMode(), interningProvider);
154-
}
155-
156-
/// <summary>
157-
/// Create an ITypeReference for this AstType.
158-
/// </summary>
159-
/// <remarks>
160-
/// The resulting type reference will read the context information from the
161-
/// <see cref="ITypeResolveContext"/>:
162-
/// For resolving type parameters, the CurrentTypeDefinition/CurrentMember is used.
163-
/// For resolving simple names, the current namespace and usings from the CurrentUsingScope
164-
/// (on CSharpTypeResolveContext only) is used.
165-
/// </remarks>
166-
public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null);
167-
168128
/// <summary>
169129
/// Gets the name lookup mode from the context (looking at the ancestors of this <see cref="AstType"/>).
170130
/// </summary>

0 commit comments

Comments
 (0)