Permalink
Browse files

Cache UsingScope during decompiler run.

  • Loading branch information...
siegfriedpammer committed Mar 10, 2018
1 parent 4f4c5bd commit 1a0052a345a79ead09a882bf05889f9cf3568806

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -32,9 +32,10 @@ public class TransformContext
public readonly CancellationToken CancellationToken;
public readonly TypeSystemAstBuilder TypeSystemAstBuilder;
public readonly DecompilerSettings Settings;
internal readonly DecompileRun DecompileRun;
readonly ITypeResolveContext decompilationContext;
/// <summary>
/// Returns the member that is being decompiled; or null if a whole type or assembly is being decompiled.
/// </summary>
@@ -59,16 +60,16 @@ public class TransformContext
/// <summary>
/// Returns the max possible set of namespaces that will be used during decompilation.
/// </summary>
public IImmutableSet<string> RequiredNamespacesSuperset { get; }
public IImmutableSet<string> RequiredNamespacesSuperset => DecompileRun.Namespaces.ToImmutableHashSet();
internal TransformContext(DecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext, IImmutableSet<string> namespaces, TypeSystemAstBuilder typeSystemAstBuilder, DecompilerSettings settings, CancellationToken cancellationToken)
internal TransformContext(DecompilerTypeSystem typeSystem, DecompileRun decompileRun, ITypeResolveContext decompilationContext, TypeSystemAstBuilder typeSystemAstBuilder)
{
this.TypeSystem = typeSystem;
this.DecompileRun = decompileRun;
this.decompilationContext = decompilationContext;
this.RequiredNamespacesSuperset = namespaces;
this.TypeSystemAstBuilder = typeSystemAstBuilder;
this.Settings = settings;
this.CancellationToken = cancellationToken;
this.CancellationToken = decompileRun.CancellationToken;
this.Settings = decompileRun.Settings;
}
}
}
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler
{
internal class DecompileRun
{
public HashSet<string> DefinedSymbols { get; private set; } = new HashSet<string>();
public HashSet<string> Namespaces { get; private set; } = new HashSet<string>();
public CancellationToken CancellationToken { get; set; }
public DecompilerSettings Settings { get; }
Lazy<CSharp.TypeSystem.UsingScope> usingScope => new Lazy<CSharp.TypeSystem.UsingScope>(() => CreateUsingScope(Namespaces));
public CSharp.TypeSystem.UsingScope UsingScope => usingScope.Value;
public DecompileRun(DecompilerSettings settings)
{
this.Settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
CSharp.TypeSystem.UsingScope CreateUsingScope(HashSet<string> requiredNamespacesSuperset)
{
var usingScope = new CSharp.TypeSystem.UsingScope();
foreach (var ns in requiredNamespacesSuperset) {
string[] parts = ns.Split('.');
AstType nsType = new SimpleType(parts[0]);
for (int i = 1; i < parts.Length; i++) {
nsType = new MemberType { Target = nsType, MemberName = parts[i] };
}
var reference = nsType.ToTypeReference(CSharp.Resolver.NameLookupMode.TypeInUsingDeclaration) as CSharp.TypeSystem.TypeOrNamespaceReference;
if (reference != null)
usingScope.Usings.Add(reference);
}
return usingScope;
}
}
}
@@ -265,6 +265,7 @@
<Compile Include="CSharp\Transforms\ReplaceMethodCallsWithOperators.cs" />
<Compile Include="CSharp\WholeProjectDecompiler.cs" />
<Compile Include="CSharp\Transforms\AddXmlDocumentationTransform.cs" />
<Compile Include="DecompileRun.cs" />
<Compile Include="Documentation\GetPotentiallyNestedClassTypeReference.cs" />
<Compile Include="Documentation\IdStringMemberReference.cs" />
<Compile Include="Documentation\IdStringProvider.cs" />
@@ -378,8 +378,9 @@ internal static ILFunction CreateILAst(MethodDefinition method, ILTransformConte
}
var il = new ILReader(typeSystem).ReadIL(method.Body, context.CancellationToken);
il.RunTransforms(CSharpDecompiler.EarlyILTransforms(true),
new ILTransformContext(il, typeSystem, context.RequiredNamespacesSuperset, context.Settings) {
CancellationToken = context.CancellationToken
new ILTransformContext(il, typeSystem, context.Settings) {
CancellationToken = context.CancellationToken,
DecompileRun = context.DecompileRun
});
return il;
}
@@ -149,8 +149,9 @@ ILFunction TransformDelegateConstruction(NewObj value, out ILInstruction target)
v.Name = contextPrefix + v.Name;
}
var nestedContext = new ILTransformContext(function, localTypeSystem, context.RequiredNamespacesSuperset, context.Settings) {
CancellationToken = context.CancellationToken
var nestedContext = new ILTransformContext(function, localTypeSystem, context.Settings) {
CancellationToken = context.CancellationToken,
DecompileRun = context.DecompileRun
};
function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)), nestedContext);
function.AcceptVisitor(new ReplaceDelegateTargetVisitor(target, function.Variables.SingleOrDefault(v => v.Index == -1 && v.Kind == VariableKind.Parameter)));
@@ -17,10 +17,13 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL.Transforms
{
@@ -40,15 +43,16 @@ public class ILTransformContext
public ILFunction Function { get; }
public IDecompilerTypeSystem TypeSystem { get; }
public DecompilerSettings Settings { get; }
public IImmutableSet<string> RequiredNamespacesSuperset { get; }
public CancellationToken CancellationToken { get; set; }
public Stepper Stepper { get; set; }
public ILTransformContext(ILFunction function, IDecompilerTypeSystem typeSystem, IImmutableSet<string> requiredNamespaces, DecompilerSettings settings = null)
internal DecompileRun DecompileRun { get; set; }
internal ResolvedUsingScope UsingScope => DecompileRun.UsingScope.Resolve(TypeSystem.Compilation);
public ILTransformContext(ILFunction function, IDecompilerTypeSystem typeSystem, DecompilerSettings settings = null)
{
this.Function = function ?? throw new ArgumentNullException(nameof(function));
this.TypeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));
this.RequiredNamespacesSuperset = requiredNamespaces ?? throw new ArgumentNullException(nameof(requiredNamespaces));
this.Settings = settings ?? new DecompilerSettings();
Stepper = new Stepper();
}
@@ -58,7 +62,7 @@ public ILTransformContext(ILTransformContext context)
this.Function = context.Function;
this.TypeSystem = context.TypeSystem;
this.Settings = context.Settings;
this.RequiredNamespacesSuperset = context.RequiredNamespacesSuperset;
this.DecompileRun = context.DecompileRun;
this.CancellationToken = context.CancellationToken;
this.Stepper = context.Stepper;
}
@@ -246,28 +246,11 @@ bool CanTransformToExtensionMethodCall(CallInstruction call)
var paramTypes = call.Method.Parameters.Skip(1).Select(p => new ResolveResult(p.Type)).ToArray();
var paramNames = call.Method.Parameters.SelectArray(p => p.Name);
var typeArgs = call.Method.TypeArguments.ToArray();
var usingScope = CreateUsingScope(context.RequiredNamespacesSuperset).Resolve(context.TypeSystem.Compilation);
var resolveContext = new CSharp.TypeSystem.CSharpTypeResolveContext(context.TypeSystem.Compilation.MainAssembly, usingScope);
var resolveContext = new CSharp.TypeSystem.CSharpTypeResolveContext(context.TypeSystem.Compilation.MainAssembly, context.UsingScope);
var resolver = new CSharp.Resolver.CSharpResolver(resolveContext);
return CSharp.Transforms.IntroduceExtensionMethods.CanTransformToExtensionMethodCall(resolver, call.Method, typeArgs, targetType, paramTypes);
}
CSharp.TypeSystem.UsingScope CreateUsingScope(IImmutableSet<string> requiredNamespacesSuperset)
{
var usingScope = new CSharp.TypeSystem.UsingScope();
foreach (var ns in requiredNamespacesSuperset) {
string[] parts = ns.Split('.');
AstType nsType = new SimpleType(parts[0]);
for (int i = 1; i < parts.Length; i++) {
nsType = new MemberType { Target = nsType, MemberName = parts[i] };
}
var reference = nsType.ToTypeReference(CSharp.Resolver.NameLookupMode.TypeInUsingDeclaration) as CSharp.TypeSystem.TypeOrNamespaceReference;
if (reference != null)
usingScope.Usings.Add(reference);
}
return usingScope;
}
static bool IsGetter(IMethod method)
{
return method.AccessorOwner is IProperty p && p.Getter == method;
@@ -21,8 +21,9 @@ public void Run(ILFunction function, ILTransformContext context)
var ilReader = new ILReader(specializingTypeSystem);
System.Threading.CancellationToken cancellationToken = new System.Threading.CancellationToken();
var proxyFunction = ilReader.ReadIL(methodDef.Body, cancellationToken);
var transformContext = new ILTransformContext(proxyFunction, specializingTypeSystem, context.RequiredNamespacesSuperset, this.context.Settings) {
CancellationToken = cancellationToken
var transformContext = new ILTransformContext(proxyFunction, specializingTypeSystem, this.context.Settings) {
CancellationToken = cancellationToken,
DecompileRun = context.DecompileRun
};
foreach (var transform in CSharp.CSharpDecompiler.GetILTransforms()) {
if (transform.GetType() != typeof(ProxyCallReplacer)) { // don't call itself on itself
@@ -61,7 +61,7 @@ public List<(LongSet, EventRegistration[])> DecompileEventMappings(string fullTy
var ilReader = new ILReader(typeSystem);
var function = ilReader.ReadIL(method.Body, cancellationToken);
var context = new ILTransformContext(function, typeSystem, ImmutableHashSet<string>.Empty) {
var context = new ILTransformContext(function, typeSystem) {
CancellationToken = cancellationToken
};
function.RunTransforms(CSharpDecompiler.GetILTransforms(), context);
@@ -118,10 +118,8 @@ public override void DecompileMethod(MethodDefinition method, ITextOutput output
reader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols;
ILFunction il = reader.ReadIL(method.Body, options.CancellationToken);
var namespaces = new HashSet<string>();
CSharpDecompiler.CollectNamespacesForDecompilation(new[] { method }, namespaces);
ILTransformContext context = new ILTransformContext(il, typeSystem, namespaces.ToImmutableHashSet(), options.DecompilerSettings) {
CancellationToken = options.CancellationToken
};
var decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings) { CancellationToken = options.CancellationToken };
ILTransformContext context = decompiler.CreateILTransformContext(il);
context.Stepper.StepLimit = options.StepLimit;
context.Stepper.IsDebug = options.IsDebug;
try {

0 comments on commit 1a0052a

Please sign in to comment.