Всем привет!
Только что попробовал поставить dotPeek от JetBrains. Главного его приемущество заключается в том, что он не падает при декомпиляции Nemerle и выдает более корректный код.
Минусы конечно тоже есть. Частенько выдается более пушстый код чем следовало бы. Например, функция:
GetHexValue(ch : char) : int
{
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
ch - 'A' : int + 0xA
else if (ch >= '0' && ch <= '9')
ch - '0' : int
else assert(false)
}
декомпилируется как:
private int GetHexValue(char ch)
{
if ((((int) ch < 65 ? 0 : ((int) ch <= 90 ? 1 : 0)) == 0 ? ((int) ch < 97 ? 0 : ((int) ch <= 122 ? 1 : 0)) : 1) != 0)
return checked ((int) ch - 65 + 10);
else if (((int) ch < 48 ? 0 : ((int) ch <= 57 ? 1 : 0)) != 0)
return checked ((int) ch - 48);
else
throw new AssertionException("Main.n", 45, "", "");
}
Что несколько более "пушисто" чем могло бы быть. Но все же это корректный! Для сравнения Рефлектор декомпилирует его вот таким вот неприглядным образом:
private int GetHexValue(char ch)
{
// This item is obfuscated and can not be translated.
if (!(((ch < 'A') || (ch > 'Z')) ? ((ch >= 'a') && (ch <= 'z')) : true) && ((ch < '0') || (ch > '9')))
{
throw new AssertionException("Main.n", 0x2d, "", "");
}
return (ch - '0');
}
по сути это полная чушь.
Для любителей разобраться в тонкостях привожу IL который декомпилировали оба декомпилятора:
.method private hidebysig instance int32 GetHexValue(char ch) cil managed
{
.maxstack 16
L_0000: ldarg.1
L_0001: ldc.i4.s 0x41
L_0003: clt
L_0005: ldc.i4.0
L_0006: ceq
L_0008: brfalse L_001a
L_000d: ldarg.1
L_000e: ldc.i4.s 90
L_0010: cgt
L_0012: ldc.i4.0
L_0013: ceq
L_0015: br L_001b
L_001a: ldc.i4.0
L_001b: brfalse L_0026
L_0020: ldc.i4.1
L_0021: br L_0041
L_0026: ldarg.1
L_0027: ldc.i4.s 0x61
L_0029: clt
L_002b: ldc.i4.0
L_002c: ceq
L_002e: brfalse L_0040
L_0033: ldarg.1
L_0034: ldc.i4.s 0x7a
L_0036: cgt
L_0038: ldc.i4.0
L_0039: ceq
L_003b: br L_0041
L_0040: ldc.i4.0
L_0041: brfalse L_0052
L_0046: ldarg.1
L_0047: ldc.i4.s 0x41
L_0049: sub.ovf
L_004a: ldc.i4.s 10
L_004c: add.ovf
L_004d: br L_0092
L_0052: ldarg.1
L_0053: ldc.i4.s 0x30
L_0055: clt
L_0057: ldc.i4.0
L_0058: ceq
L_005a: brfalse L_006c
L_005f: ldarg.1
L_0060: ldc.i4.s 0x39
L_0062: cgt
L_0064: ldc.i4.0
L_0065: ceq
L_0067: br L_006d
L_006c: ldc.i4.0
L_006d: brfalse L_007b
L_0072: ldarg.1
L_0073: ldc.i4.s 0x30
L_0075: sub.ovf
L_0076: br L_0092
L_007b: ldstr "Main.n"
L_0080: ldc.i4.s 0x2d
L_0082: ldstr ""
L_0087: ldstr ""
L_008c: newobj instance void [Nemerle]Nemerle.Core.AssertionException::.ctor(string, int32, string, string)
L_0091: throw
L_0092: ret
}
Будем надеяться на то, что в будущем dotPeek научится еще лучше декомпилировать немерл, что, в том числе, упростит упростит работу с макросами и изучение тонкостей языка.
Здравствуйте, VladD2, Вы писали:
VD>Главного его приемущество заключается в том, что он не падает при декомпиляции Nemerle
А ты проверь на Typer2.DoWalk
Здравствуйте, hardcase, Вы писали:
H>А ты проверь на Typer2.DoWalk
Выдал OutOfMemoryException на Control-Flow analysis, но декомпильнуло. Отписал им
баг-ребопрт.
В любом случае это с Рефлектором не сравнимо. Он на Немерловом коде через раз падал.
Здравствуйте, hardcase, Вы писали:
H>А я уже во всю ILSpy эксплуатирую.
Попробовал и его. Иногда, как и Рефлктор, падает на отдельных методах. Хотя и значительно реже чем рефлектор. И приятностей — хорошо декомпильнул булевы выражения. Оригинал на немерле:
GetHexValue(ch : char) : int
{
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
ch - 'A' : int + 0xA
else if (ch >= '0' && ch <= '9')
ch - '0' : int
else assert(false)
}
Вариант ILSpy-я:
private int GetHexValue(char ch)
{
checked
{
int arg_92_0;
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
{
arg_92_0 = (int)(ch - 'A' + '\n');
}
else
{
if (ch < '0' || ch > '9')
{
throw new AssertionException("Main.n", 45, "", "");
}
arg_92_0 = (int)(ch - '0');
}
return arg_92_0;
}
}