From c12678d4cbff2fd7e7bc29dca5ae83ab868bffab Mon Sep 17 00:00:00 2001 From: Alfonso Garcia-Caro Date: Fri, 12 Apr 2019 17:27:42 +0200 Subject: [PATCH] Release 2.3.0-beta-001 --- package-lock.json | 41 +++++++++++----- src/Fable.Cli/Fable.Cli.fsproj | 2 +- src/Fable.Cli/Util.fs | 2 +- src/Fable.Core/Fable.Core.JsInterop.fs | 4 ++ src/Fable.Core/Fable.Core.fsproj | 2 +- src/Fable.Core/RELEASE_NOTES.md | 4 ++ src/Fable.Transforms/FSharp2Fable.Util.fs | 59 ++++++++++++++--------- src/Fable.Transforms/FSharp2Fable.fs | 34 ++++++------- src/Fable.Transforms/Fable2Babel.fs | 2 - src/Fable.Transforms/Inject.fs | 1 - src/Fable.Transforms/Replacements.fs | 37 ++++++++++++-- src/Fable.Transforms/State.fs | 2 - src/Fable.Transforms/Transforms.Util.fs | 17 ++++++- src/fable-compiler/RELEASE_NOTES.md | 5 ++ src/fable-compiler/package-lock.json | 2 +- src/fable-compiler/package.json | 2 +- src/fable-publish-utils/PublishUtils.fs | 7 +-- 17 files changed, 152 insertions(+), 71 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1bd26b0695..f52e113bf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3429,7 +3429,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3447,11 +3448,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3464,15 +3467,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3575,7 +3581,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3585,6 +3592,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3597,17 +3605,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3624,6 +3635,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3696,7 +3708,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3706,6 +3719,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3781,7 +3795,8 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3811,6 +3826,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3828,6 +3844,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3866,11 +3883,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.3", - "bundled": true + "bundled": true, + "optional": true } } }, diff --git a/src/Fable.Cli/Fable.Cli.fsproj b/src/Fable.Cli/Fable.Cli.fsproj index 1672c46cd6..e28239894d 100644 --- a/src/Fable.Cli/Fable.Cli.fsproj +++ b/src/Fable.Cli/Fable.Cli.fsproj @@ -1,4 +1,4 @@ - + Exe diff --git a/src/Fable.Cli/Util.fs b/src/Fable.Cli/Util.fs index 89a5630b6a..654fe0ffbc 100644 --- a/src/Fable.Cli/Util.fs +++ b/src/Fable.Cli/Util.fs @@ -2,7 +2,7 @@ namespace Fable.Cli module Literals = - let [] VERSION = "2.2.3" + let [] VERSION = "2.3.0-beta-001" let [] CORE_VERSION = "2.1.0" let [] DEFAULT_PORT = 61225 let [] FORCE = "force:" diff --git a/src/Fable.Core/Fable.Core.JsInterop.fs b/src/Fable.Core/Fable.Core.JsInterop.fs index f963c73837..a9bfba0839 100644 --- a/src/Fable.Core/Fable.Core.JsInterop.fs +++ b/src/Fable.Core/Fable.Core.JsInterop.fs @@ -81,6 +81,10 @@ let importSideEffects (path: string): unit = jsNative /// Imports a file dynamically at runtime let importDynamic<'T> (path: string): JS.Promise<'T> = jsNative +/// Imports a reference from an external file dynamically at runtime +/// ATENTION: Needs fable-compiler 2.3, pass the reference directly in argument position (avoid pipes) +let importValueDynamic (x: 'T): JS.Promise<'T> = jsNative + /// Used when you need to send an F# record to a JS library accepting only plain JS objects (POJOs) let toPlainJsObj(o: 'T): obj = jsNative diff --git a/src/Fable.Core/Fable.Core.fsproj b/src/Fable.Core/Fable.Core.fsproj index 17029b3c4d..f337cde4c2 100644 --- a/src/Fable.Core/Fable.Core.fsproj +++ b/src/Fable.Core/Fable.Core.fsproj @@ -5,7 +5,7 @@ netstandard2.0 true 3.0.0 - 3.0.0-beta-005 + 3.0.0-beta-006 diff --git a/src/Fable.Core/RELEASE_NOTES.md b/src/Fable.Core/RELEASE_NOTES.md index e2b830d7f6..a75048a8b9 100644 --- a/src/Fable.Core/RELEASE_NOTES.md +++ b/src/Fable.Core/RELEASE_NOTES.md @@ -1,3 +1,7 @@ +### 3.0.0-beta-006 + +* Add `JsInterop.importValueDynamic` + ### 3.0.0-beta-005 * Move `nameof` operators to Experimental module diff --git a/src/Fable.Transforms/FSharp2Fable.Util.fs b/src/Fable.Transforms/FSharp2Fable.Util.fs index 5c43d4f1f5..853945efd5 100644 --- a/src/Fable.Transforms/FSharp2Fable.Util.fs +++ b/src/Fable.Transforms/FSharp2Fable.Util.fs @@ -10,7 +10,7 @@ open Fable.AST open Fable.Transforms type Context = - { Scope: (FSharpMemberOrFunctionOrValue * Fable.Expr) list + { Scope: (FSharpMemberOrFunctionOrValue * Fable.Ident * Fable.Expr option) list ScopeInlineValues: (FSharpMemberOrFunctionOrValue * FSharpExpr) list GenericArgs: Map EnclosingMember: FSharpMemberOrFunctionOrValue option @@ -327,11 +327,11 @@ module Patterns = /// Detects AST pattern of "raise MatchFailureException()" let (|RaisingMatchFailureExpr|_|) (expr: FSharpExpr) = match expr with - | BasicPatterns.Call(None, methodInfo, [ ], [unitType], [value]) -> + | BasicPatterns.Call(None, methodInfo, [ ], [_unitType], [value]) -> match methodInfo.FullName with | "Microsoft.FSharp.Core.Operators.raise" -> match value with - | BasicPatterns.NewRecord(recordType, [ BasicPatterns.Const (value, valueT) ; rangeFrom; rangeTo ]) -> + | BasicPatterns.NewRecord(recordType, [BasicPatterns.Const (value, _valueT) ; _rangeFrom; _rangeTo]) -> match recordType.TypeDefinition.FullName with | "Microsoft.FSharp.Core.MatchFailureException"-> Some (value.ToString()) | _ -> None @@ -664,8 +664,8 @@ module Identifiers = open Helpers open TypeHelpers - let bindExpr (ctx: Context) (fsRef: FSharpMemberOrFunctionOrValue) expr = - { ctx with Scope = (fsRef, expr)::ctx.Scope} + let putIdentInScope (ctx: Context) (fsRef: FSharpMemberOrFunctionOrValue) (ident: Fable.Ident) value = + { ctx with Scope = (fsRef, ident, value)::ctx.Scope} let makeIdentFrom (com: IFableCompiler) (ctx: Context) (fsRef: FSharpMemberOrFunctionOrValue): Fable.Ident = let sanitizedName = (fsRef.CompiledName, Naming.NoMemberPart) @@ -682,25 +682,36 @@ module Identifiers = Range = { makeRange fsRef.DeclarationLocation with identifierName = Some fsRef.DisplayName } |> Some } - /// Sanitize F# identifier and create new context - let bindIdentFrom com ctx (fsRef: FSharpMemberOrFunctionOrValue): Context*Fable.Ident = + let putArgInScope com ctx (fsRef: FSharpMemberOrFunctionOrValue): Context*Fable.Ident = let ident = makeIdentFrom com ctx fsRef - bindExpr ctx fsRef (Fable.IdentExpr ident), ident + putIdentInScope ctx fsRef ident None, ident + + let (|PutArgInScope|) com ctx fsRef = putArgInScope com ctx fsRef - let (|BindIdent|) com ctx fsRef = bindIdentFrom com ctx fsRef - - let inline tryGetBoundExprWhere (ctx: Context) r predicate = - match List.tryFind (fun (fsRef,_) -> predicate fsRef) ctx.Scope with - | Some(_, Fable.IdentExpr ident) -> + let putBindingInScope com ctx (fsRef: FSharpMemberOrFunctionOrValue) value: Context*Fable.Ident = + let ident = makeIdentFrom com ctx fsRef + putIdentInScope ctx fsRef ident (Some value), ident + + let inline tryGetIdentFromScopeIf (ctx: Context) r predicate = + match List.tryFind (fun (fsRef,_,_) -> predicate fsRef) ctx.Scope with + | Some(_,ident,_) -> let originalName = ident.Range |> Option.bind (fun r -> r.identifierName) { ident with Range = r |> Option.map (fun r -> { r with identifierName = originalName }) } |> Fable.IdentExpr |> Some - | Some(_, boundExpr) -> Some boundExpr | None -> None /// Get corresponding identifier to F# value in current scope - let tryGetBoundExpr (ctx: Context) r (fsRef: FSharpMemberOrFunctionOrValue) = - tryGetBoundExprWhere ctx r (fun fsRef' -> obj.Equals(fsRef, fsRef')) + let tryGetIdentFromScope (ctx: Context) r (fsRef: FSharpMemberOrFunctionOrValue) = + tryGetIdentFromScopeIf ctx r (fun fsRef' -> obj.Equals(fsRef, fsRef')) + + let rec tryGetBoundValueFromScope (ctx: Context) identName = + match ctx.Scope |> List.tryFind (fun (_,ident,_) -> ident.Name = identName) with + | Some(_,_,value) -> + match value with + | Some(Fable.IdentExpr ident) when not ident.IsMutable -> + tryGetBoundValueFromScope ctx ident.Name + | v -> v + | None -> None module Util = open Helpers @@ -712,7 +723,7 @@ module Util = let ctx, args = ((ctx, []), args) ||> List.fold (fun (ctx, accArgs) var -> - let newContext, arg = bindIdentFrom com ctx var + let newContext, arg = putArgInScope com ctx var newContext, arg::accArgs) ctx, List.rev args @@ -722,7 +733,7 @@ module Util = // Within private members (first arg is ConstructorThisValue) F# AST uses // ThisValue instead of Value (with .IsMemberConstructorThisValue = true) | (firstArg::restArgs1)::restArgs2 when firstArg.IsConstructorThisValue || firstArg.IsMemberThisValue -> - let ctx, thisArg = bindIdentFrom com ctx firstArg + let ctx, thisArg = putArgInScope com ctx firstArg let thisArg = { thisArg with Kind = Fable.ThisArgIdentDeclaration } let ctx = if firstArg.IsConstructorThisValue @@ -740,7 +751,7 @@ module Util = let makeTryCatch com ctx r (Transform com ctx body) catchClause finalBody = let catchClause = match catchClause with - | Some (BindIdent com ctx (catchContext, catchVar), catchBody) -> + | Some (PutArgInScope com ctx (catchContext, catchVar), catchBody) -> // Add caughtException to context so it can be retrieved by `reraise` let catchContext = { catchContext with CaughtException = Some catchVar } Some (catchVar, com.Transform(catchContext, catchBody)) @@ -889,7 +900,7 @@ module Util = if file = com.CurrentFile then makeIdentExprNonMangled entityName elif isPublicEntity ent then - makeInternalImport Fable.Any entityName file + makeInternalImport com Fable.Any entityName file else error "Cannot inline functions that reference private entities" @@ -917,7 +928,7 @@ module Util = { makeTypedIdentNonMangled typ memberName with Range = r } |> Fable.IdentExpr elif isPublicMember memb then - makeInternalImport typ memberName file + makeInternalImport com typ memberName file else defaultArg (memb.TryGetFullDisplayName()) memb.CompiledName |> sprintf "Cannot reference private members from other files: %s" @@ -1061,7 +1072,7 @@ module Util = let ident = { makeIdentFrom com ctx argId with Type = arg.Type IsCompilerGenerated = true } - let ctx = bindExpr ctx argId (Fable.IdentExpr ident) + let ctx = putIdentInScope ctx argId ident (Some arg) ctx, (ident, arg)::bindings) let ctx = { ctx with GenericArgs = genArgs.Value |> Map InlinedFunction = Some memb @@ -1132,7 +1143,7 @@ module Util = | Imported com r typ (Some argInfo) isModuleValue imported -> imported | Replaced com ctx r typ argTypes genArgs argInfo isModuleValue replaced -> replaced | Inlined com ctx r genArgs callee args expr, _ -> expr - | Try (tryGetBoundExpr ctx r) funcExpr, _ -> + | Try (tryGetIdentFromScope ctx r) funcExpr, _ -> if isModuleValue then funcExpr else staticCall r typ argInfo funcExpr @@ -1162,5 +1173,5 @@ module Util = | Emitted com r typ None emitted, _ -> emitted | Imported com r typ None true imported -> imported // TODO: Replaced? Check if there're failing tests - | Try (tryGetBoundExpr ctx r) expr, _ -> expr + | Try (tryGetIdentFromScope ctx r) expr, _ -> expr | _ -> memberRefTyped com ctx r typ v diff --git a/src/Fable.Transforms/FSharp2Fable.fs b/src/Fable.Transforms/FSharp2Fable.fs index 88ee600b98..e7f1c02b7c 100644 --- a/src/Fable.Transforms/FSharp2Fable.fs +++ b/src/Fable.Transforms/FSharp2Fable.fs @@ -203,7 +203,7 @@ let private transformObjExpr (com: IFableCompiler) (ctx: Context) (objType: FSha let! members = (objType, overrides)::otherOverrides - |> trampolineListMap (fun (typ, overrides) -> + |> trampolineListMap (fun (_typ, overrides) -> overrides |> trampolineListMap mapOverride) return Fable.ObjectExpr(members |> List.concat, makeType com ctx.GenericArgs objType, baseCall) @@ -264,7 +264,7 @@ let rec private transformDecisionTargets (com: IFableCompiler) (ctx: Context) ac | (idents, expr)::tail -> let ctx, idents = (idents, (ctx, [])) ||> List.foldBack (fun ident (ctx, idents) -> - let ctx, ident = bindIdentFrom com ctx ident + let ctx, ident = putArgInScope com ctx ident ctx, ident::idents) let! expr = transformExpr com ctx expr return! transformDecisionTargets com ctx ((idents, expr)::acc) tail @@ -309,7 +309,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = return makeCallFrom com ctx (makeRangeFrom fsExpr) typ false genArgs callee args memb | ByrefArgToTupleOptimizedIf (outArg, callee, memb, ownerGenArgs, membGenArgs, membArgs, thenExpr, elseExpr) -> - let ctx, ident = bindIdentFrom com ctx outArg + let ctx, ident = putArgInScope com ctx outArg let! callee = transformExprOpt com ctx callee let! args = transformExprList com ctx membArgs let genArgs = ownerGenArgs @ membGenArgs |> Seq.map (makeType com ctx.GenericArgs) @@ -326,7 +326,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = return Fable.Let([tupleIdent, tupleExpr], Fable.Let([ident, identExpr], ifThenElse)) | ByrefArgToTupleOptimizedTree (outArg, callee, memb, ownerGenArgs, membGenArgs, membArgs, thenExpr, elseExpr, targetsExpr) -> - let ctx, ident = bindIdentFrom com ctx outArg + let ctx, ident = putArgInScope com ctx outArg let! callee = transformExprOpt com ctx callee let! args = transformExprList com ctx membArgs let genArgs = ownerGenArgs @ membGenArgs |> Seq.map (makeType com ctx.GenericArgs) @@ -342,8 +342,8 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = return Fable.Let([ident, tupleExpr], Fable.DecisionTree(ifThenElse, targetsExpr)) | ByrefArgToTupleOptimizedLet (id1, id2, callee, memb, ownerGenArgs, membGenArgs, membArgs, restExpr) -> - let ctx, ident1 = bindIdentFrom com ctx id1 - let ctx, ident2 = bindIdentFrom com ctx id2 + let ctx, ident1 = putArgInScope com ctx id1 + let ctx, ident2 = putArgInScope com ctx id2 let! callee = transformExprOpt com ctx callee let! args = transformExprList com ctx membArgs let genArgs = ownerGenArgs @ membGenArgs |> Seq.map (makeType com ctx.GenericArgs) @@ -367,7 +367,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = return makeCallFrom com ctx (makeRangeFrom fsExpr) typ false genArgs (Some callee) args memb // TODO: Detect if it's ResizeArray and compile as FastIntegerForLoop? - | ForOf (BindIdent com ctx (newContext, ident), value, body) -> + | ForOf (PutArgInScope com ctx (newContext, ident), value, body) -> let! value = transformExpr com ctx value let! body = transformExpr com newContext body return Replacements.iterate (makeRangeFrom fsExpr) ident body value @@ -376,7 +376,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = | BasicPatterns.FastIntegerForLoop(start, limit, body, isUp) -> let r = makeRangeFrom fsExpr match body with - | BasicPatterns.Lambda (BindIdent com ctx (newContext, ident), body) -> + | BasicPatterns.Lambda (PutArgInScope com ctx (newContext, ident), body) -> let! start = transformExpr com ctx start let! limit = transformExpr com ctx limit let! body = transformExpr com newContext body @@ -414,7 +414,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = // When the type is a ref type, it means this is a reference to a constructor this value `type C() as x` | RefType _, _ -> let r = makeRangeFrom fsExpr - match tryGetBoundExprWhere ctx r (fun fsRef -> fsRef.IsConstructorThisValue) with + match tryGetIdentFromScopeIf ctx r (fun fsRef -> fsRef.IsConstructorThisValue) with | Some e -> e | None -> fail r "Cannot find ConstructorThisValue" | _, Some thisArg -> Fable.IdentExpr thisArg @@ -442,7 +442,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = return! transformExpr com ctx body else let! value = transformExpr com ctx value - let ctx, ident = bindIdentFrom com ctx var + let ctx, ident = putBindingInScope com ctx var value let! body = transformExpr com ctx body return Fable.Let([ident, value], body) @@ -450,7 +450,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = // First get a context containing all idents and use it compile the values let ctx, idents = (recBindings, (ctx, [])) - ||> List.foldBack (fun (BindIdent com ctx (newContext, ident), _) (ctx, idents) -> + ||> List.foldBack (fun (PutArgInScope com ctx (newContext, ident), _) (ctx, idents) -> (newContext, ident::idents)) let _, bindingExprs = List.unzip recBindings let! exprs = transformExprList com ctx bindingExprs @@ -512,7 +512,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = return Fable.Operation(Fable.Call(Fable.InstanceCall(Some e2), argInfo), typ, makeRangeFrom fsExpr) // TODO: Ask: for some reason the F# compiler translates `x.IsSome` as `Application(Call(x, get_IsSome),[unit])` - | BasicPatterns.Application(BasicPatterns.Call(Some _, memb, _, [], []) as optionProp, genArgs, [BasicPatterns.Const(null, _)]) + | BasicPatterns.Application(BasicPatterns.Call(Some _, memb, _, [], []) as optionProp, _genArgs, [BasicPatterns.Const(null, _)]) when memb.FullName = "Microsoft.FSharp.Core.IsSome" || memb.FullName = "Microsoft.FSharp.Core.IsNone" -> return! transformExpr com ctx optionProp @@ -529,7 +529,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = let altElseExpr = match elseExpr with - | RaisingMatchFailureExpr fileNameWhereErrorOccurs -> + | RaisingMatchFailureExpr _fileNameWhereErrorOccurs -> let errorMessage = "The match cases were incomplete" let rangeOfElseExpr = makeRangeFrom elseExpr let errorExpr = Replacements.Helpers.error (Fable.Value(Fable.StringConstant errorMessage, None)) @@ -702,7 +702,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = match snd (List.last decisionTargets) with | RaisingMatchFailureExpr fileNameWhereErrorOccurs -> match decisionExpr with - | BasicPatterns.IfThenElse(BasicPatterns.UnionCaseTest(unionValue, unionType, unionCaseInfo), _, _) -> + | BasicPatterns.IfThenElse(BasicPatterns.UnionCaseTest(_unionValue, unionType, _unionCaseInfo), _, _) -> let rangeOfLastDecisionTarget = makeRangeFrom (snd (List.last decisionTargets)) let errorMessage = sprintf "The match cases were incomplete against type of '%s' at %s" @@ -713,7 +713,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr = let throwExpr = Fable.Throw(errorExpr, Fable.Any, rangeOfLastDecisionTarget) fableDecisionTargets - |> List.replaceLast (fun lastExpr -> [], throwExpr) + |> List.replaceLast (fun _lastExpr -> [], throwExpr) | _ -> // TODO: rewrite other `MatchFailureException` to `failwith "The match cases were incomplete"` @@ -975,7 +975,7 @@ let rec checkMemberNames (com: FableCompiler) decls = com.AddUsedVarName(memberName, isRoot=true) | FSharpImplementationFileDeclaration.InitAction _ -> () -let private transformDeclarations (com: FableCompiler) ctx rootEnt rootDecls = +let private transformDeclarations (com: FableCompiler) ctx rootDecls = let rec transformDeclarationsInner (com: FableCompiler) (ctx: Context) fsDecls = fsDecls |> List.collect (fun fsDecl -> match fsDecl with @@ -1126,7 +1126,7 @@ let transformFile (com: ICompiler) (implFiles: IDictionary exn (sprintf "%s (%s)" ex.Message com.CurrentFile, ex) |> raise diff --git a/src/Fable.Transforms/Fable2Babel.fs b/src/Fable.Transforms/Fable2Babel.fs index 881ab021e7..04676be084 100644 --- a/src/Fable.Transforms/Fable2Babel.fs +++ b/src/Fable.Transforms/Fable2Babel.fs @@ -408,8 +408,6 @@ module Util = |> coreLibCall com ctx None "Reflection" "union" and transformTypeInfo (com: IBabelCompiler) ctx r (genMap: Map) t: Expression = - let error msg = - addErrorAndReturnNull com r msg let primitiveTypeInfo name = coreValue com ctx "Reflection" name let nonGenericTypeInfo fullname = diff --git a/src/Fable.Transforms/Inject.fs b/src/Fable.Transforms/Inject.fs index 18f7a4eb5d..ddadde77bc 100644 --- a/src/Fable.Transforms/Inject.fs +++ b/src/Fable.Transforms/Inject.fs @@ -5,7 +5,6 @@ open FSharp.Compiler.SourceCodeServices open Fable open Fable.AST open Fable.Transforms -open FSharp2Fable.Util open FSharp2Fable.Helpers open FSharp2Fable.Patterns open FSharp2Fable.TypeHelpers diff --git a/src/Fable.Transforms/Replacements.fs b/src/Fable.Transforms/Replacements.fs index 9ff99e6c93..a980a995a9 100644 --- a/src/Fable.Transforms/Replacements.fs +++ b/src/Fable.Transforms/Replacements.fs @@ -1,14 +1,16 @@ [] module Fable.Transforms.Replacements +#nowarn "1182" + open FSharp.Compiler.SourceCodeServices open Fable open Fable.AST open Fable.AST.Fable open Fable.Core -type Context = Fable.Transforms.FSharp2Fable.Context -type ICompiler = Fable.Transforms.FSharp2Fable.IFableCompiler +type Context = FSharp2Fable.Context +type ICompiler = FSharp2Fable.IFableCompiler type CallInfo = Fable.ReplaceCallInfo type Helper = @@ -176,7 +178,7 @@ type NumberExtKind = | BigInt let (|NumberExtKind|_|) = function - | Fable.Transforms.FSharp2Fable.Patterns.NumberKind kind -> Some (JsNumber kind) + | FSharp2Fable.Patterns.NumberKind kind -> Some (JsNumber kind) | Types.int64 -> Some (Long false) | Types.uint64 -> Some (Long true) | Types.decimal -> Some Decimal @@ -1019,7 +1021,34 @@ let fableCoreLib (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Exp Helper.CoreCall("Reflection", meth, t, args, ?loc=r) |> Some | "Fable.Core.JsInterop", _ -> match i.CompiledName, args with - | "importDynamic", _ -> Helper.GlobalCall("import", t, args, ?loc=r) |> Some + | "importDynamic", _ -> + Helper.GlobalCall("import", t, args, ?loc=r) |> Some + | "importValueDynamic", [arg] -> + let dynamicImport selector path = + let import = Helper.GlobalCall("import", t, [path], ?loc=r) + match selector with + | Value(StringConstant "*",_) -> import + | selector -> + let selector = + let m = makeIdentNonMangled "m" + Function(Delegate [m], Get(IdentExpr m, ExprGet selector, Any, None), None) + Helper.InstanceCall(import, "then", t, [selector]) + let arg = + match arg with + | IdentExpr ident -> + FSharp2Fable.Identifiers.tryGetBoundValueFromScope ctx ident.Name + |> Option.defaultValue arg + | arg -> arg + match arg with + // TODO: Check this is not a fable-library import? + | Import(selector,path,_,_,_) -> + dynamicImport selector path |> Some + | NestedLambda(args, Operation(Call(StaticCall(Import(selector,path,_,_,_)),info),_,_), None) + when argEquals args info.Args -> + dynamicImport selector path |> Some + | _ -> + "The imported value is not coming from a different file" + |> addErrorAndReturnNull com ctx.InlinePath r |> Some | Naming.StartsWith "import" suffix, _ -> match suffix, args with | "Member", [path] -> Import(makeStrConst Naming.placeholder, path, CustomImport, t, r) |> Some diff --git a/src/Fable.Transforms/State.fs b/src/Fable.Transforms/State.fs index deb09f4dbf..cf3ec20d0b 100644 --- a/src/Fable.Transforms/State.fs +++ b/src/Fable.Transforms/State.fs @@ -1,7 +1,6 @@ module Fable.Transforms.State open Fable -open System open System.Collections.Generic open FSharp.Compiler.SourceCodeServices @@ -25,7 +24,6 @@ open System.Collections.Concurrent type Project(projectOptions: FSharpProjectOptions, implFiles: IDictionary, errors: FSharpErrorInfo array) = - let timestamp = DateTime.Now let projectFile = Path.normalizePath projectOptions.ProjectFileName let inlineExprs = ConcurrentDictionary() let rootModules = diff --git a/src/Fable.Transforms/Transforms.Util.fs b/src/Fable.Transforms/Transforms.Util.fs index 6ddc7be18d..9dc63349fa 100644 --- a/src/Fable.Transforms/Transforms.Util.fs +++ b/src/Fable.Transforms/Transforms.Util.fs @@ -274,6 +274,7 @@ module AST = /// When referenced multiple times, is there a risk of double evaluation? // TODO: Improve this, see https://github.com/fable-compiler/Fable/issues/1659#issuecomment-445071965 let rec hasDoubleEvalRisk = function + | Import _ -> false | IdentExpr id -> id.IsMutable | Value((Null _ | UnitConstant | NumberConstant _ | StringConstant _ | BoolConstant _),_) -> false | Value(NewTuple exprs,_) -> exprs |> List.exists hasDoubleEvalRisk @@ -363,8 +364,9 @@ module AST = let makeCustomImport t (selector: string) (path: string) = Import(selector.Trim() |> makeStrConst, path.Trim() |> makeStrConst, CustomImport, t, None) - let makeInternalImport t (selector: string) (path: string) = - Import(selector.Trim() |> makeStrConst, path.Trim() |> makeStrConst, Internal, t, None) + let makeInternalImport (com: ICompiler) t (selector: string) (path: string) = + let path = Path.getRelativeFileOrDirPath false com.CurrentFile false path + Import(makeStrConst selector, makeStrConst path, Internal, t, None) let argInfo thisArg args argTypes = { ThisArg = thisArg @@ -399,6 +401,17 @@ module AST = | Float32 -> "Float32Array" | Float64 -> "Float64Array" + let argEquals (argIdents: Ident list) argExprs = + if List.sameLength argIdents argExprs |> not then false + else + (true, List.zip argIdents argExprs) + ||> List.fold (fun eq (id, expr) -> + if not eq then false + else + match expr with + | IdentExpr id2 -> id.Name = id2.Name + | _ -> false) + let rec listEquals f li1 li2 = match li1, li2 with | [], [] -> true diff --git a/src/fable-compiler/RELEASE_NOTES.md b/src/fable-compiler/RELEASE_NOTES.md index 25e1fe3acf..f9a51f37b1 100644 --- a/src/fable-compiler/RELEASE_NOTES.md +++ b/src/fable-compiler/RELEASE_NOTES.md @@ -1,3 +1,8 @@ +### 2.3.0-beta-001 + +* Give warnings if an anonymous record casted to an interface with `!!` mismatches any field +* Compatibility with `JsInterop.importValueDynamic` + ### 2.2.3 * Fix BitConverter @ncave diff --git a/src/fable-compiler/package-lock.json b/src/fable-compiler/package-lock.json index 2638b6fa84..ef0c39c64e 100644 --- a/src/fable-compiler/package-lock.json +++ b/src/fable-compiler/package-lock.json @@ -1,6 +1,6 @@ { "name": "fable-compiler", - "version": "2.2.3", + "version": "2.3.0-beta-001", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/fable-compiler/package.json b/src/fable-compiler/package.json index b4f4150710..ab01048769 100644 --- a/src/fable-compiler/package.json +++ b/src/fable-compiler/package.json @@ -1,6 +1,6 @@ { "name": "fable-compiler", - "version": "2.2.3", + "version": "2.3.0-beta-001", "main": "dist/index.js", "description": "Fable compiler", "keywords": [ diff --git a/src/fable-publish-utils/PublishUtils.fs b/src/fable-publish-utils/PublishUtils.fs index 5f4341608f..cd43de3fdf 100644 --- a/src/fable-publish-utils/PublishUtils.fs +++ b/src/fable-publish-utils/PublishUtils.fs @@ -5,6 +5,7 @@ open System.Text.RegularExpressions open Fable.Core open Fable.Core.JsInterop open Fable.Core.DynamicExtensions +open Fable.Import module private Helpers = let readline: obj = importAll "readline" @@ -294,7 +295,7 @@ module Publish = let json = projDir "package.json" |> readFile - |> Fable.Core.JS.JSON.parse + |> JS.JSON.parse json?version let bumpNpmVersion projDir newVersion = @@ -362,7 +363,7 @@ module Publish = let pushNpm (projDir: string) buildAction = let checkPkgVersion json: string option = - (Fable.Core.JS.JSON.parse json)?version |> Option.ofObj + (JS.JSON.parse json)?version |> Option.ofObj let releaseVersion = loadReleaseVersion projDir if needsPublishing checkPkgVersion releaseVersion (projDir "package.json") then buildAction() @@ -387,7 +388,7 @@ let pushNpm projDir buildAction = Publish.pushNpm projDir buildAction let getDotNetSDKVersionFromGlobalJson(): string = - let json = readFile "global.json" |> Fable.Core.JS.JSON.parse + let json = readFile "global.json" |> JS.JSON.parse json?sdk?version let installDotnetSdk() =