Browse Source

Merge IDecompilerTypeSystem with ICompilation.

pull/1030/head
Daniel Grunwald 7 years ago
parent
commit
b396d203bd
  1. 2
      ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs
  2. 3
      ICSharpCode.Decompiler.Tests/Util/SequencePointTests.cs
  3. 12
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  4. 2
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  5. 4
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs
  6. 2
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs
  7. 2
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  8. 4
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  9. 2
      ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs
  10. 2
      ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs
  11. 2
      ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs
  12. 4
      ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs
  13. 2
      ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs
  14. 20
      ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs
  15. 78
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  16. 9
      ICSharpCode.Decompiler/TypeSystem/ICompilation.cs
  17. 9
      ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs
  18. 42
      ICSharpCode.Decompiler/TypeSystem/Implementation/SimpleCompilation.cs
  19. 2
      ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs
  20. 6
      ILSpy.BamlDecompiler/CecilTypeResolver.cs
  21. 2
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

2
ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs

@ -1811,7 +1811,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
var compilationWithSystemCore = new SimpleCompilation(SystemCore, Mscorlib); var compilationWithSystemCore = new SimpleCompilation(SystemCore, Mscorlib);
var typeRef = ReflectionHelper.ParseReflectionName("System.Func`2, System.Core"); var typeRef = ReflectionHelper.ParseReflectionName("System.Func`2, System.Core");
ITypeDefinition c = typeRef.Resolve(compilationWithSystemCore.TypeResolveContext).GetDefinition(); ITypeDefinition c = typeRef.Resolve(new SimpleTypeResolveContext(compilationWithSystemCore)).GetDefinition();
Assert.IsNotNull(c, "System.Func<,> not found"); Assert.IsNotNull(c, "System.Func<,> not found");
Assert.AreEqual("mscorlib", c.ParentModule.AssemblyName); Assert.AreEqual("mscorlib", c.ParentModule.AssemblyName);
} }

3
ICSharpCode.Decompiler.Tests/Util/SequencePointTests.cs

@ -24,8 +24,7 @@ namespace ICSharpCode.Decompiler.Tests.Util
{ {
var decompiler = Tester.GetDecompilerForSnippet(code); var decompiler = Tester.GetDecompilerForSnippet(code);
var firstType = decompiler.TypeSystem.Compilation.GetTopLevelTypeDefinitions().First(t => code.Contains(t.Name)); var tree = decompiler.DecompileType(new FullTypeName("C"));
var tree = decompiler.DecompileType(firstType.FullTypeName);
var output = new StringWriter(); var output = new StringWriter();
tree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); tree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });

12
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -397,13 +397,13 @@ namespace ICSharpCode.Decompiler.CSharp
void DoDecompileModuleAndAssemblyAttributes(DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree) void DoDecompileModuleAndAssemblyAttributes(DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree)
{ {
foreach (var a in typeSystem.Compilation.MainModule.GetAssemblyAttributes()) { foreach (var a in typeSystem.MainModule.GetAssemblyAttributes()) {
var astBuilder = CreateAstBuilder(decompilationContext); var astBuilder = CreateAstBuilder(decompilationContext);
var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a)); var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
attrSection.AttributeTarget = "assembly"; attrSection.AttributeTarget = "assembly";
syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole); syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole);
} }
foreach (var a in typeSystem.Compilation.MainModule.GetModuleAttributes()) { foreach (var a in typeSystem.MainModule.GetModuleAttributes()) {
var astBuilder = CreateAstBuilder(decompilationContext); var astBuilder = CreateAstBuilder(decompilationContext);
var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a)); var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
attrSection.AttributeTarget = "module"; attrSection.AttributeTarget = "module";
@ -603,7 +603,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// </remarks> /// </remarks>
public SyntaxTree DecompileType(FullTypeName fullTypeName) public SyntaxTree DecompileType(FullTypeName fullTypeName)
{ {
var type = typeSystem.Compilation.FindType(fullTypeName.TopLevelTypeName).GetDefinition(); var type = typeSystem.FindType(fullTypeName.TopLevelTypeName).GetDefinition();
if (type == null) if (type == null)
throw new InvalidOperationException($"Could not find type definition {fullTypeName} in type system."); throw new InvalidOperationException($"Could not find type definition {fullTypeName} in type system.");
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule); var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);
@ -933,12 +933,12 @@ namespace ICSharpCode.Decompiler.CSharp
MethodDeclaration method = new MethodDeclaration(); MethodDeclaration method = new MethodDeclaration();
method.Name = name; method.Name = name;
method.Modifiers = Modifiers.Private | Modifiers.Static; method.Modifiers = Modifiers.Private | Modifiers.Static;
method.Parameters.Add(new ParameterDeclaration(typeSystemAstBuilder.ConvertType(typeSystem.Compilation.FindType(source)), "input")); method.Parameters.Add(new ParameterDeclaration(typeSystemAstBuilder.ConvertType(typeSystem.FindType(source)), "input"));
method.ReturnType = typeSystemAstBuilder.ConvertType(typeSystem.Compilation.FindType(target)); method.ReturnType = typeSystemAstBuilder.ConvertType(typeSystem.FindType(target));
method.Body = new BlockStatement { method.Body = new BlockStatement {
new IfElseStatement { new IfElseStatement {
Condition = new BinaryOperatorExpression { Condition = new BinaryOperatorExpression {
Left = new MemberReferenceExpression(new TypeReferenceExpression(typeSystemAstBuilder.ConvertType(typeSystem.Compilation.FindType(KnownTypeCode.IntPtr))), "Size"), Left = new MemberReferenceExpression(new TypeReferenceExpression(typeSystemAstBuilder.ConvertType(typeSystem.FindType(KnownTypeCode.IntPtr))), "Size"),
Operator = BinaryOperatorType.Equality, Operator = BinaryOperatorType.Equality,
Right = new PrimitiveExpression(4) Right = new PrimitiveExpression(4)
}, },

2
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -290,7 +290,7 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override Statement VisitYieldReturn(YieldReturn inst) protected internal override Statement VisitYieldReturn(YieldReturn inst)
{ {
var elementType = currentFunction.ReturnType.GetElementTypeFromIEnumerable(typeSystem.Compilation, true, out var isGeneric); var elementType = currentFunction.ReturnType.GetElementTypeFromIEnumerable(typeSystem, true, out var isGeneric);
return new YieldReturnStatement { return new YieldReturnStatement {
Expression = exprBuilder.Translate(inst.Value, typeHint: elementType).ConvertTo(elementType, exprBuilder) Expression = exprBuilder.Translate(inst.Value, typeHint: elementType).ConvertTo(elementType, exprBuilder)
}; };

4
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public void Run(AstNode rootNode, TransformContext context) public void Run(AstNode rootNode, TransformContext context)
{ {
this.context = context; this.context = context;
this.conversions = CSharpConversions.Get(context.TypeSystem.Compilation); this.conversions = CSharpConversions.Get(context.TypeSystem);
InitializeContext(rootNode.Annotation<UsingScope>()); InitializeContext(rootNode.Annotation<UsingScope>());
rootNode.AcceptVisitor(this); rootNode.AcceptVisitor(this);
} }
@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
usingScope = new UsingScope(usingScope, ns); usingScope = new UsingScope(usingScope, ns);
} }
} }
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem.Compilation), context.DecompiledTypeDefinition); var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.DecompiledTypeDefinition);
this.resolveContextStack.Push(currentContext); this.resolveContextStack.Push(currentContext);
this.resolver = new CSharpResolver(currentContext); this.resolver = new CSharpResolver(currentContext);
} }

2
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs

@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
usingScope = new UsingScope(usingScope, ns); usingScope = new UsingScope(usingScope, ns);
} }
} }
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem.Compilation), context.DecompiledTypeDefinition); var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.DecompiledTypeDefinition);
this.context.Push(currentContext); this.context.Push(currentContext);
this.astBuilder = CreateAstBuilder(currentContext); this.astBuilder = CreateAstBuilder(currentContext);
} }

2
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -75,7 +75,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
sequencePointBlobs.Add(method, (default, default)); sequencePointBlobs.Add(method, (default, default));
else else
sequencePointBlobs.Add(method, (document, EncodeSequencePoints(metadata, localSignatureRowId, points))); sequencePointBlobs.Add(method, (document, EncodeSequencePoints(metadata, localSignatureRowId, points)));
importScopeBlobs.Add(method, (document, EncodeImportScope(metadata, reader, ast, decompiler.TypeSystem.Compilation))); importScopeBlobs.Add(method, (document, EncodeImportScope(metadata, reader, ast, decompiler.TypeSystem)));
} }
foreach (var nestedTypeHandle in type.GetNestedTypes()) { foreach (var nestedTypeHandle in type.GetNestedTypes()) {

4
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -197,12 +197,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return false; return false;
} else if (taskType.IsKnownType(KnownTypeCode.Task)) { } else if (taskType.IsKnownType(KnownTypeCode.Task)) {
methodType = AsyncMethodType.Task; methodType = AsyncMethodType.Task;
underlyingReturnType = context.TypeSystem.Compilation.FindType(KnownTypeCode.Void); underlyingReturnType = context.TypeSystem.FindType(KnownTypeCode.Void);
if (builderType?.FullTypeName != new TopLevelTypeName(ns, "AsyncTaskMethodBuilder", 0)) if (builderType?.FullTypeName != new TopLevelTypeName(ns, "AsyncTaskMethodBuilder", 0))
return false; return false;
} else if (taskType.IsKnownType(KnownTypeCode.TaskOfT)) { } else if (taskType.IsKnownType(KnownTypeCode.TaskOfT)) {
methodType = AsyncMethodType.TaskOfT; methodType = AsyncMethodType.TaskOfT;
underlyingReturnType = TaskType.UnpackTask(context.TypeSystem.Compilation, taskType); underlyingReturnType = TaskType.UnpackTask(context.TypeSystem, taskType);
if (builderType?.FullTypeName != new TopLevelTypeName(ns, "AsyncTaskMethodBuilder", 1)) if (builderType?.FullTypeName != new TopLevelTypeName(ns, "AsyncTaskMethodBuilder", 1))
return false; return false;
} else { } else {

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

@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Children.Count]; ILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Children.Count];
for (int j = 0; j < uninlinedArgs.Length; j++) { for (int j = 0; j < uninlinedArgs.Length; j++) {
var arg = copiedExpr.Children[j]; var arg = copiedExpr.Children[j];
var type = context.TypeSystem.Compilation.FindType(arg.ResultType.ToKnownTypeCode()); var type = context.TypeSystem.FindType(arg.ResultType.ToKnownTypeCode());
uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType, arg.ILRange.Start) { uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType, arg.ILRange.Start) {
Name = "C_" + arg.ILRange.Start Name = "C_" + arg.ILRange.Start
}; };

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

