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 @@ -1811,7 +1811,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
var compilationWithSystemCore = new SimpleCompilation(SystemCore, Mscorlib);
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.AreEqual("mscorlib", c.ParentModule.AssemblyName);
}

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

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

12
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -397,13 +397,13 @@ namespace ICSharpCode.Decompiler.CSharp @@ -397,13 +397,13 @@ namespace ICSharpCode.Decompiler.CSharp
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 attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
attrSection.AttributeTarget = "assembly";
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 attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
attrSection.AttributeTarget = "module";
@ -603,7 +603,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -603,7 +603,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// </remarks>
public SyntaxTree DecompileType(FullTypeName fullTypeName)
{
var type = typeSystem.Compilation.FindType(fullTypeName.TopLevelTypeName).GetDefinition();
var type = typeSystem.FindType(fullTypeName.TopLevelTypeName).GetDefinition();
if (type == null)
throw new InvalidOperationException($"Could not find type definition {fullTypeName} in type system.");
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);
@ -933,12 +933,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -933,12 +933,12 @@ namespace ICSharpCode.Decompiler.CSharp
MethodDeclaration method = new MethodDeclaration();
method.Name = name;
method.Modifiers = Modifiers.Private | Modifiers.Static;
method.Parameters.Add(new ParameterDeclaration(typeSystemAstBuilder.ConvertType(typeSystem.Compilation.FindType(source)), "input"));
method.ReturnType = typeSystemAstBuilder.ConvertType(typeSystem.Compilation.FindType(target));
method.Parameters.Add(new ParameterDeclaration(typeSystemAstBuilder.ConvertType(typeSystem.FindType(source)), "input"));
method.ReturnType = typeSystemAstBuilder.ConvertType(typeSystem.FindType(target));
method.Body = new BlockStatement {
new IfElseStatement {
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,
Right = new PrimitiveExpression(4)
},

2
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -290,7 +290,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -290,7 +290,7 @@ namespace ICSharpCode.Decompiler.CSharp
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 {
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 @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public void Run(AstNode rootNode, TransformContext context)
{
this.context = context;
this.conversions = CSharpConversions.Get(context.TypeSystem.Compilation);
this.conversions = CSharpConversions.Get(context.TypeSystem);
InitializeContext(rootNode.Annotation<UsingScope>());
rootNode.AcceptVisitor(this);
}
@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
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.resolver = new CSharpResolver(currentContext);
}

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

@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
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.astBuilder = CreateAstBuilder(currentContext);
}

2
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -75,7 +75,7 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -75,7 +75,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
sequencePointBlobs.Add(method, (default, default));
else
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()) {

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

@ -197,12 +197,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -197,12 +197,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return false;
} else if (taskType.IsKnownType(KnownTypeCode.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))
return false;
} else if (taskType.IsKnownType(KnownTypeCode.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))
return false;
} else {

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

@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Children.Count];
for (int j = 0; j < uninlinedArgs.Length; 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) {
Name = "C_" + arg.ILRange.Start
};

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

