Browse Source

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

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
94882d0d2c
  1. 1
      .gitignore
  2. 214
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  3. 38
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  4. 4
      ICSharpCode.Decompiler/Ast/DeclareVariableInSmallestScope.cs
  5. 1
      ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs
  6. 4
      ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs
  7. 40
      ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs
  8. 4
      ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs
  9. 9
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  10. 114
      ICSharpCode.Decompiler/Tests/CodeSampleFileParser.cs
  11. 41
      ICSharpCode.Decompiler/Tests/CustomAttributes.code.cs
  12. 30
      ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeTests.cs
  13. 6
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_AssemblyCustomAttribute.cs
  14. 409
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs
  15. 46
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.cs
  16. 71
      ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs
  17. 4
      ICSharpCode.Decompiler/Tests/Generics.cs
  18. 31
      ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs
  19. 28
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  20. 14
      ICSharpCode.Decompiler/Tests/TestRunner.cs
  21. 18
      ICSharpCode.Decompiler/Tests/Types/EnumTests.cs
  22. 114
      ICSharpCode.Decompiler/Tests/Types/S_EnumSamples.cs
  23. 12
      ICSharpCode.Decompiler/Tests/Types/TypeTests.cs
  24. BIN
      ICSharpCode.Decompiler/Tests/nunit.framework.dll
  25. 93
      ILSpy.sln
  26. 5
      ILSpy/CSharpLanguage.cs
  27. 6
      ILSpy/ILAstLanguage.cs
  28. 2
      Mono.Cecil/Mono.Cecil/SecurityDeclaration.cs
  29. 16
      NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
  30. 15
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/AstStructureTests.cs
  31. 38
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AliasReferenceExpressionTests.cs
  32. 1
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AnonymousMethodTests.cs
  33. 52
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayObjectCreateExpressionTests.cs
  34. 151
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs
  35. 60
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/DefaultValueExpressionTests.cs
  36. 28
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IdentifierExpressionTests.cs
  37. 179
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs
  38. 15
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IsExpressionTests.cs
  39. 117
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/LambdaExpressionTests.cs
  40. 97
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs
  41. 18
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PointerReferenceExpressionTests.cs
  42. 232
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs
  43. 4
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/SizeOfExpressionTests.cs
  44. 9
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/StackAllocExpressionTests.cs
  45. 97
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs
  46. 6
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/UnaryOperatorExpressionTests.cs
  47. 68
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs
  48. 198
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs
  49. 2
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs
  50. 41
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs
  51. 15
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs
  52. 20
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ForStatementTests.cs
  53. 56
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/TryCatchStatementTests.cs
  54. 3
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/YieldStatementTests.cs
  55. 113
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/EventDeclarationTests.cs
  56. 60
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/FieldDeclarationTests.cs
  57. 37
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/IndexerDeclarationTests.cs
  58. 266
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs
  59. 16
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/OperatorDeclarationTests.cs
  60. 10
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs
  61. 2
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs
  62. 10
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  63. 2
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnsafeCodeTests.cs
  64. 1
      NRefactory/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  65. 1
      NRefactory/ICSharpCode.NRefactory.VB.Tests/ICSharpCode.NRefactory.VB.Tests.csproj
  66. 1
      NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj
  67. 6
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstLocation.cs
  68. 5
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs
  69. 10
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs
  70. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs
  71. 6
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs
  72. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs
  73. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs
  74. 61
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs
  75. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs
  76. 5
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs
  77. 19
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/DelegateDeclaration.cs
  78. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeDeclaration.cs
  79. 7
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs
  80. 7
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs
  81. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs
  82. 21
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs
  83. 68
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs
  84. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs
  85. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs
  86. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/FixedStatement.cs
  87. 3
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs
  88. 4
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs
  89. 14
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs
  90. 6
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs
  91. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/EnumMemberDeclaration.cs
  92. 25
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/EventDeclaration.cs
  93. 18
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/FieldDeclaration.cs
  94. 30
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/IndexerDeclaration.cs
  95. 6
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/MemberDeclaration.cs
  96. 8
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/MethodDeclaration.cs
  97. 23
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs
  98. 14
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ParameterDeclaration.cs
  99. 9
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/PropertyDeclaration.cs
  100. 164
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
  101. Some files were not shown because too many files have changed in this diff Show More

1
.gitignore vendored

@ -3,3 +3,4 @@ obj/ @@ -3,3 +3,4 @@ obj/
/ICSharpCode.Decompiler/Properties/AssemblyInfo.cs
/ILSpy/Properties/AssemblyInfo.cs
*.suo

214
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -6,8 +6,10 @@ using System.Threading; @@ -6,8 +6,10 @@ using System.Threading;
using Decompiler.Transforms;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Utils;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Ast = ICSharpCode.NRefactory.CSharp;
using ClassType = ICSharpCode.NRefactory.TypeSystem.ClassType;
using VarianceModifier = ICSharpCode.NRefactory.TypeSystem.VarianceModifier;
@ -62,14 +64,19 @@ namespace Decompiler @@ -62,14 +64,19 @@ namespace Decompiler
astCompileUnit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null);
}
public void AddAssembly(AssemblyDefinition assemblyDefinition)
public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
{
astCompileUnit.AddChild(
new UsingDeclaration {
Import = new SimpleType("System")
}, CompilationUnit.MemberRole);
foreach(TypeDefinition typeDef in assemblyDefinition.MainModule.Types) {
ConvertCustomAttributes(astCompileUnit, assemblyDefinition, AttributeTarget.Assembly);
ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, AttributeTarget.Module);
if (!onlyAssemblyLevel) {
foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types)
{
// Skip nested types - they will be added by the parent type
if (typeDef.DeclaringType != null) continue;
// Skip the <Module> class
@ -78,6 +85,7 @@ namespace Decompiler @@ -78,6 +85,7 @@ namespace Decompiler
AddType(typeDef);
}
}
}
NamespaceDeclaration GetCodeNamespace(string name)
{
@ -167,13 +175,22 @@ namespace Decompiler @@ -167,13 +175,22 @@ namespace Decompiler
if (typeDef.IsEnum) {
long expectedEnumMemberValue = 0;
bool forcePrintingInitializers = IsFlagsEnum(typeDef);
foreach (FieldDefinition field in typeDef.Fields) {
if (field.IsRuntimeSpecialName) {
// the value__ field
if (field.FieldType != typeDef.Module.TypeSystem.Int32) {
astType.AddChild(ConvertType(field.FieldType), TypeDeclaration.BaseTypeRole);
}
} else {
EnumMemberDeclaration enumMember = new EnumMemberDeclaration();
enumMember.Name = CleanName(field.Name);
long memberValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false);
if (forcePrintingInitializers || memberValue != expectedEnumMemberValue) {
enumMember.AddChild(new PrimitiveExpression(field.Constant), EnumMemberDeclaration.InitializerRole);
}
expectedEnumMemberValue = memberValue + 1;
astType.AddChild(enumMember, TypeDeclaration.MemberRole);
}
}
@ -189,9 +206,15 @@ namespace Decompiler @@ -189,9 +206,15 @@ namespace Decompiler
AddTypeMembers(astType, typeDef);
}
ConvertCustomAttributes(astType, typeDef);
return astType;
}
public void Transform(IAstTransform transform)
{
transform.Run(astCompileUnit);
}
string CleanName(string name)
{
int pos = name.LastIndexOf('`');
@ -482,22 +505,44 @@ namespace Decompiler @@ -482,22 +505,44 @@ namespace Decompiler
astMethod.Modifiers = ConvertModifiers(methodDef);
astMethod.Body = AstMethodBodyBuilder.CreateMethodBody(methodDef, context);
}
ConvertCustomAttributes(astMethod, methodDef);
ConvertCustomAttributes(astMethod, methodDef.MethodReturnType, AttributeTarget.Return);
return astMethod;
}
IEnumerable<TypeParameterDeclaration> MakeTypeParameters(IEnumerable<GenericParameter> genericParameters)
{
return genericParameters.Select(
gp => new TypeParameterDeclaration {
Name = CleanName(gp.Name),
Variance = gp.IsContravariant ? VarianceModifier.Contravariant : gp.IsCovariant ? VarianceModifier.Covariant : VarianceModifier.Invariant
});
foreach (var gp in genericParameters) {
TypeParameterDeclaration tp = new TypeParameterDeclaration();
tp.Name = CleanName(gp.Name);
if (gp.IsContravariant)
tp.Variance = VarianceModifier.Contravariant;
else if (gp.IsCovariant)
tp.Variance = VarianceModifier.Covariant;
ConvertCustomAttributes(tp, gp);
yield return tp;
}
}
IEnumerable<Constraint> MakeConstraints(IEnumerable<GenericParameter> genericParameters)
{
// TODO
return Enumerable.Empty<Constraint>();
foreach (var gp in genericParameters) {
Constraint c = new Constraint();
c.TypeParameter = CleanName(gp.Name);
// class/struct must be first
if (gp.HasReferenceTypeConstraint)
c.BaseTypes.Add(new PrimitiveType("class"));
if (gp.HasNotNullableValueTypeConstraint)
c.BaseTypes.Add(new PrimitiveType("struct"));
foreach (var constraintType in gp.Constraints)
c.BaseTypes.Add(ConvertType(constraintType));
if (gp.HasDefaultConstructorConstraint)
c.BaseTypes.Add(new PrimitiveType("new")); // new() must be last
if (c.BaseTypes.Any())
yield return c;
}
}
ConstructorDeclaration CreateConstructor(MethodDefinition methodDef)
@ -534,6 +579,8 @@ namespace Decompiler @@ -534,6 +579,8 @@ namespace Decompiler
astProp.Getter = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(propDef.GetMethod, context)
}.WithAnnotation(propDef.GetMethod);
ConvertCustomAttributes(astProp.Getter, propDef.GetMethod);
ConvertCustomAttributes(astProp.Getter, propDef.GetMethod.MethodReturnType, AttributeTarget.Return);
if (methodMapping != null)
astProp.Getter.AddAnnotation(methodMapping);
@ -545,10 +592,14 @@ namespace Decompiler @@ -545,10 +592,14 @@ namespace Decompiler
astProp.Setter = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(propDef.SetMethod, context)
}.WithAnnotation(propDef.SetMethod);
ConvertCustomAttributes(astProp.Setter, propDef.SetMethod);
ConvertCustomAttributes(astProp.Setter, propDef.SetMethod.MethodReturnType, AttributeTarget.Return);
ConvertCustomAttributes(astProp.Setter, propDef.SetMethod.Parameters.Last(), AttributeTarget.Param);
if (methodMapping != null)
astProp.Setter.AddAnnotation(methodMapping);
}
ConvertCustomAttributes(astProp, propDef);
return astProp;
}
@ -598,6 +649,7 @@ namespace Decompiler @@ -598,6 +649,7 @@ namespace Decompiler
else
initializer.Initializer = new PrimitiveExpression(fieldDef.Constant);
}
ConvertCustomAttributes(astField, fieldDef);
return astField;
}
@ -613,8 +665,152 @@ namespace Decompiler @@ -613,8 +665,152 @@ namespace Decompiler
}
// TODO: params, this
ConvertCustomAttributes(astParam, paramDef);
yield return astParam;
}
}
static void ConvertCustomAttributes(AstNode attributedNode, ICustomAttributeProvider customAttributeProvider, AttributeTarget target = AttributeTarget.None)
{
if (customAttributeProvider.HasCustomAttributes) {
var attributes = new List<ICSharpCode.NRefactory.CSharp.Attribute>();
foreach (var customAttribute in customAttributeProvider.CustomAttributes) {
var attribute = new ICSharpCode.NRefactory.CSharp.Attribute();
attribute.Type = ConvertType(customAttribute.AttributeType);
attributes.Add(attribute);
SimpleType st = attribute.Type as SimpleType;
if (st != null && st.Identifier.EndsWith("Attribute", StringComparison.Ordinal)) {
st.Identifier = st.Identifier.Substring(0, st.Identifier.Length - "Attribute".Length);
}
if(customAttribute.HasConstructorArguments) {
foreach (var parameter in customAttribute.ConstructorArguments) {
Expression parameterValue = ConvertArgumentValue(parameter);
attribute.Arguments.Add(parameterValue);
}
}
if (customAttribute.HasProperties) {
foreach (var propertyNamedArg in customAttribute.Properties) {
var propertyReference = customAttribute.AttributeType.Resolve().Properties.First(pr => pr.Name == propertyNamedArg.Name);
var propertyName = new IdentifierExpression(propertyNamedArg.Name).WithAnnotation(propertyReference);
var argumentValue = ConvertArgumentValue(propertyNamedArg.Argument);
attribute.Arguments.Add(new AssignmentExpression(propertyName, argumentValue));
}
}
if (customAttribute.HasFields) {
foreach (var fieldNamedArg in customAttribute.Fields) {
var fieldReference = customAttribute.AttributeType.Resolve().Fields.First(f => f.Name == fieldNamedArg.Name);
var fieldName = new IdentifierExpression(fieldNamedArg.Name).WithAnnotation(fieldReference);
var argumentValue = ConvertArgumentValue(fieldNamedArg.Argument);
attribute.Arguments.Add(new AssignmentExpression(fieldName, argumentValue));
}
}
}
if (target == AttributeTarget.Module || target == AttributeTarget.Assembly) {
// use separate section for each attribute
foreach (var attribute in attributes) {
var section = new AttributeSection();
section.AttributeTarget = target;
section.Attributes.Add(attribute);
attributedNode.AddChild(section, AttributedNode.AttributeRole);
}
} else {
// use single section for all attributes
var section = new AttributeSection();
section.AttributeTarget = target;
section.Attributes.AddRange(attributes);
attributedNode.AddChild(section, AttributedNode.AttributeRole);
}
}
}
private static Expression ConvertArgumentValue(CustomAttributeArgument parameter)
{
var type = parameter.Type.Resolve();
Expression parameterValue;
if (type.IsEnum)
{
parameterValue = MakePrimitive(Convert.ToInt64(parameter.Value), type);
}
else if (parameter.Value is TypeReference)
{
parameterValue = new TypeOfExpression()
{
Type = ConvertType((TypeReference)parameter.Value),
};
}
else
{
parameterValue = new PrimitiveExpression(parameter.Value);
}
return parameterValue;
}
internal static Expression MakePrimitive(long val, TypeReference type)
{
if (TypeAnalysis.IsBoolean(type) && val == 0)
return new Ast.PrimitiveExpression(false);
else if (TypeAnalysis.IsBoolean(type) && val == 1)
return new Ast.PrimitiveExpression(true);
if (type != null)
{ // cannot rely on type.IsValueType, it's not set for typerefs (but is set for typespecs)
TypeDefinition enumDefinition = type.Resolve();
if (enumDefinition != null && enumDefinition.IsEnum)
{
foreach (FieldDefinition field in enumDefinition.Fields)
{
if (field.IsStatic && object.Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false), val))
return ConvertType(enumDefinition).Member(field.Name).WithAnnotation(field);
else if (!field.IsStatic && field.IsRuntimeSpecialName)
type = field.FieldType; // use primitive type of the enum
}
if (IsFlagsEnum(enumDefinition))
{
long enumValue = val;
Expression expr = null;
foreach (FieldDefinition field in enumDefinition.Fields.Where(fld => fld.IsStatic))
{
long fieldValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false);
if (fieldValue == 0)
continue; // skip None enum value
if ((fieldValue & enumValue) == fieldValue)
{
var fieldExpression = ConvertType(enumDefinition).Member(field.Name).WithAnnotation(field);
if (expr == null)
expr = fieldExpression;
else
expr = new BinaryOperatorExpression(expr, BinaryOperatorType.BitwiseOr, fieldExpression);
enumValue &= ~fieldValue;
if (enumValue == 0)
break;
}
}
if(enumValue == 0 && expr != null)
return expr;
}
TypeCode enumBaseTypeCode = TypeAnalysis.GetTypeCode(type);
return new Ast.PrimitiveExpression(CSharpPrimitiveCast.Cast(enumBaseTypeCode, val, false)).CastTo(ConvertType(enumDefinition));
}
}
TypeCode code = TypeAnalysis.GetTypeCode(type);
if (code == TypeCode.Object)
return new Ast.PrimitiveExpression((int)val);
else
return new Ast.PrimitiveExpression(CSharpPrimitiveCast.Cast(code, val, false));
}
static bool IsFlagsEnum(TypeDefinition type)
{
if (!type.HasCustomAttributes)
return false;
return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute");
}
}
}

38
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -535,7 +535,7 @@ namespace Decompiler @@ -535,7 +535,7 @@ namespace Decompiler
return MakeRef(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name).WithAnnotation(operand));
}
case Code.Ldc_I4:
return MakePrimitive((int)operand, byteCode.InferredType);
return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType);
case Code.Ldc_I8:
case Code.Ldc_R4:
case Code.Ldc_R8:
@ -794,7 +794,7 @@ namespace Decompiler @@ -794,7 +794,7 @@ namespace Decompiler
if (TypeAnalysis.IsBoolean(actualType))
return expr;
if (actualIsIntegerOrEnum) {
return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, MakePrimitive(0, actualType));
return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, AstBuilder.MakePrimitive(0, actualType));
} else {
return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression());
}
@ -802,39 +802,21 @@ namespace Decompiler @@ -802,39 +802,21 @@ namespace Decompiler
if (TypeAnalysis.IsBoolean(actualType) && requiredIsIntegerOrEnum) {
return new ConditionalExpression {
Condition = expr,
TrueExpression = MakePrimitive(1, reqType),
FalseExpression = MakePrimitive(0, reqType)
TrueExpression = AstBuilder.MakePrimitive(1, reqType),
FalseExpression = AstBuilder.MakePrimitive(0, reqType)
};
}
if (expr is PrimitiveExpression && !requiredIsIntegerOrEnum && TypeAnalysis.IsEnum(actualType))
{
return expr.CastTo(AstBuilder.ConvertType(actualType));
}
if (actualIsIntegerOrEnum && requiredIsIntegerOrEnum) {
return expr.CastTo(AstBuilder.ConvertType(reqType));
}
return expr;
}
}
Expression MakePrimitive(long val, TypeReference type)
{
if (TypeAnalysis.IsBoolean(type) && val == 0)
return new Ast.PrimitiveExpression(false);
else if (TypeAnalysis.IsBoolean(type) && val == 1)
return new Ast.PrimitiveExpression(true);
if (type != null) { // cannot rely on type.IsValueType, it's not set for typerefs (but is set for typespecs)
TypeDefinition enumDefinition = type.Resolve();
if (enumDefinition != null && enumDefinition.IsEnum) {
foreach (FieldDefinition field in enumDefinition.Fields) {
if (field.IsStatic && object.Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false), val))
return AstBuilder.ConvertType(enumDefinition).Member(field.Name).WithAnnotation(field);
else if (!field.IsStatic && field.IsRuntimeSpecialName)
type = field.FieldType; // use primitive type of the enum
}
}
}
TypeCode code = TypeAnalysis.GetTypeCode(type);
if (code == TypeCode.Object)
return new Ast.PrimitiveExpression((int)val);
else
return new Ast.PrimitiveExpression(CSharpPrimitiveCast.Cast(code, val, false));
}
}
}

4
ICSharpCode.Decompiler/Ast/DeclareVariableInSmallestScope.cs

