Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4353,7 +4353,8 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn
| SynType.App(arg1, _, args, _, _, postfix, m) ->
TcTypeMeasureApp kindOpt cenv newOk checkConstraints occ env tpenv arg1 args postfix m

| SynType.Paren(innerType, _) ->
| SynType.Paren(innerType, _)
| SynType.SignatureParameter(usedType = innerType) ->
TcTypeOrMeasure kindOpt cenv newOk checkConstraints occ iwsam env tpenv innerType

and CheckIWSAM (cenv: cenv) (env: TcEnv) checkConstraints iwsam m tcref =
Expand Down
9 changes: 7 additions & 2 deletions src/Compiler/Service/ServiceParseTreeWalk.fs
Original file line number Diff line number Diff line change
Expand Up @@ -823,8 +823,13 @@ module SyntaxTraversal =
| SynType.MeasureDivide (ty1, ty2, _) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path)
| SynType.Tuple (path = segments) -> getTypeFromTuplePath segments |> List.tryPick (traverseSynType path)
| SynType.StaticConstantExpr (expr, _) -> traverseSynExpr [] expr
| SynType.Anon _ -> None
| _ -> None
| SynType.Paren (innerType = t)
| SynType.SignatureParameter (usedType = t) -> traverseSynType path t
| SynType.Anon _
| SynType.AnonRecd _
| SynType.LongIdent _
| SynType.Var _
| SynType.StaticConstant _ -> None

visitor.VisitType(origPath, defaultTraverse, ty)