@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public Metadata.PEFile PEFile => TypeSystem.MainModule.PEFile;
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)
{

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

@ -260,7 +260,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -260,7 +260,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
return CSharp.Transforms.IntroduceExtensionMethods.CanTransformToExtensionMethodCall(
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 @@ -542,7 +542,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
bool isNullCoalescingWithNonNullableFallback = false;
if (!MatchNullableCtor(trueInst, out var utype, out var exprToLift)) {
isNullCoalescingWithNonNullableFallback = true;
utype = context.TypeSystem.Compilation.FindType(trueInst.ResultType.ToKnownTypeCode());
utype = context.TypeSystem.FindType(trueInst.ResultType.ToKnownTypeCode());
exprToLift = trueInst;
if (nullableVars.Count == 1 && exprToLift.MatchLdLoc(nullableVars[0])) {
// v.HasValue ? ldloc v : fallback
@ -779,7 +779,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -779,7 +779,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
if (underlyingType == SpecialType.UnknownType)
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);
if (ctor != 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 @@ -178,7 +178,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
possibleIndexVariables.Add(stloc.Variable, (stloc.ChildIndex, stloc.Value));
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);
if (kind == AccessPathKind.Invalid || target != targetVariable)
return false;

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

@ -98,8 +98,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -98,8 +98,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
if (!context.Settings.ExpressionTrees) return;
this.context = context;
this.conversions = CSharpConversions.Get(context.TypeSystem.Compilation);
this.resolver = new CSharpResolver(context.TypeSystem.Compilation);
this.conversions = CSharpConversions.Get(context.TypeSystem);
this.resolver = new CSharpResolver(context.TypeSystem);
this.parameters = new Dictionary<ILVariable, (IType, string)>();
this.parameterMapping = new Dictionary<ILVariable, ILVariable>();
this.instructionsToRemove = new List<ILInstruction>();
@ -377,7 +377,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -377,7 +377,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var (converted, arrayType) = ConvertInstruction(invocation.Arguments[0]);
if (converted == null)
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)
@ -589,7 +589,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -589,7 +589,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
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);
}
@ -739,7 +739,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -739,7 +739,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
IMember method;
switch (invocation.Arguments.Count) {
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);
case 3:
if (!MatchGetMethodFromHandle(invocation.Arguments[2], out method))
@ -810,7 +810,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -810,7 +810,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (null, SpecialType.UnknownType);
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)
@ -821,7 +821,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -821,7 +821,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (null, SpecialType.UnknownType);
if (!MatchArgumentList(invocation.Arguments[1], out var arguments))
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)
return (new NewArr(type, new LdcI4(0)), arrayType);
var block = (Block)invocation.Arguments[1];
@ -959,7 +959,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -959,7 +959,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var converted = ConvertInstruction(invocation.Arguments[0]).Item1;
if (!MatchGetTypeFromHandle(invocation.Arguments[1], out var type))
return (null, SpecialType.UnknownType);
var resultType = context.TypeSystem.Compilation.FindType(KnownTypeCode.Boolean);
var resultType = context.TypeSystem.FindType(KnownTypeCode.Boolean);
if (converted != null)
return (new Comp(ComparisonKind.Inequality, Sign.None, new IsInst(converted, type), new LdNull()), resultType);
return (null, SpecialType.UnknownType);
@ -1061,7 +1061,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -1061,7 +1061,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
//castclass System.Reflection.MethodInfo(call GetMethodFromHandle(ldmembertoken op_Addition))
if (!inst.MatchCastClass(out var arg, out var type))
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;
if (!(arg is CallInstruction call && call.Method.FullName == "System.Reflection.MethodBase.GetMethodFromHandle"))
return false;
@ -1086,7 +1086,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -1086,7 +1086,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
//castclass System.Reflection.ConstructorInfo(call GetMethodFromHandle(ldmembertoken op_Addition))
if (!inst.MatchCastClass(out var arg, out var type))
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;
if (!(arg is CallInstruction call && call.Method.FullName == "System.Reflection.MethodBase.GetMethodFromHandle"))
return false;