@ -15,8 +15,8 @@ namespace Decompiler @@ -15,8 +15,8 @@ namespace Decompiler
{
static readonly ExpressionStatement assignmentPattern = new ExpressionStatement(
new AssignmentExpression(
new NamedNode("ident", new IdentifierExpression()).ToExpression(),
new AnyNode("init").ToExpression()
new NamedNode("ident", new IdentifierExpression()),
new AnyNode("init")
));
/// <summary>

1
ICSharpCode.Decompiler/Ast/Transforms/ConvertConstructorCallIntoInitializer.cs

@ -48,6 +48,7 @@ namespace Decompiler.Transforms @@ -48,6 +48,7 @@ namespace Decompiler.Transforms
if (ctors.Length == 1 && ctors[0].Body.Children.Count() == 0
&& ctors[0].Initializer.ConstructorInitializerType == ConstructorInitializerType.Base
&& ctors[0].Initializer.Arguments.Count() == 0
&& ctors[0].Parameters.Count == 0
&& ctors[0].Modifiers == ((typeDeclaration.Modifiers & Modifiers.Abstract) == Modifiers.Abstract ? Modifiers.Protected : Modifiers.Public))
{
ctors[0].Remove();

4
ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs

@ -196,8 +196,8 @@ namespace Decompiler.Transforms @@ -196,8 +196,8 @@ namespace Decompiler.Transforms
// "variableName.MemberName = right;"
ExpressionStatement closureFieldAssignmentPattern = new ExpressionStatement(
new AssignmentExpression(
new NamedNode("left", new MemberReferenceExpression { Target = new IdentifierExpression(variable.Name) }).ToExpression(),
new AnyNode("right").ToExpression()
new NamedNode("left", new MemberReferenceExpression { Target = new IdentifierExpression(variable.Name) }),
new AnyNode("right")
)
);
Match m = closureFieldAssignmentPattern.Match(cur);

40
ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs

@ -26,14 +26,14 @@ namespace Decompiler.Transforms @@ -26,14 +26,14 @@ namespace Decompiler.Transforms
/// $type $variable = $initializer;
/// </summary>
static readonly AstNode variableDeclPattern = new VariableDeclarationStatement {
Type = new AnyNode("type").ToType(),
Type = new AnyNode("type"),
Variables = {
new NamedNode(
"variable",
new VariableInitializer {
Initializer = new AnyNode("initializer").ToExpression()
Initializer = new AnyNode("initializer")
}
).ToVariable()
)
}
};
@ -41,7 +41,7 @@ namespace Decompiler.Transforms @@ -41,7 +41,7 @@ namespace Decompiler.Transforms
/// Variable declaration without initializer.
/// </summary>
static readonly AstNode simpleVariableDefinition = new VariableDeclarationStatement {
Type = new AnyNode().ToType(),
Type = new AnyNode(),
Variables = {
new VariableInitializer() // any name but no initializer
}
@ -49,7 +49,7 @@ namespace Decompiler.Transforms @@ -49,7 +49,7 @@ namespace Decompiler.Transforms
#region using
static readonly AstNode usingTryCatchPattern = new TryCatchStatement {
TryBlock = new AnyNode("body").ToBlock(),
TryBlock = new AnyNode("body"),
FinallyBlock = new BlockStatement {
new Choice {
{ "valueType",
@ -58,7 +58,7 @@ namespace Decompiler.Transforms @@ -58,7 +58,7 @@ namespace Decompiler.Transforms
{ "referenceType",
new IfElseStatement {
Condition = new BinaryOperatorExpression(
new NamedNode("ident", new IdentifierExpression()).ToExpression(),
new NamedNode("ident", new IdentifierExpression()),
BinaryOperatorType.InEquality,
new NullReferenceExpression()
),
@ -102,14 +102,14 @@ namespace Decompiler.Transforms @@ -102,14 +102,14 @@ namespace Decompiler.Transforms
#region foreach
UsingStatement foreachPattern = new UsingStatement {
ResourceAcquisition = new VariableDeclarationStatement {
Type = new AnyNode("enumeratorType").ToType(),
Type = new AnyNode("enumeratorType"),
Variables = {
new NamedNode(
"enumeratorVariable",
new VariableInitializer {
Initializer = new AnyNode("collection").ToExpression().Invoke("GetEnumerator")
}
).ToVariable()
)
}
},
EmbeddedStatement = new Choice {
@ -123,14 +123,14 @@ namespace Decompiler.Transforms @@ -123,14 +123,14 @@ namespace Decompiler.Transforms
Condition = new IdentifierExpressionBackreference("enumeratorVariable").ToExpression().Invoke("MoveNext"),
EmbeddedStatement = new BlockStatement {
new VariableDeclarationStatement {
Type = new AnyNode("itemType").ToType(),
Type = new AnyNode("itemType"),
Variables = {
new NamedNode(
"itemVariable",
new VariableInitializer {
Initializer = new IdentifierExpressionBackreference("enumeratorVariable").ToExpression().Member("Current")
}
).ToVariable()
)
}
},
new Repeat(new AnyNode("statement")).ToStatement()
@ -141,16 +141,16 @@ namespace Decompiler.Transforms @@ -141,16 +141,16 @@ namespace Decompiler.Transforms
{ "itemVariableOutsideLoop",
new BlockStatement {
new VariableDeclarationStatement {
Type = new AnyNode("itemType").ToType(),
Type = new AnyNode("itemType"),
Variables = {
new NamedNode("itemVariable", new VariableInitializer()).ToVariable()
new NamedNode("itemVariable", new VariableInitializer())
}
},
new WhileStatement {
Condition = new IdentifierExpressionBackreference("enumeratorVariable").ToExpression().Invoke("MoveNext"),
EmbeddedStatement = new BlockStatement {
new AssignmentExpression {
Left = new IdentifierExpressionBackreference("itemVariable").ToExpression(),
Left = new IdentifierExpressionBackreference("itemVariable"),
Operator = AssignmentOperatorType.Assign,
Right = new IdentifierExpressionBackreference("enumeratorVariable").ToExpression().Member("Current")
},
@ -191,20 +191,22 @@ namespace Decompiler.Transforms @@ -191,20 +191,22 @@ namespace Decompiler.Transforms
#region for
WhileStatement forPattern = new WhileStatement {
Condition = new BinaryOperatorExpression {
Left = new NamedNode("ident", new IdentifierExpression()).ToExpression(),
Left = new NamedNode("ident", new IdentifierExpression()),
Operator = BinaryOperatorType.Any,
Right = new AnyNode("endExpr").ToExpression()
Right = new AnyNode("endExpr")
},
EmbeddedStatement = new BlockStatement {
new Repeat(new AnyNode("statement")).ToStatement(),
Statements = {
new Repeat(new AnyNode("statement")),
new NamedNode(
"increment",
new ExpressionStatement(
new AssignmentExpression {
Left = new Backreference("ident").ToExpression(),
Left = new Backreference("ident"),
Operator = AssignmentOperatorType.Any,
Right = new AnyNode().ToExpression()
})).ToStatement()
Right = new AnyNode()
}))
}
}
};

4
ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs

@ -77,13 +77,13 @@ namespace Decompiler.Transforms @@ -77,13 +77,13 @@ namespace Decompiler.Transforms
}
readonly static AstNode asCastIsNullPattern = new BinaryOperatorExpression(
new AnyNode("expr").ToExpression().CastAs(new AnyNode("type").ToType()),
new AnyNode("expr").ToExpression().CastAs(new AnyNode("type")),
BinaryOperatorType.Equality,
new NullReferenceExpression()
);
readonly static AstNode asCastIsNotNullPattern = new BinaryOperatorExpression(
new AnyNode("expr").ToExpression().CastAs(new AnyNode("type").ToType()),
new AnyNode("expr").ToExpression().CastAs(new AnyNode("type")),
BinaryOperatorType.InEquality,
new NullReferenceExpression()
);

9
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -648,6 +648,15 @@ namespace Decompiler @@ -648,6 +648,15 @@ namespace Decompiler
return IsSigned(type) != null;
}
public static bool IsEnum(TypeReference type)
{
if (type == null)
return false;
// unfortunately we cannot rely on type.IsValueType here - it's not set when the instruction operand is a typeref (as opposed to a typespec)
TypeDefinition typeDef = type.Resolve() as TypeDefinition;
return typeDef != null && typeDef.IsEnum;
}
static bool? IsSigned(TypeReference type)
{
if (type == null)

114
ICSharpCode.Decompiler/Tests/CodeSampleFileParser.cs

@ -0,0 +1,114 @@ @@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ICSharpCode.Decompiler.Tests
{
static class CodeSampleFileParser
{
public static IEnumerable<string> ListSections(string s)
{
var query = from line in ToLines(s)
let sectionName = ReadSectionName(line)
where sectionName != null
select sectionName;
return query;
}
public static string GetSection(string sectionName, string s)
{
var lines = ToLines(s);
bool sectionFound = false;
var sectionText = new StringBuilder();
Action<string> parser = null;
Action<string> commonSectionReader = line =>
{
if (IsCommonSectionEnd(line))
parser = null;
else
sectionText.AppendLine(line);
};
Action<string> namedSectionReader = line =>
{
string name = ReadSectionName(line);
if (name == null)
sectionText.AppendLine(line);
else if (name != sectionName)
parser = null;
};
Action<string> defaultReader = line =>
{
if (IsCommonSectionStart(line))
parser = commonSectionReader;
else if (ReadSectionName(line) == sectionName)
{
parser = namedSectionReader;
sectionFound = true;
}
};
foreach(var line in lines)
{
(parser ?? defaultReader)(line);
}
if (sectionFound)
return sectionText.ToString();
else
return "";
}
public static bool IsCommentOrBlank(string s)
{
if(String.IsNullOrWhiteSpace(s))
return true;
return s.Trim().StartsWith("//");
}
public static string ConcatLines(IEnumerable<string> lines)
{
var buffer = new StringBuilder();
foreach (var line in lines)
{
buffer.AppendLine(line);
}
return buffer.ToString();
}
static string ReadSectionName(string line)
{
line = line.TrimStart();
if (line.StartsWith("//$$"))
return line.Substring(4).Trim();
else
return null;
}
static bool IsCommonSectionStart(string line)
{
return line.Trim() == "//$CS";
}
static bool IsCommonSectionEnd(string line)
{
return line.Trim() == "//$CE";
}
static IEnumerable<string> ToLines(string s)
{
var reader = new StringReader(s);
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
}

41
ICSharpCode.Decompiler/Tests/CustomAttributes.code.cs

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
using System;
namespace aa
{
public static class CustomAtributes
{
[Flags]
public enum EnumWithFlag
{
All = 15,
None = 0,
Item1 = 1,
Item2 = 2,
Item3 = 4,
Item4 = 8
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public MyAttribute(CustomAtributes.EnumWithFlag en)
{
}
}
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.Item1 | CustomAtributes.EnumWithFlag.Item2)]
private static int field;
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.All)]
public static string Property
{
get
{
return "aa";
}
}
[Obsolete("some message")]
public static void ObsoletedMethod()
{
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field);
AttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field;
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, attributeTargets);
}
}
}

30
ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeTests.cs

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.CustomAttributes
{
[TestFixture]
public class CustomAttributeTests : DecompilerTestBase
{
[Test]
public void CustomAttributeSamples()
{
ValidateFileRoundtrip(@"CustomAttributes\S_CustomAttributeSamples.cs");
}
[Test]
public void CustomAttributesMultiTest()
{
ValidateFileRoundtrip(@"CustomAttributes\S_CustomAttributes.cs");
}
[Test]
public void AssemblyCustomAttributesMultiTest()
{
ValidateFileRoundtrip(@"CustomAttributes\S_AssemblyCustomAttribute.cs");
}
}
}

6
ICSharpCode.Decompiler/Tests/CustomAttributes/S_AssemblyCustomAttribute.cs

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
[assembly: CLSCompliant(false)]

409
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs

@ -0,0 +1,409 @@ @@ -0,0 +1,409 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
//$CS
using System;
//$CE
//$$ TargetModule (ignored)
//[module: CLSCompliantAttribute(false)]
//$$ ParameterlessAttributeUsage
namespace ParameterLessAttributeUsage
{
[Flags]
public enum EnumWithFlagsAttribute
{
None = 0
}
}
//$$ AttributeWithEnumArgument
namespace AttributeWithEnumArgument
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
}
//$$ AttributeWithEnumExpressionArgument
namespace AttributeWithEnumExpressionArgument
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Interface)]
public class MyAttributeAttribute : Attribute
{
}
}
//$$ AttributeWithStringExpressionArgument
namespace AttributeWithStringExpressionArgument
{
[Obsolete("message")]
public class ObsoletedClass
{
}
}
//$$ AttributeWithTypeArgument
namespace AttributeWithTypeArgument
{
[AttributeUsage(AttributeTargets.All)]
public class MyTypeAttribute : Attribute
{
public MyTypeAttribute(Type t) : base()
{
}
}
[MyType(typeof(Attribute))]
public class SomeClass
{
}
}
//$$ AppliedToEvent
namespace AppliedToEvent
{
[AttributeUsage(AttributeTargets.Event)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
[MyAttribute]
public event EventHandler MyEvent;
}
}
//$$ AppliedToField
namespace AppliedToField
{
[AttributeUsage(AttributeTargets.Field)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
[MyAttribute]
public int Field;
}
}
//$$ AppliedToProperty
namespace AppliedToProperty
{
public class TestClass
{
[Obsolete("reason")]
public int Property
{
get
{
return 0;
}
}
}
}
//$$ AppliedToPropertyGet
namespace AppliedToPropertyGet
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
public int Property
{
[MyAttribute]
get
{
return 0;
}
}
}
}
//$$ AppliedToPropertySet
namespace AppliedToPropertySet
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
public int Property
{
get
{
return 3;
}
[MyAttribute]
set
{
return;
}
}
}
}
//$$ AppliedToDelegate
[Obsolete("reason")]
public delegate int AppliedToDelegate();
//$$ AppliedToMethod
namespace AppliedToMethod
{
[AttributeUsage(AttributeTargets.Method)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
[MyAttribute]
public void Method()
{
}
}
}
//$$ AppliedToInterface
[Obsolete("reason")]
public interface AppliedToInterface
{
}
//$$ AppliedToStruct
[Obsolete("reason")]
public struct AppliedToStruct
{
public int Field;
}
//$$ AppliedToParameter
namespace AppliedToParameter
{
[AttributeUsage(AttributeTargets.Parameter)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public void Method([MyAttribute]int val)
{
}
}
}
//$$ NamedInitializerProperty
namespace NamedInitializerProperty
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyAttributeAttribute : Attribute
{
}
}
//$$ NamedInitializerPropertyString
namespace NamedInitializerPropertyString
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
public string Prop
{
get
{
return "";
}
set
{
return;
}
}
}
[MyAttribute(Prop = "value")]
public class MyClass
{
}
}
//$$ NamedInitializerPropertyType
namespace NamedInitializerPropertyType
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
public Type Prop
{
get
{
return null;
}
set
{
return;
}
}
}
[MyAttribute(Prop = typeof(Enum))]
public class MyClass
{
}
}
//$$ NamedInitializerPropertyEnum
namespace NamedInitializerPropertyEnum
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
public AttributeTargets Prop
{
get
{
return AttributeTargets.All;
}
set
{
return;
}
}
}
[MyAttribute(Prop = (AttributeTargets.Class | AttributeTargets.Method))]
public class MyClass
{
}
}
//$$ NamedInitializerFieldEnum
namespace NamedInitializerFieldEnum
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
public AttributeTargets Field;
}
[MyAttribute(Field = (AttributeTargets.Class | AttributeTargets.Method))]
public class MyClass
{
}
}
//$$ TargetReturn
namespace TargetReturn
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
[return: MyAttribute]
public int MyMethod()
{
return 5;
}
}
}
//$$ TargetPropertyGetReturn
namespace TargetPropertyGetReturn
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public int Prop
{
[return: MyAttribute]
get
{
return 3;
}
}
}
}
//$$ TargetPropertySetParam
namespace TargetPropertySetParam
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public int Prop
{
[param: MyAttribute]
set
{
return;
}
}
}
}
//$$ TargetPropertySetReturn
namespace TargetPropertySetReturn
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public int Prop
{
get
{
return 3;
}
[return: MyAttribute]
set
{
return;
}
}
}
}
//$$ TargetPropertyIndexSetParam
namespace TargetPropertyIndexSetParam
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass
{
public string this[int index]
{
get
{
return "";
}
[param: MyAttribute]
set
{
return;
}
}
}
}
//$$ TargetPropertyIndexSetMultiParam
namespace TargetPropertyIndexSetMultiParam
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
public int Field;
}
public class MyClass
{
public string this[[MyAttribute(Field = 2)] int index1, [MyAttribute(Field = 3)] int index2]
{
get
{
return "";
}
[param: MyAttribute]
set
{
return;
}
}
}
}
//$$ ClassAttributeOnTypeParameter
namespace ClassAttributeOnTypeParameter
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
public class MyClass<[MyAttribute] T>
{
}
}

46
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.cs

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
namespace aa
{
public static class CustomAtributes
{
[Flags]
public enum EnumWithFlag
{
All = 15,
None = 0,
Item1 = 1,
Item2 = 2,
Item3 = 4,
Item4 = 8
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public MyAttribute(CustomAtributes.EnumWithFlag en) : base()
{
}
}
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.Item1 | CustomAtributes.EnumWithFlag.Item2)]
private static int field;
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.All)]
public static string Property
{
get
{
return "aa";
}
}
[Obsolete("some message")]
public static void ObsoletedMethod()
{
//Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, (AttributeTargets)(AttributeTargets.Property | AttributeTargets.Field));
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field);
AttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field;
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, attributeTargets);
}
}
}

71
ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;
using System.IO;
using Decompiler;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests
{
public abstract class DecompilerTestBase
{
protected static void ValidateFileRoundtrip(string samplesFileName)
{
var lines = File.ReadAllLines(Path.Combine(@"..\..\Tests", samplesFileName));
var testCode = RemoveIgnorableLines(lines);
var decompiledTestCode = RoundtripCode(testCode);
Assert.AreEqual(testCode, decompiledTestCode);
}
static string RemoveIgnorableLines(IEnumerable<string> lines)
{
return CodeSampleFileParser.ConcatLines(lines.Where(l => !CodeSampleFileParser.IsCommentOrBlank(l)));
}
/// <summary>
/// Compiles and decompiles a source code.
/// </summary>
/// <param name="code">The source code to copile.</param>
/// <returns>The decompilation result of compiled source code.</returns>
static string RoundtripCode(string code)
{
AssemblyDefinition assembly = Compile(code);
AstBuilder decompiler = new AstBuilder(new DecompilerContext());
decompiler.AddAssembly(assembly);
decompiler.Transform(new Helpers.RemoveCompilerAttribute());
StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output));
return output.ToString();
}
static AssemblyDefinition Compile(string code)
{
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = provider.CompileAssemblyFromSource(options, code);
try
{
if (results.Errors.Count > 0)
{
StringBuilder b = new StringBuilder("Compiler error:");
foreach (var error in results.Errors)
{
b.AppendLine(error.ToString());
}
throw new Exception(b.ToString());
}
return AssemblyDefinition.ReadAssembly(results.PathToAssembly);
}
finally
{
File.Delete(results.PathToAssembly);
results.TempFiles.Delete();
}
}
}
}

4
ICSharpCode.Decompiler/Tests/Generics.cs

@ -27,4 +27,8 @@ public static class Generics @@ -27,4 +27,8 @@ public static class Generics
}
}
}
public static void MethodWithConstraint<T, S>() where T : class, S where S : ICloneable, new()
{
}
}

31
ICSharpCode.Decompiler/Tests/Helpers/RemoveCompilerAttribute.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.CSharp;
using Decompiler.Transforms;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
class RemoveCompilerAttribute : DepthFirstAstVisitor<object, object>, IAstTransform
{
public override object VisitAttribute(NRefactory.CSharp.Attribute attribute, object data)
{
var section = (AttributeSection)attribute.Parent;
SimpleType type = attribute.Type as SimpleType;
if (section.AttributeTarget == AttributeTarget.Assembly &&
(type.Identifier == "CompilationRelaxations" || type.Identifier == "RuntimeCompatibility"))
{
attribute.Remove();
if (section.Attributes.Count == 0)
section.Remove();
}
return null;
}
public void Run(AstNode node)
{
node.AcceptVisitor(this, null);
}
}
}

28
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -38,6 +38,10 @@ @@ -38,6 +38,10 @@
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework">
<SpecificVersion>False</SpecificVersion>
<HintPath>.\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -48,13 +52,23 @@ @@ -48,13 +52,23 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ArrayInitializers.cs" />
<None Include="Types\S_EnumSamples.cs" />
<None Include="CustomAttributes\S_AssemblyCustomAttribute.cs" />
<Compile Include="Helpers\RemoveCompilerAttribute.cs" />
<Compile Include="Types\EnumTests.cs" />
<Compile Include="Types\TypeTests.cs" />
<Compile Include="DelegateConstruction.cs" />
<None Include="CustomAttributes\S_CustomAttributes.cs" />
<Compile Include="Loops.cs" />
<Compile Include="PropertiesAndEvents.cs" />
<None Include="CustomAttributes\S_CustomAttributeSamples.cs" />
<Compile Include="CodeSampleFileParser.cs" />
<Compile Include="CustomAttributes\CustomAttributeTests.cs" />
<Compile Include="DecompilerTestBase.cs" />
<Compile Include="ArrayInitializers.cs" />
<Compile Include="ExceptionHandling.cs" />
<Compile Include="Generics.cs" />
<Compile Include="MultidimensionalArray.cs" />
<Compile Include="Loops.cs" />
<Compile Include="PropertiesAndEvents.cs" />
<Compile Include="TestRunner.cs" />
<Compile Include="ValueTypes.cs" />
</ItemGroup>
@ -63,14 +77,16 @@ @@ -63,14 +77,16 @@
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
<ProjectReference Include="..\..\NRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
</ProjectReference>
<ProjectReference Include="..\ICSharpCode.Decompiler.csproj">
<Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project>
<Name>ICSharpCode.Decompiler</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="StackTests" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<None Include="BooleanConsumedAsInteger.il" />
<None Include="StackTests\StackTests.il" />

14
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -14,21 +14,23 @@ namespace ICSharpCode.Decompiler.Tests @@ -14,21 +14,23 @@ namespace ICSharpCode.Decompiler.Tests
{
public class TestRunner
{
public static void Main()
public static void Main(string[] args)
{
Test(@"..\..\Tests\DelegateConstruction.cs");
if (args.Length == 1)
TestFile(args[0]);
else
TestFile(@"..\..\Tests\DelegateConstruction.cs");
Console.ReadKey();
}
static void Test(string fileName)
static void TestFile(string fileName)
{
string code = File.ReadAllText(fileName);
AssemblyDefinition assembly = Compile(code);
AstBuilder decompiler = new AstBuilder(new DecompilerContext());
decompiler.AddAssembly(assembly);
decompiler.Transform(new Helpers.RemoveCompilerAttribute());
StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output));
StringWriter diff = new StringWriter();
@ -79,7 +81,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -79,7 +81,7 @@ namespace ICSharpCode.Decompiler.Tests
static AssemblyDefinition Compile(string code)
{
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> {{ "CompilerVersion", "v4.0" }});
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = provider.CompileAssemblyFromSource(options, code);

18
ICSharpCode.Decompiler/Tests/Types/EnumTests.cs

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Types
{
[TestFixture]
public class EnumTests : DecompilerTestBase
{
[Test]
public void EnumSamples()
{
ValidateFileRoundtrip(@"Types\S_EnumSamples.cs");
}
}
}

114
ICSharpCode.Decompiler/Tests/Types/S_EnumSamples.cs

@ -0,0 +1,114 @@ @@ -0,0 +1,114 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
//$CS
using System;
//$CE
//$$ SingleValue
public class TS_SingleValue
{
public AttributeTargets Method()
{
return AttributeTargets.Class;
}
}
//$$ TwoValuesOr
public class TS_TwoValuesOr
{
public AttributeTargets Method()
{
return AttributeTargets.Class | AttributeTargets.Method;
}
}
//$$ ThreeValuesOr
public class TS_ThreeValuesOr
{
public AttributeTargets Method()
{
return AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter;
}
}
//$$ UnknownNumericValue
public class TS_UnknownNumericValue
{
public AttributeTargets Method()
{
return (AttributeTargets)1000000;
}
}
//$$ AllValue
public class TS_AllValue
{
public AttributeTargets Method()
{
return AttributeTargets.All;
}
}
//$$ ZeroValue
public class TS_ZeroValue
{
public AttributeTargets Method()
{
return (AttributeTargets)0;
}
}
//$$ PreservingTypeWhenBoxed
public class TS_PreservingTypeWhenBoxed
{
public object Method()
{
return AttributeTargets.Delegate;
}
}
//$$ PreservingTypeWhenBoxedTwoEnum
public class TS_PreservingTypeWhenBoxedTwoEnum
{
public object Method()
{
return AttributeTargets.Class | AttributeTargets.Delegate;
}
}
//$$ DeclarationSimpleEnum
public enum TS_DeclarationSimpleEnum
{
Item1,
Item2
}
//$$ DeclarationLongBasedEnum
public enum TS_DeclarationLongBasedEnum : long
{
Item1,
Item2
}
//$$ DeclarationLongWithInitializers
public enum TS_DeclarationLongWithInitializers : long
{
Item1,
Item2 = 20L,
Item3
}
//$$ DeclarationShortWithInitializers
public enum TS_DeclarationShortWithInitializers : short
{
Item1,
Item2 = 20,
Item3
}
//$$ DeclarationByteWithInitializers
public enum TS_DeclarationByteWithInitializers : byte
{
Item1,
Item2 = 20,
Item3
}
//$$ DeclarationFlags
[Flags]
public enum TS_DeclarationFlags
{
None = 0,
Item1 = 1,
Item2 = 2,
Item3 = 4,
All = 7
}

12
ICSharpCode.Decompiler/Tests/Types/TypeTests.cs

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Types
{
public class TypeTests : DecompilerTestBase
{
}
}

BIN
ICSharpCode.Decompiler/Tests/nunit.framework.dll

Binary file not shown.

93
ILSpy.sln

@ -26,68 +26,68 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Decompiler.Test @@ -26,68 +26,68 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Decompiler.Test
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|x86.Build.0 = Debug|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|x86.ActiveCfg = Debug|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|x86.Build.0 = Release|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|x86.ActiveCfg = Release|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|Any CPU.Build.0 = Release|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|x86.ActiveCfg = Debug|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|x86.Build.0 = Debug|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|x86.Build.0 = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|x86.Build.0 = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|x86.ActiveCfg = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|Any CPU.Build.0 = Release|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|x86.ActiveCfg = Release|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|x86.Build.0 = Release|x86
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|Any CPU.Build.0 = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|x86.Build.0 = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|Any CPU.Build.0 = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|x86.ActiveCfg = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|x86.Build.0 = Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.ActiveCfg = net_3_5_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.ActiveCfg = net_3_5_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.ActiveCfg = net_3_5_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.ActiveCfg = net_3_5_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.Build.0 = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.Build.0 = Release|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.ActiveCfg = Release|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.Build.0 = Release|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.Build.0 = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|x86.Build.0 = Debug|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|x86.ActiveCfg = Debug|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.Build.0 = Release|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.ActiveCfg = Release|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.Build.0 = Release|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|x86.Build.0 = Release|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|x86.ActiveCfg = Release|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|Any CPU.Build.0 = Release|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|x86.ActiveCfg = Debug|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|x86.Build.0 = Debug|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|x86.Build.0 = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|x86.ActiveCfg = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.Build.0 = Debug|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|Any CPU.Build.0 = Release|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|x86.ActiveCfg = Release|Any CPU
{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|x86.Build.0 = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|x86.Build.0 = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|x86.ActiveCfg = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.Build.0 = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|x86.ActiveCfg = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|x86.Build.0 = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|x86.Build.0 = Debug|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|x86.ActiveCfg = Debug|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|Any CPU.Build.0 = Debug|x86
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.Build.0 = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|x86.ActiveCfg = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|x86.Build.0 = Release|Any CPU
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|Any CPU.ActiveCfg = Debug|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.Build.0 = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.ActiveCfg = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|Any CPU.Build.0 = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|Any CPU.Build.0 = Debug|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|x86.ActiveCfg = Debug|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|x86.Build.0 = Debug|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|Any CPU.ActiveCfg = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|Any CPU.Build.0 = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.ActiveCfg = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.Build.0 = Release|x86
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|x86.Build.0 = Debug|Any CPU
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|x86.ActiveCfg = Debug|Any CPU
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
@ -105,8 +105,7 @@ Global @@ -105,8 +105,7 @@ Global
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Release|Any CPU.Build.0 = Release|x86
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Release|Any CPU.ActiveCfg = Release|x86
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

5
ILSpy/CSharpLanguage.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.ILSpy @@ -40,7 +40,7 @@ namespace ICSharpCode.ILSpy
public class CSharpLanguage : Language
{
string name = "C#";
bool showAllMembers;
bool showAllMembers = false;
Predicate<IAstTransform> transformAbortCondition = null;
public CSharpLanguage()
@ -132,6 +132,9 @@ namespace ICSharpCode.ILSpy @@ -132,6 +132,9 @@ namespace ICSharpCode.ILSpy
}
} else {
base.DecompileAssembly(assembly, fileName, output, options);
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: null);
codeDomBuilder.AddAssembly(assembly, onlyAssemblyLevel: true);
codeDomBuilder.GenerateCode(output, transformAbortCondition);
}
}

