Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinCathcart committed May 22, 2011
2 parents 20f9a62 + bf4f8a0 commit f56b02e
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 34 deletions.
86 changes: 83 additions & 3 deletions ICSharpCode.Decompiler/Ast/AstBuilder.cs
Expand Up @@ -125,9 +125,28 @@ public void GenerateCode(ITextOutput output)

public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
{
if (assemblyDefinition.Name.Version != null) {
astCompileUnit.AddChild(
new AttributeSection {
AttributeTarget = "assembly",
Attributes = {
new NRefactory.CSharp.Attribute {
Type = new SimpleType("AssemblyVersion")
.WithAnnotation(new TypeReference(
"System.Reflection", "AssemblyVersionAttribute",
assemblyDefinition.MainModule, assemblyDefinition.MainModule.TypeSystem.Corlib)),
Arguments = {
new PrimitiveExpression(assemblyDefinition.Name.Version.ToString())
}
}
}
}, AttributedNode.AttributeRole);
}

ConvertCustomAttributes(astCompileUnit, assemblyDefinition, "assembly");
ConvertSecurityAttributes(astCompileUnit, assemblyDefinition, "assembly");
ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, "module");
AddTypeForwarderAttributes(astCompileUnit, assemblyDefinition.MainModule, "assembly");

if (!onlyAssemblyLevel) {
foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) {
Expand All @@ -142,6 +161,30 @@ public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssembly
}
}

void AddTypeForwarderAttributes(CompilationUnit astCompileUnit, ModuleDefinition module, string target)
{
if (!module.HasExportedTypes)
return;
foreach (ExportedType type in module.ExportedTypes) {
if (type.IsForwarder) {
var forwardedType = CreateTypeOfExpression(new TypeReference(type.Namespace, type.Name, module, type.Scope));
astCompileUnit.AddChild(
new AttributeSection {
AttributeTarget = target,
Attributes = {
new NRefactory.CSharp.Attribute {
Type = new SimpleType("TypeForwardedTo")
.WithAnnotation(new TypeReference(
"System.Runtime.CompilerServices", "TypeForwardedToAttribute",
module, module.TypeSystem.Corlib)),
Arguments = { forwardedType }
}
}
}, AttributedNode.AttributeRole);
}
}
}

NamespaceDeclaration GetCodeNamespace(string name)
{
if (string.IsNullOrEmpty(name)) {
Expand Down Expand Up @@ -306,6 +349,45 @@ internal static string CleanName(string name)
return name;
}

#region Create TypeOf Expression
/// <summary>
/// Creates a typeof-expression for the specified type.
/// </summary>
public static TypeOfExpression CreateTypeOfExpression(TypeReference type)
{
return new TypeOfExpression(AddEmptyTypeArgumentsForUnboundGenerics(ConvertType(type)));
}

static AstType AddEmptyTypeArgumentsForUnboundGenerics(AstType type)
{
TypeReference typeRef = type.Annotation<TypeReference>();
if (typeRef == null)
return type;
TypeDefinition typeDef = typeRef.Resolve(); // need to resolve to figure out the number of type parameters
if (typeDef == null || !typeDef.HasGenericParameters)
return type;
SimpleType sType = type as SimpleType;
MemberType mType = type as MemberType;
if (sType != null) {
while (typeDef.GenericParameters.Count > sType.TypeArguments.Count) {
sType.TypeArguments.Add(new SimpleType(""));
}
}

if (mType != null) {
AddEmptyTypeArgumentsForUnboundGenerics(mType.Target);

int outerTypeParamCount = typeDef.DeclaringType == null ? 0 : typeDef.DeclaringType.GenericParameters.Count;

while (typeDef.GenericParameters.Count - outerTypeParamCount > mType.TypeArguments.Count) {
mType.TypeArguments.Add(new SimpleType(""));
}
}

return type;
}
#endregion

#region Convert Type Reference
/// <summary>
/// Converts a type reference.
Expand Down Expand Up @@ -1378,9 +1460,7 @@ private static Expression ConvertArgumentValue(CustomAttributeArgument argument)
if (type != null && type.IsEnum) {
return MakePrimitive(Convert.ToInt64(argument.Value), type);
} else if (argument.Value is TypeReference) {
return new TypeOfExpression() {
Type = ConvertType((TypeReference)argument.Value),
};
return CreateTypeOfExpression((TypeReference)argument.Value);
} else {
return new PrimitiveExpression(argument.Value);
}
Expand Down
31 changes: 1 addition & 30 deletions ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
Expand Up @@ -601,7 +601,7 @@ AstNode TransformByteCode(ILExpression byteCode)
case ILCode.Ldstr: return new Ast.PrimitiveExpression(operand);
case ILCode.Ldtoken:
if (operand is Cecil.TypeReference) {
return new Ast.TypeOfExpression { Type = AddEmptyTypeArgumentsForUnboundGenerics(operandAsTypeRef) }.Member("TypeHandle");
return AstBuilder.CreateTypeOfExpression((TypeReference)operand).Member("TypeHandle");
} else {
return InlineAssembly(byteCode, args);
}
Expand Down Expand Up @@ -749,35 +749,6 @@ AstNode TransformByteCode(ILExpression byteCode)
}
}

