Browse Source

Fix some type system bugs.

pull/1030/head
Daniel Grunwald 7 years ago
parent
commit
c54632e7cb
  1. 3
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 11
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs
  3. 18
      ICSharpCode.Decompiler/IL/ILReader.cs
  4. 2
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  5. 11
      ICSharpCode.Decompiler/TypeSystem/GenericContext.cs

3
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1005,10 +1005,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1005,10 +1005,9 @@ namespace ICSharpCode.Decompiler.CSharp
UseDebugSymbols = settings.UseDebugSymbols,
DebugInfo = DebugInfoProvider
};
var genericContext = new Decompiler.TypeSystem.GenericContext(decompilationContext);
var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
var methodBody = typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, methodBody, genericContext, CancellationToken);
var function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, methodBody, cancellationToken: CancellationToken);
function.CheckInvariant(ILPhase.Normal);
if (entityDecl != null) {

11
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

@ -117,21 +117,14 @@ namespace ICSharpCode.Decompiler.CSharp @@ -117,21 +117,14 @@ namespace ICSharpCode.Decompiler.CSharp
static void CollectNamespacesForTypeReference(IType type, HashSet<string> namespaces)
{
switch (type) {
case ArrayType arrayType:
namespaces.Add(arrayType.Namespace);
CollectNamespacesForTypeReference(arrayType.ElementType, namespaces);
break;
case ParameterizedType parameterizedType:
namespaces.Add(parameterizedType.Namespace);
CollectNamespacesForTypeReference(parameterizedType.GenericType, namespaces);
foreach (var arg in parameterizedType.TypeArguments)
CollectNamespacesForTypeReference(arg, namespaces);
break;
case ByReferenceType byReferenceType:
CollectNamespacesForTypeReference(byReferenceType.ElementType, namespaces);
break;
case PointerType pointerType:
CollectNamespacesForTypeReference(pointerType.ElementType, namespaces);
case TypeWithElementType typeWithElementType:
CollectNamespacesForTypeReference(typeWithElementType.ElementType, namespaces);
break;
case TupleType tupleType:
foreach (var elementType in tupleType.ElementTypes) {

18
ICSharpCode.Decompiler/IL/ILReader.cs

@ -92,13 +92,11 @@ namespace ICSharpCode.Decompiler.IL @@ -92,13 +92,11 @@ namespace ICSharpCode.Decompiler.IL
throw new ArgumentException("methodDefinitionHandle.IsNil");
this.method = module.GetDefinition(methodDefinitionHandle);
if (genericContext.ClassTypeParameters == null && genericContext.MethodTypeParameters == null) {
if (method.DeclaringType.TypeParameterCount > 0 || method.TypeParameters.Count > 0) {
// no generic context specified, but it's a generic method: use the method's own type parameters
genericContext = new GenericContext(method);
}
// no generic context specified: use the method's own type parameters
genericContext = new GenericContext(method);
} else {
// generic context specified, so specialize the method for it:
this.method = this.method.Specialize(new TypeParameterSubstitution(genericContext.ClassTypeParameters, genericContext.MethodTypeParameters));
this.method = this.method.Specialize(genericContext.ToSubstitution());
}
this.genericContext = genericContext;
var methodDefinition = metadata.GetMethodDefinition(methodDefinitionHandle);
@ -177,7 +175,13 @@ namespace ICSharpCode.Decompiler.IL @@ -177,7 +175,13 @@ namespace ICSharpCode.Decompiler.IL
int offset = 0;
if (!method.IsStatic) {
offset = 1;
parameterVariables[paramIndex++] = CreateILVariable(-1, method.DeclaringType, "this");
IType declaringType = method.DeclaringType;
if (declaringType.IsUnbound()) {
// If method is a definition (and not specialized), the declaring type is also just a definition,
// and needs to be converted into a normally usable type.
declaringType = new ParameterizedType(declaringType, declaringType.TypeParameters);
}
parameterVariables[paramIndex++] = CreateILVariable(-1, declaringType, "this");
}
while (paramIndex < parameterVariables.Length) {
IType type = method.Parameters[paramIndex - offset].Type;
@ -480,7 +484,7 @@ namespace ICSharpCode.Decompiler.IL @@ -480,7 +484,7 @@ namespace ICSharpCode.Decompiler.IL
ReadInstructions(cancellationToken);
var blockBuilder = new BlockBuilder(body, variableByExceptionHandler);
blockBuilder.CreateBlocks(mainContainer, instructionBuilder, isBranchTarget, cancellationToken);
var function = new ILFunction(this.method, body.GetCodeSize(), genericContext, mainContainer);
var function = new ILFunction(this.method, body.GetCodeSize(), this.genericContext, mainContainer);
CollectionExtensions.AddRange(function.Variables, parameterVariables);
CollectionExtensions.AddRange(function.Variables, localVariables);
CollectionExtensions.AddRange(function.Variables, stackVariables);

2
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -140,7 +140,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -140,7 +140,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (subst.MethodTypeArguments != null) {
foreach (var t in subst.MethodTypeArguments) {
if (t is ITypeParameter tp)
classTypeParameters.Add(tp);
methodTypeParameters.Add(tp);
else
return null;
}

11
ICSharpCode.Decompiler/TypeSystem/GenericContext.cs

@ -16,6 +16,7 @@ @@ -16,6 +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 ICSharpCode.Decompiler.TypeSystem.Implementation;
@ -70,5 +71,15 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -70,5 +71,15 @@ namespace ICSharpCode.Decompiler.TypeSystem
else
return DummyTypeParameter.GetMethodTypeParameter(index);
}
internal TypeParameterSubstitution ToSubstitution()
{
// The TS prefers 'null' over empty lists in substitutions, and we need our substitution
// to compare equal to the ones created by the TS.
return new TypeParameterSubstitution(
classTypeArguments: ClassTypeParameters?.Count > 0 ? ClassTypeParameters : null,
methodTypeArguments: MethodTypeParameters?.Count > 0 ? MethodTypeParameters : null
);
}
}
}

Loading…
Cancel
Save