6
ILSpy/ILAstLanguage.cs

@ -30,10 +30,11 @@ using Mono.Cecil; @@ -30,10 +30,11 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
#if DEBUG
/// <summary>
/// Represents the ILAst "language" used for debugging purposes.
/// </summary>
public class ILAstLanguage : Language
sealed class ILAstLanguage : Language
{
string name;
bool inlineVariables = true;
@ -78,7 +79,6 @@ namespace ICSharpCode.ILSpy @@ -78,7 +79,6 @@ namespace ICSharpCode.ILSpy
}
}
#if DEBUG
internal static IEnumerable<ILAstLanguage> GetDebugLanguages()
{
yield return new ILAstLanguage { name = "ILAst (unoptimized)", inlineVariables = false };
@ -89,7 +89,6 @@ namespace ICSharpCode.ILSpy @@ -89,7 +89,6 @@ namespace ICSharpCode.ILSpy
}
}
#endif
public override string FileExtension {
get {
@ -104,4 +103,5 @@ namespace ICSharpCode.ILSpy @@ -104,4 +103,5 @@ namespace ICSharpCode.ILSpy
return output.ToString();
}
}
#endif
}

2
Mono.Cecil/Mono.Cecil/SecurityDeclaration.cs

@ -177,7 +177,7 @@ namespace Mono.Cecil { @@ -177,7 +177,7 @@ namespace Mono.Cecil {
{
return module.HasImage ()
? module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider))
: LazyInitializer.EnsureInitialized(ref variable);
: variable = new Collection<SecurityDeclaration>();
}
}
}

16
NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj

@ -40,21 +40,29 @@ @@ -40,21 +40,29 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="VBEditDialog.cs" />
<Compile Include="VBEditDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="VBEditDialog.Designer.cs">
<DependentUpon>VBEditDialog.cs</DependentUpon>
</Compile>
<Compile Include="VBDomView.cs" />
<Compile Include="VBDomView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="VBDomView.Designer.cs">
<DependentUpon>VBDomView.cs</DependentUpon>
</Compile>
<Compile Include="MainForm.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VBDemo.cs" />
<Compile Include="VBDemo.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="VBDemo.Designer.cs">
<DependentUpon>VBDemo.cs</DependentUpon>
</Compile>

15
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/AstStructureTests.cs

@ -27,5 +27,20 @@ namespace ICSharpCode.NRefactory.CSharp @@ -27,5 +27,20 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
}
[Test]
public void AstNodesDoNotDeriveFromEachOther()
{
// Ast nodes should derive only from abstract classes; not from concrete types.
// For example, we want to avoid that an AST consumer doing "if (node is PropertyDeclaration)"
// unknowingly also handles IndexerDeclarations.
foreach (Type type in typeof(AstNode).Assembly.GetExportedTypes()) {
if (type == typeof(CSharpModifierToken)) // CSharpModifierToken is the exception (though I'm not too happy about that)
continue;
if (type.IsSubclassOf(typeof(AstNode))) {
Assert.IsTrue(type.BaseType.IsAbstract, type.FullName);
}
}
}
}
}

38
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AliasReferenceExpressionTests.cs

@ -8,27 +8,43 @@ using NUnit.Framework; @@ -8,27 +8,43 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture]
[TestFixture, Ignore("Aliases not yet implemented")]
public class AliasReferenceExpressionTests
{
[Test, Ignore]
[Test]
public void GlobalReferenceExpressionTest()
{
CSharpParser parser = new CSharpParser();
parser.ParseTypeReference(new StringReader("global::System"));
//Assert.IsTrue(tre.TypeReference.IsGlobal);
//Assert.AreEqual("System", tre.TypeReference.Type);
throw new NotImplementedException();
AstType type = parser.ParseTypeReference(new StringReader("global::System"));
Assert.IsNotNull(
new MemberType {
Target = new SimpleType("global"),
IsDoubleColon = true,
MemberName = "System"
}.Match(type)
);
}
[Test, Ignore]
[Test]
public void GlobalTypeDeclaration()
{
VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement<VariableDeclarationStatement>("global::System.String a;");
//TypeReference typeRef = lvd.GetTypeForVariable(0);
//Assert.IsTrue(typeRef.IsGlobal);
//Assert.AreEqual("System.String", typeRef.Type);
throw new NotImplementedException();
Assert.IsNotNull(
new VariableDeclarationStatement {
Type = new MemberType {
Target = new MemberType {
Target = new SimpleType("global"),
IsDoubleColon = true,
MemberName = "System"
},
IsDoubleColon = false,
MemberName = "String",
},
Variables = {
new VariableInitializer("a")
}
}.Match(lvd)
);
}
// TODO: add tests for aliases other than 'global'

1
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AnonymousMethodTests.cs

@ -47,6 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -47,6 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
public void SimpleAnonymousMethod()
{
AnonymousMethodExpression ame = Parse("delegate(int a, int b) { return a + b; }");
Assert.IsTrue(ame.HasParameterList);
Assert.AreEqual(2, ame.Parameters.Count());
Assert.AreEqual(1, ame.Body.Statements.Count());
Assert.IsTrue(ame.Body.Children.First() is ReturnStatement);

52
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayObjectCreateExpressionTests.cs

@ -6,31 +6,51 @@ using NUnit.Framework; @@ -6,31 +6,51 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture, Ignore("Needs to be ported to new NRefactory")]
[TestFixture]
public class ArrayObjectCreateExpressionTests
{
[Test]
public void ArrayCreateExpressionTest1()
{
/*
ArrayCreateExpression ace = ParseUtilCSharp.ParseExpression<ArrayCreateExpression>("new int[5]");
Assert.AreEqual("System.Int32", ace.CreateType.Type);
Assert.IsTrue(ace.CreateType.IsKeyword);
Assert.AreEqual(1, ace.Arguments.Count);
Assert.AreEqual(new int[] {0}, ace.CreateType.RankSpecifier);
*/
throw new NotImplementedException();
ParseUtilCSharp.AssertExpression(
"new int[5]",
new ArrayCreateExpression {
Type = new PrimitiveType("int"),
Arguments = { new PrimitiveExpression(5) }
});
}
[Test]
[Test, Ignore("AdditionalArraySpecifiers not yet implemented")]
public void MultidimensionalNestedArray()
{
ParseUtilCSharp.AssertExpression(
"new int[5,2][,,][]",
new ArrayCreateExpression {
Type = new PrimitiveType("int"),
Arguments = { new PrimitiveExpression(5), new PrimitiveExpression(2) },
AdditionalArraySpecifiers = {
new ArraySpecifier(3),
new ArraySpecifier(1)
}
});
}
[Test, Ignore("Array initializers not yet implemented")]
public void ImplicitlyTypedArrayCreateExpression()
{
/*
ArrayCreateExpression ace = ParseUtilCSharp.ParseExpression<ArrayCreateExpression>("new[] { 1, 10, 100, 1000 }");
Assert.AreEqual("", ace.CreateType.Type);
Assert.AreEqual(0, ace.Arguments.Count);
Assert.AreEqual(4, ace.ArrayInitializer.CreateExpressions.Count);*/
throw new NotImplementedException();
ParseUtilCSharp.AssertExpression(
"new[] { 1, 10, 100, 1000 }",
new ArrayCreateExpression {
Initializer = new ArrayInitializerExpression {
Elements = {
new PrimitiveExpression(1),
new PrimitiveExpression(10),
new PrimitiveExpression(100),
new PrimitiveExpression(1000)
}
}
});
}
}
}

151
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs

@ -9,132 +9,157 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -9,132 +9,157 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
[TestFixture, Ignore("Port unit tests to new DOM")]
public class CastExpressionTests
{
/*
[Test]
public void SimpleCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(MyObject)o");
Assert.AreEqual("MyObject", ce.CastTo.Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(MyObject)o",
new CastExpression {
Type = new SimpleType("MyObject"),
Expression = new IdentifierExpression("o")
});
}
[Test]
public void ArrayCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(MyType[])o");
Assert.AreEqual("MyType", ce.CastTo.Type);
Assert.AreEqual(new int[] { 0 }, ce.CastTo.RankSpecifier);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(MyType[])o",
new CastExpression {
Type = new SimpleType("MyType").MakeArrayType(1),
Expression = new IdentifierExpression("o")
});
}
[Test]
public void NullablePrimitiveCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(int?)o");
Assert.AreEqual("System.Nullable", ce.CastTo.Type);
Assert.AreEqual("System.Int32", ce.CastTo.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(int?)o",
new CastExpression {
Type = new ComposedType { BaseType = new PrimitiveType("int"), HasNullableSpecifier = true },
Expression = new IdentifierExpression("o")
});
}
[Test]
public void NullableCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(MyType?)o");
Assert.AreEqual("System.Nullable", ce.CastTo.Type);
Assert.AreEqual("MyType", ce.CastTo.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(MyType?)o",
new CastExpression {
Type = new ComposedType { BaseType = new SimpleType("MyType"), HasNullableSpecifier = true },
Expression = new IdentifierExpression("o")
});
}
[Test]
public void NullableTryCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("o as int?");
Assert.AreEqual("System.Nullable", ce.CastTo.Type);
Assert.IsTrue(ce.CastTo.IsKeyword);
Assert.AreEqual("System.Int32", ce.CastTo.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.TryCast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"o as int?",
new AsExpression {
Type = new ComposedType { BaseType = new PrimitiveType("int"), HasNullableSpecifier = true },
Expression = new IdentifierExpression("o")
});
}
[Test]
public void GenericCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(List<string>)o");
Assert.AreEqual("List", ce.CastTo.Type);
Assert.AreEqual("System.String", ce.CastTo.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(List<string>)o",
new CastExpression {
Type = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } },
Expression = new IdentifierExpression("o")
});
}
[Test]
public void GenericArrayCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(List<string>[])o");
Assert.AreEqual("List", ce.CastTo.Type);
Assert.AreEqual("System.String", ce.CastTo.GenericTypes[0].Type);
Assert.AreEqual(new int[] { 0 }, ce.CastTo.RankSpecifier);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(List<string>[])o",
new CastExpression {
Type = new ComposedType {
BaseType = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } },
ArraySpecifiers = { new ArraySpecifier(1) }
},
Expression = new IdentifierExpression("o")
});
}
[Test]
public void GenericArrayAsCastExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("o as List<string>[]");
Assert.AreEqual("List", ce.CastTo.Type);
Assert.AreEqual("System.String", ce.CastTo.GenericTypes[0].Type);
Assert.AreEqual(new int[] { 0 }, ce.CastTo.RankSpecifier);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.AreEqual(CastType.TryCast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"o as List<string>[]",
new AsExpression {
Type = new ComposedType {
BaseType = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } },
ArraySpecifiers = { new ArraySpecifier(1) }
},
Expression = new IdentifierExpression("o")
});
}
[Test]
public void CastMemberReferenceOnParenthesizedExpression()
{
// yes, we really wanted to evaluate .Member on expr and THEN cast the result to MyType
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(MyType)(expr).Member");
Assert.AreEqual("MyType", ce.CastTo.Type);
Assert.IsTrue(ce.Expression is MemberReferenceExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
// yes, we really want to evaluate .Member on expr and THEN cast the result to MyType
ParseUtilCSharp.AssertExpression(
"(MyType)(expr).Member",
new CastExpression {
Type = new SimpleType("MyType"),
Expression = new ParenthesizedExpression { Expression = new IdentifierExpression("expr") }.Member("Member")
});
}
[Test]
public void TryCastParenthesizedExpression()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(o) as string");
Assert.AreEqual("System.String", ce.CastTo.ToString());
Assert.IsTrue(ce.Expression is ParenthesizedExpression);
Assert.AreEqual(CastType.TryCast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(o) as string",
new AsExpression {
Expression = new ParenthesizedExpression { Expression = new IdentifierExpression("o") },
Type = new PrimitiveType("string")
});
}
[Test]
public void CastNegation()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(uint)-negativeValue");
Assert.AreEqual("System.UInt32", ce.CastTo.ToString());
Assert.IsTrue(ce.Expression is UnaryOperatorExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
ParseUtilCSharp.AssertExpression(
"(uint)-negativeValue",
new CastExpression {
Type = new PrimitiveType("uint"),
Expression = new UnaryOperatorExpression(
UnaryOperatorType.Minus,
new IdentifierExpression("negativeValue")
)});
}
*/
[Test]
public void SubtractionIsNotCast()
{
BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>("(BigInt)-negativeValue");
Assert.IsTrue(boe.Left is ParenthesizedExpression);
Assert.IsTrue(boe.Right is IdentifierExpression);
ParseUtilCSharp.AssertExpression(
"(BigInt)-negativeValue",
new BinaryOperatorExpression {
Left = new ParenthesizedExpression { Expression = new IdentifierExpression("BigInt") },
Operator = BinaryOperatorType.Subtract,
Right = new IdentifierExpression("negativeValue")
});
}
[Test]
public void IntMaxValueToBigInt()
{
CastExpression ce = ParseUtilCSharp.ParseExpression<CastExpression>("(BigInt)int.MaxValue");
Assert.AreEqual("BigInt", ce.Type.ToString());
Assert.IsTrue(ce.Expression is MemberReferenceExpression);
ParseUtilCSharp.AssertExpression(
"(BigInt)int.MaxValue",
new CastExpression {
Type = new SimpleType("BigInt"),
Expression = new PrimitiveExpression("int").Member("MaxValue")
});
}
}
}

60
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/DefaultValueExpressionTests.cs

@ -6,48 +6,74 @@ using NUnit.Framework; @@ -6,48 +6,74 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture, Ignore("tests need to be ported")]
[TestFixture, Ignore("Aliases not yet implemented")]
public class DefaultValueExpressionTests
{
[Test]
public void SimpleDefaultValue()
{
DefaultValueExpression toe = ParseUtilCSharp.ParseExpression<DefaultValueExpression>("default(T)");
Assert.AreEqual("T", toe.Type);
Assert.AreEqual("T", ((SimpleType)toe.Type).Identifier);
}
/*
[Test]
public void FullQualifiedDefaultValue()
{
DefaultValueExpression toe = ParseUtilCSharp.ParseExpression<DefaultValueExpression>("default(global::MyNamespace.N1.MyType)");
Assert.IsTrue(toe.TypeReference.IsGlobal);
Assert.AreEqual("MyNamespace.N1.MyType", toe.TypeReference.Type);
ParseUtilCSharp.AssertExpression(
"default(global::MyNamespace.N1.MyType)",
new DefaultValueExpression {
Type = new MemberType {
Target = new MemberType {
Target = new MemberType {
Target = new SimpleType("global"),
IsDoubleColon = true,
MemberName = "MyNamespace"
},
MemberName = "N1"
},
MemberName = "MyType"
}
});
}
[Test]
public void GenericDefaultValue()
{
DefaultValueExpression toe = ParseUtilCSharp.ParseExpression<DefaultValueExpression>("default(MyNamespace.N1.MyType<string>)");
Assert.AreEqual("MyNamespace.N1.MyType", toe.TypeReference.Type);
Assert.AreEqual("System.String", toe.TypeReference.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"default(MyNamespace.N1.MyType<string>)",
new DefaultValueExpression {
Type = new MemberType {
Target = new MemberType {
Target = new SimpleType("MyNamespace"),
MemberName = "N1"
},
MemberName = "MyType",
TypeArguments = { new PrimitiveType("string") }
}
});
}
[Test]
public void DefaultValueAsIntializer()
{
// This test is failing because we need a resolver for the "default:" / "default(" conflict.
LocalVariableDeclaration lvd = ParseUtilCSharp.ParseStatement<LocalVariableDeclaration>("T a = default(T);");
DefaultValueExpression dve = (DefaultValueExpression)lvd.Variables[0].Initializer;
Assert.AreEqual("T", dve.TypeReference.Type);
// This test was problematic (in old NRefactory) because we need a resolver for the "default:" / "default(" conflict.
ParseUtilCSharp.AssertStatement(
"T a = default(T);",
new VariableDeclarationStatement {
Type = new SimpleType("T"),
Variables = {
new VariableInitializer("a", new DefaultValueExpression { Type = new SimpleType("T") })
}});
}
[Test]
public void DefaultValueInReturnStatement()
{
ReturnStatement rs = ParseUtilCSharp.ParseStatement<ReturnStatement>("return default(T);");
DefaultValueExpression dve = (DefaultValueExpression)rs.Expression;
Assert.AreEqual("T", dve.TypeReference.Type);
}*/
ParseUtilCSharp.AssertStatement(
"return default(T);",
new ReturnStatement {
Expression = new DefaultValueExpression { Type = new SimpleType("T") }
});
}
}
}

28
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IdentifierExpressionTests.cs

@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
CheckIdentifier(@"l\U00000065xer", "lexer");
}
[Test]
[Test, Ignore("The @ should not be part of IdentifierExpression.Identifier")]
public void TestKeyWordAsIdentifier()
{
CheckIdentifier("@int", "int");
@ -51,28 +51,36 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -51,28 +51,36 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
CheckIdentifier(@"i\u006et", "int");
}
[Test]
[Test, Ignore("The @ should not be part of IdentifierExpression.Identifier")]
public void TestKeyWordAsIdentifierStartingWithUnderscore()
{
CheckIdentifier("@_int", "_int");
}
[Test, Ignore]
[Test]
public void GenericMethodReference()
{
IdentifierExpression ident = ParseUtilCSharp.ParseExpression<IdentifierExpression>("M<int>");
Assert.AreEqual("M", ident.Identifier);
//Assert.AreEqual(1, ident.TypeArguments.Count);
throw new NotImplementedException();
Assert.IsNotNull(
new IdentifierExpression {
Identifier = "M" ,
TypeArguments = {
new PrimitiveType("int")
}
}.Match(ident));
}
[Test, Ignore]
[Test]
public void GenericMethodReference2()
{
IdentifierExpression ident = ParseUtilCSharp.ParseExpression<IdentifierExpression>("TargetMethod<string>");
Assert.AreEqual("TargetMethod", ident.Identifier);
//Assert.AreEqual(1, ident.TypeArguments.Count);
throw new NotImplementedException();
Assert.IsNotNull(
new IdentifierExpression {
Identifier = "TargetMethod" ,
TypeArguments = {
new PrimitiveType("string")
}
}.Match(ident));
}
}
}

179
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs

@ -7,7 +7,7 @@ using NUnit.Framework; @@ -7,7 +7,7 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture, Ignore("Port unit tests to new DOM")]
[TestFixture]
public class InvocationExpressionTests
{
[Test]
@ -19,55 +19,71 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -19,55 +19,71 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
Assert.AreEqual("myMethod", ((IdentifierExpression)ie.Target).Identifier);
}
/* TODO port unit tests to new DOM
[Test]
public void GenericInvocationExpressionTest()
{
var expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("myMethod<char>('a')");
Assert.AreEqual(1, expr.Arguments.Count());
Assert.IsTrue(expr.TargetObject is IdentifierExpression);
IdentifierExpression ident = (IdentifierExpression)expr.TargetObject;
Assert.AreEqual("myMethod", ident.Identifier);
Assert.AreEqual(1, ident.TypeArguments.Count);
Assert.AreEqual("System.Char", ident.TypeArguments[0].Type);
ParseUtilCSharp.AssertExpression(
"myMethod<char>('a')",
new InvocationExpression {
Target = new IdentifierExpression {
Identifier = "myMethod",
TypeArguments = { new PrimitiveType("char") }
},
Arguments = { new PrimitiveExpression('a') }
}
);
}
[Test]
public void GenericInvocation2ExpressionTest()
{
var expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("myMethod<T,bool>()");
Assert.AreEqual(0, expr.Arguments.Count);
Assert.IsTrue(expr.TargetObject is IdentifierExpression);
IdentifierExpression ident = (IdentifierExpression)expr.TargetObject;
Assert.AreEqual("myMethod", ident.Identifier);
Assert.AreEqual(2, ident.TypeArguments.Count);
Assert.AreEqual("T", ident.TypeArguments[0].Type);
Assert.IsFalse(ident.TypeArguments[0].IsKeyword);
Assert.AreEqual("System.Boolean", ident.TypeArguments[1].Type);
Assert.IsTrue(ident.TypeArguments[1].IsKeyword);
ParseUtilCSharp.AssertExpression(
"myMethod<T,bool>()",
new InvocationExpression {
Target = new IdentifierExpression {
Identifier = "myMethod",
TypeArguments = {
new SimpleType("T"),
new PrimitiveType("bool")
}
}
}
);
}
[Test]
public void AmbiguousGrammarGenericMethodCall()
{
InvocationExpression ie = ParseUtilCSharp.ParseExpression<InvocationExpression>("F(G<A,B>(7))");
Assert.IsTrue(ie.TargetObject is IdentifierExpression);
Assert.AreEqual(1, ie.Arguments.Count);
ie = (InvocationExpression)ie.Arguments[0];
Assert.AreEqual(1, ie.Arguments.Count);
Assert.IsTrue(ie.Arguments[0] is PrimitiveExpression);
IdentifierExpression ident = (IdentifierExpression)ie.TargetObject;
Assert.AreEqual("G", ident.Identifier);
Assert.AreEqual(2, ident.TypeArguments.Count);
ParseUtilCSharp.AssertExpression(
"F(G<A,B>(7))",
new InvocationExpression {
Target = new IdentifierExpression("F"),
Arguments = {
new InvocationExpression {
Target = new IdentifierExpression {
Identifier = "G",
TypeArguments = { new SimpleType("A"), new SimpleType("B") }
},
Arguments = { new PrimitiveExpression(7) }
}}});
}
[Test]
[Test, Ignore("Mono Parser Bug???")]
public void AmbiguousGrammarNotAGenericMethodCall()
{
BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>("F<A>+y");
Assert.AreEqual(BinaryOperatorType.GreaterThan, boe.Op);
Assert.IsTrue(boe.Left is BinaryOperatorExpression);
Assert.IsTrue(boe.Right is UnaryOperatorExpression);
ParseUtilCSharp.AssertExpression(
"F<A>+y",
new BinaryOperatorExpression {
Left = new BinaryOperatorExpression {
Left = new IdentifierExpression("F"),
Operator = BinaryOperatorType.LessThan,
Right = new IdentifierExpression("A")
},
Operator = BinaryOperatorType.GreaterThan,
Right = new UnaryOperatorExpression {
Operator = UnaryOperatorType.Plus,
Expression = new IdentifierExpression("y")
}});
}
[Test]
@ -76,80 +92,81 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -76,80 +92,81 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
// this test was written because this bug caused the AbstractASTVisitor to crash
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("WriteLine(myMethod(,))", true);
Assert.IsTrue(expr.TargetObject is IdentifierExpression);
Assert.AreEqual("WriteLine", ((IdentifierExpression)expr.TargetObject).Identifier);
Assert.IsTrue(expr.Target is IdentifierExpression);
Assert.AreEqual("WriteLine", ((IdentifierExpression)expr.Target).Identifier);
Assert.AreEqual(1, expr.Arguments.Count); // here a second null parameter was added incorrectly
Assert.IsTrue(expr.Arguments[0] is InvocationExpression);
CheckSimpleInvoke((InvocationExpression)expr.Arguments[0]);
Assert.IsTrue(expr.Arguments.Single() is InvocationExpression);
}
[Test]
[Test, Ignore("Positions not yet accurate when parsing expression only (because class/method is added around it)")]
public void NestedInvocationPositions()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("a.B().C(args)");
Assert.AreEqual(new Location(8, 1), expr.StartLocation);
Assert.AreEqual(new Location(14, 1), expr.EndLocation);
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual(new Location(6, 1), mre.StartLocation);
Assert.AreEqual(new Location(8, 1), mre.EndLocation);
Assert.AreEqual(new Location(4, 1), mre.TargetObject.StartLocation);
Assert.AreEqual(new Location(6, 1), mre.TargetObject.EndLocation);
Assert.AreEqual(new AstLocation(1, 8), expr.StartLocation);
Assert.AreEqual(new AstLocation(1, 14), expr.EndLocation);
MemberReferenceExpression mre = (MemberReferenceExpression)expr.Target;
Assert.AreEqual(new AstLocation(1, 6), mre.StartLocation);
Assert.AreEqual(new AstLocation(1, 8), mre.EndLocation);
Assert.AreEqual(new AstLocation(1, 4), mre.Target.StartLocation);
Assert.AreEqual(new AstLocation(1, 6), mre.Target.EndLocation);
}
[Test]
public void InvocationOnGenericType()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("A<T>.Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
TypeReferenceExpression tre = (TypeReferenceExpression)mre.TargetObject;
Assert.AreEqual("A", tre.TypeReference.Type);
Assert.AreEqual("T", tre.TypeReference.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"A<T>.Foo()",
new IdentifierExpression {
Identifier = "A",
TypeArguments = { new SimpleType("T") }
}.Invoke("Foo")
);
}
[Test]
public void InvocationOnInnerClassInGenericType()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("A<T>.B.Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
MemberReferenceExpression mre2 = (MemberReferenceExpression)mre.TargetObject;
Assert.AreEqual("B", mre2.MemberName);
TypeReferenceExpression tre = (TypeReferenceExpression)mre2.TargetObject;
Assert.AreEqual("A", tre.TypeReference.Type);
Assert.AreEqual("T", tre.TypeReference.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"A<T>.B.Foo()",
new IdentifierExpression {
Identifier = "A",
TypeArguments = { new SimpleType("T") }
}.Member("B").Invoke("Foo")
);
}
[Test]
public void InvocationOnGenericInnerClassInGenericType()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("A<T>.B.C<U>.Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
TypeReferenceExpression tre = (TypeReferenceExpression)mre.TargetObject;
InnerClassTypeReference ictr = (InnerClassTypeReference)tre.TypeReference;
Assert.AreEqual("B.C", ictr.Type);
Assert.AreEqual(1, ictr.GenericTypes.Count);
Assert.AreEqual("U", ictr.GenericTypes[0].Type);
Assert.AreEqual("A", ictr.BaseType.Type);
Assert.AreEqual(1, ictr.BaseType.GenericTypes.Count);
Assert.AreEqual("T", ictr.BaseType.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"A<T>.B.C<U>.Foo()",
new MemberReferenceExpression {
Target = new IdentifierExpression {
Identifier = "A",
TypeArguments = { new SimpleType("T") }
}.Member("B"),
MemberName = "C",
TypeArguments = { new SimpleType("U") }
}.Invoke("Foo"));
}
[Test]
[Test, Ignore("named arguments not yet supported")]
public void InvocationWithNamedArgument()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("a(arg: ref v)");
Assert.AreEqual(1, expr.Arguments.Count);
NamedArgumentExpression nae = (NamedArgumentExpression)expr.Arguments[0];
Assert.AreEqual("arg", nae.Name);
DirectionExpression dir = (DirectionExpression)nae.Expression;
Assert.AreEqual(FieldDirection.Ref, dir.FieldDirection);
Assert.IsInstanceOf<IdentifierExpression>(dir.Expression);
}*/
ParseUtilCSharp.AssertExpression(
"a(arg: ref v)",
new InvocationExpression {
Target = new IdentifierExpression("a"),
Arguments = {
new NamedArgumentExpression {
Identifier = "arg",
Expression = new DirectionExpression {
FieldDirection = FieldDirection.Ref,
Expression = new IdentifierExpression("v")
}}}});
}
}
}

