diff --git a/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs b/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs
index 2c141d14a..4ae9a60c5 100644
--- a/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs
+++ b/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs
@@ -33,14 +33,33 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
{
// assign short names to the fake reflection types
using C = Conversion;
- using dynamic = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.Dynamic;
- using nint = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.NInt;
- using nuint = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.NUInt;
- using Null = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.Null;
+ using dynamic = ConversionTest.Dynamic;
+ using nint = ConversionTest.NInt;
+ using nuint = ConversionTest.NUInt;
[TestFixture, Parallelizable(ParallelScope.All)]
public unsafe class ConversionTest
{
+ ///
+ /// A reflection class used to represent null.
+ ///
+ public sealed class Null { }
+
+ ///
+ /// A reflection class used to represent dynamic.
+ ///
+ public sealed class Dynamic { }
+
+ ///
+ /// A reflection class used to represent nint.
+ ///
+ public sealed class NInt { }
+
+ ///
+ /// A reflection class used to represent nuint.
+ ///
+ public sealed class NUInt { }
+
CSharpConversions conversions;
ICompilation compilation;
@@ -53,17 +72,37 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
conversions = new CSharpConversions(compilation);
}
+ public class ReplaceSpecialTypesVisitor : TypeVisitor
+ {
+ public override IType VisitTypeDefinition(ITypeDefinition type)
+ {
+ switch (type.FullName)
+ {
+ case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.Dynamic":
+ return SpecialType.Dynamic;
+ case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.Null":
+ return SpecialType.NullType;
+ case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.NInt":
+ return SpecialType.NInt;
+ case "ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.NUInt":
+ return SpecialType.NUInt;
+ default:
+ return base.VisitTypeDefinition(type);
+ }
+ }
+ }
+
Conversion ImplicitConversion(Type from, Type to)
{
- IType from2 = compilation.FindType(from);
- IType to2 = compilation.FindType(to);
+ IType from2 = compilation.FindType(from).AcceptVisitor(new ReplaceSpecialTypesVisitor());
+ IType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());
return conversions.ImplicitConversion(from2, to2);
}
Conversion ExplicitConversion(Type from, Type to)
{
- IType from2 = compilation.FindType(from);
- IType to2 = compilation.FindType(to);
+ IType from2 = compilation.FindType(from).AcceptVisitor(new ReplaceSpecialTypesVisitor());
+ IType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());
return conversions.ExplicitConversion(from2, to2);
}
@@ -509,9 +548,9 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
bool IntegerLiteralConversion(object value, Type to)
{
- IType fromType = compilation.FindType(value.GetType());
+ IType fromType = compilation.FindType(value.GetType()).AcceptVisitor(new ReplaceSpecialTypesVisitor());
ConstantResolveResult crr = new ConstantResolveResult(fromType, value);
- IType to2 = compilation.FindType(to);
+ IType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());
return conversions.ImplicitConversion(crr, to2).IsValid;
}
@@ -587,18 +626,18 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
int BetterConversion(Type s, Type t1, Type t2)
{
- IType sType = compilation.FindType(s);
- IType t1Type = compilation.FindType(t1);
- IType t2Type = compilation.FindType(t2);
+ IType sType = compilation.FindType(s).AcceptVisitor(new ReplaceSpecialTypesVisitor());
+ IType t1Type = compilation.FindType(t1).AcceptVisitor(new ReplaceSpecialTypesVisitor());
+ IType t2Type = compilation.FindType(t2).AcceptVisitor(new ReplaceSpecialTypesVisitor());
return conversions.BetterConversion(sType, t1Type, t2Type);
}
int BetterConversion(object value, Type t1, Type t2)
{
- IType fromType = compilation.FindType(value.GetType());
+ IType fromType = compilation.FindType(value.GetType()).AcceptVisitor(new ReplaceSpecialTypesVisitor());
ConstantResolveResult crr = new ConstantResolveResult(fromType, value);
- IType t1Type = compilation.FindType(t1);
- IType t2Type = compilation.FindType(t2);
+ IType t1Type = compilation.FindType(t1).AcceptVisitor(new ReplaceSpecialTypesVisitor());
+ IType t2Type = compilation.FindType(t2).AcceptVisitor(new ReplaceSpecialTypesVisitor());
return conversions.BetterConversion(crr, t1Type, t2Type);
}
diff --git a/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs b/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs
index 0abed50b6..70ea19baf 100644
--- a/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs
+++ b/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs
@@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.Semantics;
@@ -31,7 +30,7 @@ using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Semantics
{
using C = Conversion;
- using dynamic = ICSharpCode.Decompiler.TypeSystem.ReflectionHelper.Dynamic;
+ using dynamic = ConversionTest.Dynamic;
[TestFixture, Parallelizable(ParallelScope.All)]
public class ExplicitConversionsTest
@@ -50,8 +49,8 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
Conversion ExplicitConversion(Type from, Type to)
{
- IType from2 = compilation.FindType(from);
- IType to2 = compilation.FindType(to);
+ IType from2 = compilation.FindType(from).AcceptVisitor(new ConversionTest.ReplaceSpecialTypesVisitor());
+ IType to2 = compilation.FindType(to).AcceptVisitor(new ConversionTest.ReplaceSpecialTypesVisitor());
return conversions.ExplicitConversion(from2, to2);
}
diff --git a/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs b/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs
index 812d5ab83..9808804d9 100644
--- a/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs
+++ b/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs
@@ -19,7 +19,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Reflection;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
@@ -71,20 +70,20 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
}
[Test]
- public void TestToTypeReferenceInnerClass()
+ public void TestFindTypeReflectionNameInnerClass()
{
Assert.That(compilation.FindType(typeof(Environment.SpecialFolder)).ReflectionName, Is.EqualTo("System.Environment+SpecialFolder"));
}
[Test]
- public void TestToTypeReferenceUnboundGenericClass()
+ public void TestFindTypeReflectionNameUnboundGenericClass()
{
Assert.That(compilation.FindType(typeof(Action<>)).ReflectionName, Is.EqualTo("System.Action`1"));
Assert.That(compilation.FindType(typeof(Action<,>)).ReflectionName, Is.EqualTo("System.Action`2"));
}
[Test]
- public void TestToTypeReferenceBoundGenericClass()
+ public void TestFindTypeReflectionNameBoundGenericClass()
{
Assert.That(compilation.FindType(typeof(Action)).ReflectionName, Is.EqualTo("System.Action`1[[System.String]]"));
Assert.That(compilation.FindType(typeof(Action)).ReflectionName, Is.EqualTo("System.Action`2[[System.Int32],[System.Int16]]"));
@@ -92,69 +91,53 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
[Test]
- public void TestToTypeReferenceNullableType()
+ public void TestFindTypeReflectionNameNullableType()
{
Assert.That(compilation.FindType(typeof(int?)).ReflectionName, Is.EqualTo("System.Nullable`1[[System.Int32]]"));
}
[Test]
- public void TestToTypeReferenceInnerClassInUnboundGenericType()
+ public void TestFindTypeReflectionNameInnerClassInUnboundGenericType()
{
Assert.That(compilation.FindType(typeof(Dictionary<,>.ValueCollection)).ReflectionName, Is.EqualTo("System.Collections.Generic.Dictionary`2+ValueCollection"));
}
[Test]
- public void TestToTypeReferenceInnerClassInBoundGenericType()
+ public void TestFindTypeReflectionNameInnerClassInBoundGenericType()
{
Assert.That(compilation.FindType(typeof(Dictionary.KeyCollection)).ReflectionName, Is.EqualTo("System.Collections.Generic.Dictionary`2+KeyCollection[[System.String],[System.Int32]]"));
}
[Test]
- public void TestToTypeReferenceArrayType()
+ public void TestFindTypeReflectionNameArrayType()
{
Assert.That(compilation.FindType(typeof(int[])).ReflectionName, Is.EqualTo(typeof(int[]).FullName));
}
[Test]
- public void TestToTypeReferenceMultidimensionalArrayType()
+ public void TestFindTypeReflectionNameMultidimensionalArrayType()
{
Assert.That(compilation.FindType(typeof(int[,])).ReflectionName, Is.EqualTo(typeof(int[,]).FullName));
}
[Test]
- public void TestToTypeReferenceJaggedMultidimensionalArrayType()
+ public void TestFindTypeReflectionNameJaggedMultidimensionalArrayType()
{
Assert.That(compilation.FindType(typeof(int[,][,,])).ReflectionName, Is.EqualTo(typeof(int[,][,,]).FullName));
}
[Test]
- public void TestToTypeReferencePointerType()
+ public void TestFindTypeReflectionNamePointerType()
{
Assert.That(compilation.FindType(typeof(int*)).ReflectionName, Is.EqualTo(typeof(int*).FullName));
}
[Test]
- public void TestToTypeReferenceByReferenceType()
+ public void TestFindTypeReflectionNameByReferenceType()
{
Assert.That(compilation.FindType(typeof(int).MakeByRefType()).ReflectionName, Is.EqualTo(typeof(int).MakeByRefType().FullName));
}
- [Test]
- public void TestToTypeReferenceGenericType()
- {
- MethodInfo convertAllInfo = typeof(List<>).GetMethod("ConvertAll");
- ITypeReference parameterType = convertAllInfo.GetParameters()[0].ParameterType.ToTypeReference(); // Converter[[`0],[``0]]
- // cannot resolve generic types without knowing the parent entity:
- IType resolvedWithoutEntity = parameterType.Resolve(new SimpleTypeResolveContext(compilation));
- Assert.That(resolvedWithoutEntity.ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]"));
- Assert.That(((ITypeParameter)((ParameterizedType)resolvedWithoutEntity).GetTypeArgument(0)).Owner, Is.Null);
- // now try with parent entity:
- IMethod convertAll = compilation.FindType(typeof(List<>)).GetMethods(m => m.Name == "ConvertAll").Single();
- IType resolvedWithEntity = parameterType.Resolve(new SimpleTypeResolveContext(convertAll));
- Assert.That(resolvedWithEntity.ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]"));
- Assert.That(((ITypeParameter)((ParameterizedType)resolvedWithEntity).GetTypeArgument(0)).Owner, Is.SameAs(convertAll.DeclaringTypeDefinition));
- }
-
[Test]
public void ParseReflectionName()
{
@@ -204,21 +187,21 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void ParseInvalidReflectionName2()
{
var context = new SimpleTypeResolveContext(compilation.MainModule);
- Assert.Throws(() => ReflectionHelper.ParseReflectionName("`", context));
+ Assert.That(ReflectionHelper.ParseReflectionName("`", context).ReflectionName, Is.EqualTo("`"));
}
[Test]
public void ParseInvalidReflectionName3()
{
var context = new SimpleTypeResolveContext(compilation.MainModule);
- Assert.Throws(() => ReflectionHelper.ParseReflectionName("``", context));
+ Assert.That(ReflectionHelper.ParseReflectionName("``", context).ReflectionName, Is.EqualTo("``"));
}
[Test]
public void ParseInvalidReflectionName4()
{
var context = new SimpleTypeResolveContext(compilation.MainModule);
- Assert.Throws(() => ReflectionHelper.ParseReflectionName("System.Action`A", context));
+ Assert.That(ReflectionHelper.ParseReflectionName("System.Action`A", context).ReflectionName, Is.EqualTo("System.Action`A"));
}
[Test]
@@ -232,7 +215,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void ParseInvalidReflectionName5b()
{
var context = new SimpleTypeResolveContext(compilation.MainModule);
- Assert.Throws(() => ReflectionHelper.ParseReflectionName("System.Environment+`", context));
+ Assert.That(ReflectionHelper.ParseReflectionName("System.Environment+`", context).ReflectionName, Is.EqualTo("System.Environment+`"));
}
[Test]
@@ -246,7 +229,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public void ParseInvalidReflectionName7()
{
var context = new SimpleTypeResolveContext(compilation.MainModule);
- Assert.Throws(() => ReflectionHelper.ParseReflectionName("System.Int32[`]", context));
+ Assert.That(ReflectionHelper.ParseReflectionName("System.Int32[`]", context).ReflectionName, Is.EqualTo("System.Int32"));
}
[Test]
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/AstType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/AstType.cs
index a8b8da53a..35b419f86 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/AstType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/AstType.cs
@@ -16,12 +16,10 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-using System;
using System.Collections.Generic;
using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
-using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
@@ -60,11 +58,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
return other == null || other.IsNull;
}
-
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
- {
- return SpecialType.UnknownType;
- }
}
#endregion
@@ -102,11 +95,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return visitor.VisitPatternPlaceholder(this, child, data);
}
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
- {
- throw new NotSupportedException();
- }
-
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
@@ -137,34 +125,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return st != null && st.Identifier == "var" && st.TypeArguments.Count == 0;
}
- ///
- /// Create an ITypeReference for this AstType.
- /// Uses the context (ancestors of this node) to determine the correct .
- ///
- ///
- /// The resulting type reference will read the context information from the
- /// :
- /// For resolving type parameters, the CurrentTypeDefinition/CurrentMember is used.
- /// For resolving simple names, the current namespace and usings from the CurrentUsingScope
- /// (on CSharpTypeResolveContext only) is used.
- ///
- public ITypeReference ToTypeReference(InterningProvider interningProvider = null)
- {
- return ToTypeReference(GetNameLookupMode(), interningProvider);
- }
-
- ///
- /// Create an ITypeReference for this AstType.
- ///
- ///
- /// The resulting type reference will read the context information from the
- /// :
- /// For resolving type parameters, the CurrentTypeDefinition/CurrentMember is used.
- /// For resolving simple names, the current namespace and usings from the CurrentUsingScope
- /// (on CSharpTypeResolveContext only) is used.
- ///
- public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null);
-
///
/// Gets the name lookup mode from the context (looking at the ancestors of this ).
///
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs
index c042a2ca9..246183558 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs
@@ -29,8 +29,6 @@ using System.Linq;
using System.Text;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
-using ICSharpCode.Decompiler.CSharp.Resolver;
-using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
@@ -200,31 +198,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.HasRefSpecifier = true;
return this;
}
-
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
- {
- if (interningProvider == null)
- interningProvider = InterningProvider.Dummy;
- ITypeReference t = this.BaseType.ToTypeReference(lookupMode, interningProvider);
- if (this.HasNullableSpecifier)
- {
- t = interningProvider.Intern(NullableType.Create(t));
- }
- int pointerRank = this.PointerRank;
- for (int i = 0; i < pointerRank; i++)
- {
- t = interningProvider.Intern(new PointerTypeReference(t));
- }
- foreach (var a in this.ArraySpecifiers.Reverse())
- {
- t = interningProvider.Intern(new ArrayTypeReference(t, a.Dimensions));
- }
- if (this.HasRefSpecifier)
- {
- t = interningProvider.Intern(new ByReferenceTypeReference(t));
- }
- return t;
- }
}
///
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/FunctionPointerAstType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/FunctionPointerAstType.cs
index 96aee3ee9..b14d03466 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/FunctionPointerAstType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/FunctionPointerAstType.cs
@@ -24,11 +24,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-using System;
-
-using ICSharpCode.Decompiler.CSharp.Resolver;
-using ICSharpCode.Decompiler.TypeSystem;
-
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
public class FunctionPointerAstType : AstType
@@ -73,10 +68,5 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
&& this.Parameters.DoMatch(o.Parameters, match)
&& this.ReturnType.DoMatch(o.ReturnType, match);
}
-
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
- {
- throw new NotImplementedException();
- }
}
}
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/InvocationAstType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/InvocationAstType.cs
index 5dddbfb56..99f601609 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/InvocationAstType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/InvocationAstType.cs
@@ -16,13 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
-using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
@@ -61,10 +55,5 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
&& this.BaseType.DoMatch(o.BaseType, match)
&& this.Arguments.DoMatch(o.Arguments, match);
}
-
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
- {
- throw new NotImplementedException();
- }
}
}
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/MemberType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/MemberType.cs
index 00abace78..a479bfbb4 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/MemberType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/MemberType.cs
@@ -26,10 +26,6 @@
using System.Collections.Generic;
-using ICSharpCode.Decompiler.CSharp.Resolver;
-using ICSharpCode.Decompiler.CSharp.TypeSystem;
-using ICSharpCode.Decompiler.TypeSystem;
-
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
public class MemberType : AstType
@@ -119,39 +115,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
&& MatchString(this.MemberName, o.MemberName) && this.Target.DoMatch(o.Target, match)
&& this.TypeArguments.DoMatch(o.TypeArguments, match);
}
-
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
- {
- if (interningProvider == null)
- interningProvider = InterningProvider.Dummy;
-
- TypeOrNamespaceReference t;
- if (this.IsDoubleColon)
- {
- SimpleType st = this.Target as SimpleType;
- if (st != null)
- {
- t = interningProvider.Intern(new AliasNamespaceReference(interningProvider.Intern(st.Identifier)));
- }
- else
- {
- t = null;
- }
- }
- else
- {
- t = this.Target.ToTypeReference(lookupMode, interningProvider) as TypeOrNamespaceReference;
- }
- if (t == null)
- return SpecialType.UnknownType;
- var typeArguments = new List();
- foreach (var ta in this.TypeArguments)
- {
- typeArguments.Add(ta.ToTypeReference(lookupMode, interningProvider));
- }
- string memberName = interningProvider.Intern(this.MemberName);
- return interningProvider.Intern(new MemberTypeOrNamespaceReference(t, memberName, interningProvider.InternList(typeArguments), lookupMode));
- }
}
}
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/PrimitiveType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/PrimitiveType.cs
index a6f112542..d347e4421 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/PrimitiveType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/PrimitiveType.cs
@@ -27,9 +27,7 @@
using System;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
-using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.TypeSystem;
-using ICSharpCode.Decompiler.TypeSystem.Implementation;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
@@ -111,21 +109,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return Keyword;
}
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
- {
- KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(this.Keyword);
- if (typeCode == KnownTypeCode.None)
- {
- if (this.Keyword == "__arglist")
- return SpecialType.ArgList;
- return new UnknownType(null, this.Keyword);
- }
- else
- {
- return KnownTypeReference.Get(typeCode);
- }
- }
-
public static KnownTypeCode GetTypeCodeForPrimitiveType(string keyword)
{
switch (keyword)
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/SimpleType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/SimpleType.cs
index 17a19e345..013b7836c 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/SimpleType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/SimpleType.cs
@@ -26,10 +26,6 @@
using System.Collections.Generic;
-using ICSharpCode.Decompiler.CSharp.Resolver;
-using ICSharpCode.Decompiler.CSharp.TypeSystem;
-using ICSharpCode.Decompiler.TypeSystem;
-
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
public class SimpleType : AstType
@@ -64,11 +60,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
return other == null || other.IsNull;
}
-
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider)
- {
- return SpecialType.UnknownType;
- }
}
#endregion
@@ -146,25 +137,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
SimpleType o = other as SimpleType;
return o != null && MatchString(this.Identifier, o.Identifier) && this.TypeArguments.DoMatch(o.TypeArguments, match);
}
-
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
- {
- if (interningProvider == null)
- interningProvider = InterningProvider.Dummy;
- var typeArguments = new List();
- foreach (var ta in this.TypeArguments)
- {
- typeArguments.Add(ta.ToTypeReference(lookupMode, interningProvider));
- }
- string identifier = interningProvider.Intern(this.Identifier);
- if (typeArguments.Count == 0 && string.IsNullOrEmpty(identifier))
- {
- // empty SimpleType is used for typeof(List<>).
- return SpecialType.UnboundTypeArgument;
- }
- var t = new SimpleTypeOrNamespaceReference(identifier, interningProvider.InternList(typeArguments), lookupMode);
- return interningProvider.Intern(t);
- }
}
}
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TupleAstType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TupleAstType.cs
index 16f5cd4aa..4fdaf0361 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/TupleAstType.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/TupleAstType.cs
@@ -16,13 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-
-using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
-using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
@@ -49,14 +43,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return visitor.VisitTupleType(this, data);
}
- public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null)
- {
- return new TupleTypeReference(
- this.Elements.Select(e => e.Type.ToTypeReference(lookupMode, interningProvider)).ToImmutableArray(),
- this.Elements.Select(e => e.Name).ToImmutableArray()
- );
- }
-
protected internal override bool DoMatch(AstNode other, Match match)
{
return other is TupleAstType o && Elements.DoMatch(o.Elements, match);
diff --git a/ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs b/ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs
index 407bb98b5..de3416191 100644
--- a/ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs
@@ -18,6 +18,8 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection.Metadata;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
@@ -29,31 +31,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
public static class ReflectionHelper
{
- ///
- /// A reflection class used to represent null.
- ///
- public sealed class Null { }
-
- ///
- /// A reflection class used to represent dynamic.
- ///
- public sealed class Dynamic { }
-
- ///
- /// A reflection class used to represent nint.
- ///
- public sealed class NInt { }
-
- ///
- /// A reflection class used to represent nuint.
- ///
- public sealed class NUInt { }
-
- ///
- /// A reflection class used to represent an unbound type argument.
- ///
- public sealed class UnboundTypeArgument { }
-
#region ICompilation.FindType
///
/// Retrieves the specified type in this compilation.
@@ -65,7 +42,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
public static IType FindType(this ICompilation compilation, Type type)
{
- return type.ToTypeReference().Resolve(new SimpleTypeResolveContext(compilation));
+ return ParseReflectionName(type.AssemblyQualifiedName, new SimpleTypeResolveContext(compilation));
}
public static IType FindType(this ICompilation compilation, StackType stackType, Sign sign = Sign.None)
@@ -82,88 +59,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
#endregion
- #region Type.ToTypeReference()
- ///
- /// Creates a reference to the specified type.
- ///
- /// The type to be converted.
- /// Returns the type reference.
- ///
- /// If the type is open (contains type parameters '`0' or '``0'),
- /// an with the appropriate CurrentTypeDefinition/CurrentMember is required
- /// to resolve the type reference.
- /// For closed types, the root type resolve context for the compilation is sufficient.
- ///
- public static ITypeReference ToTypeReference(this Type type)
- {
- if (type == null)
- return SpecialType.UnknownType;
- if (type.IsGenericType && !type.IsGenericTypeDefinition)
- {
- ITypeReference def = ToTypeReference(type.GetGenericTypeDefinition());
- Type[] arguments = type.GetGenericArguments();
- ITypeReference[] args = new ITypeReference[arguments.Length];
- bool allUnbound = true;
- for (int i = 0; i < arguments.Length; i++)
- {
- args[i] = ToTypeReference(arguments[i]);
- allUnbound &= args[i].Equals(SpecialType.UnboundTypeArgument);
- }
- if (allUnbound)
- return def;
- else
- return new ParameterizedTypeReference(def, args);
- }
- else if (type.IsArray)
- {
- return new ArrayTypeReference(ToTypeReference(type.GetElementType()), type.GetArrayRank());
- }
- else if (type.IsPointer)
- {
- return new PointerTypeReference(ToTypeReference(type.GetElementType()));
- }
- else if (type.IsByRef)
- {
- return new ByReferenceTypeReference(ToTypeReference(type.GetElementType()));
- }
- else if (type.IsGenericParameter)
- {
- if (type.DeclaringMethod != null)
- {
- return TypeParameterReference.Create(SymbolKind.Method, type.GenericParameterPosition);
- }
- else
- {
- return TypeParameterReference.Create(SymbolKind.TypeDefinition, type.GenericParameterPosition);
- }
- }
- else if (type.DeclaringType != null)
- {
- if (type == typeof(Dynamic))
- return SpecialType.Dynamic;
- else if (type == typeof(NInt))
- return SpecialType.NInt;
- else if (type == typeof(NUInt))
- return SpecialType.NUInt;
- else if (type == typeof(Null))
- return SpecialType.NullType;
- else if (type == typeof(UnboundTypeArgument))
- return SpecialType.UnboundTypeArgument;
- ITypeReference baseTypeRef = ToTypeReference(type.DeclaringType);
- int typeParameterCount;
- string name = SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
- return new NestedTypeReference(baseTypeRef, name, typeParameterCount);
- }
- else
- {
- IModuleReference assemblyReference = new DefaultAssemblyReference(type.Assembly.FullName);
- int typeParameterCount;
- string name = SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
- return new GetClassTypeReference(assemblyReference, type.Namespace, name, typeParameterCount);
- }
- }
- #endregion
-
#region SplitTypeParameterCountFromReflectionName
///
/// Removes the ` with type parameter count from the reflection name.
@@ -214,16 +109,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
return compilation.FindType((KnownTypeCode)typeCode);
}
- ///
- /// Creates a reference to the specified type.
- ///
- /// The type to be converted.
- /// Returns the type reference.
- public static ITypeReference ToTypeReference(this TypeCode typeCode)
- {
- return KnownTypeReference.Get((KnownTypeCode)typeCode);
- }
-
///
/// Gets the type code for the specified type, or TypeCode.Empty if none of the other type codes match.
///
@@ -264,11 +149,112 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
if (reflectionTypeName == null)
throw new ArgumentNullException(nameof(reflectionTypeName));
- int pos = 0;
- IType r = ParseReflectionName(reflectionTypeName, ref pos).Resolve(resolveContext);
- if (pos < reflectionTypeName.Length)
- throw new ReflectionNameParseException(pos, "Expected end of type name");
- return r;
+ if (!TypeName.TryParse(reflectionTypeName.AsSpan(), out var result))
+ {
+ throw new ReflectionNameParseException(0, "Invalid type name: " + reflectionTypeName);
+ }
+ return ResolveTypeName(result, resolveContext);
+ }
+
+ private static IType ResolveTypeName(TypeName result, ITypeResolveContext resolveContext)
+ {
+ if (result.IsArray)
+ {
+ return new ArrayType(
+ resolveContext.Compilation,
+ ResolveTypeName(result.GetElementType(), resolveContext),
+ result.GetArrayRank()
+ );
+ }
+ else if (result.IsByRef)
+ {
+ return new ByReferenceType(
+ ResolveTypeName(result.GetElementType(), resolveContext)
+ );
+ }
+ else if (result.IsConstructedGenericType)
+ {
+ IType genericType = ResolveTypeName(result.GetGenericTypeDefinition(), resolveContext);
+ var genericArgs = result.GetGenericArguments();
+ if (genericType.TypeParameterCount == 0)
+ {
+ return genericType;
+ }
+
+ IType[] resolvedTypes = new IType[genericType.TypeParameterCount];
+ for (int i = 0; i < genericArgs.Length; i++)
+ {
+ if (i < genericArgs.Length)
+ resolvedTypes[i] = ResolveTypeName(genericArgs[i], resolveContext);
+ else
+ resolvedTypes[i] = SpecialType.UnknownType;
+ }
+ return new ParameterizedType(genericType, resolvedTypes);
+ }
+ else if (result.IsNested)
+ {
+ var declaringType = ResolveTypeName(result.DeclaringType, resolveContext).GetDefinition();
+ var plainName = SplitTypeParameterCountFromReflectionName(result.Name, out int tpc);
+ if (declaringType != null)
+ {
+ foreach (var type in declaringType.NestedTypes)
+ {
+ if (type.Name == plainName && type.TypeParameterCount == tpc + declaringType.TypeParameterCount)
+ return type;
+ }
+ }
+ return new UnknownType(new FullTypeName(result.FullName));
+ }
+ else if (result.IsPointer)
+ {
+ return new PointerType(
+ ResolveTypeName(result.GetElementType(), resolveContext)
+ );
+ }
+ else
+ {
+ Debug.Assert(result.IsSimple);
+ if (result.FullName.Length > 1 && result.FullName[0] == '`')
+ {
+ if (result.FullName.Length > 2 && result.FullName[1] == '`')
+ {
+ if (int.TryParse(result.FullName.Substring(2), out int index))
+ {
+ if (resolveContext.CurrentMember is IMethod m && index < m.TypeParameters.Count)
+ {
+ return m.TypeParameters[index];
+ }
+ return DummyTypeParameter.GetMethodTypeParameter(index);
+ }
+ }
+ else if (int.TryParse(result.FullName.Substring(1), out int index))
+ {
+ if (resolveContext.CurrentTypeDefinition != null && index < resolveContext.CurrentTypeDefinition.TypeParameterCount)
+ {
+ return resolveContext.CurrentTypeDefinition.TypeParameters[index];
+ }
+ return DummyTypeParameter.GetClassTypeParameter(index);
+ }
+ }
+ var topLevelTypeName = new TopLevelTypeName(result.FullName);
+ if (result.AssemblyName != null)
+ {
+ var module = resolveContext.Compilation.FindModuleByAssemblyNameInfo(result.AssemblyName);
+ if (module != null)
+ {
+ return (IType)module.GetTypeDefinition(topLevelTypeName) ?? new UnknownType(topLevelTypeName);
+ }
+ }
+
+ foreach (var module in resolveContext.Compilation.Modules)
+ {
+ var type = module.GetTypeDefinition(topLevelTypeName);
+ if (type != null)
+ return type;
+ }
+
+ return new UnknownType(topLevelTypeName);
+ }
}
static bool IsReflectionNameSpecialCharacter(char c)
diff --git a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
index c983e354b..1a4b11501 100644
--- a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection.Metadata;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Semantics;
@@ -814,6 +815,25 @@ namespace ICSharpCode.Decompiler.TypeSystem
return null;
}
+ public static IModule FindModuleByAssemblyNameInfo(this ICompilation compilation, AssemblyNameInfo assemblyName)
+ {
+ foreach (var module in compilation.Modules)
+ {
+ if (string.Equals(module.FullAssemblyName, assemblyName.FullName, StringComparison.OrdinalIgnoreCase))
+ {
+ return module;
+ }
+ }
+ foreach (var module in compilation.Modules)
+ {
+ if (string.Equals(module.Name, assemblyName.Name, StringComparison.OrdinalIgnoreCase))
+ {
+ return module;
+ }
+ }
+ return null;
+ }
+
///
/// When given a generic type definition, returns the self-parameterized type
/// (i.e. the type of "this" within the type definition).