Skip to content

Commit

Permalink
#965 equality/inequality for C# tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
Jand42 committed Jun 26, 2018
1 parent d744b6c commit 00f050d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
36 changes: 25 additions & 11 deletions src/compiler/WebSharper.Compiler.CSharp/CodeReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,17 +1268,31 @@ type RoslynTransformer(env: Environment) =
let leftType = env.SemanticModel.GetTypeInfo(x.Left.Node).ConvertedType |> sr.ReadType
Coalesce(left, leftType, right)
| _ ->
let symbol = env.SemanticModel.GetSymbolInfo(x.Node).Symbol :?> IMethodSymbol
let typ, meth = getTypeAndMethod symbol
if List.isEmpty meth.Generics then
// add fake generics type information to resolve nullable operations
let leftType = env.SemanticModel.GetTypeInfo(x.Left.Node).Type |> sr.ReadType
let rightType = env.SemanticModel.GetTypeInfo(x.Right.Node).Type |> sr.ReadType
let meth =
{ meth with Generics = [leftType; rightType] }
Call(None, typ, meth, [left; right])
else
Call(None, typ, meth, [left; right])
let leftTypeSymbol = env.SemanticModel.GetTypeInfo(x.Left.Node).Type
let rightTypeSymbol = env.SemanticModel.GetTypeInfo(x.Right.Node).Type
let tupleOp =
if leftTypeSymbol.IsTupleType && rightTypeSymbol.IsTupleType then
match x.Kind with
| BinaryExpressionKind.EqualsExpression ->
Some (Macros.UncheckedEquals left right)
| BinaryExpressionKind.NotEqualsExpression ->
Some (Unary(UnaryOperator.``!``, Macros.UncheckedEquals left right))
| _ -> None
else None
match tupleOp with
| Some res -> res
| _ ->
let symbol = env.SemanticModel.GetSymbolInfo(x.Node).Symbol :?> IMethodSymbol
let typ, meth = getTypeAndMethod symbol
if List.isEmpty meth.Generics then
// add fake generics type information to resolve nullable operations
let leftType = leftTypeSymbol |> sr.ReadType
let rightType = rightTypeSymbol |> sr.ReadType
let meth =
{ meth with Generics = [leftType; rightType] }
Call(None, typ, meth, [left; right])
else
Call(None, typ, meth, [left; right])
|> withExprSourcePos x.Node

member this.TransformConditionalExpression (x: ConditionalExpressionData) : Expression =
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/WebSharper.Core/Macros.fs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ let opUncheckedTy, equalsMeth, compareMeth, hashMeth =
Reflection.ReadMethod hmi
| _ -> failwith "Expecting a Call pattern"

let UncheckedEquals x y =
Call (None, NonGeneric opUncheckedTy, NonGeneric equalsMeth, [x; y])

let makeComparison cmp x y =
let eq x y = Call (None, NonGeneric opUncheckedTy, NonGeneric equalsMeth, [x; y])
let c b i = Binary (Call(None, NonGeneric opUncheckedTy, NonGeneric compareMeth, [x; y]), b, Value(Int i))
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/WebSharper.Core/Macros.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,6 @@ type Tuple =
[<Sealed>]
type TupleExtensions =
new : unit -> TupleExtensions
inherit Macro
inherit Macro

val UncheckedEquals : AST.Expression -> AST.Expression -> AST.Expression

0 comments on commit 00f050d

Please sign in to comment.