@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public Metadata.PEFile PEFile => TypeSystem.MainModule.PEFile; public Metadata.PEFile PEFile => TypeSystem.MainModule.PEFile;
internal DecompileRun DecompileRun { get; set; } internal DecompileRun DecompileRun { get; set; }
internal ResolvedUsingScope UsingScope => DecompileRun.UsingScope.Resolve(TypeSystem.Compilation); internal ResolvedUsingScope UsingScope => DecompileRun.UsingScope.Resolve(TypeSystem);
public ILTransformContext(ILFunction function, IDecompilerTypeSystem typeSystem, IDebugInfoProvider debugInfo, DecompilerSettings settings = null) public ILTransformContext(ILFunction function, IDecompilerTypeSystem typeSystem, IDebugInfoProvider debugInfo, DecompilerSettings settings = null)
{ {

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

@ -260,7 +260,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
return CSharp.Transforms.IntroduceExtensionMethods.CanTransformToExtensionMethodCall( return CSharp.Transforms.IntroduceExtensionMethods.CanTransformToExtensionMethodCall(
call.Method, new CSharp.TypeSystem.CSharpTypeResolveContext( call.Method, new CSharp.TypeSystem.CSharpTypeResolveContext(
context.TypeSystem.Compilation.MainModule, context.UsingScope context.TypeSystem.MainModule, context.UsingScope
) )
); );
} }

4
ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