78
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -74,51 +74,54 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -74,51 +74,54 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <remarks>
/// This class is thread-safe.
/// </remarks>
public class DecompilerTypeSystem : IDecompilerTypeSystem
public class DecompilerTypeSystem : SimpleCompilation, IDecompilerTypeSystem
{
readonly Metadata.PEFile moduleDefinition;
readonly ICompilation compilation;
readonly IAssemblyResolver assemblyResolver;
readonly TypeSystemOptions typeSystemOptions;
readonly MetadataModule mainModule;
public DecompilerTypeSystem(Metadata.PEFile moduleDefinition, IAssemblyResolver assemblyResolver)
: this(moduleDefinition, assemblyResolver, new DecompilerSettings())
public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver)
: this(mainModule, assemblyResolver, TypeSystemOptions.Default)
{
}
public DecompilerTypeSystem(PEFile moduleDefinition, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
static TypeSystemOptions GetOptions(DecompilerSettings settings)
{
if (settings == null)
throw new ArgumentNullException(nameof(settings));
this.moduleDefinition = moduleDefinition ?? throw new ArgumentNullException(nameof(moduleDefinition));
this.assemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver));
typeSystemOptions = TypeSystemOptions.None;
var typeSystemOptions = TypeSystemOptions.None;
if (settings.Dynamic)
typeSystemOptions |= TypeSystemOptions.Dynamic;
if (settings.TupleTypes)
typeSystemOptions |= TypeSystemOptions.Tuple;
if (settings.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.
// 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 mainMetadata = moduleDefinition.Metadata;
var mainMetadata = mainModule.Metadata;
foreach (var h in mainMetadata.GetModuleReferences()) {
var moduleRef = mainMetadata.GetModuleReference(h);
var moduleName = mainMetadata.GetString(moduleRef.Name);
foreach (var fileHandle in mainMetadata.AssemblyFiles) {
var file = mainMetadata.GetAssemblyFile(fileHandle);
if (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata) {
assemblyReferenceQueue.Enqueue((false, moduleDefinition, moduleName));
assemblyReferenceQueue.Enqueue((false, mainModule, moduleName));
break;
}
}
}
foreach (var refs in moduleDefinition.AssemblyReferences) {
assemblyReferenceQueue.Enqueue((true, moduleDefinition, refs));
foreach (var refs in mainModule.AssemblyReferences) {
assemblyReferenceQueue.Enqueue((true, mainModule, refs));
}
var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) =>
reference.IsAssembly ? "A:" + ((AssemblyReference)reference.Reference).FullName :
@ -135,7 +138,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -135,7 +138,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
asm = assemblyResolver.ResolveModule(asmRef.MainModule, (string)asmRef.Reference);
}
if (asm != null) {
referencedAssemblies.Add(asm.WithOptions(typeSystemOptions));
referencedAssemblies.Add(asm);
var metadata = asm.Metadata;
foreach (var h in metadata.ExportedTypes) {
var exportedType = metadata.GetExportedType(h);
@ -151,27 +154,30 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -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.
// Fallback to MinimalCorlib to provide the primitive types.
if (compilation.FindType(KnownTypeCode.Void).Kind == TypeKind.Unknown || compilation.FindType(KnownTypeCode.Int32).Kind == TypeKind.Unknown) {
referencedAssemblies.Add(MinimalCorlib.Instance);
compilation = new SimpleCompilation(mainAssembly, referencedAssemblies);
}
this.mainModule = (MetadataModule)compilation.MainModule;
if (!HasType(KnownTypeCode.Void) || !HasType(KnownTypeCode.Int32)) {
Init(mainModule.WithOptions(typeSystemOptions), referencedAssembliesWithOptions.Concat(new[] { MinimalCorlib.Instance }));
} else {
Init(mainModuleWithOptions, referencedAssembliesWithOptions);
}
this.MainModule = (MetadataModule)base.MainModule;
public ICompilation Compilation {
get { return compilation; }
bool HasType(KnownTypeCode code)
{
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;
}
public MetadataModule MainModule {
get { return mainModule; }
return false;
}
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 @@ -31,24 +31,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
IModule MainModule { get; }
/// <summary>
/// Gets the type resolve context that specifies this compilation and no current assembly or entity.
/// </summary>
ITypeResolveContext TypeResolveContext { get; }
/// <summary>
/// Gets the list of all modules in the compilation.
/// </summary>
/// <remarks>
/// This main module is the first entry in the list.
/// </remarks>
IList<IModule> Modules { get; }
IReadOnlyList<IModule> Modules { get; }
/// <summary>
/// Gets the referenced modules.
/// This list does not include the main module.
/// </summary>
IList<IModule> ReferencedModules { get; }
IReadOnlyList<IModule> ReferencedModules { get; }
/// <summary>
/// Gets the root namespace of this compilation.

9
ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs

@ -23,11 +23,12 @@ using ICSharpCode.Decompiler.Metadata; @@ -23,11 +23,12 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.TypeSystem
{
/// <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>
public interface IDecompilerTypeSystem
public interface IDecompilerTypeSystem : ICompilation
{
ICompilation Compilation { get; }
MetadataModule MainModule { get; }
new MetadataModule MainModule { get; }
}
}

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

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

6
ILSpy.BamlDecompiler/CecilTypeResolver.cs

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

2
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -37,7 +37,7 @@ namespace ILSpy.BamlDecompiler @@ -37,7 +37,7 @@ namespace ILSpy.BamlDecompiler
var result = new List<(LongSet, EventRegistration[])>();
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)
return result;

Loading…
Cancel
Save