diff --git a/src/fsharp/vs/Exprs.fs b/src/fsharp/vs/Exprs.fs index 34e771bc1c..212f564694 100644 --- a/src/fsharp/vs/Exprs.fs +++ b/src/fsharp/vs/Exprs.fs @@ -108,7 +108,8 @@ type E = | ILAsm of string * FSharpType list * FSharpExpr list /// Used to represent the information at an object expression member -and [] FSharpObjectExprOverride(gps: FSharpGenericParameter list, args:FSharpMemberFunctionOrValue list list, body: FSharpExpr) = +and [] FSharpObjectExprOverride(sgn: FSharpAbstractSignature, gps: FSharpGenericParameter list, args:FSharpMemberFunctionOrValue list list, body: FSharpExpr) = + member __.Signature = sgn member __.GenericParameters = gps member __.CurriedParameterGroups = args member __.Body = body @@ -444,13 +445,14 @@ module FSharpExprConvert = | Expr.Obj (_lambdaId,typ,_basev,basecall,overrides, iimpls,_m) -> let basecallR = ConvExpr cenv env basecall let ConvertMethods methods = - [ for (TObjExprMethod(_slotsig,_,tps,tmvs,body,_)) in methods -> + [ for (TObjExprMethod(slotsig,_,tps,tmvs,body,_)) in methods -> let vslR = List.map (List.map (ConvVal cenv)) tmvs + let sgn = FSharpAbstractSignature(cenv, slotsig) let tpsR = [ for tp in tps -> FSharpGenericParameter(cenv,tp) ] let env = ExprTranslationEnv.Empty.BindTypars (Seq.zip tps tpsR |> Seq.toList) let env = env.BindCurriedVals tmvs let bodyR = ConvExpr cenv env body - FSharpObjectExprOverride(tpsR, vslR, bodyR) ] + FSharpObjectExprOverride(sgn, tpsR, vslR, bodyR) ] let overridesR = ConvertMethods overrides let iimplsR = List.map (fun (ty,impls) -> ConvType cenv ty, ConvertMethods impls) iimpls diff --git a/src/fsharp/vs/Exprs.fsi b/src/fsharp/vs/Exprs.fsi index 3524d6839b..a069d0d56e 100644 --- a/src/fsharp/vs/Exprs.fsi +++ b/src/fsharp/vs/Exprs.fsi @@ -56,6 +56,8 @@ and [] FSharpExpr = /// Represents a checked method in an object expression, as seen by the F# language. and [] FSharpObjectExprOverride = + /// The signature of the implemented abstract slot + member Signature : FSharpAbstractSignature /// The generic parameters of the method member GenericParameters : FSharpGenericParameter list /// The parameters of the method diff --git a/src/fsharp/vs/Symbols.fsi b/src/fsharp/vs/Symbols.fsi index ee38c7005b..0786dc55b7 100644 --- a/src/fsharp/vs/Symbols.fsi +++ b/src/fsharp/vs/Symbols.fsi @@ -312,6 +312,7 @@ and [] FSharpAbstractParameter = /// Represents the signature of an abstract slot of a class or interface and [] FSharpAbstractSignature = + internal new : Impl.cenv * SlotSig -> FSharpAbstractSignature /// Get the arguments of the abstract slot member AbstractArguments : IList> diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 0f99df6253..bd22ec68c1 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -64,7 +64,7 @@ module Utils = | BasicPatterns.UnionCaseGet(obj,ty,uc,f1) -> printExpr 10 obj + "." + f1.Name | BasicPatterns.UnionCaseTest(obj,ty,f1) -> printExpr 10 obj + ".Is" + f1.Name | BasicPatterns.UnionCaseTag(obj,ty) -> printExpr 10 obj + ".Tag" - | BasicPatterns.ObjectExpr(ty,basecall,overrides,iimpls) -> "{ new " + printTy ty + " with ... }" + | BasicPatterns.ObjectExpr(ty,basecall,overrides,iimpls) -> "{ " + printExpr 10 basecall + " with " + printOverrides overrides + " " + printIimpls iimpls + " }" | BasicPatterns.TraitCall(tys,nm,argtys,tinst,args) -> "trait call " + nm + printTupledArgs args | BasicPatterns.Const(obj,ty) -> match obj with @@ -84,7 +84,14 @@ module Utils = and printCurriedParams (vs: FSharpMemberOrFunctionOrValue list list) = String.concat " " (List.map printParams vs) and printTy ty = ty.Format(FSharpDisplayContext.Empty) and printTyargs tyargs = match tyargs with [] -> "" | args -> "<" + String.concat "," (List.map printTy tyargs) + ">" - + and printOverrides ors = String.concat ";" (List.map printOverride ors) + and printOverride o = + match o.CurriedParameterGroups with + | [t] :: a -> + "member " + t.CompiledName + "." + o.Signature.Name + printCurriedParams a + " = " + printExpr 10 o.Body + | _ -> failwith "wrong this argument in object expression override" + and printIimpls iis = String.concat ";" (List.map printImlementation iis) + and printImlementation (i, ors) = "interface " + printTy i + " with " + printOverrides ors let rec printDeclaration (excludes:HashSet<_> option) (d: FSharpImplementationFileDeclaration) = seq { @@ -428,8 +435,8 @@ let ``Test Declarations project1`` () = "member Method(x) (a,b) = 1 @ (106,37--106,38)"; "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (m.Method(7,8),fun tupledArg -> let arg00: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg01: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let arg10: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg11: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(arg00,arg01,arg10,arg11) (9,10) (11,12)) @ (110,8--110,9)"; - "let functionThatUsesObjectExpression(unitVar0) = { new Microsoft.FSharp.Core.obj with ... } @ (114,3--114,55)"; - "let functionThatUsesObjectExpressionWithInterfaceImpl(unitVar0) = { new Microsoft.FSharp.Core.obj with ... } :> System.IComparable @ (117,3--120,38)"; + "let functionThatUsesObjectExpression(unitVar0) = { Object..ctor () with member x.ToString(unitVar1) = Operators.ToString (888) } @ (114,3--114,55)"; + "let functionThatUsesObjectExpressionWithInterfaceImpl(unitVar0) = { Object..ctor () with member x.ToString(unitVar1) = Operators.ToString (888) interface System.IComparable with member x.CompareTo(y) = 0 } :> System.IComparable @ (117,3--120,38)"; "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [| ... |] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, null)],TypeVar 0us)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)";