@ -542,7 +542,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
bool isNullCoalescingWithNonNullableFallback = false; bool isNullCoalescingWithNonNullableFallback = false;
if (!MatchNullableCtor(trueInst, out var utype, out var exprToLift)) { if (!MatchNullableCtor(trueInst, out var utype, out var exprToLift)) {
isNullCoalescingWithNonNullableFallback = true; isNullCoalescingWithNonNullableFallback = true;
utype = context.TypeSystem.Compilation.FindType(trueInst.ResultType.ToKnownTypeCode()); utype = context.TypeSystem.FindType(trueInst.ResultType.ToKnownTypeCode());
exprToLift = trueInst; exprToLift = trueInst;
if (nullableVars.Count == 1 && exprToLift.MatchLdLoc(nullableVars[0])) { if (nullableVars.Count == 1 && exprToLift.MatchLdLoc(nullableVars[0])) {
// v.HasValue ? ldloc v : fallback // v.HasValue ? ldloc v : fallback
@ -779,7 +779,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (underlyingType == SpecialType.UnknownType) if (underlyingType == SpecialType.UnknownType)
return inst; return inst;
var nullable = context.TypeSystem.Compilation.FindType(KnownTypeCode.NullableOfT).GetDefinition(); var nullable = context.TypeSystem.FindType(KnownTypeCode.NullableOfT).GetDefinition();
var ctor = nullable?.Methods.FirstOrDefault(m => m.IsConstructor && m.Parameters.Count == 1); var ctor = nullable?.Methods.FirstOrDefault(m => m.IsConstructor && m.Parameters.Count == 1);
if (ctor != null) { if (ctor != null) {
ctor = ctor.Specialize(new TypeParameterSubstitution(new[] { underlyingType }, null)); ctor = ctor.Specialize(new TypeParameterSubstitution(new[] { underlyingType }, null));

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

@ -178,7 +178,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
possibleIndexVariables.Add(stloc.Variable, (stloc.ChildIndex, stloc.Value)); possibleIndexVariables.Add(stloc.Variable, (stloc.ChildIndex, stloc.Value));
return true; return true;
} }
var resolveContext = new CSharpTypeResolveContext(context.TypeSystem.Compilation.MainModule, context.UsingScope); var resolveContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, context.UsingScope);
(var kind, var newPath, var values, var targetVariable) = AccessPathElement.GetAccessPath(instructions[pos], rootType, context.Settings, resolveContext, possibleIndexVariables); (var kind, var newPath, var values, var targetVariable) = AccessPathElement.GetAccessPath(instructions[pos], rootType, context.Settings, resolveContext, possibleIndexVariables);
if (kind == AccessPathKind.Invalid || target != targetVariable) if (kind == AccessPathKind.Invalid || target != targetVariable)
return false; return false;

20
ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

@ -98,8 +98,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (!context.Settings.ExpressionTrees) return; if (!context.Settings.ExpressionTrees) return;
this.context = context; this.context = context;
this.conversions = CSharpConversions.Get(context.TypeSystem.Compilation); this.conversions = CSharpConversions.Get(context.TypeSystem);
this.resolver = new CSharpResolver(context.TypeSystem.Compilation); this.resolver = new CSharpResolver(context.TypeSystem);
this.parameters = new Dictionary<ILVariable, (IType, string)>(); this.parameters = new Dictionary<ILVariable, (IType, string)>();
this.parameterMapping = new Dictionary<ILVariable, ILVariable>(); this.parameterMapping = new Dictionary<ILVariable, ILVariable>();
this.instructionsToRemove = new List<ILInstruction>(); this.instructionsToRemove = new List<ILInstruction>();
@ -377,7 +377,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var (converted, arrayType) = ConvertInstruction(invocation.Arguments[0]); var (converted, arrayType) = ConvertInstruction(invocation.Arguments[0]);
if (converted == null) if (converted == null)
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
return (new LdLen(StackType.I4, converted), context.TypeSystem.Compilation.FindType(KnownTypeCode.Int32)); return (new LdLen(StackType.I4, converted), context.TypeSystem.FindType(KnownTypeCode.Int32));
} }
(ILInstruction, IType) ConvertBinaryNumericOperator(CallInstruction invocation, BinaryNumericOperator op, bool? isChecked = null) (ILInstruction, IType) ConvertBinaryNumericOperator(CallInstruction invocation, BinaryNumericOperator op, bool? isChecked = null)
@ -589,7 +589,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
return (new Call(operatorMethod) { Arguments = { left, right } }, operatorMethod.ReturnType); return (new Call(operatorMethod) { Arguments = { left, right } }, operatorMethod.ReturnType);
} }
var resultType = context.TypeSystem.Compilation.FindType(KnownTypeCode.Boolean); var resultType = context.TypeSystem.FindType(KnownTypeCode.Boolean);
return (new Comp(kind, NullableType.IsNullable(leftType) ? ComparisonLiftingKind.CSharp : ComparisonLiftingKind.None, leftType.GetStackType(), leftType.GetSign(), left, right), resultType); return (new Comp(kind, NullableType.IsNullable(leftType) ? ComparisonLiftingKind.CSharp : ComparisonLiftingKind.None, leftType.GetStackType(), leftType.GetSign(), left, right), resultType);
} }
@ -739,7 +739,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
IMember method; IMember method;
switch (invocation.Arguments.Count) { switch (invocation.Arguments.Count) {
case 2: case 2:
var resultType = context.TypeSystem.Compilation.FindType(KnownTypeCode.Boolean); var resultType = context.TypeSystem.FindType(KnownTypeCode.Boolean);
return (and ? IfInstruction.LogicAnd(left, right) : IfInstruction.LogicOr(left, right), resultType); return (and ? IfInstruction.LogicAnd(left, right) : IfInstruction.LogicOr(left, right), resultType);
case 3: case 3:
if (!MatchGetMethodFromHandle(invocation.Arguments[2], out method)) if (!MatchGetMethodFromHandle(invocation.Arguments[2], out method))
@ -810,7 +810,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
indices[i] = index; indices[i] = index;
} }
return (new NewArr(type, indices), new ArrayType(context.TypeSystem.Compilation, type, arguments.Count)); return (new NewArr(type, indices), new ArrayType(context.TypeSystem, type, arguments.Count));
} }
(ILInstruction, IType) ConvertNewArrayInit(CallInstruction invocation) (ILInstruction, IType) ConvertNewArrayInit(CallInstruction invocation)
@ -821,7 +821,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
if (!MatchArgumentList(invocation.Arguments[1], out var arguments)) if (!MatchArgumentList(invocation.Arguments[1], out var arguments))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
ArrayType arrayType = new ArrayType(context.BlockContext.TypeSystem.Compilation, type); ArrayType arrayType = new ArrayType(context.BlockContext.TypeSystem, type);
if (arguments.Count == 0) if (arguments.Count == 0)
return (new NewArr(type, new LdcI4(0)), arrayType); return (new NewArr(type, new LdcI4(0)), arrayType);
var block = (Block)invocation.Arguments[1]; var block = (Block)invocation.Arguments[1];
@ -959,7 +959,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var converted = ConvertInstruction(invocation.Arguments[0]).Item1; var converted = ConvertInstruction(invocation.Arguments[0]).Item1;
if (!MatchGetTypeFromHandle(invocation.Arguments[1], out var type)) if (!MatchGetTypeFromHandle(invocation.Arguments[1], out var type))
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
var resultType = context.TypeSystem.Compilation.FindType(KnownTypeCode.Boolean); var resultType = context.TypeSystem.FindType(KnownTypeCode.Boolean);
if (converted != null) if (converted != null)
return (new Comp(ComparisonKind.Inequality, Sign.None, new IsInst(converted, type), new LdNull()), resultType); return (new Comp(ComparisonKind.Inequality, Sign.None, new IsInst(converted, type), new LdNull()), resultType);
return (null, SpecialType.UnknownType); return (null, SpecialType.UnknownType);
@ -1061,7 +1061,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
//castclass System.Reflection.MethodInfo(call GetMethodFromHandle(ldmembertoken op_Addition)) //castclass System.Reflection.MethodInfo(call GetMethodFromHandle(ldmembertoken op_Addition))
if (!inst.MatchCastClass(out var arg, out var type)) if (!inst.MatchCastClass(out var arg, out var type))
return false; return false;
if (!type.Equals(context.TypeSystem.Compilation.FindType(new FullTypeName("System.Reflection.MethodInfo")))) if (!type.Equals(context.TypeSystem.FindType(new FullTypeName("System.Reflection.MethodInfo"))))
return false; return false;
if (!(arg is CallInstruction call && call.Method.FullName == "System.Reflection.MethodBase.GetMethodFromHandle")) if (!(arg is CallInstruction call && call.Method.FullName == "System.Reflection.MethodBase.GetMethodFromHandle"))
return false; return false;
@ -1086,7 +1086,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
//castclass System.Reflection.ConstructorInfo(call GetMethodFromHandle(ldmembertoken op_Addition)) //castclass System.Reflection.ConstructorInfo(call GetMethodFromHandle(ldmembertoken op_Addition))
if (!inst.MatchCastClass(out var arg, out var type)) if (!inst.MatchCastClass(out var arg, out var type))
return false; return false;
if (!type.Equals(context.TypeSystem.Compilation.FindType(new FullTypeName("System.Reflection.ConstructorInfo")))) if (!type.Equals(context.TypeSystem.FindType(new FullTypeName("System.Reflection.ConstructorInfo"))))
return false; return false;
if (!(arg is CallInstruction call && call.Method.FullName == "System.Reflection.MethodBase.GetMethodFromHandle")) if (!(arg is CallInstruction call && call.Method.FullName == "System.Reflection.MethodBase.GetMethodFromHandle"))
return false; return false;

