Skip to content

Commit

Permalink
Fix #503
Browse files Browse the repository at this point in the history
  • Loading branch information
NN--- committed Aug 10, 2013
1 parent fad3e7d commit 8b426b9
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
24 changes: 12 additions & 12 deletions macros/StructuralEquality.n
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Nemerle.Extensions
[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Class, Inherited = false, AllowMultiple = false)]
public macro StructuralEquality(tb : TypeBuilder, params _options : list[PExpr])
{
StructuralEqualityImpl.RunBeforeInheritance(tb);
StructuralEqualityImpl.RunBeforeInheritance(tb, _options);
}

[MacroUsage(MacroPhase.WithTypedMembers, MacroTargets.Class, Inherited = false, AllowMultiple = false)]
Expand Down Expand Up @@ -81,7 +81,7 @@ namespace Nemerle.Extensions
public StructuralEquatableTypeInfoLabel : string = "StructuralEquality.StructuralEquatableTypeInfoLabel";

// implements interfaces
public RunBeforeInheritance(tb : TypeBuilder) : void
public RunBeforeInheritance(tb : TypeBuilder, options_expr : list[PExpr]) : void
{
def type = GetTypeName(tb);

Expand All @@ -98,7 +98,7 @@ namespace Nemerle.Extensions

when (tb.Ast is TopDeclaration.Variant)
foreach (vo in tb.GetVariantOptions())
vo.Ast.AddCustomAttribute(<[ StructuralEquality ]>);
vo.Ast.AddCustomAttribute(<[ StructuralEquality(..$options_expr) ]>);

// Nemerle doesn't build if Tuples from stdlib are changed
unless (tb.IsVariantOption)
Expand All @@ -122,20 +122,13 @@ namespace Nemerle.Extensions
//assert2(false);
def options = SEOptions.Parse(options_expr);

def get_relevant_fields(tb)
def get_relevant_fields(tb, ignore_fields)
{
def all_fields = tb.GetFields(BindingFlags.Public %|
BindingFlags.NonPublic %|
BindingFlags.Instance %|
BindingFlags.DeclaredOnly);

// retrieve all ignored fields
def ignore_fields =
if (tb.UserData.Contains(IgnoredFieldsLabel))
tb.UserData[IgnoredFieldsLabel] :> List[string]
else
List();

// ignored properties
when (tb.UserData.Contains(IgnoredPropertiesLabel))
{
Expand Down Expand Up @@ -164,8 +157,15 @@ namespace Nemerle.Extensions
all_fields.Filter(x => ignore_fields.BinarySearch(x.Name) < 0);
}

// retrieve all ignored fields
def ignore_fields =
if (tb.UserData.Contains(IgnoredFieldsLabel))
tb.UserData[IgnoredFieldsLabel] :> List.[string]
else
List();

// fields that are not ignored when evaluating structural equality
def relevant_fields = get_relevant_fields(tb);
def relevant_fields = get_relevant_fields(tb, ignore_fields);

// true if strict type equality is needed, i. e. no subtypes are allowed;
def typecheck_needed = !tb.IsSealed && !tb.IsVariantOption && !tb.IsValueType && options.CheckTypes;
Expand Down
33 changes: 33 additions & 0 deletions ncc/testsuite/positive/Issue-git-0503.n
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Console;
using System.Threading;
using System.Globalization;

using Nemerle.Extensions;

[StructuralEquality(Ignore = name)]
variant X
{
| A { name : string; other : int; }
| B
}

Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

def a1 = X.A("abc", 1);
def a2 = X.A("abcd", 1);
WriteLine(a1.Equals(a2));
WriteLine(a1.GetHashCode() == a2.GetHashCode());

def b1 = X.A("abc", 1);
def b2 = X.A("abc", 2);
WriteLine(!b1.Equals(b2));
WriteLine(b1.GetHashCode() != b2.GetHashCode());

/*
BEGIN-OUTPUT
True
True
True
True
END-OUTPUT
*/

0 comments on commit 8b426b9

Please sign in to comment.