AstType AddEmptyTypeArgumentsForUnboundGenerics(AstType type)
{
TypeReference typeRef = type.Annotation<TypeReference>();
if (typeRef == null)
return type;
TypeDefinition typeDef = typeRef.Resolve(); // need to resolve to figure out the number of type parameters
if (typeDef == null || !typeDef.HasGenericParameters)
return type;
SimpleType sType = type as SimpleType;
MemberType mType = type as MemberType;
if (sType != null) {
while (typeDef.GenericParameters.Count > sType.TypeArguments.Count) {
sType.TypeArguments.Add(new SimpleType(""));
}
}

if (mType != null) {
AddEmptyTypeArgumentsForUnboundGenerics(mType.Target);

int outerTypeParamCount = typeDef.DeclaringType == null ? 0 : typeDef.DeclaringType.GenericParameters.Count;

while (typeDef.GenericParameters.Count - outerTypeParamCount > mType.TypeArguments.Count) {
mType.TypeArguments.Add(new SimpleType(""));
}
}

return type;
}

static readonly AstNode objectInitializerPattern = new AssignmentExpression(
new MemberReferenceExpression {
Target = new InitializedObjectExpression()
Expand Down
15 changes: 15 additions & 0 deletions ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
Expand Up @@ -1106,6 +1106,21 @@ public void WriteAssemblyReferences(ModuleDefinition module)

public void WriteModuleHeader(ModuleDefinition module)
{
if (module.HasExportedTypes) {
foreach (ExportedType exportedType in module.ExportedTypes) {
output.Write(".class extern ");
if (exportedType.IsForwarder)
output.Write("forwarder ");
output.Write(exportedType.DeclaringType != null ? exportedType.Name : exportedType.FullName);
OpenBlock(false);
if (exportedType.DeclaringType != null)
output.WriteLine(".class extern {0}", DisassemblerHelpers.Escape(exportedType.DeclaringType.FullName));
else
output.WriteLine(".assembly extern {0}", DisassemblerHelpers.Escape(exportedType.Scope.Name));
CloseBlock();
}
}

output.WriteLine(".module {0}", module.Name);
output.WriteLine("// MVID: {0}", module.Mvid.ToString("B").ToUpperInvariant());
// TODO: imagebase, file alignment, stackreserve, subsystem
Expand Down
Expand Up @@ -15,7 +15,7 @@ public override object VisitAttribute(NRefactory.CSharp.Attribute attribute, obj
var section = (AttributeSection)attribute.Parent;
SimpleType type = attribute.Type as SimpleType;
if (section.AttributeTarget == "assembly" &&
(type.Identifier == "CompilationRelaxations" || type.Identifier == "RuntimeCompatibility"))
(type.Identifier == "CompilationRelaxations" || type.Identifier == "RuntimeCompatibility" || type.Identifier == "SecurityPermission" || type.Identifier == "AssemblyVersion"))
{
attribute.Remove();
if (section.Attributes.Count == 0)
Expand Down

0 comments on commit f56b02e

Please sign in to comment.