15
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IsExpressionTests.cs

@ -9,15 +9,16 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -9,15 +9,16 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
[TestFixture]
public class IsExpressionTests
{
[Test, Ignore]
[Test]
public void GenericArrayIsExpression()
{
/* TODO
TypeOfIsExpression ce = ParseUtilCSharp.ParseExpression<TypeOfIsExpression>("o is List<string>[]");
Assert.AreEqual("List", ce.TypeReference.Type);
Assert.AreEqual("System.String", ce.TypeReference.GenericTypes[0].Type);
Assert.AreEqual(new int[] { 0 }, ce.TypeReference.RankSpecifier);
Assert.IsTrue(ce.Expression is IdentifierExpression);*/
ParseUtilCSharp.AssertExpression(
"o is List<string>[]",
new IsExpression {
Expression = new IdentifierExpression("o"),
Type = new SimpleType("List") { TypeArguments = { new PrimitiveType("string") } }.MakeArrayType(1)
}
);
}
[Test]

117
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/LambdaExpressionTests.cs

@ -6,84 +6,103 @@ using NUnit.Framework; @@ -6,84 +6,103 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture, Ignore("Port unit tests")]
[TestFixture]
public class LambdaExpressionTests
{
static LambdaExpression ParseCSharp(string program)
{
return ParseUtilCSharp.ParseExpression<LambdaExpression>(program);
}
[Test]
[Test, Ignore("Lambdas with expression body not yet supported")]
public void ImplicitlyTypedExpressionBody()
{
/*
LambdaExpression e = ParseCSharp("(x) => x + 1");
Assert.AreEqual("x", e.Parameters[0].ParameterName);
Assert.IsTrue(e.Parameters[0].TypeReference.IsNull);
Assert.IsTrue(e.ExpressionBody is BinaryOperatorExpression);
Assert.IsTrue(e.ReturnType.IsNull);*/
throw new NotImplementedException();
ParseUtilCSharp.AssertExpression(
"(x) => x + 1",
new LambdaExpression {
Parameters = { new ParameterDeclaration { Name = "x" } },
Body = new BinaryOperatorExpression(new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
});
}
/* TODO Port unit tests
[Test]
[Test, Ignore("Lambdas with expression body not yet supported")]
public void ImplicitlyTypedExpressionBodyWithoutParenthesis()
{
LambdaExpression e = ParseCSharp("x => x + 1");
Assert.AreEqual("x", e.Parameters[0].ParameterName);
Assert.IsTrue(e.Parameters[0].TypeReference.IsNull);
Assert.IsTrue(e.ExpressionBody is BinaryOperatorExpression);
Assert.IsTrue(e.ReturnType.IsNull);
ParseUtilCSharp.AssertExpression(
"x => x + 1",
new LambdaExpression {
Parameters = { new ParameterDeclaration { Name = "x" } },
Body = new BinaryOperatorExpression(new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
});
}
[Test]
public void ImplicitlyTypedStatementBody()
{
LambdaExpression e = ParseCSharp("(x) => { return x + 1; }");
Assert.AreEqual("x", e.Parameters[0].ParameterName);
Assert.IsTrue(e.Parameters[0].TypeReference.IsNull);
Assert.IsTrue(e.StatementBody.Children[0] is ReturnStatement);
Assert.IsTrue(e.ReturnType.IsNull);
ParseUtilCSharp.AssertExpression(
"(x) => { return x + 1; }",
new LambdaExpression {
Parameters = { new ParameterDeclaration { Name = "x" } },
Body = new BlockStatement {
new ReturnStatement {
Expression = new BinaryOperatorExpression(
new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
}}});
}
[Test]
public void ImplicitlyTypedStatementBodyWithoutParenthesis()
{
LambdaExpression e = ParseCSharp("x => { return x + 1; }");
Assert.AreEqual("x", e.Parameters[0].ParameterName);
Assert.IsTrue(e.Parameters[0].TypeReference.IsNull);
Assert.IsTrue(e.StatementBody.Children[0] is ReturnStatement);
Assert.IsTrue(e.ReturnType.IsNull);
ParseUtilCSharp.AssertExpression(
"x => { return x + 1; }",
new LambdaExpression {
Parameters = { new ParameterDeclaration { Name = "x" } },
Body = new BlockStatement {
new ReturnStatement {
Expression = new BinaryOperatorExpression(
new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
}}});
}
[Test]
public void ExplicitlyTypedStatementBody()
{
LambdaExpression e = ParseCSharp("(int x) => { return x + 1; }");
Assert.AreEqual("x", e.Parameters[0].ParameterName);
Assert.AreEqual("System.Int32", e.Parameters[0].TypeReference.Type);
Assert.IsTrue(e.StatementBody.Children[0] is ReturnStatement);
Assert.IsTrue(e.ReturnType.IsNull);
ParseUtilCSharp.AssertExpression(
"(int x) => { return x + 1; }",
new LambdaExpression {
Parameters = { new ParameterDeclaration { Type = new PrimitiveType("int"), Name = "x" } },
Body = new BlockStatement {
new ReturnStatement {
Expression = new BinaryOperatorExpression(
new IdentifierExpression("x"), BinaryOperatorType.Add, new PrimitiveExpression(1))
}}});
}
[Test]
public void ExplicitlyTypedStatementBodyWithRefParameter()
[Test, Ignore("Lambdas with expression body not yet supported")]
public void ExplicitlyTypedWithRefParameter()
{
LambdaExpression e = ParseCSharp("(ref int i) => i = 1");
Assert.AreEqual("i", e.Parameters[0].ParameterName);
Assert.IsTrue((e.Parameters[0].ParamModifier & ParameterModifiers.Ref) == ParameterModifiers.Ref);
Assert.AreEqual("System.Int32", e.Parameters[0].TypeReference.Type);
Assert.IsTrue(e.ReturnType.IsNull);
ParseUtilCSharp.AssertExpression(
"(ref int i) => i = 1",
new LambdaExpression {
Parameters = {
new ParameterDeclaration {
ParameterModifier = ParameterModifier.Ref,
Type = new PrimitiveType("int"),
Name = "x"
}
},
Body = new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(1))
});
}
[Test]
[Test, Ignore("Lambdas with expression body not yet supported")]
public void LambdaExpressionContainingConditionalExpression()
{
LambdaExpression e = ParseCSharp("rr => rr != null ? rr.ResolvedType : null");
Assert.AreEqual("rr", e.Parameters[0].ParameterName);
Assert.IsTrue(e.ExpressionBody is ConditionalExpression);
Assert.IsTrue(e.ReturnType.IsNull);
}*/
ParseUtilCSharp.AssertExpression(
"rr => rr != null ? rr.ResolvedType : null",
new LambdaExpression {
Parameters = { new ParameterDeclaration { Name = "rr" } },
Body = new ConditionalExpression {
Condition = new BinaryOperatorExpression(
new IdentifierExpression("rr"), BinaryOperatorType.InEquality, new NullReferenceExpression()),
TrueExpression = new IdentifierExpression("rr").Member("ResolvedType"),
FalseExpression = new NullReferenceExpression()
}});
}
}
}

97
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs

@ -6,71 +6,84 @@ using NUnit.Framework; @@ -6,71 +6,84 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture, Ignore]
[TestFixture]
public class MemberReferenceExpressionTests
{
[Test]
public void SimpleFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("myTargetObject.myField");
//Assert.AreEqual("myField", fre.MemberName);
//Assert.IsTrue(fre.TargetObject is IdentifierExpression);
//Assert.AreEqual("myTargetObject", ((IdentifierExpression)fre.TargetObject).Identifier);
throw new NotImplementedException();
ParseUtilCSharp.AssertExpression(
"myTargetObject.myField",
new IdentifierExpression("myTargetObject").Member("myField")
);
}
[Test, Ignore("parser is broken and produces IdentifierExpression instead of PrimitiveType")]
public void ShortMaxValueTest()
{
ParseUtilCSharp.AssertExpression(
"short.MaxValue",
new PrimitiveType("short").Member("MaxValue")
);
}
[Test, Ignore("Parsing of @-identifiers is broken")]
public void IdentShortMaxValueTest()
{
ParseUtilCSharp.AssertExpression(
"@short.MaxValue",
new IdentifierExpression("short").Member("MaxValue")
);
}
/* TODO port unit tests
[Test]
public void GenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("SomeClass<string>.myField");
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("SomeClass", tr.Type);
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"SomeClass<string>.myField",
new IdentifierExpression("SomeClass") { TypeArguments = { new PrimitiveType("string") } }.Member("myField")
);
}
[Test]
public void FullNamespaceGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("Namespace.Subnamespace.SomeClass<string>.myField");
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("Namespace.Subnamespace.SomeClass", tr.Type);
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"Namespace.Subnamespace.SomeClass<string>.myField",
new MemberReferenceExpression {
Target = new IdentifierExpression("Namespace").Member("Subnamespace"),
TypeArguments = { new PrimitiveType("string") }
}.Member("myField")
);
}
[Test]
[Test, Ignore("Aliases not yet implemented")]
public void GlobalFullNamespaceGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("global::Namespace.Subnamespace.SomeClass<string>.myField");
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.IsFalse(tr is InnerClassTypeReference);
Assert.AreEqual("Namespace.Subnamespace.SomeClass", tr.Type);
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].Type);
Assert.IsTrue(tr.IsGlobal);
ParseUtilCSharp.AssertExpression(
"global::Namespace.Subnamespace.SomeClass<string>.myField",
new MemberReferenceExpression {
Target = new MemberType {
Target = new SimpleType("global"),
IsDoubleColon = true,
MemberName = "Namespace"
}.Member("Subnamespace"),
TypeArguments = { new PrimitiveType("string") }
}.Member("myField")
);
}
[Test]
public void NestedGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("MyType<string>.InnerClass<int>.myField");
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
InnerClassTypeReference ic = (InnerClassTypeReference)((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].Type);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].Type);
}*/
ParseUtilCSharp.AssertExpression(
"MyType<string>.InnerClass<int>.myField",
new MemberReferenceExpression {
Target = new IdentifierExpression("MyType") { TypeArguments = { new PrimitiveType("string") } },
MemberName = "InnerClass",
TypeArguments = { new PrimitiveType("int") }
}.Member("myField")
);
}
}
}

18
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PointerReferenceExpressionTests.cs

@ -9,13 +9,25 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -9,13 +9,25 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
[TestFixture]
public class PointerReferenceExpressionTests
{
[Test, Ignore("where did PointerReferenceExpression.MemberName go?")]
[Test, Ignore("Parser bug!")]
public void PointerReferenceExpressionTest()
{
PointerReferenceExpression pre = ParseUtilCSharp.ParseExpression<PointerReferenceExpression>("myObj.field->b");
Assert.IsTrue(pre.Target is MemberReferenceExpression);
//Assert.AreEqual("b", pre.MemberName);
throw new NotImplementedException();
Assert.AreEqual("b", pre.MemberName);
}
[Test, Ignore("Parser bug!")]
public void PointerReferenceGenericMethodTest()
{
ParseUtilCSharp.AssertExpression(
"ptr->M<string>();",
new InvocationExpression {
Target = new PointerReferenceExpression {
Target = new IdentifierExpression("ptr"),
MemberName = "M",
TypeArguments = { new PrimitiveType("string") }
}});
}
}
}

232
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs

@ -6,104 +6,220 @@ using NUnit.Framework; @@ -6,104 +6,220 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture, Ignore]
[TestFixture, Ignore("Query expressions not yet implemented")]
public class QueryExpressionTests
{
[Test]
public void SimpleExpression()
{
/*
QueryExpression qe = ParseUtilCSharp.ParseExpression<QueryExpression>(
"from c in customers where c.City == \"London\" select c"
);
Assert.AreEqual("c", qe.FromClause.Sources.First().Identifier);
Assert.AreEqual("customers", ((IdentifierExpression)qe.FromClause.Sources.First().Expression).Identifier);
Assert.AreEqual(1, qe.MiddleClauses.Count);
Assert.IsInstanceOf(typeof(QueryExpressionWhereClause), qe.MiddleClauses[0]);
QueryExpressionWhereClause wc = (QueryExpressionWhereClause)qe.MiddleClauses[0];
Assert.IsInstanceOf(typeof(BinaryOperatorExpression), wc.Condition);
Assert.IsInstanceOf(typeof(QueryExpressionSelectClause), qe.SelectOrGroupClause);*/
throw new NotImplementedException();
ParseUtilCSharp.AssertExpression(
"from c in customers where c.City == \"London\" select c",
new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "c",
Expression = new IdentifierExpression("customers")
},
new QueryWhereClause {
Condition = new BinaryOperatorExpression {
Left = new IdentifierExpression("c").Member("City"),
Operator = BinaryOperatorType.Equality,
Right = new PrimitiveExpression("London")
}
},
new QuerySelectClause {
Expression = new IdentifierExpression("c")
}
}});
}
/* TODO port unit tests
[Test]
public void ExpressionWithType1()
{
QueryExpression qe = ParseUtilCSharp.ParseExpression<QueryExpression>(
"from Customer c in customers select c"
);
Assert.AreEqual("c", qe.FromClause.Sources.First().Identifier);
Assert.AreEqual("Customer", qe.FromClause.Sources.First().Type.ToString());
Assert.AreEqual("customers", ((IdentifierExpression)qe.FromClause.Sources.First().Expression).Identifier);
Assert.IsInstanceOf(typeof(QueryExpressionSelectClause), qe.SelectOrGroupClause);
ParseUtilCSharp.AssertExpression(
"from Customer c in customers select c",
new QueryExpression {
Clauses = {
new QueryFromClause {
Type = new SimpleType("Customer"),
Identifier = "c",
Expression = new IdentifierExpression("customers")
},
new QuerySelectClause {
Expression = new IdentifierExpression("c")
}
}});
}
[Test]
public void ExpressionWithType2()
{
QueryExpression qe = ParseUtilCSharp.ParseExpression<QueryExpression>(
"from int c in customers select c"
);
Assert.AreEqual("c", qe.FromClause.Sources.First().Identifier);
Assert.AreEqual("System.Int32", qe.FromClause.Sources.First().Type.Type);
Assert.AreEqual("customers", ((IdentifierExpression)qe.FromClause.Sources.First().Expression).Identifier);
Assert.IsInstanceOf(typeof(QueryExpressionSelectClause), qe.SelectOrGroupClause);
ParseUtilCSharp.AssertExpression(
"from int c in customers select c",
new QueryExpression {
Clauses = {
new QueryFromClause {
Type = new PrimitiveType("int"),
Identifier = "c",
Expression = new IdentifierExpression("customers")
},
new QuerySelectClause {
Expression = new IdentifierExpression("c")
}
}});
}
[Test]
public void ExpressionWithType3()
{
QueryExpression qe = ParseUtilCSharp.ParseExpression<QueryExpression>(
"from S<int[]>? c in customers select c"
);
Assert.AreEqual("c", qe.FromClause.Sources.First().Identifier);
Assert.AreEqual("System.Nullable<S<System.Int32[]>>", qe.FromClause.Sources.First().Type.ToString());
Assert.AreEqual("customers", ((IdentifierExpression)qe.FromClause.Sources.First().Expression).Identifier);
Assert.IsInstanceOf(typeof(QueryExpressionSelectClause), qe.SelectOrGroupClause);
ParseUtilCSharp.AssertExpression(
"from S<int[]>? c in customers select c",
new QueryExpression {
Clauses = {
new QueryFromClause {
Type = new ComposedType {
BaseType = new SimpleType {
Identifier = "S",
TypeArguments = {
new PrimitiveType("int").MakeArrayType()
}
},
HasNullableSpecifier = true
},
Identifier = "c",
Expression = new IdentifierExpression("customers")
},
new QuerySelectClause {
Expression = new IdentifierExpression("c")
}
}});
}
[Test]
public void MultipleGenerators()
{
QueryExpression qe = ParseUtilCSharp.ParseExpression<QueryExpression>(@"
ParseUtilCSharp.AssertExpression(
@"
from c in customers
where c.City == ""London""
from o in c.Orders
where o.OrderDate.Year == 2005
select new { c.Name, o.OrderID, o.Total }");
Assert.AreEqual(3, qe.MiddleClauses.Count);
Assert.IsInstanceOf(typeof(QueryExpressionWhereClause), qe.MiddleClauses[0]);
Assert.IsInstanceOf(typeof(QueryExpressionFromClause), qe.MiddleClauses[1]);
Assert.IsInstanceOf(typeof(QueryExpressionWhereClause), qe.MiddleClauses[2]);
Assert.IsInstanceOf(typeof(QueryExpressionSelectClause), qe.SelectOrGroupClause);
select new { c.Name, o.OrderID, o.Total }",
new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "c",
Expression = new IdentifierExpression("customers")
},
new QueryWhereClause {
Condition = new BinaryOperatorExpression {
Left = new IdentifierExpression("c").Member("City"),
Operator = BinaryOperatorType.Equality,
Right = new PrimitiveExpression("London")
}
},
new QueryFromClause {
Identifier = "o",
Expression = new IdentifierExpression("c").Member("Orders")
},
new QueryWhereClause {
Condition = new BinaryOperatorExpression {
Left = new IdentifierExpression("c").Member("OrderDate").Member("Year"),
Operator = BinaryOperatorType.Equality,
Right = new PrimitiveExpression(2005)
}
},
new QuerySelectClause {
Expression = new ObjectCreateExpression {
Initializer = new ArrayInitializerExpression {
Elements = {
new IdentifierExpression("c").Member("Name"),
new IdentifierExpression("o").Member("OrderID"),
new IdentifierExpression("o").Member("Total")
}
}
}
}
}});
}
[Test]
public void ExpressionWithOrderBy()
{
QueryExpression qe = ParseUtilCSharp.ParseExpression<QueryExpression>(
"from c in customers orderby c.Name select c"
);
Assert.AreEqual("c", qe.FromClause.Sources.First().Identifier);
Assert.AreEqual("customers", ((IdentifierExpression)qe.FromClause.Sources.First().Expression).Identifier);
Assert.IsInstanceOf(typeof(QueryExpressionOrderClause), qe.MiddleClauses[0]);
Assert.IsInstanceOf(typeof(QueryExpressionSelectClause), qe.SelectOrGroupClause);
ParseUtilCSharp.AssertExpression(
"from c in customers orderby c.Name select c",
new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "c",
Expression = new IdentifierExpression("customers")
},
new QueryOrderClause {
Orderings = {
new QueryOrdering {
Expression = new IdentifierExpression("c").Member("Name")
}
}
},
new QuerySelectClause {
Expression = new IdentifierExpression("c")
}
}});
}
[Test]
public void ExpressionWithOrderByAndLet()
{
QueryExpression qe = ParseUtilCSharp.ParseExpression<QueryExpression>(
"from c in customers orderby c.Name let x = c select x"
ParseUtilCSharp.AssertExpression(
"from c in customers orderby c.Name descending let x = c select x",
new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "c",
Expression = new IdentifierExpression("customers")
},
new QueryOrderClause {
Orderings = {
new QueryOrdering {
Expression = new IdentifierExpression("c").Member("Name"),
Direction = QueryOrderingDirection.Descending
}
}
},
new QueryLetClause {
Identifier = "x",
Expression = new IdentifierExpression("c")
},
new QuerySelectClause {
Expression = new IdentifierExpression("x")
}
}});
}
[Test]
public void QueryContinuation()
{
ParseUtilCSharp.AssertExpression(
"from a in b select c into d select e",
new QueryExpression {
Clauses = {
new QueryContinuationClause {
PrecedingQuery = new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "a",
Expression = new IdentifierExpression("b")
},
new QuerySelectClause { Expression = new IdentifierExpression("c") }
}
},
Identifier = "d"
},
new QuerySelectClause { Expression = new IdentifierExpression("e") }
}
}
);
Assert.AreEqual("c", qe.FromClause.Sources.First().Identifier);
Assert.AreEqual("customers", ((IdentifierExpression)qe.FromClause.Sources.First().Expression).Identifier);
Assert.IsInstanceOf(typeof(QueryExpressionOrderClause), qe.MiddleClauses[0]);
Assert.IsInstanceOf(typeof(QueryExpressionLetClause), qe.MiddleClauses[1]);
Assert.IsInstanceOf(typeof(QueryExpressionSelectClause), qe.SelectOrGroupClause);
}*/
}
}
}

