Skip to content

Commit

Permalink
Merge branch 'main' into missing-xml-doc-for-member-getset
Browse files Browse the repository at this point in the history
  • Loading branch information
vzarytovskii authored Sep 15, 2022
2 parents 73cdd5c + b4ef994 commit d3bf71c
Show file tree
Hide file tree
Showing 35 changed files with 1,090 additions and 873 deletions.
3 changes: 3 additions & 0 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4303,6 +4303,9 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn
| SynType.LongIdent synLongId ->
TcLongIdentType kindOpt cenv newOk checkConstraints occ iwsam env tpenv synLongId

| MultiDimensionArrayType (rank, elemTy, m) ->
TcElementType cenv newOk checkConstraints occ env tpenv rank elemTy m

| SynType.App (StripParenTypes (SynType.LongIdent longId), _, args, _, _, postfix, m) ->
TcLongIdentAppType kindOpt cenv newOk checkConstraints occ iwsam env tpenv longId postfix args m

Expand Down
51 changes: 35 additions & 16 deletions src/Compiler/Checking/NicePrint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,11 @@ module internal PrintUtilities =
let isArray = not prefix && isArrayTyconRef denv.g tcref
let demangled =
if isArray then
tcref.DisplayNameCore // no backticks for arrays "int[]"
let numberOfCommas = tcref.CompiledName |> Seq.filter (fun c -> c = ',') |> Seq.length
if numberOfCommas = 0 then
"array"
else
$"array{numberOfCommas + 1}d"
else
let name =
if denv.includeStaticParametersInTypeNames then
Expand All @@ -198,11 +202,7 @@ module internal PrintUtilities =
tagEntityRefName denv tcref demangled
|> mkNav tcref.DefinitionRange

let tyconTextL =
if isArray then
tyconTagged |> rightL
else
tyconTagged |> wordL
let tyconTextL = tyconTagged |> wordL

if denv.shortTypeNames then
tyconTextL
Expand Down Expand Up @@ -562,19 +562,22 @@ module PrintTypes =
| _ -> comment "(* unsupported attribute argument *)"

/// Layout arguments of an attribute 'arg1, ..., argN'
and layoutAttribArgs denv args =
and layoutAttribArgs denv args props =
let argsL = args |> List.map (fun (AttribExpr(e1, _)) -> layoutAttribArg denv e1)
sepListL (rightL (tagPunctuation ",")) argsL
let propsL =
props
|> List.map (fun (AttribNamedArg(name,_, _, AttribExpr(e1, _))) ->
wordL (tagProperty name) ^^ WordL.equals ^^ layoutAttribArg denv e1)
sepListL (rightL (tagPunctuation ",")) (argsL @ propsL)

/// Layout an attribute 'Type(arg1, ..., argN)'
//
// REVIEW: we are ignoring "props" here
and layoutAttrib denv (Attrib(tcref, _, args, _props, _, _, _)) =
and layoutAttrib denv (Attrib(tcref, _, args, props, _, _, _)) =
let tcrefL = layoutTyconRefImpl true denv tcref
let argsL = bracketL (layoutAttribArgs denv args)
match args with
| [] -> tcrefL
| _ -> tcrefL ++ argsL
let argsL = bracketL (layoutAttribArgs denv args props)
if List.isEmpty args && List.isEmpty props then
tcrefL
else
tcrefL ++ argsL

and layoutILAttribElement denv arg =
match arg with
Expand Down Expand Up @@ -873,6 +876,16 @@ module PrintTypes =
| [arg] -> layoutTypeWithInfoAndPrec denv env 2 arg ^^ tcL
| args -> bracketIfL (prec <= 1) (bracketL (layoutTypesWithInfoAndPrec denv env 2 (sepL (tagPunctuation ",")) args) --- tcL)

and layoutTypeForGenericMultidimensionalArrays denv env prec tcref innerT level =
let innerLayout = layoutTypeWithInfoAndPrec denv env prec innerT

let arrayLayout =
tagEntityRefName denv tcref $"array{level}d"
|> mkNav tcref.DefinitionRange
|> wordL

innerLayout ^^ arrayLayout

/// Layout a type, taking precedence into account to insert brackets where needed
and layoutTypeWithInfoAndPrec denv env prec ty =
let g = denv.g
Expand All @@ -893,6 +906,10 @@ module PrintTypes =
// Always prefer 'float' to 'float<1>'
| TType_app (tc, args, _) when tc.IsMeasureableReprTycon && List.forall (isDimensionless g) args ->
layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided g tc args)

