Browse Source

Fixed SD2-867: Equals/GetHashCode code generation for VB.NET

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.1@2336 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
4513c2fac1
  1. 77
      src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs
  2. 6
      src/Setup/Files.wxs

77
src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs

@ -26,14 +26,30 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
{ {
TypeReference intReference = new TypeReference("System.Int32"); TypeReference intReference = new TypeReference("System.Int32");
MethodDeclaration method = new MethodDeclaration("GetHashCode", Modifiers.Public | Modifiers.Override, intReference, null, null); MethodDeclaration method = new MethodDeclaration("GetHashCode", Modifiers.Public | Modifiers.Override, intReference, null, null);
Expression expr = CallGetHashCode(new IdentifierExpression(currentClass.Fields[0].Name));
for (int i = 1; i < currentClass.Fields.Count; i++) {
IdentifierExpression identifier = new IdentifierExpression(currentClass.Fields[i].Name);
expr = new BinaryOperatorExpression(expr, BinaryOperatorType.ExclusiveOr,
CallGetHashCode(identifier));
}
method.Body = new BlockStatement(); method.Body = new BlockStatement();
method.Body.AddChild(new ReturnStatement(expr));
VariableDeclaration var;
var = new VariableDeclaration("hashCode", new PrimitiveExpression(0, "0"), intReference);
method.Body.AddChild(new LocalVariableDeclaration(var));
Expression expr;
foreach (IField field in currentClass.Fields) {
expr = new AssignmentExpression(new IdentifierExpression(var.Name),
AssignmentOperatorType.ExclusiveOr,
new InvocationExpression(new FieldReferenceExpression(new IdentifierExpression(field.Name), "GetHashCode")));
if (IsValueType(field.ReturnType)) {
method.Body.AddChild(new ExpressionStatement(expr));
} else {
method.Body.AddChild(new IfElseStatement(
new BinaryOperatorExpression(new IdentifierExpression(field.Name),
BinaryOperatorType.ReferenceInequality,
new PrimitiveExpression(null, "null")),
new ExpressionStatement(expr)
));
}
}
method.Body.AddChild(new ReturnStatement(new IdentifierExpression(var.Name)));
nodes.Add(method); nodes.Add(method);
TypeReference boolReference = new TypeReference("System.Boolean"); TypeReference boolReference = new TypeReference("System.Boolean");
@ -49,14 +65,14 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
expr = new UnaryOperatorExpression(expr, UnaryOperatorType.Not); expr = new UnaryOperatorExpression(expr, UnaryOperatorType.Not);
method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(false, "false")))); method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(false, "false"))));
expr = new BinaryOperatorExpression(new ThisReferenceExpression(), // expr = new BinaryOperatorExpression(new ThisReferenceExpression(),
BinaryOperatorType.Equality, // BinaryOperatorType.ReferenceEquality,
new IdentifierExpression("obj")); // new IdentifierExpression("obj"));
method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(true, "true")))); // method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(true, "true"))));
VariableDeclaration var = new VariableDeclaration("my" + currentClass.Name, var = new VariableDeclaration("my" + currentClass.Name,
new CastExpression(currentType, new IdentifierExpression("obj"), CastType.Cast), new CastExpression(currentType, new IdentifierExpression("obj"), CastType.Cast),
currentType); currentType);
method.Body.AddChild(new LocalVariableDeclaration(var)); method.Body.AddChild(new LocalVariableDeclaration(var));
expr = TestEquality(var.Name, currentClass.Fields[0]); expr = TestEquality(var.Name, currentClass.Fields[0]);
@ -70,16 +86,39 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
nodes.Add(method); nodes.Add(method);
} }
static InvocationExpression CallGetHashCode(Expression expr) static bool IsValueType(IReturnType type)
{
IClass c = type.GetUnderlyingClass();
return c != null && (c.ClassType == Dom.ClassType.Struct || c.ClassType == Dom.ClassType.Enum);
}
static bool CanCompareEqualityWithOperator(IReturnType type)
{ {
return new InvocationExpression(new FieldReferenceExpression(expr, "GetHashCode")); // return true for value types except float and double
// return false for reference types except string.
IClass c = type.GetUnderlyingClass();
return c != null
&& c.FullyQualifiedName != "System.Single"
&& c.FullyQualifiedName != "System.Double"
&& (c.ClassType == Dom.ClassType.Struct
|| c.ClassType == Dom.ClassType.Enum
|| c.FullyQualifiedName == "System.String");
} }
static Expression TestEquality(string other, IField field) static Expression TestEquality(string other, IField field)
{ {
return new BinaryOperatorExpression(new FieldReferenceExpression(new ThisReferenceExpression(), field.Name), if (CanCompareEqualityWithOperator(field.ReturnType)) {
BinaryOperatorType.Equality, return new BinaryOperatorExpression(new FieldReferenceExpression(new ThisReferenceExpression(), field.Name),
new FieldReferenceExpression(new IdentifierExpression(other), field.Name)); BinaryOperatorType.Equality,
new FieldReferenceExpression(new IdentifierExpression(other), field.Name));
} else {
InvocationExpression ie = new InvocationExpression(
new FieldReferenceExpression(new TypeReferenceExpression("System.Object"), "Equals")
);
ie.Arguments.Add(new FieldReferenceExpression(new ThisReferenceExpression(), field.Name));
ie.Arguments.Add(new FieldReferenceExpression(new IdentifierExpression(other), field.Name));
return ie;
}
} }
public override bool IsActive { public override bool IsActive {

6
src/Setup/Files.wxs

@ -73,7 +73,7 @@
<Registry Id="SD.booprojfile.command" Type="string" Key="shell\open\command" Value="&quot;[#SharpDevelop.exe]&quot; &quot;%1&quot;" /> <Registry Id="SD.booprojfile.command" Type="string" Key="shell\open\command" Value="&quot;[#SharpDevelop.exe]&quot; &quot;%1&quot;" />
<Registry Id="SD.booprojfile.icon" Type="string" Key="DefaultIcon" Value="&quot;[#prjx.ico]&quot;" /> <Registry Id="SD.booprojfile.icon" Type="string" Key="DefaultIcon" Value="&quot;[#prjx.ico]&quot;" />
</Registry> </Registry>
<Registry Id="SD.booprojfile.association" Root="HKCR" Type="string" Key=".booproj" Value="SD.booproj" /> <Registry Id="SD.booprojfile.association" Root="HKCR" Type="string" Key=".booproj" Value="SD.booprojfile" />
</Component> </Component>
<Component Id="SharpDevelopCombineFileAssociation" Guid="9D7E0D45-CD48-4A52-8875-939A78B8F710" DiskId="1"> <Component Id="SharpDevelopCombineFileAssociation" Guid="9D7E0D45-CD48-4A52-8875-939A78B8F710" DiskId="1">
<Registry Id="SD.cmbxfile" Root="HKCR" Type="string" Key="SD.cmbxfile" Value="SharpDevelop 1.x Combine" KeyPath="yes"> <Registry Id="SD.cmbxfile" Root="HKCR" Type="string" Key="SD.cmbxfile" Value="SharpDevelop 1.x Combine" KeyPath="yes">
@ -94,7 +94,7 @@
<Registry Id="SD.csproj.command" Type="string" Key="shell\open\command" Value="&quot;[#SharpDevelop.exe]&quot; &quot;%1&quot;" /> <Registry Id="SD.csproj.command" Type="string" Key="shell\open\command" Value="&quot;[#SharpDevelop.exe]&quot; &quot;%1&quot;" />
<Registry Id="SD.csproj.icon" Type="string" Key="DefaultIcon" Value="&quot;[#prjx.ico]&quot;" /> <Registry Id="SD.csproj.icon" Type="string" Key="DefaultIcon" Value="&quot;[#prjx.ico]&quot;" />
</Registry> </Registry>
<Registry Id="SD.csproj.association" Root="HKCR" Type="string" Key=".csproj" Value="SD.csproj" /> <Registry Id="SD.csproj.association" Root="HKCR" Type="string" Key=".csproj" Value="SD.csprojfile" />
</Component> </Component>
<Component Id="SharpDevelop11ProjectFileAssociation" Guid="DD3AAFF7-A307-4918-A33E-35620A2118F6" DiskId="1"> <Component Id="SharpDevelop11ProjectFileAssociation" Guid="DD3AAFF7-A307-4918-A33E-35620A2118F6" DiskId="1">
<Registry Id="SD.prjxfile" Root="HKCR" Type="string" Key="SD.prjxfile" Value="SharpDevelop 1.x Project" KeyPath="yes"> <Registry Id="SD.prjxfile" Root="HKCR" Type="string" Key="SD.prjxfile" Value="SharpDevelop 1.x Project" KeyPath="yes">
@ -1253,4 +1253,4 @@
</Directory> </Directory>
</DirectoryRef> </DirectoryRef>
</Fragment> </Fragment>
</Wix> </Wix>

Loading…
Cancel
Save