4
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/SizeOfExpressionTests.cs

@ -9,11 +9,11 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -9,11 +9,11 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
[TestFixture]
public class SizeOfExpressionTests
{
[Test, Ignore("type references not implemented yet")]
[Test]
public void SizeOfExpressionTest()
{
SizeOfExpression soe = ParseUtilCSharp.ParseExpression<SizeOfExpression>("sizeof(MyType)");
Assert.AreEqual("MyType", soe.Type);
Assert.AreEqual("MyType", ((SimpleType)soe.Type).Identifier);
}
}
}

9
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/StackAllocExpressionTests.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Linq;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
@ -9,11 +10,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -9,11 +10,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
[TestFixture]
public class StackAllocExpressionTests
{
[Test, Ignore]
[Test]
public void StackAllocExpressionTest()
{
var sae = ParseUtilCSharp.ParseExpression<StackAllocExpression>("stackalloc int[100]");
throw new NotImplementedException(); // TODO: verify type + length expression
var vd = ParseUtilCSharp.ParseStatement<VariableDeclarationStatement>("int* a = stackalloc int[100];");
StackAllocExpression sae = (StackAllocExpression)vd.Variables.Single().Initializer;
Assert.AreEqual("int", ((PrimitiveType)sae.Type).Keyword);
Assert.AreEqual(100, ((PrimitiveExpression)sae.CountExpression).Value);
}
}
}

97
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs

@ -6,86 +6,113 @@ using NUnit.Framework; @@ -6,86 +6,113 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
{
[TestFixture, Ignore]
[TestFixture]
public class TypeOfExpressionTests
{
[Test]
public void SimpleTypeOfExpressionTest()
{
//TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(MyNamespace.N1.MyType)");
//Assert.AreEqual("MyNamespace.N1.MyType", toe.TypeReference.Type);
throw new NotImplementedException();
ParseUtilCSharp.AssertExpression(
"typeof(MyNamespace.N1.MyType)",
new TypeOfExpression {
Type = new MemberType {
Target = new MemberType {
Target = new SimpleType("MyNamespace"),
MemberName = "N1"
},
MemberName = "MyType"
}});
}
/* TODO
[Test]
[Test, Ignore("Aliases not yet implemented")]
public void GlobalTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(global::System.Console)");
Assert.AreEqual("System.Console", toe.TypeReference.Type);
ParseUtilCSharp.AssertExpression(
"typeof(global::System.Console)",
new TypeOfExpression {
Type = new MemberType {
Target = new MemberType {
Target = new SimpleType("global"),
IsDoubleColon = true,
MemberName = "System"
},
MemberName = "Console"
}});
}
[Test]
public void PrimitiveTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(int)");
Assert.AreEqual("System.Int32", toe.TypeReference.Type);
Assert.AreEqual("int", ((PrimitiveType)toe.Type).Keyword);
}
[Test]
public void VoidTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(void)");
Assert.AreEqual("System.Void", toe.TypeReference.Type);
Assert.AreEqual("void", ((PrimitiveType)toe.Type).Keyword);
}
[Test]
public void ArrayTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(MyType[])");
Assert.AreEqual("MyType", toe.TypeReference.Type);
Assert.AreEqual(new int[] {0}, toe.TypeReference.RankSpecifier);
ParseUtilCSharp.AssertExpression(
"typeof(MyType[])",
new TypeOfExpression {
Type = new SimpleType("MyType").MakeArrayType()
});
}
[Test]
public void GenericTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(MyNamespace.N1.MyType<string>)");
Assert.AreEqual("MyNamespace.N1.MyType", toe.TypeReference.Type);
Assert.AreEqual("System.String", toe.TypeReference.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"typeof(MyNamespace.N1.MyType<string>)",
new TypeOfExpression {
Type = new MemberType {
Target = new MemberType {
Target = new SimpleType("MyNamespace"),
MemberName = "N1"
},
MemberName = "MyType",
TypeArguments = { new PrimitiveType("string") }
}});
}
[Test]
public void NestedGenericTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(MyType<string>.InnerClass<int>.InnerInnerClass)");
InnerClassTypeReference ic = (InnerClassTypeReference)toe.TypeReference;
Assert.AreEqual("InnerInnerClass", ic.Type);
Assert.AreEqual(0, ic.GenericTypes.Count);
ic = (InnerClassTypeReference)ic.BaseType;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].Type);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"typeof(MyType<string>.InnerClass<int>.InnerInnerClass)",
new TypeOfExpression {
Type = new MemberType {
Target = new MemberType {
Target = new SimpleType("MyType") { TypeArguments = { new PrimitiveType("string") } },
MemberName = "InnerClass",
TypeArguments = { new PrimitiveType("int") }
},
MemberName = "InnerInnerClass"
}});
}
[Test]
public void NullableTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(MyStruct?)");
Assert.AreEqual("System.Nullable", toe.TypeReference.Type);
Assert.AreEqual("MyStruct", toe.TypeReference.GenericTypes[0].Type);
ParseUtilCSharp.AssertExpression(
"typeof(MyStruct?)",
new TypeOfExpression {
Type = new ComposedType {
BaseType = new SimpleType("MyType"),
HasNullableSpecifier = true
}});
}
[Test]
[Test, Ignore("How do we represent unbound types in the AST?")]
public void UnboundTypeOfExpressionTest()
{
TypeOfExpression toe = ParseUtilCSharp.ParseExpression<TypeOfExpression>("typeof(MyType<,>)");
Assert.AreEqual("MyType", toe.TypeReference.Type);
Assert.IsTrue(toe.TypeReference.GenericTypes[0].IsNull);
Assert.IsTrue(toe.TypeReference.GenericTypes[1].IsNull);
}*/
throw new NotImplementedException("How do we represent unbound types in the AST?");
}
}
}

6
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/UnaryOperatorExpressionTests.cs

@ -84,9 +84,9 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -84,9 +84,9 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
Assert.AreEqual(UnaryOperatorType.Dereference, uoe.Operator);
ParenthesizedExpression pe = (ParenthesizedExpression)uoe.Expression;
CastExpression ce = (CastExpression)pe.Expression;
//Assert.AreEqual("SomeType", ce.CastTo.Type);
//Assert.AreEqual(1, ce.CastTo.PointerNestingLevel);
Assert.Ignore("need to check target type"); // TODO
ComposedType type = (ComposedType)ce.Type;
Assert.AreEqual("SomeType", ((SimpleType)type.BaseType).Identifier);
Assert.AreEqual(1, type.PointerRank);
UnaryOperatorExpression adrOf = (UnaryOperatorExpression)ce.Expression;
Assert.AreEqual(UnaryOperatorType.AddressOf, adrOf.Operator);

68
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs

@ -7,55 +7,41 @@ using NUnit.Framework; @@ -7,55 +7,41 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
{
[TestFixture, Ignore("delegates are completely broken at the moment")]
[TestFixture]
public class DelegateDeclarationTests
{
void TestParameters(DelegateDeclaration dd)
{
Assert.AreEqual(3, dd.Parameters.Count());
Assert.AreEqual("a", ((ParameterDeclaration)dd.Parameters.ElementAt(0)).Name);
//Assert.AreEqual("System.Int32", ((ParameterDeclaration)dd.Parameters.ElementAt(0)).TypeReference.Type);
Assert.Ignore("check types"); // TODO
Assert.AreEqual("secondParam", ((ParameterDeclaration)dd.Parameters.ElementAt(1)).Name);
//Assert.AreEqual("System.Int32", ((ParameterDeclaration)dd.Parameters.ElementAt(1)).TypeReference.Type);
Assert.AreEqual("lastParam", ((ParameterDeclaration)dd.Parameters.ElementAt(2)).Name);
//Assert.AreEqual("MyObj", ((ParameterDeclaration)dd.Parameters.ElementAt(2)).TypeReference.Type);
}
[Test]
public void SimpleCSharpDelegateDeclarationTest()
{
string program = "public delegate void MyDelegate(int a, int secondParam, MyObj lastParam);\n";
DelegateDeclaration dd = ParseUtilCSharp.ParseGlobal<DelegateDeclaration>(program);
Assert.AreEqual("MyDelegate", dd.Name);
//Assert.AreEqual("System.Void", dd.ReturnType.Type);
TestParameters(dd);
ParseUtilCSharp.AssertGlobal(
"public delegate void MyDelegate(int a, int secondParam, MyObj lastParam);",
new DelegateDeclaration {
Modifiers = Modifiers.Public,
ReturnType = new PrimitiveType("void"),
Name = "MyDelegate",
Parameters = {
new ParameterDeclaration(new PrimitiveType("int"), "a"),
new ParameterDeclaration(new PrimitiveType("int"), "secondParam"),
new ParameterDeclaration(new SimpleType("MyObj"), "lastParam")
}});
}
[Test, Ignore]
public void DelegateWithoutNameDeclarationTest()
{
string program = "public delegate void(int a, int secondParam, MyObj lastParam);\n";
DelegateDeclaration dd = ParseUtilCSharp.ParseGlobal<DelegateDeclaration>(program, true);
//Assert.AreEqual("System.Void", dd.ReturnType.Type);
//Assert.AreEqual("?", dd.Name);
TestParameters(dd);
}
[Test, Ignore]
[Test, Ignore("Generics not yet supported")]
public void GenericDelegateDeclarationTest()
{
string program = "public delegate T CreateObject<T>() where T : ICloneable;\n";
DelegateDeclaration dd = ParseUtilCSharp.ParseGlobal<DelegateDeclaration>(program);
Assert.AreEqual("CreateObject", dd.Name);
//Assert.AreEqual("T", dd.ReturnType.Type);
Assert.AreEqual(0, dd.Parameters.Count());
/*Assert.AreEqual(1, dd.Templates.Count);
Assert.AreEqual("T", dd.Templates[0].Name);
Assert.AreEqual(1, dd.Templates[0].Bases.Count);
Assert.AreEqual("ICloneable", dd.Templates[0].Bases[0].Type);*/ throw new NotImplementedException();
ParseUtilCSharp.AssertGlobal(
"public delegate T CreateObject<T>() where T : ICloneable;",
new DelegateDeclaration {
Modifiers = Modifiers.Public,
ReturnType = new SimpleType("T"),
Name = "CreateObject",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Constraints = {
new Constraint {
TypeParameter = "T",
BaseTypes = { new SimpleType("ICloneable") }
}
}});
}
[Test]
@ -66,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope @@ -66,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Assert.AreEqual("MyDelegate", ((DelegateDeclaration)nd.Members.Single()).Name);
}
[Test, Ignore("inner classes not yet implemented")]
[Test]
public void DelegateDeclarationInClass()
{
string program = "class Outer { delegate void Inner(); }";

198
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs

@ -70,85 +70,111 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope @@ -70,85 +70,111 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Assert.AreEqual(Modifiers.Static, td.Modifiers);
}
[Test, Ignore]
[Test, Ignore("Generics not yet supported")]
public void GenericClassTypeDeclarationTest()
{
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("public class G<T> {}");
Assert.AreEqual(ClassType.Class, td.ClassType);
Assert.AreEqual("G", td.Name);
Assert.AreEqual(Modifiers.Public, td.Modifiers);
/*Assert.AreEqual(0, td.BaseTypes.Count);
Assert.AreEqual(1, td.TypeArguments.Count());
Assert.AreEqual("T", td.TypeArguments.Single().Name);*/ throw new NotImplementedException();
ParseUtilCSharp.AssertGlobal(
"public class G<T> {}",
new TypeDeclaration {
Modifiers = Modifiers.Public,
ClassType = ClassType.Class,
Name = "G",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } }
});
}
[Test, Ignore]
[Test, Ignore("Constraints not yet supported")]
public void GenericClassWithWhere()
{
string declr = @"
public class Test<T> where T : IMyInterface
{
}
";
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(declr);
Assert.AreEqual(ClassType.Class, td.ClassType);
Assert.AreEqual("Test", td.Name);
/*Assert.AreEqual(1, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
Assert.AreEqual("IMyInterface", td.Templates[0].Bases[0].Type);*/ throw new NotImplementedException();
ParseUtilCSharp.AssertGlobal(
@"public class Test<T> where T : IMyInterface { }",
new TypeDeclaration {
Modifiers = Modifiers.Public,
ClassType = ClassType.Class,
Name = "Test",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Constraints = {
new Constraint {
TypeParameter = "T",
BaseTypes = { new SimpleType("IMyInterface") }
}
}});
}
[Test, Ignore]
[Test, Ignore("Generic classes not yet supported")]
public void ComplexGenericClassTypeDeclarationTest()
{
string declr = @"
public class Generic<T, S> : System.IComparable where S : G<T[]> where T : MyNamespace.IMyInterface
{
}
";
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(declr);
Assert.AreEqual(ClassType.Class, td.ClassType);
Assert.AreEqual("Generic", td.Name);
Assert.AreEqual(Modifiers.Public, td.Modifiers);
/*Assert.AreEqual(1, td.BaseTypes.Count);
Assert.AreEqual("System.IComparable", td.BaseTypes[0].Type);
Assert.AreEqual(2, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
Assert.AreEqual("MyNamespace.IMyInterface", td.Templates[0].Bases[0].Type);
Assert.AreEqual("S", td.Templates[1].Name);
Assert.AreEqual("G", td.Templates[1].Bases[0].Type);
Assert.AreEqual(1, td.Templates[1].Bases[0].GenericTypes.Count);
Assert.IsTrue(td.Templates[1].Bases[0].GenericTypes[0].IsArrayType);
Assert.AreEqual("T", td.Templates[1].Bases[0].GenericTypes[0].Type);
Assert.AreEqual(new int[] {0}, td.Templates[1].Bases[0].GenericTypes[0].RankSpecifier);*/ throw new NotImplementedException();
ParseUtilCSharp.AssertGlobal(
"public class Generic<in T, out S> : System.IComparable where S : G<T[]>, new() where T : MyNamespace.IMyInterface",
new TypeDeclaration {
Modifiers = Modifiers.Public,
ClassType = ClassType.Class,
Name = "Generic",
TypeParameters = {
new TypeParameterDeclaration { Variance = VarianceModifier.Contravariant, Name = "T" },
new TypeParameterDeclaration { Variance = VarianceModifier.Covariant, Name = "S" }
},
BaseTypes = {
new MemberType {
Target = new SimpleType("System"),
MemberName = "IComparable"
}
},
Constraints = {
new Constraint {
TypeParameter = "S",
BaseTypes = {
new SimpleType {
Identifier = "G",
TypeArguments = { new SimpleType("T").MakeArrayType() }
},
new PrimitiveType("new")
}
},
new Constraint {
TypeParameter = "T",
BaseTypes = {
new MemberType {
Target = new SimpleType("MyNamespace"),
MemberName = "IMyInterface"
}
}
}
}
});
}
[Test, Ignore]
[Test, Ignore("Base types not yet implemented")]
public void ComplexClassTypeDeclarationTest()
{
string declr = @"
ParseUtilCSharp.AssertGlobal(
@"
[MyAttr()]
public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
{
}
";
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(declr);
Assert.AreEqual(ClassType.Class, td.ClassType);
Assert.AreEqual("MyClass", td.Name);
Assert.AreEqual(Modifiers.Public | Modifiers.Abstract, td.Modifiers);
Assert.AreEqual(1, td.Attributes.Count());
/* Assert.AreEqual(3, td.BaseTypes.Count);
Assert.AreEqual("MyBase", td.BaseTypes[0].Type);
Assert.AreEqual("Interface1", td.BaseTypes[1].Type);
Assert.AreEqual("My.Test.Interface2", td.BaseTypes[2].Type);*/ throw new NotImplementedException();
}",
new TypeDeclaration {
Attributes = {
new AttributeSection {
Attributes = {
new Attribute { Type = new SimpleType("MyAttr") }
}
}
},
Modifiers = Modifiers.Public | Modifiers.Abstract,
ClassType = ClassType.Class,
Name = "MyClass",
BaseTypes = {
new SimpleType("MyBase"),
new SimpleType("Interface1"),
new MemberType {
Target = new MemberType {
Target = new SimpleType("My"),
MemberName = "Test"
},
MemberName = "Interface2"
}
}});
}
[Test]
@ -178,27 +204,37 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -178,27 +204,37 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual("MyEnum", td.Name);
}
[Test, Ignore]
[Test, Ignore("Mono parser bug?")]
public void ContextSensitiveKeywordTest()
{
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("partial class partial<[partial: where] where> where where : partial<where> { }");
Assert.AreEqual(Modifiers.Partial, td.Modifiers);
Assert.AreEqual("partial", td.Name);
/*
Assert.AreEqual(1, td.Templates.Count);
TemplateDefinition tp = td.Templates[0];
Assert.AreEqual("where", tp.Name);
Assert.AreEqual(1, tp.Attributes.Count);
Assert.AreEqual("partial", tp.Attributes[0].AttributeTarget);
Assert.AreEqual(1, tp.Attributes[0].Attributes.Count);
Assert.AreEqual("where", tp.Attributes[0].Attributes[0].Name);
Assert.AreEqual(1, tp.Bases.Count);
Assert.AreEqual("partial", tp.Bases[0].Type);
Assert.AreEqual("where", tp.Bases[0].GenericTypes[0].Type);*/ throw new NotImplementedException();
ParseUtilCSharp.AssertGlobal(
"partial class partial<[partial: where] where> where where : partial<where> { }",
new TypeDeclaration {
Modifiers = Modifiers.Partial,
ClassType = ClassType.Class,
Name = "partial",
TypeParameters = {
new TypeParameterDeclaration {
Attributes = {
new AttributeSection {
AttributeTarget = AttributeTarget.Unknown,
Attributes = { new Attribute { Type = new SimpleType("where") } }
}
},
Name = "where"
}
},
Constraints = {
new Constraint {
TypeParameter = "where",
BaseTypes = {
new SimpleType {
Identifier = "partial",
TypeArguments = { new SimpleType("where") }
}
}
}
}});
}
[Test]

2
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs

@ -43,7 +43,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope @@ -43,7 +43,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Assert.AreEqual("My.Name.Space", ud.Namespace);
}
[Test]
[Test, Ignore("Aliases to generic types not yet supported")]
public void UsingAliasDeclarationTest()
{
string program = "using TESTME=System;\n" +

41
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs

@ -11,7 +11,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -11,7 +11,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
/// <summary>
/// Helper methods for parser unit tests.
/// </summary>
public class ParseUtilCSharp
public static class ParseUtilCSharp
{
public static T ParseGlobal<T>(string code, bool expectErrors = false) where T : AstNode
{
@ -26,6 +26,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -26,6 +26,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
return (T)node;
}
public static void AssertGlobal(string code, AstNode expectedNode)
{
var node = ParseGlobal<AstNode>(code);
if (expectedNode.Match(node) == null) {
Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedNode), ToCSharp(node));
}
}
public static T ParseStatement<T>(string stmt, bool expectErrors = false) where T : AstNode
{
CSharpParser parser = new CSharpParser();
@ -39,6 +47,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -39,6 +47,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
return (T)statement;
}
public static void AssertStatement(string code, CSharp.Statement expectedStmt)
{
var stmt = ParseStatement<CSharp.Statement>(code);
if (expectedStmt.Match(stmt) == null) {
Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedStmt), ToCSharp(stmt));
}
}
public static T ParseExpression<T>(string expr, bool expectErrors = false) where T : AstNode
{
if (expectErrors) Assert.Ignore("errors not yet implemented");
@ -53,6 +69,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -53,6 +69,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
return (T)parsedExpression;
}
public static void AssertExpression(string code, CSharp.Expression expectedExpr)
{
var expr = ParseExpression<CSharp.Expression>(code);
if (expectedExpr.Match(expr) == null) {
Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedExpr), ToCSharp(expr));
}
}
public static T ParseTypeMember<T>(string expr, bool expectErrors = false) where T : AttributedNode
{
if (expectErrors) Assert.Ignore("errors not yet implemented");
@ -67,5 +91,20 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -67,5 +91,20 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
Assert.IsTrue(type.IsAssignableFrom(m.GetType()), String.Format("Parsed member was {0} instead of {1} ({2})", m.GetType(), type, m));
return (T)m;
}
public static void AssertTypeMember(string code, CSharp.AttributedNode expectedMember)
{
var member = ParseTypeMember<CSharp.AttributedNode>(code);
if (expectedMember.Match(member) == null) {
Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedMember), ToCSharp(member));
}
}
static string ToCSharp(AstNode node)
{
StringWriter w = new StringWriter();
node.AcceptVisitor(new OutputVisitor(w, new CSharpFormattingPolicy()), null);
return w.ToString();
}
}
}

15
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs

@ -6,14 +6,25 @@ using NUnit.Framework; @@ -6,14 +6,25 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
{
[TestFixture]
[TestFixture, Ignore("fixed is not implemented")]
public class FixedStatementTests
{
[Test]
public void FixedStatementTest()
{
FixedStatement fixedStmt = ParseUtilCSharp.ParseStatement<FixedStatement>("fixed (int* ptr = &myIntArr) { }");
// TODO : Extend test.
ParseUtilCSharp.AssertStatement(
"fixed (int* ptr = &myIntArr) { }",
new FixedStatement {
Type = new PrimitiveType("int").MakePointerType(),
Variables = {
new VariableInitializer {
Name = "ptr",
Initializer = new UnaryOperatorExpression(UnaryOperatorType.AddressOf, new IdentifierExpression("myIntArr"))
}
},
EmbeddedStatement = new BlockStatement()
});
}
}
}

20
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ForStatementTests.cs

@ -10,11 +10,17 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -10,11 +10,17 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
[TestFixture]
public class ForStatementTests
{
[Test]
[Test, Ignore("variable type in foreach is broken")]
public void ForeachStatementTest()
{
ForeachStatement foreachStmt = ParseUtilCSharp.ParseStatement<ForeachStatement>("foreach (int i in myColl) {} ");
// TODO : Extend test.
ParseUtilCSharp.AssertStatement(
"foreach (int i in myColl) {} ",
new ForeachStatement {
VariableType = new PrimitiveType("int"),
VariableName = "i",
InExpression = new IdentifierExpression("myColl"),
EmbeddedStatement = new BlockStatement()
});
}
[Test, Ignore("for statement is broken when Initializers.Count()!=1")]
@ -40,7 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -40,7 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
Assert.IsTrue(inc.Expression is UnaryOperatorExpression);
}
[Test, Ignore("for statement is broken when Initializers.Count()!=1")]
[Test]
public void ForStatementTestMultipleInitializers()
{
ForStatement forStmt = ParseUtilCSharp.ParseStatement<ForStatement>("for (i = 0, j = 1; i < 6; ++i) {} ");
@ -48,10 +54,12 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -48,10 +54,12 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
Assert.IsTrue(forStmt.Iterators.All(i => i is ExpressionStatement));
}
[Test, Ignore("for statement is broken when Iterators.Count()!=1")]
[Test]
public void ForStatementTestMultipleIterators()
{
ForStatement forStmt = ParseUtilCSharp.ParseStatement<ForStatement>("for (int i = 5; i < 6; ++i, j--) {} ");
ForStatement forStmt = ParseUtilCSharp.ParseStatement<ForStatement>("for (int i = 5, j = 10; i < 6; ++i, j--) {} ");
Assert.AreEqual(1, forStmt.Initializers.Count());
Assert.AreEqual(2, ((VariableDeclarationStatement)forStmt.Initializers.Single()).Variables.Count());
Assert.AreEqual(2, forStmt.Iterators.Count());
Assert.IsTrue(forStmt.Iterators.All(i => i is ExpressionStatement));
}

56
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/TryCatchStatementTests.cs

