Skip to content

Commit

Permalink
#1294 #1367 new C# feature support
Browse files Browse the repository at this point in the history
  • Loading branch information
Jand42 committed Aug 3, 2024
1 parent 2908ef6 commit 13437a5
Show file tree
Hide file tree
Showing 11 changed files with 672 additions and 239 deletions.
2 changes: 1 addition & 1 deletion paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ strategy: min
storage: none

nuget Mono.Cecil ~> 0.11.0
nuget Microsoft.CodeAnalysis.CSharp ~> 4.0.1
nuget Microsoft.CodeAnalysis.CSharp ~> 4.8.0
nuget System.CodeDom 4.4.0
nuget System.Runtime.Loader 4.3.0
nuget System.Configuration.ConfigurationManager 4.7.0
Expand Down
44 changes: 23 additions & 21 deletions paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ NUGET
System.Collections.Immutable (>= 1.5)
System.Security.Permissions (>= 4.7)
System.Text.Encoding.CodePages (>= 4.0.1)
Microsoft.CodeAnalysis.Analyzers (3.3.2)
Microsoft.CodeAnalysis.Common (4.0.1)
Microsoft.CodeAnalysis.Analyzers (>= 3.3.2)
System.Collections.Immutable (>= 5.0)
System.Memory (>= 4.5.4)
System.Reflection.Metadata (>= 5.0)
System.Runtime.CompilerServices.Unsafe (>= 5.0)
System.Text.Encoding.CodePages (>= 4.5.1)
System.Threading.Tasks.Extensions (>= 4.5.4)
Microsoft.CodeAnalysis.CSharp (4.0.1)
Microsoft.CodeAnalysis.Common (4.0.1)
Microsoft.CodeAnalysis.Analyzers (3.3.4)
Microsoft.CodeAnalysis.Common (4.8)
Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
System.Collections.Immutable (>= 7.0)
System.Memory (>= 4.5.5) - restriction: || (&& (== net8.0) (< net6.0)) (== netstandard2.0)
System.Reflection.Metadata (>= 7.0)
System.Runtime.CompilerServices.Unsafe (>= 6.0)
System.Text.Encoding.CodePages (>= 7.0) - restriction: || (&& (== net8.0) (< net6.0)) (== netstandard2.0)
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net8.0) (< net6.0)) (== netstandard2.0)
Microsoft.CodeAnalysis.CSharp (4.8)
Microsoft.CodeAnalysis.Common (4.8)
Microsoft.CSharp (4.7)
Microsoft.DotNet.PlatformAbstractions (2.0)
System.AppContext (>= 4.1)
Expand Down Expand Up @@ -83,7 +83,7 @@ NUGET
Microsoft.Net.Http.Headers (2.0)
Microsoft.Extensions.Primitives (>= 2.0)
System.Buffers (>= 4.4)
Microsoft.NETCore.Platforms (2.1.2)
Microsoft.NETCore.Platforms (1.1)
Microsoft.NETCore.Targets (1.1)
Microsoft.TypeScript.MSBuild (4.9.4)
Microsoft.Win32.Registry (4.3)
Expand Down Expand Up @@ -169,8 +169,9 @@ NUGET
System.Runtime.Extensions (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Collections.Immutable (5.0)
System.Memory (>= 4.5.4) - restriction: || (&& (== net8.0) (>= net461)) (&& (== net8.0) (< netcoreapp2.1)) (&& (== net8.0) (< netstandard2.0)) (&& (== net8.0) (>= uap10.1)) (== netstandard2.0)
System.Collections.Immutable (7.0)
System.Memory (>= 4.5.5) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (== netstandard2.0)
System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (&& (== net8.0) (< net7.0)) (== netstandard2.0)
System.Configuration.ConfigurationManager (4.7)
System.Security.Cryptography.ProtectedData (>= 4.7)
System.Security.Permissions (>= 4.7)
Expand Down Expand Up @@ -267,7 +268,7 @@ NUGET
System.Runtime (>= 4.1)
System.Runtime.Extensions (>= 4.1)
System.Threading (>= 4.0.11)
System.Memory (4.5.5)
System.Memory (4.5.5) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (== netstandard2.0)
System.Buffers (>= 4.5.1) - restriction: || (&& (== net8.0) (>= monotouch)) (&& (== net8.0) (>= net461)) (&& (== net8.0) (< netcoreapp2.0)) (&& (== net8.0) (< netstandard1.1)) (&& (== net8.0) (< netstandard2.0)) (&& (== net8.0) (>= xamarinios)) (&& (== net8.0) (>= xamarinmac)) (&& (== net8.0) (>= xamarintvos)) (&& (== net8.0) (>= xamarinwatchos)) (== netstandard2.0)
System.Numerics.Vectors (>= 4.4) - restriction: || (&& (== net8.0) (< netcoreapp2.0)) (== netstandard2.0)
System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (== net8.0) (>= monotouch)) (&& (== net8.0) (>= net461)) (&& (== net8.0) (< netcoreapp2.0)) (&& (== net8.0) (< netcoreapp2.1)) (&& (== net8.0) (< netstandard1.1)) (&& (== net8.0) (< netstandard2.0)) (&& (== net8.0) (>= uap10.1)) (&& (== net8.0) (>= xamarinios)) (&& (== net8.0) (>= xamarinmac)) (&& (== net8.0) (>= xamarintvos)) (&& (== net8.0) (>= xamarinwatchos)) (== netstandard2.0)
Expand Down Expand Up @@ -303,7 +304,7 @@ NUGET
Microsoft.NETCore.Targets (>= 1.1)
System.Runtime (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.Numerics.Vectors (4.5) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netcoreapp2.0)) (== netstandard2.0)
System.Numerics.Vectors (4.4) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netcoreapp2.0)) (== netstandard2.0)
System.ObjectModel (4.0.12)
System.Collections (>= 4.0.11)
System.Diagnostics.Debug (>= 4.0.11)
Expand All @@ -330,8 +331,9 @@ NUGET
Microsoft.NETCore.Targets (>= 1.0.1)
System.Reflection (>= 4.1)
System.Runtime (>= 4.1)
System.Reflection.Metadata (5.0)
System.Collections.Immutable (>= 5.0) - restriction: || (&& (== net8.0) (>= net461)) (&& (== net8.0) (< net5.0)) (&& (== net8.0) (< netstandard1.1)) (&& (== net8.0) (< netstandard2.0)) (== netstandard2.0)
System.Reflection.Metadata (7.0)
System.Collections.Immutable (>= 7.0)
System.Memory (>= 4.5.5) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (== netstandard2.0)
System.Reflection.Primitives (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
Expand Down Expand Up @@ -498,9 +500,9 @@ NUGET
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
System.Runtime (>= 4.3)
System.Text.Encoding.CodePages (4.5.1)
Microsoft.NETCore.Platforms (>= 2.1.2) - restriction: || (== net8.0) (&& (== netstandard2.0) (>= netcoreapp2.0))
System.Runtime.CompilerServices.Unsafe (>= 4.5.2)
System.Text.Encoding.CodePages (7.0)
System.Memory (>= 4.5.5) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (== netstandard2.0)
System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (&& (== net8.0) (< net7.0)) (== netstandard2.0)
System.Text.Encoding.Extensions (4.0.11)
Microsoft.NETCore.Platforms (>= 1.0.1)
Microsoft.NETCore.Targets (>= 1.0.1)
Expand Down
122 changes: 122 additions & 0 deletions src/compiler/WebSharper.Compiler.CSharp/CodeReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,34 @@ module Definitions =
([] : list<Expression>),
(id : Expression -> Expression)

let SeqModule =
TypeDefinition {
Assembly = "FSharp.Core"
FullName = "Microsoft.FSharp.Collections.SeqModule"
}

let SeqType =
TypeDefinition {
Assembly = "netstandard"
FullName = "System.Collections.Generic.IEnumerable`1"
}

let SeqIter =
Method {
MethodName = "Iterate"
Parameters = [ FSharpFuncType(TypeParameter 0, VoidType); GenericType SeqType [TypeParameter 0] ]
ReturnType = VoidType
Generics = 1
}

let SeqLength =
Method {
MethodName = "Length"
Parameters = [ GenericType SeqType [TypeParameter 0] ]
ReturnType = NonGenericType Definitions.Int
Generics = 1
}

type RoslynTransformer(env: Environment) =
let getConstantValueOfExpression x =
let l =
Expand Down Expand Up @@ -790,6 +818,7 @@ type RoslynTransformer(env: Environment) =
| ExpressionData.RangeExpression x -> this.TransformRangeExpression x
| ExpressionData.SwitchExpression x -> this.TransformSwitchExpression x
| ExpressionData.WithExpression x -> this.TransformWithExpression x
| ExpressionData.CollectionExpression x -> this.TransformCollectionExpression x
let conversion = env.SemanticModel.GetConversion(x.Node)
if conversion.IsUserDefined then
let symbol = conversion.MethodSymbol
Expand Down Expand Up @@ -825,6 +854,7 @@ type RoslynTransformer(env: Environment) =
| TypeData.TupleType x -> TODO x //this.TransformTupleType x
| TypeData.OmittedTypeArgument x -> TODO x //this.TransformOmittedTypeArgument x
| TypeData.RefType x -> TODO x //this.TransformRefType x
| TypeData.ScopedType x -> TODO x //this.TransformScopedType x

member this.TransformName (x: NameData) : Expression =
match x with
Expand Down Expand Up @@ -1345,6 +1375,8 @@ type RoslynTransformer(env: Environment) =
MutatingBinaryOperator.``>>=``
| AssignmentExpressionKind.CoalesceAssignmentExpression ->
MutatingBinaryOperator.``??=``
| AssignmentExpressionKind.UnsignedRightShiftAssignmentExpression ->
MutatingBinaryOperator.``>>>=``
MutatingBinary(left, op, right) |> Some
| _ -> None
else None
Expand Down Expand Up @@ -2674,6 +2706,42 @@ type RoslynTransformer(env: Environment) =
let pattern = x.Pattern |> this.TransformPattern
fun v -> Unary(UnaryOperator.``!``, pattern v)

member this.TransformListPattern (x: ListPatternData) : _ =
let patterns = x.Patterns |> Seq.map this.TransformPattern |> List.ofSeq
let designation = x.Designation |> Option.map this.TransformVariableDesignation
let typ = env.SemanticModel.GetTypeInfo(x.Node).ConvertedType

let getItem =
if typ.TypeKind = TypeKind.Array then
fun v i ->
ItemGet(Var v, Value (Int i), Pure)
else
let itemMeth =
match typ.GetMembers("get_Item").OfType<IMethodSymbol>() |> Seq.tryHead with
| Some m -> m |> sr.ReadMethod
| None -> failwith "List patterns are only supported for types defining Item property"
let td = typ |> sr.ReadType
fun v i ->
Call (Some (Var v), NonGeneric td.TypeDefinition, NonGeneric itemMeth, [ Value (Int i) ])

fun v ->
let sliceIdx = x.Patterns |> Seq.tryFindIndex (function PatternData.SlicePattern _ -> true | _ -> false)
match sliceIdx with
| None ->
let length = List.length patterns
List.reduce (^&&) [
Call(None, NonGeneric Definitions.SeqModule, NonGeneric Definitions.SeqLength, [ Var v ]) ^== (Value (Int length))
for i, p in Seq.indexed patterns do
let e = Id.New(mut = false)
Let (e, getItem v i, p e)
]
| Some sliceIdx ->
Expression.Undefined // todo list pattern with slice

member this.TransformSlicePattern (x: SlicePatternData) : _ =
let pattern = x.Pattern |> Option.map this.TransformPattern
fun v -> Expression.Undefined

member this.TransformPattern (x: PatternData) : _ =
match x with
| PatternData.DiscardPattern x -> this.TransformDiscardPattern x
Expand All @@ -2686,6 +2754,8 @@ type RoslynTransformer(env: Environment) =
| PatternData.TypePattern x -> this.TransformTypePattern x
| PatternData.BinaryPattern x -> this.TransformBinaryPattern x
| PatternData.UnaryPattern x -> this.TransformUnaryPattern x
| PatternData.ListPattern x -> this.TransformListPattern x
| PatternData.SlicePattern x -> this.TransformSlicePattern x

member this.TransformIsPatternExpression (x: IsPatternExpressionData) : _ =
let expression = x.Expression |> this.TransformExpression
Expand Down Expand Up @@ -2757,6 +2827,58 @@ type RoslynTransformer(env: Environment) =
let initializer = x.Initializer |> RoslynTransformer(env.WithInitializing(o)).TransformInitializerExpression
Let(o, JSRuntime.Clone(expression), Sequential [initializer; Var o])

member this.TransformExpressionElement (x: ExpressionElementData) : _ =
let expression = x.Expression |> this.TransformExpression
expression, false

member this.TransformSpreadElement (x: SpreadElementData) : _ =
let expression = x.Expression |> this.TransformExpression
expression, true

member this.TransformCollectionElement (x: CollectionElementData) : _ =
match x with
| CollectionElementData.ExpressionElement x -> this.TransformExpressionElement x
| CollectionElementData.SpreadElement x -> this.TransformSpreadElement x

member this.TransformCollectionExpression (x: CollectionExpressionData) : _ =
let elements = x.Elements |> Seq.map this.TransformCollectionElement |> List.ofSeq

let iocType = env.SemanticModel.GetTypeInfo(x.Node).ConvertedType
let coll = Id.New(mut = false)
let x = Id.New(mut = false)

let iocTypOpt =
match iocType with
| :? INamedTypeSymbol as nt -> Some (sr.ReadNamedType nt)
| _ -> None

let emptyColl, addItem =
if iocType.TypeKind = TypeKind.Array then
NewArray [],
fun item -> ApplAny(ItemGet(Var coll, Value (String "push"), Pure), [ item ])
else
let addSymbol =
let addMethods = iocType.GetMembers("Add").OfType<IMethodSymbol>() |> Array.ofSeq
if addMethods.Length = 1 then
addMethods.[0]
else
failwith "Collection initializer for collection expression only supported with a non-overloaded Add method"
let addM = addSymbol |> sr.ReadGenericMethod
Ctor(iocTypOpt.Value, ConstructorInfo.Default(), []),
fun item -> Call(Some (Var coll), iocTypOpt.Value, addM, [ item ])

Let(coll, emptyColl,
Sequential [
for (e, isSpread) in elements do
if isSpread then
Call(None, NonGeneric Definitions.SeqModule, NonGeneric Definitions.SeqIter,
[ Lambda([x], None, addItem (Var x)); e ])
else
addItem e
Var coll
]
)

open System.Linq

let rec private isWebControlType (sr: SymbolReader) (c: INamedTypeSymbol) =
Expand Down
Loading

0 comments on commit 13437a5

Please sign in to comment.