// Special case for nested array<array<'t>> shape
| TTypeMultiDimensionalArrayAsGeneric (tcref, innerT, level) ->
layoutTypeForGenericMultidimensionalArrays denv env prec tcref innerT level

// Layout a type application
| TType_ucase (UnionCaseRef(tc, _), args)
Expand Down Expand Up @@ -2387,7 +2404,9 @@ module InferredSigPrinting =
let nmL = layoutAccessibility denv mspec.Accessibility nmL
let denv = denv.AddAccessibility mspec.Accessibility
let basic = imdefL denv def
let modNameL = wordL (tagKeyword "module") ^^ nmL
let modNameL =
wordL (tagKeyword "module") ^^ nmL
|> layoutAttribs denv None false mspec.TypeOrMeasureKind mspec.Attribs
let modNameEqualsL = modNameL ^^ WordL.equals
let isNamespace = function | Namespace _ -> true | _ -> false
let modIsOuter = (outerPath |> List.forall (fun (_, istype) -> isNamespace istype) )
Expand Down
16 changes: 16 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,3 +1059,19 @@ let getTypeFromTuplePath (path: SynTupleTypeSegment list) : SynType list =
|> List.choose (function
| SynTupleTypeSegment.Type t -> Some t
| _ -> None)

let (|MultiDimensionArrayType|_|) (t: SynType) =
match t with
| SynType.App (StripParenTypes (SynType.LongIdent (SynLongIdent ([ identifier ], _, _))), _, [ elementType ], _, _, true, m) ->
if System.Text.RegularExpressions.Regex.IsMatch(identifier.idText, "^array\d\d?d$") then
let rank =
identifier.idText
|> Seq.filter System.Char.IsDigit
|> Seq.toArray
|> System.String
|> int

Some(rank, elementType, m)
else
None
| _ -> None
2 changes: 2 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,5 @@ val normalizeTupleExpr: exprs: SynExpr list -> commas: range list -> SynExpr lis
val desugarGetSetMembers: memberDefns: SynMemberDefns -> SynMemberDefns

val getTypeFromTuplePath: path: SynTupleTypeSegment list -> SynType list

val (|MultiDimensionArrayType|_|): t: SynType -> (int * SynType * range) option
16 changes: 15 additions & 1 deletion src/Compiler/TypedTree/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10384,7 +10384,7 @@ let (|EmptyModuleOrNamespaces|_|) (moduleOrNamespaceContents: ModuleOrNamespaceC
| ModuleOrNamespaceContents.TMDefRec _
| ModuleOrNamespaceContents.TMDefs _ -> true
| _ -> false)

