Skip to content

Commit

Permalink
Anonymous records!
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsogarciacaro committed Feb 21, 2019
1 parent f441f84 commit b377710
Show file tree
Hide file tree
Showing 11 changed files with 567 additions and 482 deletions.
Binary file modified lib/fcs/FSharp.Compiler.Service.dll
Binary file not shown.
35 changes: 23 additions & 12 deletions lib/fcs/FSharp.Compiler.Service.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28180,7 +28180,7 @@ Special cases where representation uses Lambda.
</member>
<member name="T:Microsoft.FSharp.Compiler.SourceCodeServices.FSharpObjectExprOverride">
<summary>
Represents a checked method in an object expression, as seen by the F# language.
Represents a checked method in an object expression, as seen by the F# language.
</summary>
</member>
<member name="P:Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr.Type">
Expand All @@ -28195,12 +28195,12 @@ Special cases where representation uses Lambda.
</member>
<member name="P:Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr.ImmediateSubExpressions">
<summary>
The immediate sub-expressions of the expression.
The immediate sub-expressions of the expression.
</summary>
</member>
<member name="T:Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr">
<summary>
Represents a checked and reduced expression, as seen by the F# language. The active patterns
Represents a checked and reduced expression, as seen by the F# language. The active patterns
in &apos;FSharp.Compiler.SourceCodeServices&apos; can be used to analyze information about the expression.

Pattern matching is reduced to decision trees and conditional tests. Some other
Expand Down Expand Up @@ -29777,7 +29777,7 @@ Special cases where representation uses Lambda.
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|TraitCall|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches expressions for an unresolved call to a trait
Matches expressions for an unresolved call to a trait
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|ObjectExpr|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
Expand Down Expand Up @@ -29817,7 +29817,7 @@ Special cases where representation uses Lambda.
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|WhileLoop|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches while loops
Matches while loops
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|FastIntegerForLoop|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
Expand All @@ -29827,7 +29827,7 @@ Special cases where representation uses Lambda.
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|Sequential|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches sequential expressions
Matches sequential expressions
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|AddressOf|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
Expand Down Expand Up @@ -29863,7 +29863,7 @@ Special cases where representation uses Lambda.
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|NewArray|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches array expressions
Matches array expressions
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|Coerce|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
Expand All @@ -29878,7 +29878,7 @@ Special cases where representation uses Lambda.
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|NewTuple|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches tuple expressions
Matches tuple expressions
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|UnionCaseTest|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
Expand Down Expand Up @@ -29916,9 +29916,20 @@ Special cases where representation uses Lambda.
Matches expressions which get a field from a record or class
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|AnonRecordGet|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches expressions getting a field from an anonymous record. The integer represents the
index into the sorted fields of the anonymous record.
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|NewAnonRecord|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches anonymous record expressions
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|NewRecord|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches record expressions
Matches record expressions
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|LetRec|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
Expand All @@ -29943,7 +29954,7 @@ Special cases where representation uses Lambda.
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|NewObject|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches expressions which are calls to object constructors
Matches expressions which are calls to object constructors
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|Call|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
Expand Down Expand Up @@ -29985,12 +29996,12 @@ Special cases where representation uses Lambda.
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|Application|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches expressions which are the application of function values
Matches expressions which are the application of function values
</summary>
</member>
<member name="M:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns.|Value|_|(Microsoft.FSharp.Compiler.SourceCodeServices.FSharpExpr)">
<summary>
Matches expressions which are uses of values
Matches expressions which are uses of values
</summary>
</member>
<member name="T:Microsoft.FSharp.Compiler.SourceCodeServices.BasicPatterns">
Expand Down
8 changes: 6 additions & 2 deletions src/Fable.Transforms/AST/AST.Fable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type ImportKind =

type EnumKind = NumberEnum of Expr | StringEnum of Expr
type NewArrayKind = ArrayValues of Expr list | ArrayAlloc of Expr
type NewRecordKind = DeclaredRecord of FSharpEntity | AnonymousRecord of fieldNames: string[]

type ValueKind =
| TypeInfo of Type * SourceLocation option // Error messages need location info
Expand All @@ -146,7 +147,7 @@ type ValueKind =
| NewArray of NewArrayKind * Type
| NewList of headAndTail: (Expr * Expr) option * Type
| NewTuple of Expr list
| NewRecord of Expr list * FSharpEntity * genArgs: Type list
| NewRecord of Expr list * NewRecordKind * genArgs: Type list
| NewUnion of Expr list * FSharpUnionCase * FSharpEntity * genArgs: Type list
| NewErasedUnion of Expr * genericArgs: Type list
member this.Type =
Expand All @@ -169,7 +170,10 @@ type ValueKind =
| NewArray(_, t) -> Array t
| NewList(_, t) -> List t
| NewTuple exprs -> exprs |> List.map (fun e -> e.Type) |> Tuple
| NewRecord(_, ent, genArgs) -> DeclaredType(ent, genArgs)
| NewRecord(_, kind, genArgs) ->
match kind with
| DeclaredRecord ent -> DeclaredType(ent, genArgs)
| AnonymousRecord _ -> Any
| NewUnion(_, _, ent, genArgs) -> DeclaredType(ent, genArgs)
| NewErasedUnion(_, genArgs) -> ErasedUnion genArgs