Expand Down
23 changes: 19 additions & 4 deletions src/Compiler/Service/ServiceParsedInputOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,15 @@ module ParsedInput =
| SynType.HashConstraint (t, _) -> walkType t
| SynType.MeasureDivide (t1, t2, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.MeasurePower (t, _, _) -> walkType t
| SynType.Paren (t, _) -> walkType t
| _ -> None
| SynType.Paren (t, _)
| SynType.SignatureParameter (usedType = t) -> walkType t
| SynType.StaticConstantExpr (e, _) -> walkExpr e
| SynType.StaticConstantNamed (ident, value, _) -> List.tryPick walkType [ ident; value ]
| SynType.Anon _
| SynType.AnonRecd _
| SynType.LongIdent _
| SynType.Var _
| SynType.StaticConstant _ -> None

and walkClause clause =
let (SynMatchClause (pat = pat; whenExpr = e1; resultExpr = e2)) = clause
Expand Down Expand Up @@ -1661,7 +1668,8 @@ module ParsedInput =
| SynType.Array (_, t, _)
| SynType.HashConstraint (t, _)
| SynType.MeasurePower (t, _, _)
| SynType.Paren (t, _) -> walkType t
| SynType.Paren (t, _)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also adjust

  • traverseSynType in ServiceParseTreeWalk
  • walkType in GetEntityKind (what is that funciton anyway? It has so much code walking duplication!)

Maybe also remove the default | _ -> pattern matching in those two cases so these missing cases would have been discovered, and check for other missing cases there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've addressed the missing cases.

| SynType.SignatureParameter (usedType = t) -> walkType t
| SynType.Fun (argType = t1; returnType = t2)
| SynType.MeasureDivide (t1, t2, _) ->
walkType t1
Expand All @@ -1675,7 +1683,14 @@ module ParsedInput =
| SynType.WithGlobalConstraints (t, typeConstraints, _) ->
walkType t
List.iter walkTypeConstraint typeConstraints
| _ -> ()
| SynType.StaticConstantExpr (e, _) -> walkExpr e
| SynType.StaticConstantNamed (ident, value, _) ->
walkType ident
walkType value
| SynType.Anon _
| SynType.AnonRecd _
| SynType.Var _
| SynType.StaticConstant _ -> ()

and walkClause (SynMatchClause (pat = pat; whenExpr = e1; resultExpr = e2)) =
walkPat pat
Expand Down
5 changes: 4 additions & 1 deletion src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ type SynType =

| Paren of innerType: SynType * range: range

| SignatureParameter of attributes: SynAttributes * optional: bool * id: Ident option * usedType: SynType * range: range

member x.Range =
match x with
| SynType.App (range = m)
Expand All @@ -452,7 +454,8 @@ type SynType =
| SynType.HashConstraint (range = m)
| SynType.MeasureDivide (range = m)
| SynType.MeasurePower (range = m)
| SynType.Paren (range = m) -> m
| SynType.Paren (range = m)
| SynType.SignatureParameter (range = m) -> m
| SynType.LongIdent lidwd -> lidwd.Range

[<NoEquality; NoComparison; RequireQualifiedAccess>]
Expand Down
8 changes: 8 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,14 @@ type SynType =

| Paren of innerType: SynType * range: range

/// F# syntax: a: b, used in signatures and type annotations
| SignatureParameter of
attributes: SynAttributes *
optional: bool *
id: Ident option *
usedType: SynType *
range: range

/// Gets the syntax range of this construct
member Range: range

Expand Down
17 changes: 12 additions & 5 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -5082,22 +5082,29 @@ topTupleTypeElements:
topAppType:
| attributes appType COLON appType
{ match $2 with
| SynType.LongIdent(SynLongIdent([id], _, _)) -> $4, SynArgInfo($1, false, Some id)
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
let m = rhs2 parseState 1 4
SynType.SignatureParameter($1, false, Some id, $4, m), SynArgInfo($1, false, Some id)
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }

| attributes QMARK ident COLON appType
{ $5, SynArgInfo($1, true, Some $3) }
{ let m = rhs2 parseState 1 5
SynType.SignatureParameter($1, true, Some $3, $5, m), SynArgInfo($1, true, Some $3) }

| attributes appType
{ ($2, SynArgInfo($1, false, None)) }
{ let m = rhs2 parseState 1 2
SynType.SignatureParameter($1, false, None, $2, m), SynArgInfo($1, false, None) }

| appType COLON appType
{ match $1 with
| SynType.LongIdent(SynLongIdent([id], _, _)) -> $3, SynArgInfo([], false, Some id)
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
let m = rhs2 parseState 1 3
SynType.SignatureParameter([], false, Some id, $3, m), SynArgInfo([], false, Some id)
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }

| QMARK ident COLON appType
{ $4, SynArgInfo([], true, Some $2) }
{ let m = rhs2 parseState 1 4
SynType.SignatureParameter([], true, Some $2, $4, m), SynArgInfo([], true, Some $2) }

| appType
{ $1, SynArgInfo([], false, None) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8483,6 +8483,16 @@ FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType get_innerTy
FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType innerType
FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.SynType+SignatureParameter: Boolean get_optional()
FSharp.Compiler.Syntax.SynType+SignatureParameter: Boolean optional
FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Syntax.SynType get_usedType()
FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Syntax.SynType usedType
FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes
FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes()
FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_id()
FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] id
FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst constant
FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst get_constant()
FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Text.Range get_range()
Expand All @@ -8508,6 +8518,7 @@ FSharp.Compiler.Syntax.SynType+Tags: Int32 LongIdentApp
FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasureDivide
FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasurePower
FSharp.Compiler.Syntax.SynType+Tags: Int32 Paren
FSharp.Compiler.Syntax.SynType+Tags: Int32 SignatureParameter
FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstant
FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantExpr
FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNamed
Expand Down Expand Up @@ -8541,6 +8552,7 @@ FSharp.Compiler.Syntax.SynType: Boolean IsLongIdentApp
FSharp.Compiler.Syntax.SynType: Boolean IsMeasureDivide
FSharp.Compiler.Syntax.SynType: Boolean IsMeasurePower
FSharp.Compiler.Syntax.SynType: Boolean IsParen
FSharp.Compiler.Syntax.SynType: Boolean IsSignatureParameter
FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstant
FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantExpr
FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNamed
Expand All @@ -8558,6 +8570,7 @@ FSharp.Compiler.Syntax.SynType: Boolean get_IsLongIdentApp()
FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasureDivide()
FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasurePower()
FSharp.Compiler.Syntax.SynType: Boolean get_IsParen()
FSharp.Compiler.Syntax.SynType: Boolean get_IsSignatureParameter()
FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstant()
FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantExpr()
FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNamed()
Expand All @@ -8575,6 +8588,7 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewLongIdentApp(F
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasureDivide(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasurePower(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynRationalConst, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewParen(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewSignatureParameter(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstant(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantExpr(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNamed(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range)
Expand All @@ -8592,6 +8606,7 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+LongIdentApp
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasureDivide
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasurePower
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Paren
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+SignatureParameter
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstant
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantExpr
FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNamed
Expand Down
41 changes: 41 additions & 0 deletions tests/service/SyntaxTreeTests/SignatureTypeTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,44 @@ type Z with
assertRange (14, 0) (14, 4) mType3
assertRange (14, 7) (14, 11) mWith3
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"

[<Test>]
let ``SynValSig contains parameter names`` () =
let parseResults =
getParseResultsOfSignatureFile
"""
module Meh
val InferSynValData:
memberFlagsOpt: SynMemberFlags option * pat: SynPat option * SynReturnInfo option * origRhsExpr: SynExpr ->
x: string ->
SynValData2
"""

match parseResults with
| ParsedInput.SigFile (ParsedSigFileInput (modules=[
SynModuleOrNamespaceSig(decls=[
SynModuleSigDecl.Val(valSig = SynValSig(synType =
SynType.Fun(
argType =
SynType.Tuple(path = [
SynTupleTypeSegment.Type(SynType.SignatureParameter(id = Some memberFlagsOpt))
SynTupleTypeSegment.Star _
SynTupleTypeSegment.Type(SynType.SignatureParameter(id = Some pat))
SynTupleTypeSegment.Star _
SynTupleTypeSegment.Type(SynType.App _)
SynTupleTypeSegment.Star _
SynTupleTypeSegment.Type(SynType.SignatureParameter(id = Some origRhsExpr))
])
returnType =
SynType.Fun(
argType = SynType.SignatureParameter(id = Some x)
returnType = SynType.LongIdent _
)
)
))
] ) ])) ->
Assert.AreEqual("memberFlagsOpt", memberFlagsOpt.idText)
Assert.AreEqual("pat", pat.idText)
Assert.AreEqual("origRhsExpr", origRhsExpr.idText)
Assert.AreEqual("x", x.idText)
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
70 changes: 70 additions & 0 deletions tests/service/SyntaxTreeTests/TypeTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -524,3 +524,73 @@ let _: struct (int * int = ()
assertRange (2, 7) (2, 24) mTuple

| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"

[<Test>]
let ``Named parameters in delegate type`` () =
let parseResults =
getParseResults
"""
type Foo = delegate of a: A * b: B -> c:C -> D
"""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput(modules = [
SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Types(typeDefns = [
SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(kind =
SynTypeDefnKind.Delegate(signature = SynType.Fun(
argType =
SynType.Tuple(path = [
SynTupleTypeSegment.Type(SynType.SignatureParameter(id = Some a))
SynTupleTypeSegment.Star _
SynTupleTypeSegment.Type(SynType.SignatureParameter(id = Some b))
])
returnType =
SynType.Fun(
argType = SynType.SignatureParameter(id = Some c)
returnType = SynType.LongIdent _
)
))))
])
])
])) ->
Assert.AreEqual("a", a.idText)
Assert.AreEqual("b", b.idText)
Assert.AreEqual("c", c.idText)
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"

[<Test>]
let ``Attributes in optional named member parameter`` () =
let parseResults =
getParseResults
"""
type X =
abstract member Y: [<Foo; Bar>] ?a: A -> B
"""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput(modules = [
SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Types(typeDefns = [
SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(
members = [
SynMemberDefn.AbstractSlot(slotSig = SynValSig(synType =
SynType.Fun(
argType = SynType.SignatureParameter(
[ { Attributes = [ _ ; _ ] } ],
true,
Some a,
SynType.LongIdent _,
m
)
returnType = SynType.LongIdent _
)
))
]
))
])
])
])) ->
Assert.AreEqual("a", a.idText)
assertRange (3, 23) (3, 41) m
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
29 changes: 28 additions & 1 deletion tests/service/SyntaxTreeTests/UnionCaseTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,31 @@ type Currency =
])) ->
assertRange (7, 4) (7, 11) mPrivate
| _ ->
Assert.Fail "Could not get valid AST"
Assert.Fail "Could not get valid AST"

[<Test>]
let ``SynUnionCaseKind.FullType`` () =
let parseResults =
getParseResults
"""
type X =
| a: int * z:int
"""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput(modules = [
SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Types(typeDefns = [
SynTypeDefn(typeRepr = SynTypeDefnRepr.Simple(simpleRepr =
SynTypeDefnSimpleRepr.Union(unionCases = [
SynUnionCase(caseType = SynUnionCaseKind.FullType(fullType = SynType.Tuple(path = [
SynTupleTypeSegment.Type(SynType.LongIdent _)
SynTupleTypeSegment.Star _
SynTupleTypeSegment.Type(SynType.SignatureParameter(id = Some z))
])))
])))
])
])
])) ->
Assert.AreEqual("z", z.idText)
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"