let emptyModuleOrNamespaces =
defs
|> List.choose (function
Expand All @@ -10407,3 +10407,17 @@ let (|EmptyModuleOrNamespaces|_|) (moduleOrNamespaceContents: ModuleOrNamespaceC
else
None
| _ -> None

let (|TTypeMultiDimensionalArrayAsGeneric|_|) (t: TType) =
let rec (|Impl|_|) t =
match t with
| TType_app(tc, [Impl(outerTc, innerT, currentLevel)], _) when tc.DisplayNameCore = "array" ->
Some (outerTc, innerT, currentLevel + 1)
| TType_app(tc, [arg], _) when tc.DisplayNameCore = "array" ->
Some (tc, arg, 1)
| _ -> None

match t with
| Impl (tc, arg, level) ->
if level > 2 then Some (tc, arg, level) else None
| _ -> None
3 changes: 3 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2687,3 +2687,6 @@ type TraitConstraintInfo with
/// This will match anything that does not have any types or bindings.
val (|EmptyModuleOrNamespaces|_|):
moduleOrNamespaceContents: ModuleOrNamespaceContents -> (ModuleOrNamespace list) option

/// Captures an application type with a multi-dimensional array as postfix.
val (|TTypeMultiDimensionalArrayAsGeneric|_|): t: TType -> (TyconRef * TType * int) option
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
<PackageDescription>.NET Core compatible version of the F# compiler fsc.exe.</PackageDescription>
<PackageReleaseNotes>/blob/main/release-notes.md#FSharp-Tools-$(FSProductVersionReleaseNotesVersion)</PackageReleaseNotes>
<NoDefaultExcludes>true</NoDefaultExcludes>
<!-- Workaround to get rid of:
error NU1505: Duplicate 'PackageDownload' items found.
Remove the duplicate items or use the Update functionality to ensure a consistent restore behavior.
The duplicate 'PackageDownload' items are:
Microsoft.NETCore.App.Host.win-x64 [6.0.2], Microsoft.NETCore.App.Host.win-x64 [6.0.2], Microsoft.NETCore.App.Host.win-x64 [6.0.2], Microsoft.NETCore.App.Host.win-x64 [6.0.2].
-->
<NoWarn>$(NoWarn);NU1505</NoWarn>
</PropertyGroup>

<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ module Basic =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 1, Line 10, Col 3, Line 10, Col 59, "This expression was expected to have type\n 'int[]' \nbut here has type\n 'unit' ")
(Error 1, Line 10, Col 3, Line 10, Col 59, "This expression was expected to have type\n 'int array' \nbut here has type\n 'unit' ")
(Error 267, Line 10, Col 3, Line 10, Col 59, "This is not a valid constant expression or custom attribute value")
(Error 850, Line 10, Col 3, Line 10, Col 59, "This attribute cannot be used in this version of F#")
(Error 850, Line 13, Col 3, Line 13, Col 52, "This attribute cannot be used in this version of F#")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ module MethodsAndProperties =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 1, Line 11, Col 24, Line 11, Col 33, "This expression was expected to have type\n ''a[,]' \nbut here has type\n 'int[]' ")
(Error 1, Line 12, Col 25, Line 12, Col 32, "This expression was expected to have type\n ''a[]' \nbut here has type\n 'int[,]' ")
(Error 1, Line 13, Col 26, Line 13, Col 37, "This expression was expected to have type\n ''a[]' \nbut here has type\n 'int[,,]' ")
(Error 1, Line 14, Col 27, Line 14, Col 38, "This expression was expected to have type\n ''a[]' \nbut here has type\n 'int[,,,]' ")
(Error 1, Line 11, Col 24, Line 11, Col 33, "This expression was expected to have type\n ''a array2d' \nbut here has type\n 'int array' ")
(Error 1, Line 12, Col 25, Line 12, Col 32, "This expression was expected to have type\n ''a array' \nbut here has type\n 'int array2d' ")
(Error 1, Line 13, Col 26, Line 13, Col 37, "This expression was expected to have type\n ''a array' \nbut here has type\n 'int array3d' ")
(Error 1, Line 14, Col 27, Line 14, Col 38, "This expression was expected to have type\n ''a array' \nbut here has type\n 'int array4d' ")
]

// SOURCE=E_IndexerArityMismatch02.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_IndexerArityMismatch02.fs
Expand All @@ -110,10 +110,10 @@ module MethodsAndProperties =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 1, Line 11, Col 24, Line 11, Col 35, "This expression was expected to have type\n ''a[,,]' \nbut here has type\n 'int[]' ")
(Error 1, Line 12, Col 25, Line 12, Col 32, "This expression was expected to have type\n ''a[]' \nbut here has type\n 'int[,]' ")
(Error 1, Line 13, Col 27, Line 13, Col 38, "This expression was expected to have type\n ''a[,,]' \nbut here has type\n 'int[,,,]' ")
(Error 1, Line 14, Col 27, Line 14, Col 36, "This expression was expected to have type\n ''a[,]' \nbut here has type\n 'int[,,,]' ")
(Error 1, Line 11, Col 24, Line 11, Col 35, "This expression was expected to have type\n ''a array3d' \nbut here has type\n 'int array' ")
(Error 1, Line 12, Col 25, Line 12, Col 32, "This expression was expected to have type\n ''a array' \nbut here has type\n 'int array2d' ")
(Error 1, Line 13, Col 27, Line 13, Col 38, "This expression was expected to have type\n ''a array3d' \nbut here has type\n 'int array4d' ")
(Error 1, Line 14, Col 27, Line 14, Col 36, "This expression was expected to have type\n ''a array2d' \nbut here has type\n 'int array4d' ")
]

// SOURCE=E_IndexerIndeterminateType01.fs SCFLAGS=--test:ErrorRanges # E_IndexerIndeterminateType01.fs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ module RecordTypes =
|> verifyTypeCheck
|> shouldFail
|> withDiagnostics [
(Error 1, Line 7, Col 17, Line 7, Col 47, "This expression was expected to have type\n 'int[]' \nbut here has type\n 'RecType' ")
(Error 1, Line 7, Col 17, Line 7, Col 47, "This expression was expected to have type\n 'int array' \nbut here has type\n 'RecType' ")
]