@ -7,7 +7,7 @@ using NUnit.Framework; @@ -7,7 +7,7 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
{
[TestFixture, Ignore]
[TestFixture]
public class TryCatchStatementTests
{
[Test]
@ -20,28 +20,54 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -20,28 +20,54 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
Assert.AreEqual(string.Empty, tryCatchStatement.CatchClauses.Single().VariableName);
}
/* TODO port tests
[Test]
public void SimpleTryCatchStatementTest2()
{
TryCatchStatement tryCatchStatement = ParseUtilCSharp.ParseStatement<TryCatchStatement>("try { } catch (Exception e) { } ");
Assert.IsTrue(tryCatchStatement.FinallyBlock.IsNull);
Assert.AreEqual(1, tryCatchStatement.CatchClauses.Count);
Assert.AreEqual("Exception", tryCatchStatement.CatchClauses[0].TypeReference.Type);
Assert.AreEqual("e", tryCatchStatement.CatchClauses[0].VariableName);
ParseUtilCSharp.AssertStatement(
"try { } catch (Exception e) { } ",
new TryCatchStatement {
TryBlock = new BlockStatement(),
CatchClauses = {
new CatchClause {
Type = new SimpleType("Exception"),
VariableName = "e",
Body = new BlockStatement()
}
}});
}
[Test]
public void SimpleTryCatchFinallyStatementTest()
{
TryCatchStatement tryCatchStatement = ParseUtilCSharp.ParseStatement<TryCatchStatement>("try { } catch (Exception) { } catch { } finally { } ");
Assert.IsFalse(tryCatchStatement.FinallyBlock.IsNull);
Assert.AreEqual(2, tryCatchStatement.CatchClauses.Count);
Assert.AreEqual("Exception", tryCatchStatement.CatchClauses[0].TypeReference.Type);
Assert.IsEmpty(tryCatchStatement.CatchClauses[0].VariableName);
Assert.IsTrue(tryCatchStatement.CatchClauses[1].TypeReference.IsNull);
Assert.IsEmpty(tryCatchStatement.CatchClauses[1].VariableName);
ParseUtilCSharp.AssertStatement(
"try { } catch (Exception) { } catch { } finally { } ",
new TryCatchStatement {
TryBlock = new BlockStatement(),
CatchClauses = {
new CatchClause {
Type = new SimpleType("Exception"),
Body = new BlockStatement()
},
new CatchClause { Body = new BlockStatement() }
},
FinallyBlock = new BlockStatement()
});
}
[Test]
public void TestEmptyFinallyDoesNotMatchNullFinally()
{
TryCatchStatement c1 = new TryCatchStatement {
TryBlock = new BlockStatement(),
CatchClauses = { new CatchClause { Body = new BlockStatement() } }
};
TryCatchStatement c2 = new TryCatchStatement {
TryBlock = new BlockStatement(),
CatchClauses = { new CatchClause { Body = new BlockStatement() } },
FinallyBlock = new BlockStatement()
};
Assert.IsNull(c1.Match(c2));
Assert.IsNull(c2.Match(c1)); // and vice versa
}
*/
}
}

3
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/YieldStatementTests.cs

@ -21,8 +21,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -21,8 +21,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
[Test]
public void YieldBreakStatementTest()
{
YieldStatement yieldStmt = ParseUtilCSharp.ParseStatement<YieldStatement>("yield break;");
Assert.IsTrue(yieldStmt.Expression.IsNull);
ParseUtilCSharp.ParseStatement<YieldBreakStatement>("yield break;");
}
[Test]

113
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/EventDeclarationTests.cs

@ -6,79 +6,84 @@ using NUnit.Framework; @@ -6,79 +6,84 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
{
[TestFixture, Ignore]
[TestFixture, Ignore("events are broken")]
public class EventDeclarationTests
{
[Test]
public void SimpleEventDeclarationTest()
{
CustomEventDeclaration ed = ParseUtilCSharp.ParseTypeMember<CustomEventDeclaration>("event System.EventHandler MyEvent;");
Assert.AreEqual("MyEvent", ed.Name);
//Assert.AreEqual("System.EventHandler", ed.TypeReference.Type);
Assert.Ignore(); // check type
Assert.IsTrue(ed.AddAccessor.IsNull);
Assert.IsTrue(ed.RemoveAccessor.IsNull);
ParseUtilCSharp.AssertTypeMember(
"event EventHandler MyEvent;",
new EventDeclaration {
ReturnType = new SimpleType("EventHandler"),
Variables = {
new VariableInitializer {
Name = "MyEvent"
}
}});
}
/* TODO Port tests
[Test]
public void MultipleEventDeclarationTest()
{
TypeDeclaration t = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("class C { public event EventHandler A, B; }");
Assert.AreEqual(2, t.Children.Count);
EventDeclaration ed = (EventDeclaration)t.Children[0];
Assert.AreEqual(Modifiers.Public, ed.Modifier);
Assert.AreEqual("EventHandler", ed.TypeReference.Type);
Assert.AreEqual("A", ed.Name);
ed = (EventDeclaration)t.Children[1];
Assert.AreEqual(Modifiers.Public, ed.Modifier);
Assert.AreEqual("EventHandler", ed.TypeReference.Type);
Assert.AreEqual("B", ed.Name);
ParseUtilCSharp.AssertTypeMember(
"public event EventHandler A = null, B = delegate {};",
new EventDeclaration {
Modifiers = Modifiers.Public,
ReturnType = new SimpleType("EventHandler"),
Variables = {
new VariableInitializer {
Name = "A",
Initializer = new NullReferenceExpression()
},
new VariableInitializer {
Name = "B",
Initializer = new AnonymousMethodExpression()
}
}});
}
[Test]
public void EventImplementingInterfaceDeclarationTest()
public void AddRemoveEventDeclarationTest()
{
EventDeclaration ed = ParseUtilCSharp.ParseTypeMember<EventDeclaration>("event EventHandler MyInterface.MyEvent;");
Assert.AreEqual("MyEvent", ed.Name);
Assert.AreEqual("EventHandler", ed.TypeReference.Type);
Assert.IsFalse(ed.HasAddRegion);
Assert.IsFalse(ed.HasRemoveRegion);
Assert.AreEqual("MyInterface", ed.InterfaceImplementations[0].InterfaceType.Type);
Assert.AreEqual("MyEvent", ed.InterfaceImplementations[0].MemberName);
ParseUtilCSharp.AssertTypeMember(
"public event System.EventHandler MyEvent { add { } remove { } }",
new CustomEventDeclaration {
Modifiers = Modifiers.Public,
ReturnType = new MemberType {
Target = new SimpleType("System"),
MemberName = "EventHandler"
},
Name = "MyEvent",
AddAccessor = new Accessor { Body = new BlockStatement() },
RemoveAccessor = new Accessor { Body = new BlockStatement() }
});
}
[Test]
public void EventImplementingGenericInterfaceDeclarationTest()
{
EventDeclaration ed = ParseUtilCSharp.ParseTypeMember<EventDeclaration>("event EventHandler MyInterface<string>.MyEvent;");
Assert.AreEqual("MyEvent", ed.Name);
Assert.AreEqual("EventHandler", ed.TypeReference.Type);
Assert.IsFalse(ed.HasAddRegion);
Assert.IsFalse(ed.HasRemoveRegion);
Assert.AreEqual("MyInterface", ed.InterfaceImplementations[0].InterfaceType.Type);
Assert.AreEqual("System.String", ed.InterfaceImplementations[0].InterfaceType.GenericTypes[0].Type);
Assert.AreEqual("MyEvent", ed.InterfaceImplementations[0].MemberName);
ParseUtilCSharp.AssertTypeMember(
"event EventHandler MyInterface<string>.MyEvent { add { } [Attr] remove {} }",
new CustomEventDeclaration {
ReturnType = new SimpleType("EventHandler"),
PrivateImplementationType = new SimpleType{
Identifier = "MyInterface",
TypeArguments = { new PrimitiveType("string") }
},
Name = "MyEvent",
AddAccessor = new Accessor { Body = new BlockStatement() },
RemoveAccessor = new Accessor {
Attributes = {
new AttributeSection {
Attributes = {
new Attribute { Type = new SimpleType("Attr") }
}
}
},
Body = new BlockStatement()
}
});
}
[Test]
public void AddRemoveEventDeclarationTest()
{
EventDeclaration ed = ParseUtilCSharp.ParseTypeMember<EventDeclaration>("event System.EventHandler MyEvent { add { } remove { } }");
Assert.AreEqual("MyEvent", ed.Name);
Assert.AreEqual("System.EventHandler", ed.TypeReference.Type);
Assert.IsTrue(ed.HasAddRegion);
Assert.IsTrue(ed.HasRemoveRegion);
}*/
}
}

60
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/FieldDeclarationTests.cs

@ -6,22 +6,62 @@ using NUnit.Framework; @@ -6,22 +6,62 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
{
[TestFixture, Ignore]
[TestFixture]
public class FieldDeclarationTests
{
[Test]
[Test, Ignore("multidimensional array rank incorrect?")]
public void SimpleFieldDeclarationTest()
{
throw new NotImplementedException();
/*
FieldDeclaration fd = ParseUtilCSharp.ParseTypeMember<FieldDeclaration>("int[,,,] myField;");
Assert.AreEqual("System.Int32", fd.TypeReference.Type);
Assert.AreEqual(new int[] { 3 } , fd.TypeReference.RankSpecifier);
Assert.AreEqual(1, fd.Fields.Count);
ParseUtilCSharp.AssertTypeMember(
"int[,,,] myField;",
new FieldDeclaration {
ReturnType = new PrimitiveType("int").MakeArrayType(4),
Variables = { new VariableInitializer("myField") }
});
}
[Test]
public void MultipleFieldDeclarationTest()
{
ParseUtilCSharp.AssertTypeMember(
"int a = 1, b = 2;",
new FieldDeclaration {
ReturnType = new PrimitiveType("int"),
Variables = {
new VariableInitializer("a", new PrimitiveExpression(1)),
new VariableInitializer("b", new PrimitiveExpression(2)),
}
});
}
Assert.AreEqual("myField", ((VariableDeclaration)fd.Fields[0]).Name);*/
[Test]
public void FieldWithArrayInitializer()
{
ParseUtilCSharp.AssertTypeMember(
"public static readonly int[] arr = { 1, 2, 3 };",
new FieldDeclaration {
Modifiers = Modifiers.Public | Modifiers.Static | Modifiers.Readonly,
ReturnType = new PrimitiveType("int").MakeArrayType(),
Variables = {
new VariableInitializer {
Name = "arr",
Initializer = new ArrayInitializerExpression {
Elements = {
new PrimitiveExpression(1),
new PrimitiveExpression(2),
new PrimitiveExpression(3)
}
}
}
}});
}
// TODO add more tests
[Test, Ignore("How do we represent fixed-size fields in the AST?")]
public void FieldWithFixedSize()
{
ParseUtilCSharp.AssertTypeMember(
"public unsafe fixed int Field[100];",
new FieldDeclaration());
}
}
}

37
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/IndexerDeclarationTests.cs

@ -13,13 +13,16 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -13,13 +13,16 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
[Test]
public void IndexerDeclarationTest()
{
IndexerDeclaration id = ParseUtilCSharp.ParseTypeMember<IndexerDeclaration>("int this[int a, string b] { get { } set { } }");
IndexerDeclaration id = ParseUtilCSharp.ParseTypeMember<IndexerDeclaration>("public int this[int a, string b] { get { } protected set { } }");
Assert.AreEqual(2, id.Parameters.Count());
Assert.IsNotNull(id.Getter, "No get region found!");
Assert.IsNotNull(id.Setter, "No set region found!");
Assert.AreEqual(Modifiers.Public, id.Modifiers);
Assert.AreEqual(Modifiers.None, id.Getter.Modifiers);
Assert.AreEqual(Modifiers.Protected, id.Setter.Modifiers);
}
[Test, Ignore("type reference is not yet implemented")]
[Test, Ignore("explicit interface implementation not yet supported")]
public void IndexerImplementingInterfaceTest()
{
IndexerDeclaration id = ParseUtilCSharp.ParseTypeMember<IndexerDeclaration>("int MyInterface.this[int a, string b] { get { } set { } }");
@ -27,21 +30,29 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -27,21 +30,29 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Assert.IsNotNull(id.Getter, "No get region found!");
Assert.IsNotNull(id.Setter, "No set region found!");
Assert.AreEqual("MyInterface", id.PrivateImplementationType);
Assert.AreEqual("MyInterface", ((SimpleType)id.PrivateImplementationType).Identifier);
}
[Test, Ignore]
[Test, Ignore("explicit interface implementation not yet supported")]
public void IndexerImplementingGenericInterfaceTest()
{
throw new NotImplementedException();
/*
IndexerDeclaration id = ParseUtilCSharp.ParseTypeMember<IndexerDeclaration>("int MyInterface<string>.this[int a, string b] { get { } set { } }");
Assert.AreEqual(2, id.Parameters.Count);
Assert.IsNotNull(id.GetAccessor, "No get region found!");
Assert.IsNotNull(id.SetAccessor, "No set region found!");
Assert.AreEqual("MyInterface", id.InterfaceImplementations[0].InterfaceType.Type);
Assert.AreEqual("System.String", id.InterfaceImplementations[0].InterfaceType.GenericTypes[0].Type);*/
ParseUtilCSharp.AssertTypeMember(
"int MyInterface<string>.this[int a, string b] { get { } [Attr] set { } }",
new IndexerDeclaration {
ReturnType = new PrimitiveType("int"),
PrivateImplementationType = new SimpleType {
Identifier = "MyInterface",
TypeArguments = { new PrimitiveType("string") }
},
Parameters = {
new ParameterDeclaration(new PrimitiveType("int"), "a"),
new ParameterDeclaration(new PrimitiveType("string"), "b")
},
Getter = new Accessor { Body = new BlockStatement() },
Setter = new Accessor {
Attributes = { new AttributeSection(new Attribute { Type = new SimpleType("Attr") }) },
Body = new BlockStatement()
}});
}
}
}

266
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs

@ -3,49 +3,50 @@ @@ -3,49 +3,50 @@
using System;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
{
[TestFixture]
[TestFixture, Ignore("Generics not yet implemented")]
public class MethodDeclarationTests
{
[Test, Ignore("type references not yet implemented")]
[Test]
public void SimpleMethodDeclarationTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("void MyMethod() {} ");
Assert.AreEqual("System.Void", md.ReturnType);
Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
Assert.AreEqual(0, md.Parameters.Count());
Assert.IsFalse(md.IsExtensionMethod);
}
[Test, Ignore("type references not yet implemented")]
[Test]
public void AbstractMethodDeclarationTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("abstract void MyMethod();");
Assert.AreEqual("System.Void", md.ReturnType);
Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
Assert.AreEqual(0, md.Parameters.Count());
Assert.IsFalse(md.IsExtensionMethod);
Assert.IsTrue(md.Body.IsNull);
Assert.AreEqual(Modifiers.Abstract, md.Modifiers);
}
[Test, Ignore("type references not yet implemented")]
[Test]
public void DefiningPartialMethodDeclarationTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("partial void MyMethod();");
Assert.AreEqual("System.Void", md.ReturnType);
Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
Assert.AreEqual(0, md.Parameters.Count());
Assert.IsFalse(md.IsExtensionMethod);
Assert.IsTrue(md.Body.IsNull);
Assert.AreEqual(Modifiers.Partial, md.Modifiers);
}
[Test, Ignore("type references not yet implemented")]
[Test]
public void ImplementingPartialMethodDeclarationTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("partial void MyMethod() { }");
Assert.AreEqual("System.Void", md.ReturnType);
Assert.AreEqual("void", ((PrimitiveType)md.ReturnType).Keyword);
Assert.AreEqual(0, md.Parameters.Count());
Assert.IsFalse(md.IsExtensionMethod);
Assert.IsFalse(md.Body.IsNull);
@ -81,6 +82,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -81,6 +82,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Assert.AreEqual(2, md.StartLocation.Line, "StartLocation.Y");
Assert.AreEqual(5, md.EndLocation.Line, "EndLocation.Y");
Assert.AreEqual(3, md.StartLocation.Column, "StartLocation.X");
Assert.AreEqual(4, md.EndLocation.Column, "EndLocation.X");
}
[Test]
@ -89,142 +91,176 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -89,142 +91,176 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("void MyMethod(int) {} ", true);
Assert.AreEqual("System.Void", md.ReturnType);
Assert.AreEqual(1, md.Parameters.Count());
//Assert.AreEqual("?", ((ParameterDeclarationExpression)md.Parameters[0]).ParameterName);
Assert.AreEqual("int", ((PrimitiveType)md.Parameters.Single().Type).Keyword);
}
/* TODO: port unit tests
[Test]
public void GenericVoidMethodDeclarationTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("void MyMethod<T>(T a) {} ");
Assert.AreEqual("System.Void", md.ReturnType);
Assert.AreEqual(1, md.Parameters.Count());
Assert.AreEqual("T", md.Parameters.Single().Type);
Assert.AreEqual("a", md.Parameters.Single().Name);
Assert.AreEqual(1, md.TypeParameters.Count());
Assert.AreEqual("T", md.Templates[0].Name);
ParseUtilCSharp.AssertTypeMember(
"void MyMethod<T>(T a) {} ",
new MethodDeclaration {
ReturnType = new PrimitiveType("void"),
Name = "MyMethod",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Body = new BlockStatement()
});
}
[Test]
public void GenericMethodDeclarationTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("T MyMethod<T>(T a) {} ");
Assert.AreEqual("T", md.TypeReference.Type);
Assert.AreEqual(1, md.Parameters.Count);
Assert.AreEqual("T", ((ParameterDeclarationExpression)md.Parameters[0]).TypeReference.Type);
Assert.AreEqual("a", ((ParameterDeclarationExpression)md.Parameters[0]).ParameterName);
Assert.AreEqual(1, md.Templates.Count);
Assert.AreEqual("T", md.Templates[0].Name);
ParseUtilCSharp.AssertTypeMember(
"T MyMethod<T>(T a) {} ",
new MethodDeclaration {
ReturnType = new SimpleType("T"),
Name = "MyMethod",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Body = new BlockStatement()
});
}
[Test]
public void GenericMethodDeclarationWithConstraintTest()
{
string program = "T MyMethod<T>(T a) where T : ISomeInterface {} ";
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(program);
Assert.AreEqual("T", md.TypeReference.Type);
Assert.AreEqual(1, md.Parameters.Count);
Assert.AreEqual("T", ((ParameterDeclarationExpression)md.Parameters[0]).TypeReference.Type);
Assert.AreEqual("a", ((ParameterDeclarationExpression)md.Parameters[0]).ParameterName);
Assert.AreEqual(1, md.Templates.Count);
Assert.AreEqual("T", md.Templates[0].Name);
Assert.AreEqual(1, md.Templates[0].Bases.Count);
Assert.AreEqual("ISomeInterface", md.Templates[0].Bases[0].Type);
ParseUtilCSharp.AssertTypeMember(
"T MyMethod<T>(T a) where T : ISomeInterface {} ",
new MethodDeclaration {
ReturnType = new SimpleType("T"),
Name = "MyMethod",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = {
new Constraint {
TypeParameter = "T",
BaseTypes = { new SimpleType("ISomeInterface") }
}
},
Body = new BlockStatement()
});
}
[Test]
public void GenericMethodInInterface()
{
const string program = @"interface MyInterface {
ParseUtilCSharp.AssertGlobal(
@"interface MyInterface {
T MyMethod<T>(T a) where T : ISomeInterface;
}
";
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
MethodDeclaration md = (MethodDeclaration)td.Children[0];
Assert.AreEqual("T", md.TypeReference.Type);
Assert.AreEqual(1, md.Parameters.Count);
Assert.AreEqual("T", ((ParameterDeclarationExpression)md.Parameters[0]).TypeReference.Type);
Assert.AreEqual("a", ((ParameterDeclarationExpression)md.Parameters[0]).ParameterName);
Assert.AreEqual(1, md.Templates.Count);
Assert.AreEqual("T", md.Templates[0].Name);
Assert.AreEqual(1, md.Templates[0].Bases.Count);
Assert.AreEqual("ISomeInterface", md.Templates[0].Bases[0].Type);
",
new TypeDeclaration {
ClassType = ClassType.Interface,
Members = {
new MethodDeclaration {
ReturnType = new SimpleType("T"),
Name = "MyMethod",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = {
new Constraint {
TypeParameter = "T",
BaseTypes = { new SimpleType("ISomeInterface") }
}
}
}}});
}
[Test]
public void GenericVoidMethodInInterface()
{
const string program = @"interface MyInterface {
ParseUtilCSharp.AssertGlobal(
@"interface MyInterface {
void MyMethod<T>(T a) where T : ISomeInterface;
}
";
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
MethodDeclaration md = (MethodDeclaration)td.Children[0];
Assert.AreEqual("System.Void", md.TypeReference.Type);
Assert.AreEqual(1, md.Parameters.Count);
Assert.AreEqual("T", ((ParameterDeclarationExpression)md.Parameters[0]).TypeReference.Type);
Assert.AreEqual("a", ((ParameterDeclarationExpression)md.Parameters[0]).ParameterName);
Assert.AreEqual(1, md.Templates.Count);
Assert.AreEqual("T", md.Templates[0].Name);
Assert.AreEqual(1, md.Templates[0].Bases.Count);
Assert.AreEqual("ISomeInterface", md.Templates[0].Bases[0].Type);
",
new TypeDeclaration {
ClassType = ClassType.Interface,
Members = {
new MethodDeclaration {
ReturnType = new PrimitiveType("void"),
Name = "MyMethod",
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = {
new Constraint {
TypeParameter = "T",
BaseTypes = { new SimpleType("ISomeInterface") }
}
}
}}});
}
[Test]
public void ShadowingMethodInInterface()
{
const string program = @"interface MyInterface : IDisposable {
ParseUtilCSharp.AssertGlobal(
@"interface MyInterface : IDisposable {
new void Dispose();
}
";
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
MethodDeclaration md = (MethodDeclaration)td.Children[0];
Assert.AreEqual("System.Void", md.TypeReference.Type);
Assert.AreEqual(0, md.Parameters.Count);
Assert.AreEqual(Modifiers.New, md.Modifier);
",
new TypeDeclaration {
ClassType = ClassType.Interface,
BaseTypes = { new SimpleType("IDisposable") },
Members = {
new MethodDeclaration {
Modifiers = Modifiers.New,
ReturnType = new PrimitiveType("void"),
Name = "Dispose"
}}});
}
[Test]
public void MethodImplementingInterfaceTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("int MyInterface.MyMethod() {} ");
Assert.AreEqual("System.Int32", md.TypeReference.Type);
Assert.AreEqual("MyInterface", md.InterfaceImplementations[0].InterfaceType.Type);
ParseUtilCSharp.AssertGlobal(
"int MyInterface.MyMethod() {} ",
new MethodDeclaration {
ReturnType = new PrimitiveType("int"),
PrivateImplementationType = new SimpleType("MyInterface"),
Name = "MyMethod",
Body = new BlockStatement()
});
}
[Test]
public void MethodImplementingGenericInterfaceTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("int MyInterface<string>.MyMethod() {} ");
Assert.AreEqual("System.Int32", md.TypeReference.Type);
Assert.AreEqual("MyInterface", md.InterfaceImplementations[0].InterfaceType.Type);
Assert.AreEqual("System.String", md.InterfaceImplementations[0].InterfaceType.GenericTypes[0].Type);
ParseUtilCSharp.AssertGlobal(
"int MyInterface<string>.MyMethod() {} ",
new MethodDeclaration {
ReturnType = new PrimitiveType("int"),
PrivateImplementationType = new SimpleType("MyInterface") { TypeArguments = { new PrimitiveType("string") } },
Name = "MyMethod",
Body = new BlockStatement()
});
}
[Test]
public void VoidMethodImplementingInterfaceTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("void MyInterface.MyMethod() {} ");
Assert.AreEqual("System.Void", md.TypeReference.Type);
Assert.AreEqual("MyInterface", md.InterfaceImplementations[0].InterfaceType.Type);
ParseUtilCSharp.AssertGlobal(
"void MyInterface.MyMethod() {} ",
new MethodDeclaration {
ReturnType = new PrimitiveType("void"),
PrivateImplementationType = new SimpleType("MyInterface"),
Name = "MyMethod",
Body = new BlockStatement()
});
}
[Test]
public void VoidMethodImplementingGenericInterfaceTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>("void MyInterface<string>.MyMethod() {} ");
Assert.AreEqual("System.Void", md.TypeReference.Type);
Assert.AreEqual("MyInterface", md.InterfaceImplementations[0].InterfaceType.Type);
Assert.AreEqual("System.String", md.InterfaceImplementations[0].InterfaceType.GenericTypes[0].Type);
ParseUtilCSharp.AssertGlobal(
"void MyInterface<string>.MyMethod() {} ",
new MethodDeclaration {
ReturnType = new PrimitiveType("void"),
PrivateImplementationType = new SimpleType("MyInterface"),
Name = "MyMethod",
Body = new BlockStatement()
});
}
[Test]
@ -234,9 +270,9 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -234,9 +270,9 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
"void a<T>() where T { }", true // expect errors
);
Assert.AreEqual("a", md.Name);
Assert.AreEqual(1, md.Templates.Count);
Assert.AreEqual("T", md.Templates[0].Name);
Assert.AreEqual(0, md.Templates[0].Bases.Count);
Assert.AreEqual(1, md.TypeParameters.Count);
Assert.AreEqual("T", md.TypeParameters.Single().Name);
Assert.AreEqual(0, md.Constraints.Count());
}
[Test]
@ -246,11 +282,11 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -246,11 +282,11 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
"public static int ToInt32(this string s) { return int.Parse(s); }"
);
Assert.AreEqual("ToInt32", md.Name);
Assert.AreEqual("s", md.Parameters.First().Name);
Assert.AreEqual(ParameterModifier.This, md.Parameters.First().ParameterModifier);
Assert.AreEqual("string", ((PrimitiveType)md.Parameters.First().Type).Keyword);
Assert.IsTrue(md.IsExtensionMethod);
Assert.AreEqual("s", md.Parameters[0].ParameterName);
Assert.AreEqual("System.String", md.Parameters[0].TypeReference.Type);
}
*/
[Test]
public void VoidExtensionMethodTest()
@ -265,7 +301,6 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -265,7 +301,6 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Assert.IsTrue(md.IsExtensionMethod);
}
/* TODO
[Test]
public void MethodWithEmptyAssignmentErrorInBody()
{
@ -277,27 +312,32 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -277,27 +312,32 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
"}", true // expect errors
);
Assert.AreEqual("A", md.Name);
Assert.AreEqual(new Location(1, 2), md.Body.StartLocation);
Assert.AreEqual(new Location(2, 5), md.Body.EndLocation);
Assert.AreEqual(new AstLocation(1, 2), md.Body.StartLocation);
Assert.AreEqual(new AstLocation(2, 5), md.Body.EndLocation);
}
[Test]
public void OptionalParameterTest()
{
MethodDeclaration md = ParseUtilCSharp.ParseTypeMember<MethodDeclaration>(
"public void Foo(string bar = null, int baz = 0) { }"
);
Assert.AreEqual("Foo", md.Name);
Assert.AreEqual("bar", md.Parameters[0].ParameterName);
Assert.AreEqual("System.String", md.Parameters[0].TypeReference.Type);
Assert.AreEqual(ParameterModifiers.In | ParameterModifiers.Optional, md.Parameters[0].ParamModifier);
Assert.IsNull(((PrimitiveExpression)md.Parameters[0].DefaultValue).Value);
Assert.AreEqual("baz", md.Parameters[1].ParameterName);
Assert.AreEqual("System.Int32", md.Parameters[1].TypeReference.Type);
Assert.AreEqual(ParameterModifiers.In | ParameterModifiers.Optional, md.Parameters[1].ParamModifier);
Assert.AreEqual(0, ((PrimitiveExpression)md.Parameters[1].DefaultValue).Value);
}*/
ParseUtilCSharp.AssertTypeMember(
"public void Foo(string bar = null, int baz = 0) { }",
new MethodDeclaration {
Modifiers = Modifiers.Public,
ReturnType = new PrimitiveType("void"),
Name = "Foo",
Body = new BlockStatement(),
Parameters = {
new ParameterDeclaration {
Type = new PrimitiveType("string"),
Name = "bar",
DefaultExpression = new NullReferenceExpression()
},
new ParameterDeclaration {
Type = new PrimitiveType("int"),
Name = "baz",
DefaultExpression = new PrimitiveExpression(0)
}
}});
}
}
}