78
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -74,51 +74,54 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <remarks> /// <remarks>
/// This class is thread-safe. /// This class is thread-safe.
/// </remarks> /// </remarks>
public class DecompilerTypeSystem : IDecompilerTypeSystem public class DecompilerTypeSystem : SimpleCompilation, IDecompilerTypeSystem
{ {
readonly Metadata.PEFile moduleDefinition; public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver)
readonly ICompilation compilation; : this(mainModule, assemblyResolver, TypeSystemOptions.Default)
readonly IAssemblyResolver assemblyResolver;
readonly TypeSystemOptions typeSystemOptions;
readonly MetadataModule mainModule;
public DecompilerTypeSystem(Metadata.PEFile moduleDefinition, IAssemblyResolver assemblyResolver)
: this(moduleDefinition, assemblyResolver, new DecompilerSettings())
{ {
} }
public DecompilerTypeSystem(PEFile moduleDefinition, IAssemblyResolver assemblyResolver, DecompilerSettings settings) static TypeSystemOptions GetOptions(DecompilerSettings settings)
{ {
if (settings == null) var typeSystemOptions = TypeSystemOptions.None;
throw new ArgumentNullException(nameof(settings));
this.moduleDefinition = moduleDefinition ?? throw new ArgumentNullException(nameof(moduleDefinition));
this.assemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver));
typeSystemOptions = TypeSystemOptions.None;
if (settings.Dynamic) if (settings.Dynamic)
typeSystemOptions |= TypeSystemOptions.Dynamic; typeSystemOptions |= TypeSystemOptions.Dynamic;
if (settings.TupleTypes) if (settings.TupleTypes)
typeSystemOptions |= TypeSystemOptions.Tuple; typeSystemOptions |= TypeSystemOptions.Tuple;
if (settings.ExtensionMethods) if (settings.ExtensionMethods)
typeSystemOptions |= TypeSystemOptions.ExtensionMethods; typeSystemOptions |= TypeSystemOptions.ExtensionMethods;
var mainAssembly = moduleDefinition.WithOptions(typeSystemOptions); return typeSystemOptions;
}
public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
: this(mainModule, assemblyResolver, GetOptions(settings ?? throw new ArgumentNullException(nameof(settings))))
{
}
public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)
{
if (mainModule == null)
throw new ArgumentNullException(nameof(mainModule));
if (assemblyResolver == null)
throw new ArgumentNullException(nameof(assemblyResolver));
// Load referenced assemblies and type-forwarder references. // Load referenced assemblies and type-forwarder references.
// This is necessary to make .NET Core/PCL binaries work better. // This is necessary to make .NET Core/PCL binaries work better.
var referencedAssemblies = new List<IModuleReference>(); var referencedAssemblies = new List<PEFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference)>(); var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference)>();
var mainMetadata = moduleDefinition.Metadata; var mainMetadata = mainModule.Metadata;
foreach (var h in mainMetadata.GetModuleReferences()) { foreach (var h in mainMetadata.GetModuleReferences()) {
var moduleRef = mainMetadata.GetModuleReference(h); var moduleRef = mainMetadata.GetModuleReference(h);
var moduleName = mainMetadata.GetString(moduleRef.Name); var moduleName = mainMetadata.GetString(moduleRef.Name);
foreach (var fileHandle in mainMetadata.AssemblyFiles) { foreach (var fileHandle in mainMetadata.AssemblyFiles) {
var file = mainMetadata.GetAssemblyFile(fileHandle); var file = mainMetadata.GetAssemblyFile(fileHandle);
if (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata) { if (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata) {
assemblyReferenceQueue.Enqueue((false, moduleDefinition, moduleName)); assemblyReferenceQueue.Enqueue((false, mainModule, moduleName));
break; break;
} }
} }
} }
foreach (var refs in moduleDefinition.AssemblyReferences) { foreach (var refs in mainModule.AssemblyReferences) {
assemblyReferenceQueue.Enqueue((true, moduleDefinition, refs)); assemblyReferenceQueue.Enqueue((true, mainModule, refs));
} }
var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) => var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) =>
reference.IsAssembly ? "A:" + ((AssemblyReference)reference.Reference).FullName : reference.IsAssembly ? "A:" + ((AssemblyReference)reference.Reference).FullName :
@ -135,7 +138,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
asm = assemblyResolver.ResolveModule(asmRef.MainModule, (string)asmRef.Reference); asm = assemblyResolver.ResolveModule(asmRef.MainModule, (string)asmRef.Reference);
} }
if (asm != null) { if (asm != null) {
referencedAssemblies.Add(asm.WithOptions(typeSystemOptions)); referencedAssemblies.Add(asm);
var metadata = asm.Metadata; var metadata = asm.Metadata;
foreach (var h in metadata.ExportedTypes) { foreach (var h in metadata.ExportedTypes) {
var exportedType = metadata.GetExportedType(h); var exportedType = metadata.GetExportedType(h);
@ -151,27 +154,30 @@ namespace ICSharpCode.Decompiler.TypeSystem
} }
} }
} }
compilation = new SimpleCompilation(mainAssembly, referencedAssemblies); var mainModuleWithOptions = mainModule.WithOptions(typeSystemOptions);
var referencedAssembliesWithOptions = referencedAssemblies.Select(file => file.WithOptions(typeSystemOptions));
// Primitive types are necessary to avoid assertions in ILReader. // Primitive types are necessary to avoid assertions in ILReader.
// Fallback to MinimalCorlib to provide the primitive types. // Fallback to MinimalCorlib to provide the primitive types.
if (compilation.FindType(KnownTypeCode.Void).Kind == TypeKind.Unknown || compilation.FindType(KnownTypeCode.Int32).Kind == TypeKind.Unknown) { if (!HasType(KnownTypeCode.Void) || !HasType(KnownTypeCode.Int32)) {
referencedAssemblies.Add(MinimalCorlib.Instance); Init(mainModule.WithOptions(typeSystemOptions), referencedAssembliesWithOptions.Concat(new[] { MinimalCorlib.Instance }));
compilation = new SimpleCompilation(mainAssembly, referencedAssemblies); } else {
} Init(mainModuleWithOptions, referencedAssembliesWithOptions);
this.mainModule = (MetadataModule)compilation.MainModule;
} }
this.MainModule = (MetadataModule)base.MainModule;
public ICompilation Compilation { bool HasType(KnownTypeCode code)
get { return compilation; } {
TopLevelTypeName name = KnownTypeReference.Get(code).TypeName;
if (mainModule.GetTypeDefinition(name) != null)
return true;
foreach (var file in referencedAssemblies) {
if (file.GetTypeDefinition(name) != null)
return true;
} }
return false;
public MetadataModule MainModule {
get { return mainModule; }
} }
public Metadata.PEFile ModuleDefinition {
get { return moduleDefinition; }
} }
public new MetadataModule MainModule { get; }
} }
} }