Expand Down
13 changes: 12 additions & 1 deletion src/Fable.Transforms/FSharp2Fable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,13 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
| _ -> return failwith "makeFunctionArgs returns args with different length"

// Getters and Setters
| BasicPatterns.AnonRecordGet(callee, calleeType, fieldIndex) ->
let! callee = transformExpr com ctx callee
let fieldName = calleeType.AnonRecordTypeDetails.SortedFieldNames.[fieldIndex]
let typ = makeType com ctx.GenericArgs fsExpr.Type
let kind = Fable.FieldGet(fieldName, false, typ)
return Fable.Get(callee, kind, typ, makeRangeFrom fsExpr)

| BasicPatterns.FSharpFieldGet(callee, calleeType, field) ->
let! callee = transformExprOpt com ctx callee
let callee =
Expand Down Expand Up @@ -637,7 +644,11 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
| BasicPatterns.NewRecord(fsType, argExprs) ->
let! argExprs = transformExprList com ctx argExprs
let genArgs = makeGenArgs com ctx.GenericArgs (getGenericArguments fsType)
return Fable.NewRecord(argExprs, fsType.TypeDefinition, genArgs) |> Fable.Value
return Fable.NewRecord(argExprs, Fable.DeclaredRecord fsType.TypeDefinition, genArgs) |> Fable.Value

| BasicPatterns.NewAnonRecord(fsType, argExprs) ->
let! argExprs = transformExprList com ctx argExprs
return Fable.NewRecord(argExprs, Fable.AnonymousRecord fsType.AnonRecordTypeDetails.SortedFieldNames, []) |> Fable.Value

| BasicPatterns.NewUnionCase(fsType, unionCase, argExprs) ->
let! argExprs = transformExprList com ctx argExprs
Expand Down
16 changes: 12 additions & 4 deletions src/Fable.Transforms/Fable2Babel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,10 @@ module Util =
|> ArrayExpression :> Expression

let makeJsObject pairs =
pairs |> List.mapToArray (fun (name, value) ->
pairs |> Seq.map (fun (name, value) ->
let prop, computed = memberFromName name
ObjectProperty(prop, value, computed_=computed) |> U3.Case1)
|> Seq.toArray
|> ObjectExpression :> Expression

let assign range left right =
Expand Down Expand Up @@ -552,10 +553,17 @@ module Util =
match kind with
| Fable.NumberEnum x
| Fable.StringEnum x -> com.TransformAsExpr(ctx, x)
| Fable.NewRecord(values, ent, _) ->
let consRef = jsConstructor com ctx ent
| Fable.NewRecord(values, kind, _) ->
let values = List.mapToArray (fun x -> com.TransformAsExpr(ctx, x)) values
upcast NewExpression(consRef, values)
match kind with
| Fable.DeclaredRecord ent ->
let consRef = jsConstructor com ctx ent
upcast NewExpression(consRef, values)
| Fable.AnonymousRecord fieldNames ->
Array.zip fieldNames values
|> makeJsObject
|> Array.singleton
|> coreLibCall com ctx "Types" "anonRecord"
| Fable.NewUnion(values, uci, ent, _) ->
// Union cases with EraseAttribute are used for `Custom`-like cases in unions meant for `keyValueList`
match FSharp2Fable.Helpers.tryFindAtt Atts.erase uci.Attributes with
Expand Down
9 changes: 6 additions & 3 deletions src/Fable.Transforms/FableTransforms.fs
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,12 @@ module private Transforms =
let info = { info with Args = uncurryArgs com info.SignatureArgTypes info.Args }
Operation(Emit(macro, Some info), t, r)
// Uncurry also values in setters or new record/union/tuple
| Value(NewRecord(args, ent, genArgs)) ->
let args = uncurryConsArgs args ent.FSharpFields
Value(NewRecord(args, ent, genArgs))
| Value(NewRecord(args, kind, genArgs)) ->
let args =
match kind with
| DeclaredRecord ent -> uncurryConsArgs args ent.FSharpFields
| AnonymousRecord _ -> uncurryArgs com AutoUncurrying args
Value(NewRecord(args, kind, genArgs))
| Value(NewUnion(args, uci, ent, genArgs)) ->
let args = uncurryConsArgs args uci.UnionCaseFields
Value(NewUnion(args, uci, ent, genArgs))
Expand Down
4 changes: 4 additions & 0 deletions src/fable-library/Types.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ Record.prototype.CompareTo = function(other) {
return recordCompare(this, other);
};

export function anonRecord(o) {
return Object.assign(Object.create(Record), o);
}

export const FSharpRef = declare(function FSharpRef(contents) {
this.contents = contents;
}, Record);
Expand Down
Loading

1 comment on commit b377710

@ncave
Copy link
Collaborator

@ncave ncave commented on b377710 Feb 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work, only hours after it was published upstream :)

Please sign in to comment.