16
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/OperatorDeclarationTests.cs

@ -10,43 +10,43 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -10,43 +10,43 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
[TestFixture]
public class OperatorDeclarationTests
{
[Test, Ignore("type references not yet implemented")]
[Test]
public void ImplictOperatorDeclarationTest()
{
OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember<OperatorDeclaration>("public static implicit operator double(MyObject f) { return 0.5d; }");
Assert.AreEqual(OperatorType.Implicit, od.OperatorType);
Assert.AreEqual(1, od.Parameters.Count());
Assert.AreEqual("System.Double", od.ReturnType);
Assert.AreEqual("double", ((PrimitiveType)od.ReturnType).Keyword);
Assert.AreEqual("op_Implicit", od.Name);
}
[Test, Ignore("type references not yet implemented")]
[Test]
public void ExplicitOperatorDeclarationTest()
{
OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember<OperatorDeclaration>("public static explicit operator double(MyObject f) { return 0.5d; }");
Assert.AreEqual(OperatorType.Explicit, od.OperatorType);
Assert.AreEqual(1, od.Parameters.Count());
Assert.AreEqual("System.Double", od.ReturnType);
Assert.AreEqual("double", ((PrimitiveType)od.ReturnType).Keyword);
Assert.AreEqual("op_Explicit", od.Name);
}
[Test, Ignore("type references not yet implemented")]
[Test]
public void BinaryPlusOperatorDeclarationTest()
{
OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember<OperatorDeclaration>("public static MyObject operator +(MyObject a, MyObject b) {}");
Assert.AreEqual(OperatorType.Addition, od.OperatorType);
Assert.AreEqual(2, od.Parameters.Count());
Assert.AreEqual("MyObject", od.ReturnType);
Assert.AreEqual("MyObject", ((SimpleType)od.ReturnType).Identifier);
Assert.AreEqual("op_Addition", od.Name);
}
[Test, Ignore("type references not yet implemented")]
[Test]
public void UnaryPlusOperatorDeclarationTest()
{
OperatorDeclaration od = ParseUtilCSharp.ParseTypeMember<OperatorDeclaration>("public static MyObject operator +(MyObject a) {}");
Assert.AreEqual(OperatorType.UnaryPlus, od.OperatorType);
Assert.AreEqual(1, od.Parameters.Count());
Assert.AreEqual("MyObject", od.ReturnType);
Assert.AreEqual("MyObject", ((SimpleType)od.ReturnType).Identifier);
Assert.AreEqual("op_UnaryPlus", od.Name);
}
}

10
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs

@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Assert.AreEqual(new AstLocation(4, code.IndexOf("}\n\t}") + 1 - line4Pos + 1), pd.Setter.Body.EndLocation);
}
[Test, Ignore("type references not yet implemented")]
[Test, Ignore("explicit interface implementation not yet implemented")]
public void PropertyImplementingInterfaceTest()
{
PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember<PropertyDeclaration>("int MyInterface.MyProperty { get {} } ");
@ -74,10 +74,10 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -74,10 +74,10 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Assert.IsFalse(pd.Getter.IsNull);
Assert.IsTrue(pd.Setter.IsNull);
Assert.AreEqual("MyInterface", pd.PrivateImplementationType);
Assert.AreEqual("MyInterface", ((SimpleType)pd.PrivateImplementationType).Identifier);
}
[Test, Ignore("type references not yet implemented")]
[Test, Ignore("explicit interface implementation not yet implemented")]
public void PropertyImplementingGenericInterfaceTest()
{
PropertyDeclaration pd = ParseUtilCSharp.ParseTypeMember<PropertyDeclaration>("int MyInterface<string>.MyProperty { get {} } ");
@ -85,9 +85,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -85,9 +85,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Assert.IsFalse(pd.Getter.IsNull);
Assert.IsTrue(pd.Setter.IsNull);
throw new NotImplementedException();
//Assert.AreEqual("MyInterface", pd.InterfaceImplementations[0].InterfaceType.Type);
//Assert.AreEqual("System.String", pd.InterfaceImplementations[0].InterfaceType.GenericTypes[0].Type);
Assert.IsNotNull(new SimpleType { Identifier = "MyInterface", TypeArguments = { new PrimitiveType("string") } }.Match(pd.PrivateImplementationType));
}
}
}

2
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs

@ -122,7 +122,7 @@ class A { @@ -122,7 +122,7 @@ class A {
Assert.AreEqual("System.Void", Resolve(program).Type.ReflectionName);
}
[Test]
[Test, Ignore("parser is broken for events")]
public void EventCallTest()
{
string program = @"using System;

10
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -366,7 +366,7 @@ class TestClass { @@ -366,7 +366,7 @@ class TestClass {
Assert.AreEqual("System.Collections.ArrayList", member.Type.FullName, "the full type should be resolved");
}
[Test]
[Test, Ignore("Parser position bug")]
public void ImportAliasNamespaceResolveTest()
{
NamespaceResolveResult ns;
@ -394,7 +394,7 @@ class TestClass { @@ -394,7 +394,7 @@ class TestClass {
Assert.AreEqual("System.Collections.ArrayList", rr.Type.FullName, "a");
}
[Test]
[Test, Ignore("Parser position bug")]
public void ResolveNamespaceSD_863()
{
string program = @"using System;
@ -432,7 +432,7 @@ namespace A.B { @@ -432,7 +432,7 @@ namespace A.B {
Assert.AreEqual("A.B.C", trr.Type.FullName);
}
[Test]
[Test, Ignore("parser is broken and produces IdentifierExpression instead of PrimitiveType")]
public void ShortMaxValueTest()
{
string program = @"using System;
@ -471,7 +471,7 @@ class TestClass { @@ -471,7 +471,7 @@ class TestClass {
Assert.AreEqual("XX.XX.Test", mrr.Member.FullName);
}
[Test]
[Test, Ignore("Parser position bug")]
public void ClassNameLookup1()
{
string program = @"namespace MainNamespace {
@ -490,7 +490,7 @@ namespace Test.Subnamespace { @@ -490,7 +490,7 @@ namespace Test.Subnamespace {
Assert.AreEqual("Test.Subnamespace.Test.TheClass", trr.Type.FullName);
}
[Test]
[Test, Ignore("Parser position bug")]
public void ClassNameLookup2()
{
string program = @"using Test.Subnamespace;

2
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnsafeCodeTests.cs

@ -9,7 +9,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -9,7 +9,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[TestFixture]
public class UnsafeCodeTests : ResolverTestBase
{
[Test, Ignore("Parser produces parse tree that doesn't match DOM definition??")]
[Test, Ignore("fixed statement not implemented in parser")]
public void FixedStatement()
{
string program = @"using System;

1
NRefactory/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>

1
NRefactory/ICSharpCode.NRefactory.VB.Tests/ICSharpCode.NRefactory.VB.Tests.csproj

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>

1
NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
<AssemblyName>ICSharpCode.NRefactory.VB</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>

6
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstLocation.cs

@ -57,11 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -57,11 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp
get { return column; }
}
public override bool Equals (object other)
public override bool Equals (object obj)
{
if (!(other is AstLocation))
if (!(obj is AstLocation))
return false;
return (AstLocation)other == this;
return (AstLocation)obj == this;
}
public override int GetHashCode ()

5
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs

@ -606,6 +606,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -606,6 +606,11 @@ namespace ICSharpCode.NRefactory.CSharp
}
protected internal abstract bool DoMatch(AstNode other, Match match);
internal virtual bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{
return DoMatch(pos, match);
}
#endregion
// the Root role must be available when creating the null nodes, so we can't put it in the Roles class

10
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNodeCollection.cs

@ -174,18 +174,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -174,18 +174,12 @@ namespace ICSharpCode.NRefactory.CSharp
if (cur1 == null)
break;
Pattern pattern = cur1 as Pattern;
if (pattern == null && cur1.NodeType == NodeType.Placeholder)
pattern = cur1.GetChildByRole(TypePlaceholder.ChildRole) as Pattern;
if (pattern != null) {
Debug.Assert(stack.Count == patternStack.Count);
success = pattern.DoMatchCollection(role, cur2, match, stack);
success = cur1.DoMatchCollection(role, cur2, match, stack);
Debug.Assert(stack.Count >= patternStack.Count);
while (stack.Count > patternStack.Count)
patternStack.Push(cur1.NextSibling);
} else {
success = cur1.DoMatch(cur2, match);
}
cur1 = cur1.NextSibling;
if (cur2 != null)
cur2 = cur2.NextSibling;

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -40,7 +40,7 @@ namespace ICSharpCode.NRefactory.CSharp
return new ComposedType { BaseType = this }.MakePointerType();
}
public virtual AstType MakeArrayType(int rank)
public virtual AstType MakeArrayType(int rank = 1)
{
return new ComposedType { BaseType = this }.MakeArrayType(rank);
}

6
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs

@ -48,6 +48,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -48,6 +48,12 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CSharpModifierToken o = other as CSharpModifierToken;
return o != null && this.modifier == o.modifier;
}
// Not worth using a dictionary for such few elements.
// This table is sorted in the order that modifiers should be output when generating code.
static readonly List<KeyValuePair<Modifiers, int>> lengthTable = new List<KeyValuePair<Modifiers, int>> () {

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CSharpTokenNode.cs

@ -88,7 +88,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -88,7 +88,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CSharpTokenNode o = other as CSharpTokenNode;
return o != null;
return o != null && !o.IsNull && !(o is CSharpModifierToken);
}
public override string ToString ()

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Expressions/ArrayCreateExpression.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -41,7 +41,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ArrayCreateExpression o = other as ArrayCreateExpression;
return o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match) && this.Initializer.DoMatch(o.Initializer, match);
return o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match) && this.AdditionalArraySpecifiers.DoMatch(o.AdditionalArraySpecifiers, match) && this.Initializer.DoMatch(o.Initializer, match);
}
}
}

61
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryExpression o = other as QueryExpression;
return o != null && this.Clauses.DoMatch(o.Clauses, match);
return o != null && !o.IsNull && this.Clauses.DoMatch(o.Clauses, match);
}
}
@ -54,12 +54,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -54,12 +54,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override NodeType NodeType {
get { return NodeType.QueryClause; }
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryClause o = other as QueryClause;
throw new NotImplementedException();
}
}
/// <summary>
@ -103,6 +97,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -103,6 +97,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQueryContinuationClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryContinuationClause o = other as QueryContinuationClause;
return o != null && MatchString(this.Identifier, o.Identifier) && this.PrecedingQuery.DoMatch(o.PrecedingQuery, match);
}
}
public class QueryFromClause : QueryClause
@ -133,6 +133,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -133,6 +133,13 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQueryFromClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryFromClause o = other as QueryFromClause;
return o != null && this.Type.DoMatch(o.Type, match) && MatchString(this.Identifier, o.Identifier)
&& this.Expression.DoMatch(o.Expression, match);
}
}
public class QueryLetClause : QueryClause
@ -163,6 +170,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -163,6 +170,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQueryLetClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryLetClause o = other as QueryLetClause;
return o != null && MatchString(this.Identifier, o.Identifier) && this.Expression.DoMatch(o.Expression, match);
}
}
@ -181,6 +194,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -181,6 +194,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQueryWhereClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryWhereClause o = other as QueryWhereClause;
return o != null && this.Condition.DoMatch(o.Condition, match);
}
}
/// <summary>
@ -266,6 +285,16 @@ namespace ICSharpCode.NRefactory.CSharp @@ -266,6 +285,16 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQueryJoinClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryJoinClause o = other as QueryJoinClause;
return o != null && this.IsGroupJoin == o.IsGroupJoin
&& this.Type.DoMatch(o.Type, match) && MatchString(this.JoinIdentifier, o.JoinIdentifier)
&& this.InExpression.DoMatch(o.InExpression, match) && this.OnExpression.DoMatch(o.OnExpression, match)
&& this.EqualsExpression.DoMatch(o.EqualsExpression, match)
&& MatchString(this.IntoIdentifier, o.IntoIdentifier);
}
}
public class QueryOrderClause : QueryClause
@ -284,6 +313,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -284,6 +313,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQueryOrderClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryOrderClause o = other as QueryOrderClause;
return o != null && this.Orderings.DoMatch(o.Orderings, match);
}
}
public class QueryOrdering : AstNode
@ -340,6 +375,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -340,6 +375,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQuerySelectClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QuerySelectClause o = other as QuerySelectClause;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
}
public class QueryGroupClause : QueryClause
@ -371,5 +412,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -371,5 +412,11 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitQueryGroupClause (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
QueryGroupClause o = other as QueryGroupClause;
return o != null && this.Projection.DoMatch(o.Projection, match) && this.Key.DoMatch(o.Key, match);
}
}
}

9
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/AttributeSection.cs

@ -64,6 +64,15 @@ namespace ICSharpCode.NRefactory.CSharp @@ -64,6 +64,15 @@ namespace ICSharpCode.NRefactory.CSharp
return o != null && this.AttributeTarget == o.AttributeTarget && this.Attributes.DoMatch(o.Attributes, match);
}
public AttributeSection()
{
}
public AttributeSection(Attribute attr)
{
this.Attributes.Add(attr);
}
public static string GetAttributeTargetName(AttributeTarget attributeTarget)
{
switch (attributeTarget) {

5
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/Constraint.cs

@ -31,6 +31,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -31,6 +31,9 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary>
/// where TypeParameter : BaseTypes
/// </summary>
/// <remarks>
/// new(), struct and class constraints are represented using a PrimitiveType "new", "struct" or "class"
/// </remarks>
public class Constraint : AstNode
{
public readonly static Role<CSharpTokenNode> ColonRole = TypeDeclaration.ColonRole;
@ -51,8 +54,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -51,8 +54,6 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
// TODO: what about new(), struct and class constraints?
public AstNodeCollection<AstType> BaseTypes {
get { return GetChildrenByRole (BaseTypeRole); }
}

19
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/DelegateDeclaration.cs

@ -40,6 +40,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -40,6 +40,11 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public AstType ReturnType {
get { return GetChildByRole (Roles.Type); }
set { SetChildByRole (Roles.Type, value); }
}
public string Name {
get {
return GetChildByRole (Roles.Identifier).Name;
@ -49,11 +54,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -49,11 +54,6 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public AstType ReturnType {
get { return GetChildByRole (Roles.Type); }
set { SetChildByRole (Roles.Type, value); }
}
public AstNodeCollection<TypeParameterDeclaration> TypeParameters {
get { return GetChildrenByRole (Roles.TypeParameter); }
}
@ -78,5 +78,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -78,5 +78,14 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitDelegateDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
DelegateDeclaration o = other as DelegateDeclaration;
return o != null && this.MatchAttributesAndModifiers(o, match)
&& this.ReturnType.DoMatch(o.ReturnType, match) && MatchString(this.Name, o.Name)
&& this.TypeParameters.DoMatch(o.TypeParameters, match) && this.Parameters.DoMatch(o.Parameters, match)
&& this.Constraints.DoMatch(o.Constraints, match);
}
}
}

9
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeDeclaration.cs

@ -87,5 +87,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -87,5 +87,14 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitTypeDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
TypeDeclaration o = other as TypeDeclaration;
return o != null && this.ClassType == o.ClassType && this.MatchAttributesAndModifiers(o, match)
&& MatchString(this.Name, o.Name) && this.TypeParameters.DoMatch(o.TypeParameters, match)
&& this.BaseTypes.DoMatch(o.BaseTypes, match) && this.Constraints.DoMatch(o.Constraints, match)
&& this.Members.DoMatch(o.Members, match);
}
}
}

7
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs

@ -15,12 +15,17 @@ namespace ICSharpCode.NRefactory.CSharp @@ -15,12 +15,17 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary>
public class TypeParameterDeclaration : AstNode
{
public static readonly Role<AttributeSection> AttributeRole = AttributedNode.AttributeRole;
public static readonly Role<CSharpTokenNode> VarianceRole = new Role<CSharpTokenNode>("Variance");
public override NodeType NodeType {
get { return NodeType.Unknown; }
}
public AstNodeCollection<AttributeSection> Attributes {
get { return GetChildrenByRole (AttributeRole); }
}
public VarianceModifier Variance {
get; set;
}
@ -42,7 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -42,7 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
TypeParameterDeclaration o = other as TypeParameterDeclaration;
return o != null && this.Variance == o.Variance && MatchString(this.Name, o.Name);
return o != null && this.Variance == o.Variance && MatchString(this.Name, o.Name) && this.Attributes.DoMatch(o.Attributes, match);
}
}
}

7
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Identifier.cs

@ -43,6 +43,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -43,6 +43,11 @@ namespace ICSharpCode.NRefactory.CSharp
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
public override NodeType NodeType {
@ -95,7 +100,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -95,7 +100,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
Identifier o = other as Identifier;
return o != null && MatchString(this.Name, o.Name);
return o != null && !o.IsNull && MatchString(this.Name, o.Name);
}
}
}

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/MemberType.cs

@ -77,7 +77,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -77,7 +77,7 @@ namespace ICSharpCode.NRefactory.CSharp
b.Append(this.MemberName);
if (this.TypeArguments.Any()) {
b.Append('<');
b.Append(string.Join(", ", this.TypeArguments));
b.Append(DotNet35Compat.StringJoin(", ", this.TypeArguments));
b.Append('>');
}
return b.ToString();

21
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs

@ -29,14 +29,14 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -29,14 +29,14 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
}
}
internal virtual bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<PossibleMatch> backtrackingStack)
public static implicit operator AstType(Pattern p)
{
return DoMatch(pos, match);
return p != null ? new TypePlaceholder(p) : null;
}
public AstType ToType()
public static implicit operator Expression(Pattern p)
{
return new TypePlaceholder(this);
return p != null ? new ExpressionPlaceholder(p) : null;
}
public Expression ToExpression()
@ -44,19 +44,24 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -44,19 +44,24 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
return new ExpressionPlaceholder(this);
}
public static implicit operator Statement(Pattern p)
{
return p != null ? new StatementPlaceholder(p) : null;
}
public Statement ToStatement()
{
return new StatementPlaceholder(this);
}
public BlockStatement ToBlock()
public static implicit operator BlockStatement(Pattern p)
{
return new BlockStatementPlaceholder(this);
return p != null ? new BlockStatementPlaceholder(p) : null;
}
public VariableInitializer ToVariable()
public static implicit operator VariableInitializer(Pattern p)
{
return new VariablePlaceholder(this);
return p != null ? new VariablePlaceholder(p) : null;
}
// Make debugging easier by giving Patterns a ToString() implementation

68
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs

@ -2,16 +2,19 @@ @@ -2,16 +2,19 @@
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp.PatternMatching
{
// Placeholders do not store their child in the AST tree; but keep it as a separate child.
// This allows reusing the child in multiple placeholders; thus enabling the sharing of AST subtrees.
sealed class TypePlaceholder : AstType
{
public static readonly Role<AstNode> ChildRole = new Role<AstNode>("Child", AstNode.Null);
readonly AstNode child;
public TypePlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
this.child = child;
}
public override NodeType NodeType {
@ -20,20 +23,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -20,20 +23,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
return child.DoMatch(other, match);
}
internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{
return child.DoMatchCollection(role, pos, match, backtrackingStack);
}
}
sealed class ExpressionPlaceholder : Expression
{
readonly AstNode child;
public ExpressionPlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
this.child = child;
}
public override NodeType NodeType {
@ -42,20 +52,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -42,20 +52,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
return child.DoMatch(other, match);
}
internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{
return child.DoMatchCollection(role, pos, match, backtrackingStack);
}
}
sealed class StatementPlaceholder : Statement
{
readonly AstNode child;
public StatementPlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
this.child = child;
}
public override NodeType NodeType {
@ -64,20 +81,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -64,20 +81,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
return child.DoMatch(other, match);
}
internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{
return child.DoMatchCollection(role, pos, match, backtrackingStack);
}
}
sealed class BlockStatementPlaceholder : BlockStatement
{
readonly AstNode child;
public BlockStatementPlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
this.child = child;
}
public override NodeType NodeType {
@ -86,20 +110,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -86,20 +110,27 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
return child.DoMatch(other, match);
}
internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{
return child.DoMatchCollection(role, pos, match, backtrackingStack);
}
}
sealed class VariablePlaceholder : VariableInitializer
{
readonly AstNode child;
public VariablePlaceholder(AstNode child)
{
AddChild(child, TypePlaceholder.ChildRole);
this.child = child;
}
public override NodeType NodeType {
@ -108,12 +139,17 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching @@ -108,12 +139,17 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, GetChildByRole(TypePlaceholder.ChildRole), data);
return ((IPatternAstVisitor<T, S>)visitor).VisitPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
return GetChildByRole(TypePlaceholder.ChildRole).DoMatch(other, match);
return child.DoMatch(other, match);
}
internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack<Pattern.PossibleMatch> backtrackingStack)
{
return child.DoMatchCollection(role, pos, match, backtrackingStack);
}
}
}

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/SimpleType.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -76,7 +76,7 @@ namespace ICSharpCode.NRefactory.CSharp
StringBuilder b = new StringBuilder(this.Identifier);
if (this.TypeArguments.Any()) {
b.Append('<');
b.Append(string.Join(", ", this.TypeArguments));
b.Append(DotNet35Compat.StringJoin(", ", this.TypeArguments));
b.Append('>');
}
return b.ToString();

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/BlockStatement.cs

