11module Fable.FSharp2Fable.Compiler
22
3+ #if ! FABLE_ COMPILER
34open System.IO
5+ #endif
46open System.Collections .Generic
57open System.Text .RegularExpressions
68
@@ -22,10 +24,10 @@ open Util
2224let private (| SpecialValue | _ |) com ctx = function
2325 | BasicPatterns.ILFieldGet ( None, typ, fieldName) as fsExpr when typ.HasTypeDefinition ->
2426 match typ.TypeDefinition.TryFullName, fieldName with
25- | Some " System.String" , " Empty" -> Some ( makeConst " " )
26- | Some " System.Guid" , " Empty" -> Some ( makeConst " 00000000-0000-0000-0000-000000000000" )
27+ | Some " System.String" , " Empty" -> Some ( makeStrConst " " )
28+ | Some " System.Guid" , " Empty" -> Some ( makeStrConst " 00000000-0000-0000-0000-000000000000" )
2729 | Some " System.TimeSpan" , " Zero" ->
28- Fable.Wrapped( makeConst 0 , makeType com ctx.typeArgs fsExpr.Type) |> Some
30+ Fable.Wrapped( makeIntConst 0 , makeType com ctx.typeArgs fsExpr.Type) |> Some
2931 | Some " System.DateTime" , " MaxValue"
3032 | Some " System.DateTime" , " MinValue" ->
3133 CoreLibCall( " Date" , Some ( Naming.lowerFirst fieldName), false , [])
@@ -132,7 +134,7 @@ and private transformNonListNewUnionCase com ctx (fsExpr: FSharpExpr) fsType uni
132134 | KeyValueUnion ->
133135 let key , value =
134136 match argExprs with
135- | [] -> lowerCaseName unionCase, makeConst true
137+ | [] -> lowerCaseName unionCase, makeBoolConst true
136138 | [ expr] -> lowerCaseName unionCase, expr
137139 | [ key; expr] when hasAtt Atts.erase unionCase.Attributes -> key, expr
138140 | _ -> FableError( " KeyValue Union Cases must have one or zero fields: " + unionType.FullName, range) |> raise
@@ -144,13 +146,13 @@ and private transformNonListNewUnionCase com ctx (fsExpr: FSharpExpr) fsType uni
144146 | PojoUnion ->
145147 List.zip ( Seq.toList unionCase.UnionCaseFields) argExprs
146148 |> List.map ( fun ( fi , e ) -> fi.Name, e)
147- |> List.append [ " type" , makeConst unionCase.Name]
149+ |> List.append [ " type" , makeStrConst unionCase.Name]
148150 |> makeJsObject ( Some range)
149151 | ListUnion ->
150152 failwithf " transformNonListNewUnionCase must not be used with List %O " range
151153 | OtherType ->
152154 let argExprs = [
153- makeConst unionCase.Name // Include Tag name in args
155+ makeStrConst unionCase.Name // Include Tag name in args
154156 Fable.Value( Fable.ArrayConst( Fable.ArrayValues argExprs, Fable.Any))
155157 ]
156158 buildApplyInfo com ctx ( Some range) unionType unionType ( unionType.FullName)
@@ -225,14 +227,14 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
225227
226228 | CreateEvent ( callee, eventName, meth, typArgs, methTypArgs, methArgs) ->
227229 let callee , args = com.Transform ctx callee, List.map ( com.Transform ctx) methArgs
228- let callee = Fable.Apply( callee, [ makeConst eventName], Fable.ApplyGet, Fable.Any, None)
230+ let callee = Fable.Apply( callee, [ makeStrConst eventName], Fable.ApplyGet, Fable.Any, None)
229231 let r , typ = makeRangeFrom fsExpr, makeType com ctx.typeArgs fsExpr.Type
230232 makeCallFrom com ctx r typ meth ( typArgs, methTypArgs) ( Some callee) args
231233
232- | CheckArrayLength ( Transform com ctx arr, length) ->
234+ | CheckArrayLength ( Transform com ctx arr, length, FableType com ctx typ ) ->
233235 let r = makeRangeFrom fsExpr
234- let lengthExpr = Fable.Apply( arr, [ makeConst " length" ], Fable.ApplyGet, Fable.Number Int32, r)
235- makeEqOp r [ lengthExpr; makeConst length] BinaryEqualStrict
236+ let lengthExpr = Fable.Apply( arr, [ makeStrConst " length" ], Fable.ApplyGet, Fable.Number Int32, r)
237+ makeEqOp r [ lengthExpr; makeTypeConst typ length] BinaryEqualStrict
236238
237239 | PrintFormat ( Transform com ctx expr) -> expr
238240
@@ -250,7 +252,7 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
250252 ([ record], updatedFields)
251253 ||> List.fold ( fun acc ( FieldName fieldName , e ) ->
252254 let r , value = makeRangeFrom e, com.Transform ctx e
253- let e = Fable.Set( record, Some( makeConst fieldName), value, r)
255+ let e = Fable.Set( record, Some( makeStrConst fieldName), value, r)
254256 e:: acc)
255257 Fable.Sequential( assignments, r)
256258
@@ -280,20 +282,8 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
280282 |> makeLoop ( makeRangeFrom fsExpr)
281283
282284 (* * Values *)
283- // Arrays with small data (ushort, byte) won't fit the NewArray pattern
284- // as they would require too much memory
285- | BasicPatterns.Const(:? System.Array as arr, typ) ->
286- let arrExprs = [
287- for i in 0 .. ( arr.GetLength( 0 ) - 1 ) ->
288- arr.GetValue( i) |> makeConst
289- ]
290- match arr.GetType() .GetElementType() .FullName with
291- | NumberKind kind -> Fable.Number kind
292- | _ -> Fable.Any
293- |> makeArray <| arrExprs
294-
295285 | BasicPatterns.Const( value, FableType com ctx typ) ->
296- let e = makeConst value
286+ let e = makeTypeConst typ value
297287 if e.Type = typ then e
298288 // Enumerations are compiled as const but they have a different type
299289 else Fable.Wrapped ( e, typ)
@@ -457,29 +447,29 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
457447 | None -> makeType com ctx.typeArgs calleeType
458448 |> makeNonGenTypeRef com
459449 let r , typ = makeRangeFrom fsExpr, makeType com ctx.typeArgs fsExpr.Type
460- makeGetFrom com ctx r typ callee ( makeConst fieldName)
450+ makeGetFrom com ctx r typ callee ( makeStrConst fieldName)
461451
462452 | BasicPatterns.TupleGet (_ tupleType, tupleElemIndex, Transform com ctx tupleExpr) ->
463453 let r , typ = makeRangeFrom fsExpr, makeType com ctx.typeArgs fsExpr.Type
464- makeGetFrom com ctx r typ tupleExpr ( makeConst tupleElemIndex)
454+ makeGetFrom com ctx r typ tupleExpr ( makeIntConst tupleElemIndex)
465455
466456 | BasicPatterns.UnionCaseGet ( Transform com ctx unionExpr, fsType, unionCase, FieldName fieldName) ->
467457 let typ , range = makeType com ctx.typeArgs fsExpr.Type, makeRangeFrom fsExpr
468458 match fsType with
469459 | ErasedUnion | OptionUnion ->
470460 Fable.Wrapped( unionExpr, typ)
471461 | ListUnion ->
472- makeGet range typ unionExpr ( Naming.lowerFirst fieldName |> makeConst )
462+ makeGet range typ unionExpr ( Naming.lowerFirst fieldName |> makeStrConst )
473463 | PojoUnion ->
474- makeConst fieldName |> makeGet range typ unionExpr
464+ makeStrConst fieldName |> makeGet range typ unionExpr
475465 | KeyValueUnion ->
476466 FableError( " KeyValueUnion types cannot be used in pattern matching" , ?range= range) |> raise
477467 | StringEnum ->
478468 FableError( " StringEnum types cannot have fields" , ?range= range) |> raise
479469 | OtherType ->
480470 let i = unionCase.UnionCaseFields |> Seq.findIndex ( fun x -> x.Name = fieldName)
481- let fields = makeGet range typ unionExpr ( " Fields" |> makeConst )
482- makeGet range typ fields ( i |> makeConst )
471+ let fields = makeGet range typ unionExpr ( " Fields" |> makeStrConst )
472+ makeGet range typ fields ( i |> makeIntConst )
483473
484474 | BasicPatterns.ILFieldSet ( callee, typ, fieldName, value) ->
485475 failwithf " Unsupported ILField reference %O : %A " ( makeRange fsExpr.Range) fsExpr
@@ -489,11 +479,11 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
489479 match callee with
490480 | Some ( Transform com ctx callee) -> callee
491481 | None -> makeNonGenTypeRef com calleeType
492- Fable.Set ( callee, Some ( makeConst fieldName), value, makeRangeFrom fsExpr)
482+ Fable.Set ( callee, Some ( makeStrConst fieldName), value, makeRangeFrom fsExpr)
493483
494484 | BasicPatterns.UnionCaseTag ( Transform com ctx unionExpr, _ unionType) ->
495485 let r , typ = makeRangeFrom fsExpr, makeType com ctx.typeArgs fsExpr.Type
496- makeGetFrom com ctx r typ unionExpr ( makeConst " tag" )
486+ makeGetFrom com ctx r typ unionExpr ( makeStrConst " tag" )
497487
498488 | BasicPatterns.UnionCaseSet ( Transform com ctx unionExpr, _ type, _ case, _ caseField, _ valueExpr) ->
499489 makeRange fsExpr.Range |> failwithf " Unexpected UnionCaseSet %O "
@@ -640,8 +630,8 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
640630
641631 | BasicPatterns.UnionCaseTest( Transform com ctx unionExpr, fsType, unionCase) ->
642632 let checkCase name =
643- let left = makeGet None Fable.String unionExpr ( makeConst name)
644- let right = makeConst unionCase.Name
633+ let left = makeGet None Fable.String unionExpr ( makeStrConst name)
634+ let right = makeStrConst unionCase.Name
645635 makeBinOp ( makeRangeFrom fsExpr) Fable.Boolean [ left; right] BinaryEqualStrict
646636 match fsType with
647637 | ErasedUnion ->
@@ -665,7 +655,7 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
665655 makeBinOp ( makeRangeFrom fsExpr) Fable.Boolean [ unionExpr; Fable.Value Fable.Null] opKind
666656 | ListUnion ->
667657 let opKind = if unionCase.CompiledName = " Empty" then BinaryEqual else BinaryUnequal
668- let expr = makeGet None Fable.Any unionExpr ( makeConst " tail" )
658+ let expr = makeGet None Fable.Any unionExpr ( makeStrConst " tail" )
669659 makeBinOp ( makeRangeFrom fsExpr) Fable.Boolean [ expr; Fable.Value Fable.Null] opKind
670660 | StringEnum ->
671661 makeBinOp ( makeRangeFrom fsExpr) Fable.Boolean [ unionExpr; lowerCaseName unionCase] BinaryEqualStrict
@@ -678,30 +668,31 @@ and private transformExprWithRole (role: Role) (com: IFableCompiler) ctx fsExpr
678668
679669 (* * Pattern Matching *)
680670 | Switch( matchValue, cases, defaultCase, decisionTargets) ->
681- let transformCases assignVar =
671+ let transformCases caseType assignVar =
682672 let transformBody idx =
683673 let body = transformExpr com ctx ( snd decisionTargets.[ idx])
684674 match assignVar with
685675 | Some assignVar -> Fable.Set( assignVar, None, body, body.Range)
686676 | None -> body
687677 let cases =
688678 cases |> Seq.map ( fun kv ->
689- List.map makeConst kv.Value, transformBody kv.Key)
679+ List.map ( makeTypeConst caseType ) kv.Value, transformBody kv.Key)
690680 |> Seq.toList
691681 let defaultCase = transformBody defaultCase
692682 cases, defaultCase
693683 let matchValue =
694684 let t = makeType com ctx.typeArgs matchValue.FullType
695685 makeValueFrom com ctx None t UnknownRole matchValue
696686 let r , typ = makeRangeFrom fsExpr, makeType com ctx.typeArgs fsExpr.Type
687+ let caseType = matchValue.Type
697688 match typ with
698689 | Fable.Unit ->
699- let cases , defaultCase = transformCases None
690+ let cases , defaultCase = transformCases caseType None
700691 Fable.Switch( matchValue, cases, Some defaultCase, typ, r)
701692 | _ ->
702693 let assignVar = com.GetUniqueVar() |> makeIdent
703694 let cases , defaultCase =
704- Fable.IdentValue assignVar |> Fable.Value |> Some |> transformCases
695+ Fable.IdentValue assignVar |> Fable.Value |> Some |> transformCases caseType
705696 makeSequential r [
706697 Fable.VarDeclaration( assignVar, Fable.Value Fable.Null, true )
707698 Fable.Switch( matchValue, cases, Some defaultCase, typ, r)
@@ -1189,6 +1180,9 @@ let private getProjectMaps (com: ICompiler) (parsedProj: FSharpCheckProjectResul
11891180 // This dictionary must be mutable so `dict` cannot be used
11901181 let dic = Dictionary()
11911182 dic.Add( Naming.current, Map.empty)
1183+
1184+ #if FABLE_ COMPILER
1185+ #else
11921186 parsedProj.ProjectContext.GetReferencedAssemblies()
11931187 |> Seq.choose ( fun assembly ->
11941188 assembly.FileName |> Option.bind ( fun asmPath ->
@@ -1231,6 +1225,7 @@ let private getProjectMaps (com: ICompiler) (parsedProj: FSharpCheckProjectResul
12311225 dic.Add( asmPath, fableMap)
12321226 with _ -> ()
12331227 )
1228+ #endif
12341229 dic
12351230
12361231let transformFiles ( com : ICompiler ) ( parsedProj : FSharpCheckProjectResults ) ( projInfo : FSProjectInfo ) =
@@ -1239,8 +1234,8 @@ let transformFiles (com: ICompiler) (parsedProj: FSharpCheckProjectResults) (pro
12391234 ||> Map.findOrRun ( fun () -> getProjectMaps com parsedProj projInfo)
12401235 // Cache for entities and inline expressions
12411236 let entitiesCache = Dictionary< string, Fable.Entity>()
1242- let inlineExprsCache : Dictionary < string , Dictionary < FSharpMemberOrFunctionOrValue , int > * FSharpExpr > =
1243- Map.findOrNew " inline" projInfo.Extra
1237+ let newCache = fun () -> Dictionary< string, Dictionary< FSharpMemberOrFunctionOrValue, int> * FSharpExpr>()
1238+ let inlineExprsCache = Map.findOrRun newCache " inline" projInfo.Extra
12441239 // Start transforming files
12451240 let entryFile =
12461241 parsedProj.AssemblyContents.ImplementationFiles
0 commit comments