Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
72e020ae35
  1. 157
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 72
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs
  3. 6
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
  4. 20
      NRefactory/ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs

157
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -256,6 +256,20 @@ namespace ICSharpCode.Decompiler.Ast
AddTypeMembers(astType, typeDef); AddTypeMembers(astType, typeDef);
if (astType.Members.Any(m => m is IndexerDeclaration)) {
// Remove the [DefaultMember] attribute if the class contains indexers
foreach (AttributeSection section in astType.Attributes) {
foreach (Ast.Attribute attr in section.Attributes) {
TypeReference tr = attr.Type.Annotation<TypeReference>();
if (tr != null && tr.Name == "DefaultMemberAttribute" && tr.Namespace == "System.Reflection") {
attr.Remove();
}
}
if (section.Attributes.Count == 0)
section.Remove();
}
}
} }
context.CurrentType = oldCurrentType; context.CurrentType = oldCurrentType;
@ -573,53 +587,22 @@ namespace ICSharpCode.Decompiler.Ast
} }
// Add properties // Add properties
CreateProperties(astType, typeDef); foreach(PropertyDefinition propDef in typeDef.Properties) {
astType.Members.Add(CreateProperty(propDef));
// Add constructors
foreach(MethodDefinition methodDef in typeDef.Methods) {
if (!methodDef.IsConstructor) continue;
astType.AddChild(CreateConstructor(methodDef), TypeDeclaration.MemberRole);
} }
// Add methods // Add methods
foreach(MethodDefinition methodDef in typeDef.Methods) { foreach(MethodDefinition methodDef in typeDef.Methods) {
if (methodDef.IsConstructor || MemberIsHidden(methodDef, context.Settings)) continue; if (MemberIsHidden(methodDef, context.Settings)) continue;
astType.AddChild(CreateMethod(methodDef), TypeDeclaration.MemberRole); if (methodDef.IsConstructor)
} astType.Members.Add(CreateConstructor(methodDef));
}
private void CreateProperties(TypeDeclaration astType, TypeDefinition typeDef)
{
CustomAttribute attributeToRemove = null;
foreach (PropertyDefinition propDef in typeDef.Properties) {
MemberDeclaration astProp = CreateProperty(propDef);
if (astProp.Name == "Item" && propDef.HasParameters) {
var defaultMember = GetDefaultMember(astType.Annotation<TypeDefinition>());
if (defaultMember.Item1 == "Item") {
astProp = ConvertPropertyToIndexer((PropertyDeclaration)astProp, propDef);
attributeToRemove = defaultMember.Item2;
} else if ((propDef.GetMethod ?? propDef.SetMethod).HasOverrides) {
astProp = ConvertPropertyToIndexer((PropertyDeclaration)astProp, propDef);
}
}
astType.AddChild(astProp, TypeDeclaration.MemberRole);
}
if (attributeToRemove != null) {
var astAttr = astType.Attributes.SelectMany(sec => sec.Attributes).First(attr => attr.Annotation<CustomAttribute>() == attributeToRemove);
var attrSection = (AttributeSection)astAttr.Parent;
if (attrSection.Attributes.Count == 1)
attrSection.Remove();
else else
astAttr.Remove(); astType.Members.Add(CreateMethod(methodDef));
} }
} }
MethodDeclaration CreateMethod(MethodDefinition methodDef) AttributedNode CreateMethod(MethodDefinition methodDef)
{ {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MemberMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
@ -646,6 +629,22 @@ namespace ICSharpCode.Decompiler.Ast
} }
} }
} }
// Convert MethodDeclaration to OperatorDeclaration if possible
if (methodDef.IsSpecialName && !methodDef.HasGenericParameters) {
OperatorType? opType = OperatorDeclaration.GetOperatorType(methodDef.Name);
if (opType.HasValue) {
OperatorDeclaration op = new OperatorDeclaration();
op.CopyAnnotationsFrom(astMethod);
op.ReturnType = astMethod.ReturnType.Detach();
op.OperatorType = opType.Value;
op.Modifiers = astMethod.Modifiers;
astMethod.Parameters.MoveTo(op.Parameters);
astMethod.Attributes.MoveTo(op.Attributes);
op.Body = astMethod.Body.Detach();
return op;
}
}
astMethod.WithAnnotation(methodMapping); astMethod.WithAnnotation(methodMapping);
return astMethod; return astMethod;
} }
@ -708,34 +707,6 @@ namespace ICSharpCode.Decompiler.Ast
return astMethod; return astMethod;
} }
IndexerDeclaration ConvertPropertyToIndexer(PropertyDeclaration astProp, PropertyDefinition propDef)
{
var astIndexer = new IndexerDeclaration();
astIndexer.Name = astProp.Name;
astIndexer.CopyAnnotationsFrom(astProp);
astProp.Attributes.MoveTo(astIndexer.Attributes);
astIndexer.Modifiers = astProp.Modifiers;
astIndexer.PrivateImplementationType = astProp.PrivateImplementationType.Detach();
astIndexer.ReturnType = astProp.ReturnType.Detach();
astIndexer.Getter = astProp.Getter.Detach();
astIndexer.Setter = astProp.Setter.Detach();
astIndexer.Parameters.AddRange(MakeParameters(propDef.Parameters));
if (astIndexer.Getter != null && propDef.GetMethod != null) {
// Create mapping - used in debugger
MemberMapping memberMapping = propDef.GetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
astIndexer.Getter.WithAnnotation(memberMapping);
}
if (astIndexer.Setter != null && propDef.SetMethod != null) {
// Create mapping - used in debugger
MemberMapping memberMapping = propDef.SetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
astIndexer.Setter.WithAnnotation(memberMapping);
}
return astIndexer;
}
Modifiers FixUpVisibility(Modifiers m) Modifiers FixUpVisibility(Modifiers m)
{ {
Modifiers v = m & Modifiers.VisibilityMask; Modifiers v = m & Modifiers.VisibilityMask;
@ -749,19 +720,19 @@ namespace ICSharpCode.Decompiler.Ast
return m & ~Modifiers.Private; return m & ~Modifiers.Private;
} }
PropertyDeclaration CreateProperty(PropertyDefinition propDef) MemberDeclaration CreateProperty(PropertyDefinition propDef)
{ {
PropertyDeclaration astProp = new PropertyDeclaration(); PropertyDeclaration astProp = new PropertyDeclaration();
astProp.AddAnnotation(propDef); astProp.AddAnnotation(propDef);
var accessor = propDef.GetMethod ?? propDef.SetMethod; var accessor = propDef.GetMethod ?? propDef.SetMethod;
Modifiers getterModifiers = Modifiers.None; Modifiers getterModifiers = Modifiers.None;
Modifiers setterModifiers = Modifiers.None; Modifiers setterModifiers = Modifiers.None;
if (!propDef.DeclaringType.IsInterface && !accessor.HasOverrides) { if (accessor.HasOverrides) {
astProp.PrivateImplementationType = ConvertType(accessor.Overrides.First().DeclaringType);
} else if (!propDef.DeclaringType.IsInterface) {
getterModifiers = ConvertModifiers(propDef.GetMethod); getterModifiers = ConvertModifiers(propDef.GetMethod);
setterModifiers = ConvertModifiers(propDef.SetMethod); setterModifiers = ConvertModifiers(propDef.SetMethod);
astProp.Modifiers = FixUpVisibility(getterModifiers | setterModifiers); astProp.Modifiers = FixUpVisibility(getterModifiers | setterModifiers);
} else if (accessor.HasOverrides) {
astProp.PrivateImplementationType = ConvertType(accessor.Overrides.First().DeclaringType);
} }
astProp.Name = CleanName(propDef.Name); astProp.Name = CleanName(propDef.Name);
astProp.ReturnType = ConvertType(propDef.PropertyType, propDef); astProp.ReturnType = ConvertType(propDef.PropertyType, propDef);
@ -797,9 +768,55 @@ namespace ICSharpCode.Decompiler.Ast
astProp.Setter.WithAnnotation(methodMapping); astProp.Setter.WithAnnotation(methodMapping);
} }
ConvertCustomAttributes(astProp, propDef); ConvertCustomAttributes(astProp, propDef);
// Check whether the property is an indexer:
if (propDef.HasParameters) {
PropertyDefinition basePropDef = propDef;
if (accessor.HasOverrides) {
// if the property is explicitly implementing an interface, look up the property in the interface:
MethodDefinition baseAccessor = accessor.Overrides.First().Resolve();
if (baseAccessor != null) {
foreach (PropertyDefinition baseProp in baseAccessor.DeclaringType.Properties) {
if (baseProp.GetMethod == baseAccessor || baseProp.SetMethod == baseAccessor) {
basePropDef = baseProp;
break;
}
}
}
}
// figure out the name of the indexer:
string defaultMemberName = null;
var defaultMemberAttribute = basePropDef.DeclaringType.CustomAttributes.FirstOrDefault(IsDefaultMemberAttribute);
if (defaultMemberAttribute != null && defaultMemberAttribute.ConstructorArguments.Count == 1) {
defaultMemberName = defaultMemberAttribute.ConstructorArguments[0].Value as string;
}
if (basePropDef.Name == defaultMemberName) {
return ConvertPropertyToIndexer(astProp, propDef);
}
}
return astProp; return astProp;
} }
bool IsDefaultMemberAttribute(CustomAttribute ca)
{
return ca.AttributeType.Name == "DefaultMemberAttribute" && ca.AttributeType.Namespace == "System.Reflection";
}
IndexerDeclaration ConvertPropertyToIndexer(PropertyDeclaration astProp, PropertyDefinition propDef)
{
var astIndexer = new IndexerDeclaration();
astIndexer.Name = astProp.Name;
astIndexer.CopyAnnotationsFrom(astProp);
astProp.Attributes.MoveTo(astIndexer.Attributes);
astIndexer.Modifiers = astProp.Modifiers;
astIndexer.PrivateImplementationType = astProp.PrivateImplementationType.Detach();
astIndexer.ReturnType = astProp.ReturnType.Detach();
astIndexer.Getter = astProp.Getter.Detach();
astIndexer.Setter = astProp.Setter.Detach();
astIndexer.Parameters.AddRange(MakeParameters(propDef.Parameters));
return astIndexer;
}
AttributedNode CreateEvent(EventDefinition eventDef) AttributedNode CreateEvent(EventDefinition eventDef)
{ {
if (eventDef.AddMethod != null && eventDef.AddMethod.IsAbstract) { if (eventDef.AddMethod != null && eventDef.AddMethod.IsAbstract) {

72
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs

@ -29,41 +29,45 @@ using System.Linq;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public enum OperatorType { public enum OperatorType
{
// Values must correspond to Mono.CSharp.Operator.OpType
// due to the casts used in OperatorDeclaration.
// Unary operators // Unary operators
LogicalNot, LogicalNot = Mono.CSharp.Operator.OpType.LogicalNot,
OnesComplement, OnesComplement = Mono.CSharp.Operator.OpType.OnesComplement,
Increment, Increment = Mono.CSharp.Operator.OpType.Increment,
Decrement, Decrement = Mono.CSharp.Operator.OpType.Decrement,
True, True = Mono.CSharp.Operator.OpType.True,
False, False = Mono.CSharp.Operator.OpType.False,
// Unary and Binary operators // Unary and Binary operators
Addition, Addition = Mono.CSharp.Operator.OpType.Addition,
Subtraction, Subtraction = Mono.CSharp.Operator.OpType.Subtraction,
UnaryPlus, UnaryPlus = Mono.CSharp.Operator.OpType.UnaryPlus,
UnaryNegation, UnaryNegation = Mono.CSharp.Operator.OpType.UnaryNegation,
// Binary operators // Binary operators
Multiply, Multiply = Mono.CSharp.Operator.OpType.Multiply,
Division, Division = Mono.CSharp.Operator.OpType.Division,
Modulus, Modulus = Mono.CSharp.Operator.OpType.Modulus,
BitwiseAnd, BitwiseAnd = Mono.CSharp.Operator.OpType.BitwiseAnd,
BitwiseOr, BitwiseOr = Mono.CSharp.Operator.OpType.BitwiseOr,
ExclusiveOr, ExclusiveOr = Mono.CSharp.Operator.OpType.ExclusiveOr,
LeftShift, LeftShift = Mono.CSharp.Operator.OpType.LeftShift,
RightShift, RightShift = Mono.CSharp.Operator.OpType.RightShift,
Equality, Equality = Mono.CSharp.Operator.OpType.Equality,
Inequality, Inequality = Mono.CSharp.Operator.OpType.Inequality,
GreaterThan, GreaterThan = Mono.CSharp.Operator.OpType.GreaterThan,
LessThan, LessThan = Mono.CSharp.Operator.OpType.LessThan,
GreaterThanOrEqual, GreaterThanOrEqual = Mono.CSharp.Operator.OpType.GreaterThanOrEqual,
LessThanOrEqual, LessThanOrEqual = Mono.CSharp.Operator.OpType.LessThanOrEqual,
// Implicit and Explicit // Implicit and Explicit
Implicit, Implicit = Mono.CSharp.Operator.OpType.Implicit,
Explicit Explicit = Mono.CSharp.Operator.OpType.Explicit
} }
public class OperatorDeclaration : AttributedNode public class OperatorDeclaration : AttributedNode
@ -98,11 +102,25 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (Roles.Body, value); } set { SetChildByRole (Roles.Body, value); }
} }
/// <summary>
/// Gets the operator type from the method name, or null, if the method does not represent one of the known operator types.
/// </summary>
public static OperatorType? GetOperatorType(string methodName)
{
return (OperatorType?)Mono.CSharp.Operator.GetType(methodName);
}
/// <summary>
/// Gets the method name for the operator type. ("op_Addition", "op_Implicit", etc.)
/// </summary>
public static string GetName(OperatorType type) public static string GetName(OperatorType type)
{ {
return Mono.CSharp.Operator.GetMetadataName((Mono.CSharp.Operator.OpType)type); return Mono.CSharp.Operator.GetMetadataName((Mono.CSharp.Operator.OpType)type);
} }
/// <summary>
/// Gets the token for the operator type ("+", "implicit", etc.)
/// </summary>
public static string GetToken(OperatorType type) public static string GetToken(OperatorType type)
{ {
return Mono.CSharp.Operator.GetName((Mono.CSharp.Operator.OpType)type); return Mono.CSharp.Operator.GetName((Mono.CSharp.Operator.OpType)type);

6
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -1626,8 +1626,10 @@ namespace ICSharpCode.NRefactory.CSharp
LPar(); LPar();
Space(policy.SpacesWithinCatchParentheses); Space(policy.SpacesWithinCatchParentheses);
catchClause.Type.AcceptVisitor(this, data); catchClause.Type.AcceptVisitor(this, data);
Space(); if (!string.IsNullOrEmpty(catchClause.VariableName)) {
WriteIdentifier(catchClause.VariableName); Space();
WriteIdentifier(catchClause.VariableName);
}
Space(policy.SpacesWithinCatchParentheses); Space(policy.SpacesWithinCatchParentheses);
RPar(); RPar();
} }

20
NRefactory/ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs

@ -551,25 +551,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (location != null) if (location != null)
newOperator.AddChild (new CSharpTokenNode (Convert (location[0]), "operator".Length), OperatorDeclaration.OperatorKeywordRole); newOperator.AddChild (new CSharpTokenNode (Convert (location[0]), "operator".Length), OperatorDeclaration.OperatorKeywordRole);
int opLength = 1; int opLength = OperatorDeclaration.GetToken(newOperator.OperatorType).Length;
switch (newOperator.OperatorType) {
case OperatorType.LeftShift:
case OperatorType.RightShift:
case OperatorType.LessThanOrEqual:
case OperatorType.GreaterThanOrEqual:
case OperatorType.Equality:
case OperatorType.Inequality:
// case OperatorType.LogicalAnd:
// case OperatorType.LogicalOr:
opLength = 2;
break;
case OperatorType.True:
opLength = "true".Length;
break;
case OperatorType.False:
opLength = "false".Length;
break;
}
if (location != null) if (location != null)
newOperator.AddChild (new CSharpTokenNode (Convert (location[1]), opLength), OperatorDeclaration.OperatorTypeRole); newOperator.AddChild (new CSharpTokenNode (Convert (location[1]), opLength), OperatorDeclaration.OperatorTypeRole);
} }

Loading…
Cancel
Save