Browse Source

Fix #195 IL identfier escaping.

pull/143/merge
Daniel Grunwald 14 years ago
parent
commit
399a87e5a1
  1. 22
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  2. 7
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

22
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -156,14 +156,21 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -156,14 +156,21 @@ namespace ICSharpCode.Decompiler.Disassembler
writer.WriteReference(Escape(field.Name), field);
}
static bool IsValidIdentifierCharacter(char c)
{
return c == '_' || c == '$' || c == '@' || c == '?' || c == '`';
}
static bool IsValidIdentifier(string identifier)
{
if (string.IsNullOrEmpty(identifier))
return false;
if (!(char.IsLetter(identifier[0]) || identifier[0] == '_' || identifier[0] == '.'))
return false;
if (!(char.IsLetter(identifier[0]) || IsValidIdentifierCharacter(identifier[0]))) {
// As a special case, .ctor and .cctor are valid despite starting with a dot
return identifier == ".ctor" || identifier == ".cctor";
}
for (int i = 1; i < identifier.Length; i++) {
if (!(char.IsLetterOrDigit(identifier[i]) || identifier[i] == '_' || identifier[i] == '.' || identifier[i] == '`'))
if (!(char.IsLetterOrDigit(identifier[i]) || IsValidIdentifierCharacter(identifier[i]) || identifier[i] == '.'))
return false;
}
return true;
@ -196,7 +203,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -196,7 +203,7 @@ namespace ICSharpCode.Decompiler.Disassembler
"vararg", "variant", "vector", "virtual", "void", "wchar", "winapi", "with", "wrapper",
// These are not listed as keywords in spec, but ILAsm treats them as such
"property", "type", "flags", "callconv"
"property", "type", "flags", "callconv", "strict"
);
static HashSet<string> BuildKeywordList(params string[] keywords)
@ -210,10 +217,13 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -210,10 +217,13 @@ namespace ICSharpCode.Decompiler.Disassembler
public static string Escape(string identifier)
{
if (IsValidIdentifier(identifier) && !ilKeywords.Contains(identifier))
if (IsValidIdentifier(identifier) && !ilKeywords.Contains(identifier)) {
return identifier;
else
} else {
// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,
// but we follow Microsoft's ILDasm and use \'.
return "'" + NRefactory.CSharp.OutputVisitor.ConvertString(identifier).Replace("'", "\\'") + "'";
}
}
public static void WriteTo(this TypeReference type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)

7
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -335,7 +335,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -335,7 +335,12 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(na.Name));
output.Write(" = ");
WriteConstant(na.Argument.Value);
if (na.Argument.Value is string) {
// secdecls use special syntax for strings
output.Write("string('{0}')", NRefactory.CSharp.OutputVisitor.ConvertString((string)na.Argument.Value).Replace("'", "\'"));
} else {
WriteConstant(na.Argument.Value);
}
}
string GetAssemblyQualifiedName(TypeReference type)

Loading…
Cancel
Save