未验证 提交 50bbec3c 编写于 作者: F Florian Verdonck 提交者: GitHub

Extract logic to create get/set members to ParseHelpers. (#13373)

上级 d5312aae
......@@ -403,3 +403,332 @@ let grabXmlDocAtRangeStart (parseState: IParseState, optAttributes: SynAttribute
let grabXmlDoc (parseState: IParseState, optAttributes: SynAttributeList list, elemIdx) =
grabXmlDocAtRangeStart (parseState, optAttributes, rhs parseState elemIdx)
let reportParseErrorAt m s = errorR (Error(s, m))
let raiseParseErrorAt m s =
reportParseErrorAt m s
// This initiates error recovery
raise RecoverableParseError
let mkSynMemberDefnGetSet
(parseState: IParseState)
(opt_inline: bool)
(mWith: range)
(classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * SynReturnInfo option * range option * SynExpr * range) list)
(mAnd: range option)
(mWhole: range)
(propertyNameBindingPat: SynPat)
(optPropertyType: SynReturnInfo option)
(visNoLongerUsed: SynAccess option)
(memFlagsBuilder: SynMemberKind -> SynMemberFlags)
(attrs: SynAttributeList list)
(rangeStart: range)
: SynMemberDefn list =
let isMutable = false
let mutable hasGet = false
let mutable hasSet = false
let xmlDoc = grabXmlDocAtRangeStart (parseState, attrs, rangeStart)
let tryMkSynMemberDefnMember
(withPropertyKeyword: PropertyKeyword option)
(optInline, optAttrs: SynAttributeList list, (bindingPat, mBindLhs), optReturnType, mEquals, expr, mExpr)
=
let optInline = opt_inline || optInline
// optional attributes are only applied to getters and setters
// the "top level" attrs will be applied to both
let optAttrs =
optAttrs
|> List.map (fun attrList ->
{ attrList with
Attributes =
attrList.Attributes
|> List.map (fun a ->
{ a with
AppliesToGetterAndSetter = true
})
})
let attrs = attrs @ optAttrs
let trivia: SynBindingTrivia =
{
LetKeyword = None
EqualsRange = mEquals
}
let binding =
mkSynBinding
(xmlDoc, bindingPat)
(visNoLongerUsed,
optInline,
isMutable,
mBindLhs,
DebugPointAtBinding.NoneAtInvisible,
optReturnType,
expr,
mExpr,
[],
attrs,
Some(memFlagsBuilder SynMemberKind.Member),
trivia)
let (SynBinding (accessibility = vis; isInline = isInline; attributes = attrs; headPat = pv; range = mBindLhs)) =
binding
let memberKind =
let getset =
let rec go p =
match p with
| SynPat.LongIdent(longDotId = SynLongIdent ([ id ], _, _)) -> id.idText
| SynPat.Named (SynIdent (nm, _), _, _, _)
| SynPat.As (_, SynPat.Named (SynIdent (nm, _), _, _, _), _) -> nm.idText
| SynPat.Typed (p, _, _) -> go p
| SynPat.Attrib (p, _, _) -> go p
| _ -> raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidDeclarationSyntax ())
go pv
if getset = "get" then
if hasGet then
reportParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired ())
None
else
hasGet <- true
Some SynMemberKind.PropertyGet
else if getset = "set" then
if hasSet then
reportParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired ())
None
else
hasSet <- true
Some SynMemberKind.PropertySet
else
raiseParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired ())
match memberKind with
| None -> None
| Some memberKind ->
// REVIEW: It's hard not to ignore the optPropertyType type annotation for 'set' properties. To apply it,
// we should apply it to the last argument, but at this point we've already pushed the patterns that
// make up the arguments onto the RHS. So we just always give a warning.
(match optPropertyType with
| Some _ -> errorR (Error(FSComp.SR.parsTypeAnnotationsOnGetSet (), mBindLhs))
| None -> ())
let optReturnType =
match (memberKind, optReturnType) with
| SynMemberKind.PropertySet, _ -> optReturnType
| _, None -> optPropertyType
| _ -> optReturnType
// REDO with the correct member kind
let trivia: SynBindingTrivia =
{
LetKeyword = None
EqualsRange = mEquals
}
let binding =
mkSynBinding
(PreXmlDoc.Empty, bindingPat)
(vis,
isInline,
isMutable,
mBindLhs,
DebugPointAtBinding.NoneAtInvisible,
optReturnType,
expr,
mExpr,
[],
attrs,
Some(memFlagsBuilder memberKind),
trivia)
let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, rhsRetInfo, rhsExpr, mBindLhs, spBind, trivia)) =
binding
let mWholeBindLhs =
(mBindLhs, attrs)
||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
let (SynValData (_, valSynInfo, _)) = valSynData
// Setters have all arguments tupled in their internal TAST form, though they don't appear to be
// tupled from the syntax
let memFlags: SynMemberFlags = memFlagsBuilder memberKind
let valSynInfo =
let adjustValueArg valueArg =
match valueArg with
| [ _ ] -> valueArg
| _ -> SynInfo.unnamedTopArg
match memberKind, valSynInfo, memFlags.IsInstance with
| SynMemberKind.PropertyGet, SynValInfo ([], _ret), false
| SynMemberKind.PropertyGet, SynValInfo ([ _ ], _ret), true ->
raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterMustHaveAtLeastOneArgument ())
| SynMemberKind.PropertyGet, SynValInfo (thisArg :: indexOrUnitArgs :: rest, ret), true ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
SynValInfo([ thisArg; indexOrUnitArgs ], ret)
| SynMemberKind.PropertyGet, SynValInfo (indexOrUnitArgs :: rest, ret), false ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
SynValInfo([ indexOrUnitArgs ], ret)
| SynMemberKind.PropertySet, SynValInfo ([ thisArg; valueArg ], ret), true ->
SynValInfo([ thisArg; adjustValueArg valueArg ], ret)
| SynMemberKind.PropertySet, SynValInfo (thisArg :: indexArgs :: valueArg :: rest, ret), true ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
SynValInfo([ thisArg; indexArgs @ adjustValueArg valueArg ], ret)
| SynMemberKind.PropertySet, SynValInfo ([ valueArg ], ret), false -> SynValInfo([ adjustValueArg valueArg ], ret)
| SynMemberKind.PropertySet, SynValInfo (indexArgs :: valueArg :: rest, ret), _ ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
SynValInfo([ indexArgs @ adjustValueArg valueArg ], ret)
| _ ->
// should be unreachable, cover just in case
raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidProperty ())
let valSynData = SynValData(Some(memFlags), valSynInfo, None)
// Fold together the information from the first lambda pattern and the get/set binding
// This uses the 'this' variable from the first and the patterns for the get/set binding,
// replacing the get/set identifier. A little gross.
let bindingPatAdjusted, xmlDocAdjusted =
let trivia: SynBindingTrivia =
{
LetKeyword = None
EqualsRange = mEquals
}
let bindingOuter =
mkSynBinding
(xmlDoc, propertyNameBindingPat)
(vis,
optInline,
isMutable,
mWholeBindLhs,
spBind,
optReturnType,
expr,
mExpr,
[],
attrs,
Some(memFlagsBuilder SynMemberKind.Member),
trivia)
let (SynBinding (_, _, _, _, _, doc2, _, bindingPatOuter, _, _, _, _, _)) =
bindingOuter
let lidOuter, lidVisOuter =
match bindingPatOuter with
| SynPat.LongIdent (lid, _, None, None, SynArgPats.Pats [], lidVisOuter, _m) -> lid, lidVisOuter
| SynPat.Named (SynIdent (id, _), _, visOuter, _m)
| SynPat.As (_, SynPat.Named (SynIdent (id, _), _, visOuter, _m), _) -> SynLongIdent([ id ], [], [ None ]), visOuter
| _ -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax ())
// Merge the visibility from the outer point with the inner point, e.g.
// member <VIS1> this.Size with <VIS2> get () = m_size
let mergeLidVisOuter lidVisInner =
match lidVisInner, lidVisOuter with
| None, None -> None
| Some lidVisInner, None
| None, Some lidVisInner -> Some lidVisInner
| Some _, Some _ ->
errorR (Error(FSComp.SR.parsMultipleAccessibilitiesForGetSet (), mWholeBindLhs))
lidVisInner
// Replace the "get" or the "set" with the right name
let rec go p =
match p with
| SynPat.LongIdent (longDotId = SynLongIdent ([ id ], _, _)
typarDecls = tyargs
argPats = SynArgPats.Pats args
accessibility = lidVisInner
range = m) ->
// Setters have all arguments tupled in their internal form, though they don't
// appear to be tupled from the syntax. Somewhat unfortunate
let args =
if id.idText = "set" then
match args with
| [ SynPat.Paren (SynPat.Tuple (false, indexPats, _), indexPatRange); valuePat ] when id.idText = "set" ->
[
SynPat.Tuple(false, indexPats @ [ valuePat ], unionRanges indexPatRange valuePat.Range)
]
| [ indexPat; valuePat ] -> [ SynPat.Tuple(false, args, unionRanges indexPat.Range valuePat.Range) ]
| [ valuePat ] -> [ valuePat ]
| _ -> raiseParseErrorAt m (FSComp.SR.parsSetSyntax ())
else
args
SynPat.LongIdent(
lidOuter,
withPropertyKeyword,
Some(id),
tyargs,
SynArgPats.Pats args,
mergeLidVisOuter lidVisInner,
m
)
| SynPat.Named (_, _, lidVisInner, m)
| SynPat.As (_, SynPat.Named (_, _, lidVisInner, m), _) ->
SynPat.LongIdent(lidOuter, None, None, None, SynArgPats.Pats [], mergeLidVisOuter lidVisInner, m)
| SynPat.Typed (p, ty, m) -> SynPat.Typed(go p, ty, m)
| SynPat.Attrib (p, attribs, m) -> SynPat.Attrib(go p, attribs, m)
| SynPat.Wild m -> SynPat.Wild(m)
| _ -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax ())
go pv, PreXmlDoc.Merge doc2 doc
let binding =
SynBinding(
vis,
SynBindingKind.Normal,
isInline,
isMutable,
attrs,
xmlDocAdjusted,
valSynData,
bindingPatAdjusted,
rhsRetInfo,
rhsExpr,
mWholeBindLhs,
spBind,
trivia
)
let memberRange =
unionRanges rangeStart mWhole |> unionRangeWithXmlDoc xmlDocAdjusted
Some(SynMemberDefn.Member(binding, memberRange))
// Iterate over 1 or 2 'get'/'set' entries
match classDefnMemberGetSetElements with
| [ h ] -> List.choose id [ tryMkSynMemberDefnMember (Some(PropertyKeyword.With mWith)) h ]
| [ g; s ] ->
List.choose
id
[
tryMkSynMemberDefnMember (Some(PropertyKeyword.With mWith)) g
tryMkSynMemberDefnMember (Option.map PropertyKeyword.And mAnd) s
]
| _ -> []
......@@ -156,3 +156,22 @@ val grabXmlDoc: parseState: IParseState * optAttributes: SynAttributeList list *
val ParseAssemblyCodeType:
s: string -> reportLibraryOnlyFeatures: bool -> langVersion: LanguageVersion -> m: range -> ILType
val reportParseErrorAt: range -> (int * string) -> unit
val raiseParseErrorAt: range -> (int * string) -> 'a
val mkSynMemberDefnGetSet:
parseState: IParseState ->
opt_inline: bool ->
mWith: range ->
classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * SynReturnInfo option * range option * SynExpr * range) list ->
mAnd: range option ->
mWhole: range ->
propertyNameBindingPat: SynPat ->
optPropertyType: SynReturnInfo option ->
visNoLongerUsed: SynAccess option ->
memFlagsBuilder: (SynMemberKind -> SynMemberFlags) ->
attrs: SynAttributeList list ->
rangeStart: range ->
SynMemberDefn list
......@@ -79,17 +79,10 @@ let addAttribs attrs p = SynPat.Attrib(p, attrs, p.Range)
let parse_error_rich = Some (fun (ctxt: ParseErrorContext<_>) ->
errorR(SyntaxError(box ctxt, ctxt.ParseState.LexBuffer.LexemeRange)))
let reportParseErrorAt m s = errorR(Error(s, m))
let unionRangeWithPos (r:range) p =
let r2 = mkRange r.FileName p p
unionRanges r r2
let raiseParseErrorAt m s =
reportParseErrorAt m s;
// This initiates error recovery
raise RecoverableParseError
/// Report a good error at the end of file, e.g. for non-terminated strings
let checkEndOfFileError t =
match t with
......@@ -1872,198 +1865,8 @@ memberCore:
{ let mWith, (classDefnMemberGetSetElements, mAnd) = $4
let mWhole = (rhs parseState 2, classDefnMemberGetSetElements) ||> unionRangeWithListBy (fun (_, _, _, _, _, _, m2) -> m2)
let propertyNameBindingPat, _ = $2
let optPropertyType = $3
let isMutable = false
(fun visNoLongerUsed memFlagsBuilder attrs rangeStart ->
let mutable hasGet = false
let mutable hasSet = false
let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, rangeStart)
let tryMkSynMemberDefnMember
(withPropertyKeyword: PropertyKeyword option)
(optInline, (optAttrs: SynAttributeList list), (bindingPat, mBindLhs), optReturnType, mEquals, expr, mExpr)
=
let optInline = $1 || optInline
// optional attributes are only applied to getters and setters
// the "top level" attrs will be applied to both
let optAttrs =
optAttrs |> List.map (fun attrList ->
{ attrList with Attributes = attrList.Attributes |> List.map (fun a -> { a with AppliesToGetterAndSetter = true } ) })
let attrs = attrs @ optAttrs
let trivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = mEquals }
let binding = mkSynBinding (xmlDoc, bindingPat) (visNoLongerUsed, optInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, mExpr, [], attrs, Some (memFlagsBuilder SynMemberKind.Member), trivia)
let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, _, _, mBindLhs, spBind, _)) = binding
let memberKind =
let getset =
let rec go p =
match p with
| SynPat.LongIdent (longDotId=SynLongIdent([id], _, _)) -> id.idText
| SynPat.Named (SynIdent(nm, _), _, _, _) | SynPat.As (_, SynPat.Named (SynIdent(nm, _), _, _, _), _) -> nm.idText
| SynPat.Typed (p, _, _) -> go p
| SynPat.Attrib (p, _, _) -> go p
| _ -> raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidDeclarationSyntax())
go pv
if getset = "get" then
if hasGet then
reportParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired())
None
else
hasGet <- true
Some SynMemberKind.PropertyGet
else if getset = "set" then
if hasSet then
reportParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired())
None
else
hasSet <- true
Some SynMemberKind.PropertySet
else
raiseParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired())
match memberKind with
| None -> None
| Some memberKind ->
// REVIEW: It's hard not to ignore the optPropertyType type annotation for 'set' properties. To apply it,
// we should apply it to the last argument, but at this point we've already pushed the patterns that
// make up the arguments onto the RHS. So we just always give a warning.
begin match optPropertyType with
| Some _ -> errorR(Error(FSComp.SR.parsTypeAnnotationsOnGetSet(), mBindLhs))
| None -> ()
end
let optReturnType =
match (memberKind, optReturnType) with
| SynMemberKind.PropertySet, _ -> optReturnType
| _, None -> optPropertyType
| _ -> optReturnType
// REDO with the correct member kind
let trivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = mEquals }
let binding = mkSynBinding (PreXmlDoc.Empty, bindingPat) (vis, isInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, mExpr, [], attrs, Some(memFlagsBuilder memberKind), trivia)
let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, rhsRetInfo, rhsExpr, mBindLhs, spBind, trivia)) = binding
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
let (SynValData(_, valSynInfo, _)) = valSynData
// Setters have all arguments tupled in their internal TAST form, though they don't appear to be
// tupled from the syntax
let memFlags : SynMemberFlags = memFlagsBuilder memberKind
let valSynInfo =
let adjustValueArg valueArg =
match valueArg with
| [_] -> valueArg
| _ -> SynInfo.unnamedTopArg
match memberKind, valSynInfo, memFlags.IsInstance with
| SynMemberKind.PropertyGet, SynValInfo ([], _ret), false
| SynMemberKind.PropertyGet, SynValInfo ([_], _ret), true ->
raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterMustHaveAtLeastOneArgument())
| SynMemberKind.PropertyGet, SynValInfo (thisArg :: indexOrUnitArgs :: rest, ret), true ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
SynValInfo ([thisArg; indexOrUnitArgs], ret)
| SynMemberKind.PropertyGet, SynValInfo (indexOrUnitArgs :: rest, ret), false ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
SynValInfo ([indexOrUnitArgs], ret)
| SynMemberKind.PropertySet, SynValInfo ([thisArg;valueArg], ret), true ->
SynValInfo ([thisArg; adjustValueArg valueArg], ret)
| SynMemberKind.PropertySet, SynValInfo (thisArg :: indexArgs :: valueArg :: rest, ret), true ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
SynValInfo ([thisArg; indexArgs @ adjustValueArg valueArg], ret)
| SynMemberKind.PropertySet, SynValInfo ([valueArg], ret), false ->
SynValInfo ([adjustValueArg valueArg], ret)
| SynMemberKind.PropertySet, SynValInfo (indexArgs :: valueArg :: rest, ret), _ ->
if not rest.IsEmpty then
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
SynValInfo ([indexArgs @ adjustValueArg valueArg], ret)
| _ ->
// should be unreachable, cover just in case
raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidProperty ())
let valSynData = SynValData(Some(memFlags), valSynInfo, None)
// Fold together the information from the first lambda pattern and the get/set binding
// This uses the 'this' variable from the first and the patterns for the get/set binding,
// replacing the get/set identifier. A little gross.
let bindingPatAdjusted, xmlDocAdjusted =
let trivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = mEquals }
let bindingOuter = mkSynBinding (xmlDoc, propertyNameBindingPat) (vis, optInline, isMutable, mWholeBindLhs, spBind, optReturnType, expr, mExpr, [], attrs, Some(memFlagsBuilder SynMemberKind.Member), trivia)
let (SynBinding (_, _, _, _, _, doc2, _, bindingPatOuter, _, _, _, _, _)) = bindingOuter
let lidOuter, lidVisOuter =
match bindingPatOuter with
| SynPat.LongIdent (lid, _, None, None, SynArgPats.Pats [], lidVisOuter, m) -> lid, lidVisOuter
| SynPat.Named (SynIdent(id, _), _, visOuter, m) | SynPat.As(_, SynPat.Named (SynIdent(id, _), _, visOuter, m), _) -> SynLongIdent([id], [], [None]), visOuter
| p -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax())
// Merge the visibility from the outer point with the inner point, e.g.
// member <VIS1> this.Size with <VIS2> get () = m_size
let mergeLidVisOuter lidVisInner =
match lidVisInner, lidVisOuter with
| None, None -> None
| Some lidVisInner, None | None, Some lidVisInner -> Some lidVisInner
| Some _, Some _ ->
errorR(Error(FSComp.SR.parsMultipleAccessibilitiesForGetSet(), mWholeBindLhs))
lidVisInner
// Replace the "get" or the "set" with the right name
let rec go p =
match p with
| SynPat.LongIdent (longDotId=SynLongIdent([id], _, _); typarDecls=tyargs; argPats=SynArgPats.Pats args; accessibility=lidVisInner; range=m) ->
// Setters have all arguments tupled in their internal form, though they don't
// appear to be tupled from the syntax. Somewhat unfortunate
let args =
if id.idText = "set" then
match args with
| [SynPat.Paren(SynPat.Tuple (false, indexPats, _), indexPatRange);valuePat] when id.idText = "set" ->
[SynPat.Tuple(false, indexPats@[valuePat], unionRanges indexPatRange valuePat.Range)]
| [indexPat;valuePat] ->
[SynPat.Tuple(false, args, unionRanges indexPat.Range valuePat.Range)]
| [valuePat] ->
[valuePat]
| _ ->
raiseParseErrorAt m (FSComp.SR.parsSetSyntax())
else
args
SynPat.LongIdent (lidOuter, withPropertyKeyword, Some(id), tyargs, SynArgPats.Pats args, mergeLidVisOuter lidVisInner, m)
| SynPat.Named (_, _, lidVisInner, m)
| SynPat.As (_, SynPat.Named (_, _, lidVisInner, m), _) -> SynPat.LongIdent (lidOuter, None, None, None, SynArgPats.Pats [], mergeLidVisOuter lidVisInner, m)
| SynPat.Typed (p, ty, m) -> SynPat.Typed(go p, ty, m)
| SynPat.Attrib (p, attribs, m) -> SynPat.Attrib(go p, attribs, m)
| SynPat.Wild(m) -> SynPat.Wild(m)
| _ -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax())
go pv, PreXmlDoc.Merge doc2 doc
let binding = SynBinding (vis, SynBindingKind.Normal, isInline, isMutable, attrs, xmlDocAdjusted, valSynData, bindingPatAdjusted, rhsRetInfo, rhsExpr, mWholeBindLhs, spBind, trivia)
let memberRange = unionRanges rangeStart mWhole |> unionRangeWithXmlDoc xmlDocAdjusted
Some (SynMemberDefn.Member (binding, memberRange))
// Iterate over 1 or 2 'get'/'set' entries
match classDefnMemberGetSetElements with
| [ h ] -> List.choose id [ tryMkSynMemberDefnMember (Some (PropertyKeyword.With mWith)) h ]
| [ g ; s ] -> List.choose id [ tryMkSynMemberDefnMember (Some (PropertyKeyword.With mWith)) g ; tryMkSynMemberDefnMember (Option.map PropertyKeyword.And mAnd) s ]
| _ -> [])
}
let optPropertyType = $3
mkSynMemberDefnGetSet parseState $1 mWith classDefnMemberGetSetElements mAnd mWhole propertyNameBindingPat optPropertyType }
abstractMemberFlags:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册