Hello! I might have a dumb question so please bear with me :)
Why is IDecompilerTypeSystem.FindType() expecting generic types to not include the argument list, just the arity (`1), but if I get the same type as an IType (let's say I got it from a return type of a method) the ReflectionName property has the argument list?.
For example:
decompiler.TypeSystem.FindType(new FullTypeName("System.Threading.Tasks.Task`1[[System.String]]")) // returns Unknown
decompiler.TypeSystem.FindType(new FullTypeName("System.Threading.Tasks.Task`1")) // works
IMethod myMethod = ...
Console.Write(myMethod.ReturnType.ReflectionName); //outputs "System.Threading.Tasks.Task`1[[System.String]]"
Shouldn't the FullTypeName ctor also include the arguments?
var taskOfT = decompiler.TypeSystem.FindType(KnownTypeCode.TaskOfT).GetDefinition(); var taskOfString = new ParameterizedType(taskOfT, new[] { decompiler.TypeSystem.FindType(KnownTypeCode.String) });
KnownTypeCode
overload for all known types is faster than using the FullTypeName
overload
FullTypeName
can be used for any fully-qualified type definition in the type system. However, if you are looking for "special types" like void, int, string, IEnumerable<T>, Nullable<T>, Task, Task<T>, Span<T>, Memory<T>, etc. (see https://github.com/icsharpcode/ILSpy/blob/master/ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs#L26 for the full list)
typeSystem.FindType(KnownTypeCode.TaskOfT)
should yield the same result as typeSystem.FindType(new FullTypeName("System.Threading.Tasks.Task
1"))`, however the first one should be faster, because it directly uses the KnownTypeCache instead of having to parse a type-name and searching the whole compilation.
@dgrunwald Thank you. I'm trying to do it, when I initialise an instance of CSharpCompiler that points to my current assembly,
var file = Assembly.GetEntryAssembly().Location;
var decompiler = new CSharpDecompiler(file, new UniversalAssemblyResolver(file, true, ".NETCOREAPP"), new DecompilerSettings());
I get the exception
An unhandled exception of type 'ICSharpCode.Decompiler.Metadata.AssemblyResolutionException' occurred in ICSharpCode.Decompiler.dll: 'Failed to resolve assembly: 'ICSharpCode.Decompiler, Version=4.0.0.4521, Culture=neutral, PublicKeyToken=d4bfe873e7598c49'
Reading the source file of UniversalAssemblyResolver
(specifically, method ResolveInternal
), I see that it doesn't search in the NuGet directory.
When I do dotnet publish
and run my application, it works (the instantiation of CSharpDecompiler
), because it includes the ICSharpCode.Decompiler
dll in the publish
folder.
Is there a way to make it work in development, by looking in NuGet packages?
I've 'fixed' #1764 by changing _.MatchLdcI(1)
to _.MatchLdcI(1) || _.MatchLdcF4(1) || _.MatchLdcF8(1)
in 3 places.
Test cases are passing fine (except for Cecil which has always had path issues). Am I overlooking something obvious or is this a simple fix?
byte*
/sbyte*
.
paraphrasing the ILAst of the obfuscated code, before "Duplicate block exit" + "Extract else block" the control flow looks like this:
if (...) {
call Something()
} else {
while (true) {
if (...)
return;
}
}
return;
and after it looks like this:
if (...) {
call Something()
return;
}
while (true) {
if (...)
return;
}
return;
public void Issue1524V3(string str)
{
if (!string.IsNullOrEmpty(str))
{
return;
}
if (int.TryParse(str, out int id))
{
Console.WriteLine(new Func<int>(() => id));
}
}
public void Issue1524V4(string str)
{
if (string.IsNullOrEmpty(str))
{
if (int.TryParse(str, out int id))
{
Console.WriteLine(new Func<int>(() => id));
}
}
}
stloc V_1(newobj <>c__DisplayClass10_0..ctor())
is before the first if
TransformDisplayClassUsage
removes the display class init and store, but it runs after ConditionDetection
ConditionDetection
(or a part of it) againAssemblyResolver.AddSearchDirectory
?