@@ -217,6 +217,7 @@ let (|Nameof|_|) com ctx = function
217
217
| IdentExpr ident -> Some ident.DisplayName
218
218
| Get(_, ByKey( ExprKey( StringConst prop)), _, _) -> Some prop
219
219
| Get(_, ByKey( FieldKey fi), _, _) -> Some fi.Name
220
+ | Get(_, FieldIndex( fieldName, _), _, _) -> Some fieldName
220
221
| NestedLambda( args, Call( IdentExpr ident, info, _, _), None) ->
221
222
if List.sameLength args info.Args && List.zip args info.Args |> List.forall ( fun ( a1 , a2 ) ->
222
223
match a2 with IdentExpr id2 -> a1.Name = id2.Name | _ -> false )
@@ -695,6 +696,50 @@ let isCompatibleWithJsComparison = function
695
696
// * `.GetHashCode` called directly defaults to identity hash (for reference types except string) if not implemented.
696
697
// * `LanguagePrimitive.PhysicalHash` creates an identity hash no matter whether GetHashCode is implemented or not.
697
698
699
+ let getEntityHashMethod ( com : ICompiler ) ( ent : Entity ) =
700
+ if ( ent.IsFSharpUnion || ent.IsFSharpRecord) then
701
+ if com.Options.EraseUnions
702
+ then " Util" , " structuralHash"
703
+ else " Util" , " hashSafe"
704
+ elif ent.IsValueType
705
+ then " Util" , " hashSafe"
706
+ else " Util" , " identityHash"
707
+
708
+ let getEntityEqualsMethod ( com : ICompiler ) ( ent : Entity ) =
709
+ if ( ent.IsFSharpUnion || ent.IsFSharpRecord) then
710
+ if com.Options.EraseUnions
711
+ then " Util" , " equals"
712
+ else " Util" , " equalsSafe"
713
+ elif ent.IsValueType
714
+ then " Util" , " equalsSafe"
715
+ else " Util" , " equals"
716
+
717
+ let getEntityCompareMethod ( com : ICompiler ) ( ent : Entity ) =
718
+ if ( ent.IsFSharpUnion || ent.IsFSharpRecord) then
719
+ if com.Options.EraseUnions
720
+ then " Util" , " compare"
721
+ else " Util" , " compareSafe"
722
+ elif ent.IsValueType
723
+ then " Util" , " compareSafe"
724
+ else " Util" , " compare"
725
+
726
+ let identityHashMethod ( com : ICompiler ) = function
727
+ | Boolean | Char | String | Number _ | Enum _ | Option _ | Tuple _ | List _
728
+ | Builtin ( BclInt64 | BclUInt64 | BclDecimal | BclBigInt)
729
+ | Builtin ( BclGuid | BclTimeSpan | BclDateTime | BclDateTimeOffset)
730
+ | Builtin ( FSharpSet _ | FSharpMap _ | FSharpChoice _ | FSharpResult _) ->
731
+ " Util" , " structuralHash"
732
+ | DeclaredType( ent, _) -> com.GetEntity( ent) |> getEntityHashMethod com
733
+ | _ -> " Util" , " identityHash"
734
+
735
+ let structuralHashMethod ( com : ICompiler ) = function
736
+ | MetaType -> " Reflection" , " getHashCode"
737
+ | DeclaredType( ent, _) ->
738
+ let ent = com.GetEntity( ent)
739
+ if not ent.IsInterface then getEntityHashMethod com ent
740
+ else " Util" , " structuralHash"
741
+ | _ -> " Util" , " structuralHash"
742
+
698
743
let identityHash com r ( arg : Expr ) =
699
744
let methodName =
700
745
match arg.Type with
@@ -747,10 +792,8 @@ let rec equals (com: ICompiler) ctx r equal (left: Expr) (right: Expr) =
747
792
Helper.LibCall( com, coreModFor bt, " equals" , Boolean, [ left; right], ?loc= r) |> is equal
748
793
| DeclaredType( ent, _) ->
749
794
let ent = com.GetEntity( ent)
750
- if ent.IsFSharpUnion || ent.IsFSharpRecord || ent.IsValueType then
751
- Helper.LibCall( com, " Util" , " equalsSafe" , Boolean, [ left; right], ?loc= r) |> is equal
752
- else
753
- Helper.LibCall( com, " Util" , " equals" , Boolean, [ left; right], ?loc= r) |> is equal
795
+ let moduleName , methodName = getEntityEqualsMethod com ent
796
+ Helper.LibCall( com, moduleName, methodName, Boolean, [ left; right], ?loc= r) |> is equal
754
797
| Array t ->
755
798
let f = makeComparerFunction com ctx t
756
799
Helper.LibCall( com, " Array" , " equalsWith" , Boolean, [ f; left; right], ?loc= r) |> is equal
@@ -775,10 +818,8 @@ and compare (com: ICompiler) ctx r (left: Expr) (right: Expr) =
775
818
Helper.LibCall( com, coreModFor bt, " compare" , Number Int32, [ left; right], ?loc= r)
776
819
| DeclaredType( ent, _) ->
777
820
let ent = com.GetEntity( ent)
778
- if ent.IsFSharpUnion || ent.IsFSharpRecord || ent.IsValueType then
779
- Helper.LibCall( com, " Util" , " compareSafe" , Number Int32, [ left; right], ?loc= r)
780
- else
781
- Helper.LibCall( com, " Util" , " compare" , Number Int32, [ left; right], ?loc= r)
821
+ let moduleName , methodName = getEntityCompareMethod com ent
822
+ Helper.LibCall( com, moduleName, methodName, Number Int32, [ left; right], ?loc= r)
782
823
| Array t ->
783
824
let f = makeComparerFunction com ctx t
784
825
Helper.LibCall( com, " Array" , " compareWith" , Number Int32, [ f; left; right], ?loc= r)
0 commit comments