// SOURCE=E_RecordsNotNull01.fs # E_RecordsNotNull01.fs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@
<Compile Include="Signatures\TestHelpers.fs" />
<Compile Include="Signatures\ModuleOrNamespaceTests.fs" />
<Compile Include="Signatures\RecordTests.fs" />
<Compile Include="Signatures\ArrayTests.fs" />
</ItemGroup>
<ItemGroup>
<Content Include="resources\**" CopyToOutputDirectory="Never" CopyToPublishDirectory="PreserveNewest" />
Expand Down
51 changes: 51 additions & 0 deletions tests/FSharp.Compiler.ComponentTests/Signatures/ArrayTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module FSharp.Compiler.ComponentTests.Signatures.SignatureTests

open Xunit
open FSharp.Compiler.ComponentTests.Signatures.TestHelpers

[<Theory>]
[<InlineData("let a : int[] = [| 1 |]",
"val a: int array")>]
[<InlineData("let b: int array = [| 2 |]",
"val b: int array")>]
[<InlineData("let c: array<int> = [| 3 |]",
"val c: int array")>]
let ``Value with int array return type`` implementation expectedSignature =
assertSingleSignatureBinding implementation expectedSignature

[<Fact>]
let ``2 dimensional array`` () =
assertSingleSignatureBinding
"let a : int[,] = failwith \"todo\""
"val a: int array2d"

[<Fact>]
let ``3 dimensional array`` () =
assertSingleSignatureBinding
"let a : int[,,] = failwith \"todo\""
"val a: int array3d"

[<Fact>]
let ``4 dimensional array`` () =
assertSingleSignatureBinding
"let a : int[,,,] = failwith \"todo\""
"val a: int array4d"

[<Fact>]
let ``5 till 32 dimensional array`` () =
[ 5 .. 32 ]
|> List.iter (fun idx ->
let arrayType =
[ 1 .. idx ]
|> List.fold (fun acc _ -> $"array<{acc}>") "int"

assertSingleSignatureBinding
$"let a : {arrayType} = failwith \"todo\""
$"val a: int array{idx}d"
)

[<Fact>]
let ``Use array2d syntax in implementation`` () =
assertSingleSignatureBinding
"let y : int array2d = Array2D.init 0 0 (fun _ _ -> 0)"
"val y: int array2d"
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,25 @@ do ()
"""
|> printSignatures
|> should equal "namespace Foobar"

[<Fact>]
let ``Attribute on nested module`` () =
FSharp
"""
namespace MyApp.Types
[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Area =
type Meh = class end
"""
|> printSignatures
|> prependNewline
|> should equal """
namespace MyApp.Types
[<RequireQualifiedAccess; CompilationRepresentation (enum<CompilationRepresentationFlags> (4))>]
module Area =
type Meh =
class end"""
62 changes: 62 additions & 0 deletions tests/FSharp.Compiler.ComponentTests/Signatures/RecordTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,65 @@ type PullActions =
/// Any repo which doesn't have a master branch will have one created for it.
Log: int
}"""

[<Fact>]
let ``Attribute on record field with argument`` () =
FSharp
"""
namespace MyApp.Types
open System
type SomeEnum =
| ValueOne = 1
| ValueTwo = 2
| ValueThree = 3
[<AttributeUsage(AttributeTargets.All)>]
type MyAttribute() =
inherit System.Attribute()
member val SomeValue: SomeEnum = SomeEnum.ValueOne with get, set
type SomeTypeName =
{
/// Some Xml doc
FieldOne : string
[<MyAttribute(SomeValue = SomeEnum.ValueTwo)>]
FieldTwo : string list
/// Some other Xml doc
[<MyAttribute(SomeValue = SomeEnum.ValueThree)>]
FieldThree : string
}
"""
|> printSignatures
|> prependNewline
|> should equal
"""
namespace MyApp.Types
[<Struct>]
type SomeEnum =
| ValueOne = 1
| ValueTwo = 2
| ValueThree = 3
[<System.AttributeUsage (enum<System.AttributeTargets> (32767))>]
type MyAttribute =
inherit System.Attribute
new: unit -> MyAttribute
member SomeValue: SomeEnum
type SomeTypeName =
{
/// Some Xml doc
FieldOne: string
[<My (SomeValue = enum<SomeEnum> (2))>]
FieldTwo: string list
/// Some other Xml doc
[<My (SomeValue = enum<SomeEnum> (3))>]
FieldThree: string
}"""
Loading

0 comments on commit d3bf71c

Please sign in to comment.