9
ICSharpCode.Decompiler/TypeSystem/ICompilation.cs

@ -31,24 +31,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary> /// </summary>
IModule MainModule { get; } IModule MainModule { get; }
/// <summary>
/// Gets the type resolve context that specifies this compilation and no current assembly or entity.
/// </summary>
ITypeResolveContext TypeResolveContext { get; }
/// <summary> /// <summary>
/// Gets the list of all modules in the compilation. /// Gets the list of all modules in the compilation.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This main module is the first entry in the list. /// This main module is the first entry in the list.
/// </remarks> /// </remarks>
IList<IModule> Modules { get; } IReadOnlyList<IModule> Modules { get; }
/// <summary> /// <summary>
/// Gets the referenced modules. /// Gets the referenced modules.
/// This list does not include the main module. /// This list does not include the main module.
/// </summary> /// </summary>
IList<IModule> ReferencedModules { get; } IReadOnlyList<IModule> ReferencedModules { get; }
/// <summary> /// <summary>
/// Gets the root namespace of this compilation. /// Gets the root namespace of this compilation.

9
ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs

@ -23,11 +23,12 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.TypeSystem namespace ICSharpCode.Decompiler.TypeSystem
{ {
/// <summary> /// <summary>
/// Allows resolving cecil types into the NRefactory type system. /// Main interface for the decompiler type system.
///
/// The MetadataModule class allows decoding/resolving metadata tokens into type system entities.
/// </summary> /// </summary>
public interface IDecompilerTypeSystem public interface IDecompilerTypeSystem : ICompilation
{ {
ICompilation Compilation { get; } new MetadataModule MainModule { get; }
MetadataModule MainModule { get; }
} }
} }

