@@ -347,21 +347,6 @@ module Annotation =
347347 GenericTypeAnnotation( Identifier name, ?typeParameters= typeParamInst) :> TypeAnnotationInfo
348348 |> TypeAnnotation |> Some
349349
350- let makeInterfaceDecl ( com : IBabelCompiler ) ctx ( ent : Fable.Entity ) ( entName : string ) ( baseExpr : Expression option ) =
351- let genTypeParams = getEntityGenParams ent
352- let newTypeParams = Set.difference genTypeParams ctx.ScopedTypeParams
353- let ctx = { ctx with ScopedTypeParams = Set.union ctx.ScopedTypeParams newTypeParams }
354- let attached = Util.getEntityExplicitInterfaceMembers com ctx ent
355- let extends =
356- Util.getInterfaceExtends com ctx ent
357- |> Seq.toArray
358- |> function [||] -> None | e -> Some e
359- // Type declaration merging only works well with class declarations, not class expressions
360- let id = Identifier( entName)
361- let body = ObjectTypeAnnotation([| yield ! attached |])
362- let typeParamDecl = genTypeParams |> makeTypeParamDecl
363- InterfaceDeclaration( id, body, ?extends_= extends, ?typeParameters= typeParamDecl)
364-
365350 let typeAnnotation com ctx typ : TypeAnnotationInfo =
366351 match typ with
367352 | Fable.MetaType -> upcast AnyTypeAnnotation()
@@ -1214,7 +1199,7 @@ module Util =
12141199
12151200 let transformBindingAsStatements ( com : IBabelCompiler ) ctx ( var : Fable.Ident ) ( value : Fable.Expr ) =
12161201 if isJsStatement ctx false value then
1217- let var = typedIdent com ctx var
1202+ let var = ident var
12181203 let decl = VariableDeclaration( var) :> Statement
12191204 let body = com.TransformAsStatements( ctx, Some( Assign var), value)
12201205 Array.append [| decl|] body
@@ -1645,7 +1630,7 @@ module Util =
16451630 let tailcallChance =
16461631 Option.map ( fun name ->
16471632 NamedTailCallOpportunity( com, ctx, name, args) :> ITailCallOpportunity) name
1648- let args = discardUnitArg args |> List.map ( typedIdent com ctx )
1633+ let args = discardUnitArg args
16491634 let declaredVars = ResizeArray()
16501635 let mutable isTailCallOptimized = false
16511636 let ctx =
@@ -1663,21 +1648,21 @@ module Util =
16631648 match isTailCallOptimized, tailcallChance with
16641649 | true , Some tc ->
16651650 // Replace args, see NamedTailCallOpportunity constructor
1666- let args , body =
1667- let tcArgs =
1668- tc.Args
1669- |> List.map ( fun arg -> Identifier ( arg ) )
1670- let varDecls =
1671- tcArgs
1672- |> List.map ( fun arg -> Some ( arg :> Expression ))
1673- |> List.zip args
1674- |> multiVarDeclaration Const
1675- tcArgs , BlockStatement( Array.append [| varDecls|] body.Body)
1651+ let args ' =
1652+ List.zip args tc.Args
1653+ |> List.map ( fun ( id , tcArg ) ->
1654+ makeTypedIdent id.Type tcArg |> typedIdent com ctx )
1655+ let varDecls =
1656+ List.zip args tc.Args
1657+ |> List.map ( fun ( id , tcArg ) ->
1658+ id |> typedIdent com ctx , Some ( Identifier ( tcArg ) :> Expression ))
1659+ |> multiVarDeclaration Const
1660+ let body = BlockStatement( Array.append [| varDecls|] body.Body)
16761661 // Make sure we don't get trapped in an infinite loop, see #1624
16771662 let body = BlockStatement( Array.append body.Body [| BreakStatement()|])
1678- args, LabeledStatement( Identifier tc.Label, WhileStatement( BooleanLiteral true , body))
1663+ args' , LabeledStatement( Identifier tc.Label, WhileStatement( BooleanLiteral true , body))
16791664 :> Statement |> Array.singleton |> BlockStatement
1680- | _ -> args, body
1665+ | _ -> args |> List.map ( typedIdent com ctx ) , body
16811666 let body =
16821667 if declaredVars.Count = 0 then body
16831668 else
@@ -1719,121 +1704,26 @@ module Util =
17191704 else
17201705 None
17211706
1722- let getInterfaceExtends com ctx ( ent : Fable.Entity ) =
1707+ let getClassImplements com ctx ( ent : Fable.Entity ) =
17231708 let mkNative genArgs typeName =
17241709 let id = Identifier( typeName)
17251710 let typeParamInst = makeGenTypeParamInst com ctx genArgs
1726- InterfaceExtends ( id, ?typeParameters= typeParamInst) |> Some
1711+ ClassImplements ( id, ?typeParameters= typeParamInst) |> Some
17271712 let mkImport genArgs moduleName typeName =
17281713 let id = makeImportTypeId com ctx moduleName typeName
17291714 let typeParamInst = makeGenTypeParamInst com ctx genArgs
1730- InterfaceExtends( id, ?typeParameters= typeParamInst) |> Some
1731-
1732- // let isIEquatable = FSharp2Fable.Util.hasInterface Types.iequatable ent
1733- // let isIComparable = FSharp2Fable.Util.hasInterface Types.icomparable ent
1734-
1715+ ClassImplements( id, ?typeParameters= typeParamInst) |> Some
17351716 ent.AllInterfaces |> Seq.choose ( fun ifc ->
17361717 match ifc.Definition.FullName with
1737- | Types.ienumerableGeneric ->
1738- mkImport ifc.GenericArgs " Seq" " IEnumerable"
1739- | Types.ienumeratorGeneric ->
1740- mkImport ifc.GenericArgs " Seq" " IEnumerator"
1741- | Types.iequatable ->
1742- mkImport [ Fable.Any] " Util" " IEquatable"
1743- | Types.icomparable ->
1744- mkImport [ Fable.Any] " Util" " IComparable"
1745- // | Types.iequatableGeneric when not isIEquatable ->
1746- // mkImport ifc.GenericArgs "Util" "IEquatable"
1747- // | Types.icomparableGeneric when not isIComparable ->
1748- // mkImport ifc.GenericArgs "Util" "IComparable"
1749- | Types.comparer ->
1750- mkImport ifc.GenericArgs " Util" " IComparer"
1751- // this is not needed, as it's already included in every object
1752- // | Types.equalityComparer ->
1753- // mkImport ifc.GenericArgs "Util" "IEqualityComparer"
1754- | Types.idisposable ->
1755- mkImport [] " Util" " IDisposable"
1756- | Types.icollectionGeneric ->
1757- mkImport ifc.GenericArgs " Util" " ICollection"
1758- | " Fable.Collections.IMutableSet`1" ->
1759- mkImport ifc.GenericArgs " Util" " IMutableSet"
1760- | " Fable.Collections.IMutableMap`2" ->
1761- mkImport ifc.GenericArgs " Util" " IMutableMap"
1762- // TODO: add other interfaces
1718+ | " Fable.Collections.IMutableSet`1" -> mkNative ifc.GenericArgs " Set"
1719+ | " Fable.Collections.IMutableMap`2" -> mkNative ifc.GenericArgs " Map"
17631720 | _ -> None
17641721 )
17651722
1766- // must match the above list (with the exception of IEqualityComparer)
1767- let alreadyDeclaredInterfaces =
1768- set [
1769- Types.ienumerableGeneric
1770- Types.ienumeratorGeneric
1771- Types.iequatable
1772- Types.icomparable
1773- // Types.iequatableGeneric
1774- // Types.icomparableGeneric
1775- Types.comparer
1776- Types.equalityComparer
1777- Types.idisposable
1778- Types.icollectionGeneric
1779- " Fable.Collections.IMutableSet`1"
1780- " Fable.Collections.IMutableMap`2"
1781- ]
1782-
1783- let isOtherInterfaceMember ( memb : Fable.MemberFunctionOrValue ) =
1784- let isInterface , fullName =
1785- if memb.IsExplicitInterfaceImplementation then
1786- true , memb.CompiledName.Replace( " -" , " ." )
1787- else
1788- let ent = memb.ApparentEnclosingEntity
1789- ent.IsInterface, memb.FullName
1790- let lastDot = fullName.LastIndexOf( " ." )
1791- let entName = if lastDot < 0 then fullName else fullName.Substring( 0 , lastDot)
1792- isInterface && not ( alreadyDeclaredInterfaces.Contains entName)
1793-
1794- let getEntityExplicitInterfaceMembers com ctx ( ent : Fable.Entity ) =
1795- ent.MembersFunctionsAndValues
1796- |> Seq.filter isOtherInterfaceMember
1797- |> Seq.map ( fun memb ->
1798- let args =
1799- List.concat memb.CurriedParameterGroups
1800- |> List.mapi ( fun i p ->
1801- let name =
1802- defaultArg p.Name ( " arg" + ( string i))
1803- |> Naming.sanitizeIdentForbiddenChars |> Naming.checkJsKeywords
1804- name, p.Type
1805- )
1806- let argTypes = args |> List.map snd
1807- let retType = memb.ReturnParameter.Type
1808- let genTypeParams = getGenericTypeParams ( argTypes @ [ retType])
1809- let newTypeParams = Set.difference genTypeParams ctx.ScopedTypeParams
1810- let ctx = { ctx with ScopedTypeParams = Set.union ctx.ScopedTypeParams newTypeParams }
1811- let funcArgs =
1812- args
1813- |> Seq.map ( fun ( name , typ ) ->
1814- let typeInfo = typeAnnotation com ctx typ
1815- FunctionTypeParam( Identifier( name), typeInfo)
1816- ) |> Seq.toArray
1817- let returnType = retType |> typeAnnotation com ctx
1818- let typeParamDecl = makeTypeParamDecl newTypeParams
1819- let funcTypeInfo =
1820- FunctionTypeAnnotation( funcArgs, returnType, ?typeParameters= typeParamDecl)
1821- :> TypeAnnotationInfo
1822- // TODO!!! This should be the compiled name if the interface is not mangled
1823- let name = memb.DisplayName
1824- let membId = Identifier( name)
1825- ObjectTypeProperty( membId, funcTypeInfo)
1826- )
1827- |> Seq.toArray
1828-
1829- let getEntityFieldsAsProps ( com : IBabelCompiler ) ctx ( ent : Fable.Entity ) =
1830- ent.FSharpFields
1831- |> Seq.map ( fun field ->
1832- let id , computed = memberFromName field.Name
1833- let ta = typeAnnotation com ctx field.FieldType
1834- let isStatic = if field.IsStatic then Some true else None
1835- ObjectTypeProperty( id, ta, computed_= computed, ?`` static `` = isStatic))
1836- |> Seq.toArray
1723+ let getUnionFieldsAsIdents ( com : IBabelCompiler ) ctx ( ent : Fable.Entity ) =
1724+ let tagId = makeTypedIdent ( Fable.Number Int32) " tag"
1725+ let fieldsId = makeTypedIdent ( Fable.Array Fable.Any) " fields"
1726+ [| tagId; fieldsId |]
18371727
18381728 let getEntityFieldsAsIdents com ( ent : Fable.Entity ) =
18391729 ent.FSharpFields
@@ -1844,9 +1734,30 @@ module Util =
18441734 id)
18451735 |> Seq.toArray
18461736
1737+ let getEntityFieldsAsProps ( com : IBabelCompiler ) ctx ( ent : Fable.Entity ) =
1738+ if ( ent.IsFSharpUnion) then
1739+ getUnionFieldsAsIdents com ctx ent
1740+ |> Array.map ( fun id ->
1741+ let prop = ident id
1742+ let ta = typeAnnotation com ctx id.Type
1743+ ObjectTypeProperty( prop, ta))
1744+ else
1745+ ent.FSharpFields
1746+ |> Seq.map ( fun field ->
1747+ let prop , computed = memberFromName field.Name
1748+ let ta = typeAnnotation com ctx field.FieldType
1749+ let isStatic = if field.IsStatic then Some true else None
1750+ ObjectTypeProperty( prop, ta, computed_= computed, ?`` static `` = isStatic))
1751+ |> Seq.toArray
1752+
18471753 let declareClassType ( com : IBabelCompiler ) ctx ( ent : Fable.Entity ) entName ( consArgs : Pattern []) ( consBody : BlockStatement ) ( baseExpr : Expression option ) classMembers =
18481754 let consId = Identifier " constructor"
18491755 let typeParamDecl = makeEntityTypeParamDecl com ctx ent
1756+ let implements =
1757+ if com.Options.Typescript then
1758+ let implements = Util.getClassImplements com ctx ent |> Seq.toArray
1759+ if Array.isEmpty implements then None else Some implements
1760+ else None
18501761 let consBody =
18511762 if ent.IsFSharpExceptionDeclaration then
18521763 let super = callSuperConstructor None [] |> ExpressionStatement :> Statement
@@ -1862,13 +1773,13 @@ module Util =
18621773 else Array.empty
18631774 let classMembers = Array.append [| classCons |] classMembers
18641775 let classBody = ClassBody([| yield ! classFields; yield ! classMembers |])
1865- let classExpr = ClassExpression( classBody, ?superClass= baseExpr, ?typeParameters= typeParamDecl)
1776+ let classExpr = ClassExpression( classBody, ?superClass= baseExpr, ?typeParameters= typeParamDecl, ?implements = implements )
18661777 classExpr |> declareModuleMember ent.IsPublic entName false
18671778
18681779 let declareType ( com : IBabelCompiler ) ctx ( ent : Fable.Entity ) entName ( consArgs : Pattern []) ( consBody : BlockStatement ) baseExpr classMembers : ModuleDeclaration list =
18691780 let typeDeclaration = declareClassType com ctx ent entName consArgs consBody baseExpr classMembers
18701781 let reflectionDeclaration =
1871- let genArgs = Array.init ( ent.GenericParameters.Length) ( fun i -> " gen" + string i |> makeIdent |> typedIdent com ctx )
1782+ let genArgs = Array.init ( ent.GenericParameters.Length) ( fun i -> " gen" + string i |> makeIdent |> ident )
18721783 let body = transformReflectionInfo com ctx None ent ( Array.map ( fun x -> x :> _) genArgs)
18731784 let returnType =
18741785 if com.Options.Typescript then
@@ -1878,12 +1789,7 @@ module Util =
18781789 let args = genArgs |> Array.map ( fun x -> x :> Pattern)
18791790 makeFunctionExpression None ( args, body, returnType, None)
18801791 |> declareModuleMember ent.IsPublic ( entName + Naming.reflectionSuffix) false
1881- if com.Options.Typescript then
1882- let interfaceDecl = makeInterfaceDecl com ctx ent entName baseExpr
1883- let interfaceDeclaration = ExportNamedDeclaration( interfaceDecl) :> ModuleDeclaration
1884- [ interfaceDeclaration; typeDeclaration; reflectionDeclaration]
1885- else
1886- [ typeDeclaration; reflectionDeclaration]
1792+ [ typeDeclaration; reflectionDeclaration]
18871793
18881794 let transformModuleFunction ( com : IBabelCompiler ) ctx ( info : Fable.MemberInfo ) ( membName : string ) args body =
18891795 let args , body , returnType , typeParamDecl =
@@ -1930,14 +1836,12 @@ module Util =
19301836 |]
19311837
19321838 let transformUnion ( com : IBabelCompiler ) ctx ( ent : Fable.Entity ) ( entName : string ) classMembers =
1933-
1934- let tagId = makeTypedIdent ( Fable.Number Int32) " tag"
1935- let fieldsId = makeTypedIdent ( Fable.Array Fable.Any) " fields"
1839+ let fieldIds = getUnionFieldsAsIdents com ctx ent
19361840 let args =
1937- [| typedIdent com ctx tagId :> Pattern
1938- typedIdent com ctx fieldsId |> restElement |]
1841+ [| typedIdent com ctx fieldIds .[ 0 ] :> Pattern
1842+ typedIdent com ctx fieldIds .[ 1 ] |> restElement |]
19391843 let body =
1940- [| tagId ; fieldsId |]
1844+ fieldIds
19411845 |> Array.map ( fun id ->
19421846 let left = get None thisExpr id.Name
19431847 let right =
0 commit comments