@ -77,7 +77,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -77,7 +77,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
BlockStatement o = other as BlockStatement;
return o != null && this.Statements.DoMatch(o.Statements, match);
return o != null && !o.IsNull && this.Statements.DoMatch(o.Statements, match);
}
#region Builder methods

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/Statements/FixedStatement.cs

@ -67,7 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -67,7 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
FixedStatement o = other as FixedStatement;
return o != null && this.Variables.DoMatch(o.Variables, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
return o != null && this.Type.DoMatch(o.Type, match) && this.Variables.DoMatch(o.Variables, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);
}
}
}

3
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs

@ -64,7 +64,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -64,7 +64,8 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
throw new NotImplementedException();
Accessor o = other as Accessor;
return o != null && !o.IsNull && this.MatchAttributesAndModifiers(o, match) && this.Body.DoMatch(o.Body, match);
}
}
}

4
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs

@ -58,9 +58,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -58,9 +58,9 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.CSharp.PatternMatching.Match match)
protected bool MatchAttributesAndModifiers(AttributedNode o, PatternMatching.Match match)
{
throw new NotImplementedException();
return this.Modifiers == o.Modifiers && this.Attributes.DoMatch(o.Attributes, match);
}
}
}

14
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ConstructorDeclaration.cs

@ -70,6 +70,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -70,6 +70,13 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitConstructorDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ConstructorDeclaration o = other as ConstructorDeclaration;
return o != null && this.MatchAttributesAndModifiers(o, match) && this.Parameters.DoMatch(o.Parameters, match)
&& this.Initializer.DoMatch(o.Initializer, match) && this.Body.DoMatch(o.Body, match);
}
}
public enum ConstructorInitializerType {
@ -98,6 +105,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -98,6 +105,11 @@ namespace ICSharpCode.NRefactory.CSharp
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
public override NodeType NodeType {
@ -123,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -123,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ConstructorInitializer o = other as ConstructorInitializer;
return o != null && this.ConstructorInitializerType == o.ConstructorInitializerType && this.Arguments.DoMatch(o.Arguments, match);
return o != null && !o.IsNull && this.ConstructorInitializerType == o.ConstructorInitializerType && this.Arguments.DoMatch(o.Arguments, match);
}
}
}

6
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/DestructorDeclaration.cs

@ -61,5 +61,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -61,5 +61,11 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitDestructorDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
DestructorDeclaration o = other as DestructorDeclaration;
return o != null && this.MatchAttributesAndModifiers(o, match) && this.Body.DoMatch(o.Body, match);
}
}
}

9
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/EnumMemberDeclaration.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// EnumMemberDeclaration.cs
//
// Author:
@ -53,6 +53,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -53,6 +53,13 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitEnumMemberDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
EnumMemberDeclaration o = other as EnumMemberDeclaration;
return o != null && this.MatchAttributesAndModifiers(o, match)
&& MatchString(this.Name, o.Name) && this.Initializer.DoMatch(o.Initializer, match);
}
}
}

25
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/EventDeclaration.cs

@ -28,8 +28,17 @@ using System.Collections.Generic; @@ -28,8 +28,17 @@ using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp
{
public class EventDeclaration : MemberDeclaration
public class EventDeclaration : AttributedNode
{
public override NodeType NodeType {
get { return NodeType.Member; }
}
public AstType ReturnType {
get { return GetChildByRole (Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
public AstNodeCollection<VariableInitializer> Variables {
get { return GetChildrenByRole (Roles.Variable); }
}
@ -38,6 +47,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -38,6 +47,13 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitEventDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
EventDeclaration o = other as EventDeclaration;
return o != null && this.MatchAttributesAndModifiers(o, match)
&& this.ReturnType.DoMatch(o.ReturnType, match) && this.Variables.DoMatch(o.Variables, match);
}
}
public class CustomEventDeclaration : MemberDeclaration
@ -67,5 +83,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -67,5 +83,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitCustomEventDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CustomEventDeclaration o = other as CustomEventDeclaration;
return o != null && this.MatchMember(o, match)
&& this.AddAccessor.DoMatch(o.AddAccessor, match) && this.RemoveAccessor.DoMatch(o.RemoveAccessor, match);
}
}
}

18
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/FieldDeclaration.cs

@ -29,8 +29,17 @@ using System.Linq; @@ -29,8 +29,17 @@ using System.Linq;
namespace ICSharpCode.NRefactory.CSharp
{
public class FieldDeclaration : MemberDeclaration
public class FieldDeclaration : AttributedNode
{
public override NodeType NodeType {
get { return NodeType.Member; }
}
public AstType ReturnType {
get { return GetChildByRole (Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
public AstNodeCollection<VariableInitializer> Variables {
get { return GetChildrenByRole (Roles.Variable); }
}
@ -39,5 +48,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -39,5 +48,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitFieldDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
FieldDeclaration o = other as FieldDeclaration;
return o != null && this.MatchAttributesAndModifiers(o, match)
&& this.ReturnType.DoMatch(o.ReturnType, match) && this.Variables.DoMatch(o.Variables, match);
}
}
}

30
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/IndexerDeclaration.cs

@ -29,8 +29,11 @@ using System.Linq; @@ -29,8 +29,11 @@ using System.Linq;
namespace ICSharpCode.NRefactory.CSharp
{
public class IndexerDeclaration : PropertyDeclaration
public class IndexerDeclaration : MemberDeclaration
{
public static readonly Role<Accessor> GetterRole = PropertyDeclaration.GetterRole;
public static readonly Role<Accessor> SetterRole = PropertyDeclaration.SetterRole;
public CSharpTokenNode LBracketToken {
get { return GetChildByRole (Roles.LBracket); }
}
@ -43,9 +46,34 @@ namespace ICSharpCode.NRefactory.CSharp @@ -43,9 +46,34 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.RBracket); }
}
public CSharpTokenNode LBraceToken {
get { return GetChildByRole (Roles.LBrace); }
}
public Accessor Getter {
get { return GetChildByRole(GetterRole); }
set { SetChildByRole(GetterRole, value); }
}
public Accessor Setter {
get { return GetChildByRole(SetterRole); }
set { SetChildByRole(SetterRole, value); }
}
public CSharpTokenNode RBraceToken {
get { return GetChildByRole (Roles.RBrace); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitIndexerDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
IndexerDeclaration o = other as IndexerDeclaration;
return o != null && this.MatchMember(o, match) && this.Parameters.DoMatch(o.Parameters, match)
&& this.Getter.DoMatch(o.Getter, match) && this.Setter.DoMatch(o.Setter, match);
}
}
}

6
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/MemberDeclaration.cs

@ -55,5 +55,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -55,5 +55,11 @@ namespace ICSharpCode.NRefactory.CSharp
public override NodeType NodeType {
get { return NodeType.Member; }
}
protected bool MatchMember(MemberDeclaration o, PatternMatching.Match match)
{
return MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)
&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match) && MatchString(this.Name, o.Name);
}
}
}

8
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/MethodDeclaration.cs

@ -67,5 +67,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -67,5 +67,13 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitMethodDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
MethodDeclaration o = other as MethodDeclaration;
return o != null && this.MatchMember(o, match) && this.TypeParameters.DoMatch(o.TypeParameters, match)
&& this.Parameters.DoMatch(o.Parameters, match) && this.Constraints.DoMatch(o.Constraints, match)
&& this.Body.DoMatch(o.Body, match);
}
}
}

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

@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp
Explicit
}
public class OperatorDeclaration : MemberDeclaration
public class OperatorDeclaration : AttributedNode
{
public static readonly Role<CSharpTokenNode> OperatorTypeRole = new Role<CSharpTokenNode>("OperatorType", CSharpTokenNode.Null);
public static readonly Role<CSharpTokenNode> OperatorKeywordRole = Roles.Keyword;
@ -76,6 +76,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -76,6 +76,11 @@ namespace ICSharpCode.NRefactory.CSharp
set;
}
public AstType ReturnType {
get { return GetChildByRole (Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
public CSharpTokenNode LParToken {
get { return GetChildByRole (Roles.LPar); }
}
@ -103,9 +108,25 @@ namespace ICSharpCode.NRefactory.CSharp @@ -103,9 +108,25 @@ namespace ICSharpCode.NRefactory.CSharp
return Mono.CSharp.Operator.GetName((Mono.CSharp.Operator.OpType)type);
}
public override NodeType NodeType {
get { return NodeType.Member; }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitOperatorDeclaration (this, data);
}
public string Name {
get { return GetName(this.OperatorType); }
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
OperatorDeclaration o = other as OperatorDeclaration;
return o != null && this.MatchAttributesAndModifiers(o, match) && this.OperatorType == o.OperatorType
&& this.ReturnType.DoMatch(o.ReturnType, match)
&& this.Parameters.DoMatch(o.Parameters, match) && this.Body.DoMatch(o.Body, match);
}
}
}

14
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/ParameterDeclaration.cs

@ -85,7 +85,19 @@ namespace ICSharpCode.NRefactory.CSharp @@ -85,7 +85,19 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ParameterDeclaration o = other as ParameterDeclaration;
return o != null && this.Attributes.DoMatch(o.Attributes, match) && this.ParameterModifier == o.ParameterModifier && MatchString(this.Name, o.Name) && this.DefaultExpression.DoMatch(o.DefaultExpression, match);
return o != null && this.Attributes.DoMatch(o.Attributes, match) && this.ParameterModifier == o.ParameterModifier
&& this.Type.DoMatch(o.Type, match) && MatchString(this.Name, o.Name)
&& this.DefaultExpression.DoMatch(o.DefaultExpression, match);
}
public ParameterDeclaration()
{
}
public ParameterDeclaration(AstType type, string name)
{
this.Type = type;
this.Name = name;
}
}
}

9
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/PropertyDeclaration.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// PropertyDeclaration.cs
//
// Author:
@ -53,5 +53,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -53,5 +53,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitPropertyDeclaration (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
PropertyDeclaration o = other as PropertyDeclaration;
return o != null && this.MatchMember(o, match)
&& this.Getter.DoMatch(o.Getter, match) && this.Setter.DoMatch(o.Setter, match);
}
}
}

164
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -22,7 +22,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -22,7 +22,7 @@ namespace ICSharpCode.NRefactory.CSharp
readonly IOutputFormatter formatter;
readonly CSharpFormattingPolicy policy;
AstNode currentContainerNode;
readonly Stack<AstNode> containerStack = new Stack<AstNode>();
readonly Stack<AstNode> positionStack = new Stack<AstNode>();
/// <summary>
@ -65,21 +65,23 @@ namespace ICSharpCode.NRefactory.CSharp @@ -65,21 +65,23 @@ namespace ICSharpCode.NRefactory.CSharp
#region StartNode/EndNode
void StartNode(AstNode node)
{
Debug.Assert(currentContainerNode == null || node.Parent == currentContainerNode);
// Ensure that nodes are visited in the proper nested order.
// Jumps to different subtrees are allowed only for the child of a placeholder node.
Debug.Assert(containerStack.Count == 0 || node.Parent == containerStack.Peek() || containerStack.Peek().NodeType == NodeType.Placeholder);
if (positionStack.Count > 0)
WriteSpecialsUpToNode(node);
currentContainerNode = node;
containerStack.Push(node);
positionStack.Push(node.FirstChild);
formatter.StartNode(node);
}
object EndNode(AstNode node)
{
Debug.Assert(node == currentContainerNode);
Debug.Assert(node == containerStack.Peek());
AstNode pos = positionStack.Pop();
Debug.Assert(pos == null || pos.Parent == node);
WriteSpecials(pos, null);
currentContainerNode = node.Parent;
containerStack.Pop();
formatter.EndNode(node);
return null;
}
@ -146,13 +148,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -146,13 +148,14 @@ namespace ICSharpCode.NRefactory.CSharp
/// Writes a comma.
/// </summary>
/// <param name="nextNode">The next node after the comma.</param>
void Comma(AstNode nextNode)
/// <param name="noSpacesAfterComma">When set prevents printing a space after comma.</param>
void Comma(AstNode nextNode, bool noSpaceAfterComma = false)
{
WriteSpecialsUpToRole(AstNode.Roles.Comma, nextNode);
Space(policy.SpacesBeforeComma);
formatter.WriteToken(",");
lastWritten = LastWritten.Other;
Space(policy.SpacesAfterComma);
Space(!noSpaceAfterComma && policy.SpacesAfterComma);
}
void WriteCommaSeparatedList(IEnumerable<AstNode> list)
@ -179,12 +182,34 @@ namespace ICSharpCode.NRefactory.CSharp @@ -179,12 +182,34 @@ namespace ICSharpCode.NRefactory.CSharp
RPar();
}
void WriteCommaSeparatedListInBrackets(IEnumerable<AstNode> list)
#if DOTNET35
void WriteCommaSeparatedList(IEnumerable<VariableInitializer> list)
{
WriteCommaSeparatedList(list.SafeCast<VariableInitializer, AstNode>());
}
void WriteCommaSeparatedList(IEnumerable<AstType> list)
{
WriteCommaSeparatedList(list.SafeCast<AstType, AstNode>());
}
void WriteCommaSeparatedListInParenthesis(IEnumerable<Expression> list, bool spaceWithin)
{
WriteCommaSeparatedListInParenthesis(list.SafeCast<Expression, AstNode>(), spaceWithin);
}
void WriteCommaSeparatedListInParenthesis(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
{
WriteCommaSeparatedListInParenthesis(list.SafeCast<ParameterDeclaration, AstNode>(), spaceWithin);
}
#endif
void WriteCommaSeparatedListInBrackets(IEnumerable<Expression> list)
{
WriteToken("[", AstNode.Roles.LBracket);
if (list.Any()) {
Space(policy.SpacesWithinBrackets);
WriteCommaSeparatedList(list);
WriteCommaSeparatedList(list.SafeCast<Expression, AstNode>());
Space(policy.SpacesWithinBrackets);
}
WriteToken("]", AstNode.Roles.RBracket);
@ -207,7 +232,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -207,7 +232,7 @@ namespace ICSharpCode.NRefactory.CSharp
void WriteIdentifier(string identifier, Role<Identifier> identifierRole = null)
{
WriteSpecialsUpToRole(identifierRole ?? AstNode.Roles.Identifier);
if (IsKeyword(identifier, currentContainerNode)) {
if (IsKeyword(identifier, containerStack.Peek())) {
if (lastWritten == LastWritten.KeywordOrIdentifier)
Space(); // this space is not strictly required, so we call Space()
formatter.WriteToken("@");
@ -265,7 +290,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -265,7 +290,8 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary>
void Semicolon()
{
if (currentContainerNode.Role != ForStatement.InitializerRole && currentContainerNode.Role != ForStatement.IteratorRole && currentContainerNode.Role != UsingStatement.ResourceAcquisitionRole) {
Role role = containerStack.Peek().Role; // get the role of the current node
if (!(role == ForStatement.InitializerRole || role == ForStatement.IteratorRole || role == UsingStatement.ResourceAcquisitionRole)) {
WriteToken(";", AstNode.Roles.Semicolon);
NewLine();
}
@ -351,7 +377,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -351,7 +377,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
if (typeParameters.Any()) {
WriteToken("<", AstNode.Roles.LChevron);
WriteCommaSeparatedList(typeParameters);
WriteCommaSeparatedList(typeParameters.SafeCast<TypeParameterDeclaration, AstNode>());
WriteToken(">", AstNode.Roles.RChevron);
}
}
@ -758,52 +784,75 @@ namespace ICSharpCode.NRefactory.CSharp @@ -758,52 +784,75 @@ namespace ICSharpCode.NRefactory.CSharp
public object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{
StartNode(primitiveExpression);
formatter.WriteToken(ToCSharpString(primitiveExpression));
lastWritten = LastWritten.Other;
WritePrimitiveValue(primitiveExpression.Value);
return EndNode(primitiveExpression);
}
internal static string ToCSharpString(PrimitiveExpression primitiveExpression)
void WritePrimitiveValue(object val)
{
if (primitiveExpression.Value == null) {
return "null";
if (val == null) {
// usually NullReferenceExpression should be used for this, but we'll handle it anyways
WriteKeyword("null");
return;
}
object val = primitiveExpression.Value;
if (val is bool) {
if ((bool)val) {
return "true";
WriteKeyword("true");
} else {
return "false";
WriteKeyword("false");
}
return;
}
if (val is string) {
return "\"" + ConvertString(val.ToString()) + "\"";
}
if (val is char) {
return "'" + ConvertCharLiteral((char)val) + "'";
}
if (val is decimal) {
return ((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m";
}
if (val is float) {
return ((float)val).ToString(NumberFormatInfo.InvariantInfo) + "f";
formatter.WriteToken("\"" + ConvertString(val.ToString()) + "\"");
lastWritten = LastWritten.Other;
} else if (val is char) {
formatter.WriteToken("'" + ConvertCharLiteral((char)val) + "'");
lastWritten = LastWritten.Other;
} else if (val is decimal) {
formatter.WriteToken(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m");
lastWritten = LastWritten.Other;
} else if (val is float) {
float f = (float)val;
if (float.IsInfinity(f) || float.IsNaN(f)) {
// Strictly speaking, these aren't PrimitiveExpressions;
// but we still support writing these to make life easier for code generators.
WriteKeyword("float");
WriteToken(".", AstNode.Roles.Dot);
if (float.IsPositiveInfinity(f))
WriteIdentifier("PositiveInfinity");
else if (float.IsNegativeInfinity(f))
WriteIdentifier("NegativeInfinity");
else
WriteIdentifier("NaN");
return;
}
if (val is double) {
string text = ((double)val).ToString(NumberFormatInfo.InvariantInfo);
if (text.IndexOf('.') < 0 && text.IndexOf('E') < 0)
return text + ".0";
formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "f");
lastWritten = LastWritten.Other;
} else if (val is double) {
double f = (double)val;
if (double.IsInfinity(f) || double.IsNaN(f)) {
// Strictly speaking, these aren't PrimitiveExpressions;
// but we still support writing these to make life easier for code generators.
WriteKeyword("double");
WriteToken(".", AstNode.Roles.Dot);
if (double.IsPositiveInfinity(f))
WriteIdentifier("PositiveInfinity");
else if (double.IsNegativeInfinity(f))
WriteIdentifier("NegativeInfinity");
else
return text;
WriteIdentifier("NaN");
return;
}
if (val is IFormattable) {
string number = f.ToString("R", NumberFormatInfo.InvariantInfo);
if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0)
number += ".0";
formatter.WriteToken(number);
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
lastWritten = LastWritten.KeywordOrIdentifier;
} else if (val is IFormattable) {
StringBuilder b = new StringBuilder();
// if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
// b.Append("0x");
@ -817,13 +866,15 @@ namespace ICSharpCode.NRefactory.CSharp @@ -817,13 +866,15 @@ namespace ICSharpCode.NRefactory.CSharp
if (val is long || val is ulong) {
b.Append("L");
}
return b.ToString();
formatter.WriteToken(b.ToString());
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
lastWritten = LastWritten.KeywordOrIdentifier;
} else {
return val.ToString();
formatter.WriteToken(val.ToString());
lastWritten = LastWritten.Other;
}
}
static string ConvertCharLiteral(char ch)
{
if (ch == '\'') return "\\'";
@ -1043,7 +1094,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1043,7 +1094,7 @@ namespace ICSharpCode.NRefactory.CSharp
StartNode(queryOrderClause);
WriteKeyword("orderby");
Space();
WriteCommaSeparatedList(queryOrderClause.Orderings);
WriteCommaSeparatedList(queryOrderClause.Orderings.SafeCast<QueryOrdering, AstNode>());
return EndNode(queryOrderClause);
}
@ -1093,6 +1144,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1093,6 +1144,7 @@ namespace ICSharpCode.NRefactory.CSharp
StartNode(attribute);
attribute.Type.AcceptVisitor(this, data);
Space(policy.BeforeMethodCallParentheses);
if (attribute.Arguments.Count != 0 || !attribute.GetChildByRole(AstNode.Roles.LPar).IsNull)
WriteCommaSeparatedListInParenthesis(attribute.Arguments, policy.WithinMethodCallParentheses);
return EndNode(attribute);
}
@ -1106,8 +1158,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1106,8 +1158,11 @@ namespace ICSharpCode.NRefactory.CSharp
WriteToken(":", AttributeSection.Roles.Colon);
Space();
}
WriteCommaSeparatedList(attributeSection.Attributes);
WriteCommaSeparatedList(attributeSection.Attributes.SafeCast<Attribute, AstNode>());
WriteToken("]", AstNode.Roles.RBracket);
if (attributeSection.Parent is ParameterDeclaration || attributeSection.Parent is TypeParameterDeclaration)
Space();
else
NewLine();
return EndNode(attributeSection);
}
@ -1186,7 +1241,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1186,7 +1241,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (first) {
first = false;
} else {
Comma(member);
Comma(member, noSpaceAfterComma: true);
NewLine();
}
member.AcceptVisitor(this, data);
@ -1355,7 +1410,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1355,7 +1410,7 @@ namespace ICSharpCode.NRefactory.CSharp
LPar();
Space(policy.WithinForParentheses);
WriteCommaSeparatedList(forStatement.Initializers);
WriteCommaSeparatedList(forStatement.Initializers.SafeCast<Statement, AstNode>());
WriteToken(";", AstNode.Roles.Semicolon);
Space(policy.SpacesAfterSemicolon);
@ -1363,7 +1418,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1363,7 +1418,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteToken(";", AstNode.Roles.Semicolon);
Space(policy.SpacesAfterSemicolon);
WriteCommaSeparatedList(forStatement.Iterators);
WriteCommaSeparatedList(forStatement.Iterators.SafeCast<Statement, AstNode>());
Space(policy.WithinForParentheses);
RPar();
@ -1899,6 +1954,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1899,6 +1954,9 @@ namespace ICSharpCode.NRefactory.CSharp
{
StartNode(memberType);
memberType.Target.AcceptVisitor(this, data);
if (memberType.IsDoubleColon)
WriteToken("::", MemberType.Roles.Dot);
else
WriteToken(".", MemberType.Roles.Dot);
WriteIdentifier(memberType.MemberName);
WriteTypeArguments(memberType.TypeArguments);
@ -1935,6 +1993,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1935,6 +1993,11 @@ namespace ICSharpCode.NRefactory.CSharp
{
StartNode(primitiveType);
WriteKeyword(primitiveType.Keyword);
if (primitiveType.Keyword == "new") {
// new() constraint
LPar();
RPar();
}
return EndNode(primitiveType);
}
@ -1953,6 +2016,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1953,6 +2016,7 @@ namespace ICSharpCode.NRefactory.CSharp
public object VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, object data)
{
StartNode(typeParameterDeclaration);
WriteAttributes(typeParameterDeclaration.Attributes);
switch (typeParameterDeclaration.Variance) {
case VarianceModifier.Invariant:
break;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save