42
ICSharpCode.Decompiler/TypeSystem/Implementation/SimpleCompilation.cs

@ -27,26 +27,35 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
/// </summary> /// </summary>
public class SimpleCompilation : ICompilation public class SimpleCompilation : ICompilation
{ {
readonly ITypeResolveContext context;
readonly CacheManager cacheManager = new CacheManager(); readonly CacheManager cacheManager = new CacheManager();
readonly KnownTypeCache knownTypeCache; IModule mainModule;
readonly IModule mainModule; KnownTypeCache knownTypeCache;
readonly IList<IModule> assemblies; IReadOnlyList<IModule> assemblies;
readonly IList<IModule> referencedAssemblies; IReadOnlyList<IModule> referencedAssemblies;
bool initialized;
INamespace rootNamespace; INamespace rootNamespace;
public SimpleCompilation(IModuleReference mainAssembly, params IModuleReference[] assemblyReferences) public SimpleCompilation(IModuleReference mainAssembly, params IModuleReference[] assemblyReferences)
: this(mainAssembly, (IEnumerable<IModuleReference>)assemblyReferences)
{ {
Init(mainAssembly, assemblyReferences);
} }
public SimpleCompilation(IModuleReference mainAssembly, IEnumerable<IModuleReference> assemblyReferences) public SimpleCompilation(IModuleReference mainAssembly, IEnumerable<IModuleReference> assemblyReferences)
{
Init(mainAssembly, assemblyReferences);
}
protected SimpleCompilation()
{
}
protected void Init(IModuleReference mainAssembly, IEnumerable<IModuleReference> assemblyReferences)
{ {
if (mainAssembly == null) if (mainAssembly == null)
throw new ArgumentNullException("mainAssembly"); throw new ArgumentNullException("mainAssembly");
if (assemblyReferences == null) if (assemblyReferences == null)
throw new ArgumentNullException("assemblyReferences"); throw new ArgumentNullException("assemblyReferences");
this.context = new SimpleTypeResolveContext(this); var context = new SimpleTypeResolveContext(this);
this.mainModule = mainAssembly.Resolve(context); this.mainModule = mainAssembly.Resolve(context);
List<IModule> assemblies = new List<IModule>(); List<IModule> assemblies = new List<IModule>();
assemblies.Add(this.mainModule); assemblies.Add(this.mainModule);
@ -66,43 +75,40 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.assemblies = assemblies.AsReadOnly(); this.assemblies = assemblies.AsReadOnly();
this.referencedAssemblies = referencedAssemblies.AsReadOnly(); this.referencedAssemblies = referencedAssemblies.AsReadOnly();
this.knownTypeCache = new KnownTypeCache(this); this.knownTypeCache = new KnownTypeCache(this);
this.initialized = true;
} }
public IModule MainModule { public IModule MainModule {
get { get {
if (mainModule == null) if (!initialized)
throw new InvalidOperationException("Compilation isn't initialized yet"); throw new InvalidOperationException("Compilation isn't initialized yet");
return mainModule; return mainModule;
} }
} }
public IList<IModule> Modules { public IReadOnlyList<IModule> Modules {
get { get {
if (assemblies == null) if (!initialized)
throw new InvalidOperationException("Compilation isn't initialized yet"); throw new InvalidOperationException("Compilation isn't initialized yet");
return assemblies; return assemblies;
} }
} }
public IList<IModule> ReferencedModules { public IReadOnlyList<IModule> ReferencedModules {
get { get {
if (referencedAssemblies == null) if (!initialized)
throw new InvalidOperationException("Compilation isn't initialized yet"); throw new InvalidOperationException("Compilation isn't initialized yet");
return referencedAssemblies; return referencedAssemblies;
} }
} }
public ITypeResolveContext TypeResolveContext {
get { return context; }
}
public INamespace RootNamespace { public INamespace RootNamespace {
get { get {
INamespace ns = LazyInit.VolatileRead(ref this.rootNamespace); INamespace ns = LazyInit.VolatileRead(ref this.rootNamespace);
if (ns != null) { if (ns != null) {
return ns; return ns;
} else { } else {
if (referencedAssemblies == null) if (!initialized)
throw new InvalidOperationException("Compilation isn't initialized yet"); throw new InvalidOperationException("Compilation isn't initialized yet");
return LazyInit.GetOrSet(ref this.rootNamespace, CreateRootNamespace()); return LazyInit.GetOrSet(ref this.rootNamespace, CreateRootNamespace());
} }
@ -144,7 +150,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override string ToString() public override string ToString()
{ {
return "[SimpleCompilation " + mainModule.AssemblyName + "]"; return "[" + GetType().Name + " " + mainModule.AssemblyName + "]";
} }
} }
} }

2
ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs

@ -53,7 +53,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </remarks> /// </remarks>
public static IType FindType(this ICompilation compilation, Type type) public static IType FindType(this ICompilation compilation, Type type)
{ {
return type.ToTypeReference().Resolve(compilation.TypeResolveContext); return type.ToTypeReference().Resolve(new SimpleTypeResolveContext(compilation));
} }
#endregion #endregion

6
ILSpy.BamlDecompiler/CecilTypeResolver.cs

@ -16,18 +16,16 @@ namespace ILSpy.BamlDecompiler
{ {
readonly PEFile module; readonly PEFile module;
readonly DecompilerTypeSystem typeSystem; readonly DecompilerTypeSystem typeSystem;
readonly ICompilation compilation;
public NRTypeResolver(PEFile module, IAssemblyResolver resolver) public NRTypeResolver(PEFile module, IAssemblyResolver resolver)
{ {
this.module = module ?? throw new ArgumentNullException(nameof(module)); this.module = module ?? throw new ArgumentNullException(nameof(module));
this.typeSystem = new DecompilerTypeSystem(module, resolver); this.typeSystem = new DecompilerTypeSystem(module, resolver);
this.compilation = typeSystem.Compilation;
} }
public bool IsLocalAssembly(string name) public bool IsLocalAssembly(string name)
{ {
return MakeShort(name) == compilation.MainModule.AssemblyName; return MakeShort(name) == typeSystem.MainModule.AssemblyName;
} }
string MakeShort(string name) string MakeShort(string name)
@ -50,7 +48,7 @@ namespace ILSpy.BamlDecompiler
string fullName = bracket > -1 ? name.Substring(0, name.IndexOf('[')) : name.Substring(0, comma); string fullName = bracket > -1 ? name.Substring(0, name.IndexOf('[')) : name.Substring(0, comma);
string assemblyName = name.Substring(comma + 1).Trim(); string assemblyName = name.Substring(comma + 1).Trim();
var type = compilation.FindType(new FullTypeName(fullName)).GetDefinition(); var type = typeSystem.FindType(new FullTypeName(fullName)).GetDefinition();
if (type == null) if (type == null)
return new UnresolvableType(name); return new UnresolvableType(name);

2
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -37,7 +37,7 @@ namespace ILSpy.BamlDecompiler
var result = new List<(LongSet, EventRegistration[])>(); var result = new List<(LongSet, EventRegistration[])>();
var typeSystem = new DecompilerTypeSystem(module, assemblyResolver); var typeSystem = new DecompilerTypeSystem(module, assemblyResolver);
var typeDefinition = typeSystem.Compilation.FindType(new FullTypeName(fullTypeName)).GetDefinition(); var typeDefinition = typeSystem.FindType(new FullTypeName(fullTypeName)).GetDefinition();
if (typeDefinition == null) if (typeDefinition == null)
return result; return result;

Loading…
Cancel
Save