mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
MergeSimilarTypes: add support for more kinds of types
This commit is contained in:
@@ -23,6 +23,7 @@ using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
using ICSharpCode.Decompiler.CSharp.Resolver;
|
||||
using ICSharpCode.Decompiler.Metadata;
|
||||
@@ -713,6 +714,15 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
|
||||
ImmutableArray.CreateRange(elementNames));
|
||||
}
|
||||
|
||||
FunctionPointerType MakeFunctionPointerType(ICompilation comp, IType returnType)
|
||||
{
|
||||
return new FunctionPointerType(
|
||||
(MetadataModule)comp.MainModule,
|
||||
SignatureCallingConvention.Default, ImmutableArray<IType>.Empty,
|
||||
returnType, returnIsRefReadOnly: false,
|
||||
ImmutableArray<IType>.Empty, ImmutableArray<ReferenceKind>.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BestCommonTypeMergesTupleElementNames()
|
||||
{
|
||||
@@ -730,6 +740,21 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
|
||||
Assert.That(success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BestCommonTypeMergesFunctionPointerTupleElementNames()
|
||||
{
|
||||
var comp = RefAssemblyCompilation.Instance;
|
||||
var inference = new TypeInference(comp);
|
||||
|
||||
Assert.That(
|
||||
inference.GetBestCommonType(new[] {
|
||||
new ResolveResult(MakeFunctionPointerType(comp, MakeTupleType(comp, "a", "b"))),
|
||||
new ResolveResult(MakeFunctionPointerType(comp, MakeTupleType(comp, "a", "c")))
|
||||
}, out bool success),
|
||||
Is.EqualTo(MakeFunctionPointerType(comp, MakeTupleType(comp, "a", null))));
|
||||
Assert.That(success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FixingMergesTupleElementNamesOfExactAndLowerBounds()
|
||||
{
|
||||
|
||||
@@ -1101,6 +1101,15 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
|
||||
var nullability = MergeNullability(arrA.Nullability, arrB.Nullability, variance);
|
||||
return new ArrayType(arrA.Compilation, mergedElem, arrA.Dimensions, nullability);
|
||||
}
|
||||
if (a is ByReferenceType refA && b is ByReferenceType refB)
|
||||
{
|
||||
var mergedElem = MergeSimilarTypes(
|
||||
refA.ElementType, refB.ElementType,
|
||||
variance.Combine(VarianceModifier.Invariant));
|
||||
if (mergedElem == null)
|
||||
return null;
|
||||
return new ByReferenceType(mergedElem);
|
||||
}
|
||||
if (a is PointerType ptrA && b is PointerType ptrB)
|
||||
{
|
||||
var mergedElem = MergeSimilarTypes(
|
||||
@@ -1110,6 +1119,47 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
|
||||
return null;
|
||||
return new PointerType(mergedElem);
|
||||
}
|
||||
if (a is FunctionPointerType fnPtrA && b is FunctionPointerType fnPtrB
|
||||
&& fnPtrA.CallingConvention == fnPtrB.CallingConvention
|
||||
&& fnPtrA.CustomCallingConventions.SequenceEqual(fnPtrB.CustomCallingConventions)
|
||||
&& fnPtrA.ReturnIsRefReadOnly == fnPtrB.ReturnIsRefReadOnly
|
||||
&& fnPtrA.ParameterTypes.Length == fnPtrB.ParameterTypes.Length
|
||||
&& fnPtrA.ParameterReferenceKinds.SequenceEqual(fnPtrB.ParameterReferenceKinds))
|
||||
{
|
||||
var mergedReturn = MergeSimilarTypes(
|
||||
fnPtrA.ReturnType, fnPtrB.ReturnType,
|
||||
variance.Combine(VarianceModifier.Covariant));
|
||||
if (mergedReturn == null)
|
||||
return null;
|
||||
var mergedParameters = ImmutableArray.CreateBuilder<IType>(fnPtrA.ParameterTypes.Length);
|
||||
for (int i = 0; i < fnPtrA.ParameterTypes.Length; i++)
|
||||
{
|
||||
var mergedParameter = MergeSimilarTypes(
|
||||
fnPtrA.ParameterTypes[i], fnPtrB.ParameterTypes[i],
|
||||
variance.Combine(VarianceModifier.Contravariant));
|
||||
if (mergedParameter == null)
|
||||
return null;
|
||||
mergedParameters.Add(mergedParameter);
|
||||
}
|
||||
return fnPtrA.WithSignature(mergedReturn, mergedParameters.MoveToImmutable());
|
||||
}
|
||||
if (a is ModifiedType modA && b is ModifiedType modB
|
||||
&& modA.Kind == modB.Kind
|
||||
&& modA.Modifier.Equals(modB.Modifier))
|
||||
{
|
||||
var mergedElem = MergeSimilarTypes(modA.ElementType, modB.ElementType, variance);
|
||||
if (mergedElem == null)
|
||||
return null;
|
||||
return new ModifiedType(modA.Modifier, mergedElem, modA.Kind == TypeKind.ModReq);
|
||||
}
|
||||
if (a is UnknownType unknownTypeA && b is UnknownType unknownTypeB
|
||||
&& unknownTypeA.FullTypeName == unknownTypeB.FullTypeName)
|
||||
{
|
||||
if (unknownTypeA.IsReferenceType == unknownTypeB.IsReferenceType)
|
||||
return unknownTypeA;
|
||||
else
|
||||
return unknownTypeA.WithoutReferenceTypeKnowledge();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user