From 53e4a5de717284659b7e6294781188d518c55d2a Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Sat, 14 Aug 2021 15:37:48 +0300 Subject: [PATCH 01/25] wip --- src/fsharp/LexFilter.fs | 8 +- src/fsharp/ParseHelpers.fs | 28 +- src/fsharp/ParseHelpers.fsi | 4 +- src/fsharp/XmlDoc.fs | 43 +-- src/fsharp/XmlDoc.fsi | 6 +- src/fsharp/lex.fsl | 4 + src/fsharp/pars.fsy | 110 +++--- .../FSharp.Compiler.Service.Tests.fsproj | 5 +- tests/service/Common.fs | 3 + tests/service/XmlDocTests.fs | 350 ++++++++++++++++++ 10 files changed, 476 insertions(+), 85 deletions(-) create mode 100644 tests/service/XmlDocTests.fs diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs index 6084c450f26..fe30bc9912a 100644 --- a/src/fsharp/LexFilter.fs +++ b/src/fsharp/LexFilter.fs @@ -638,8 +638,11 @@ type LexFilterImpl (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbu setLexbufState state let lastTokenEnd = state.EndPos let token = lexer lexbuf - // Now we've got the token, remember the lexbuf state, associating it with the token - // and remembering it as the last observed lexbuf state for the wrapped lexer function. + + LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) + + // Now we've got the token, remember the lexbuf state, associating it with the token + // and remembering it as the last observed lexbuf state for the wrapped lexer function. let tokenLexbufState = getLexbufState() savedLexbufState <- tokenLexbufState haveLexbufState <- true @@ -648,6 +651,7 @@ type LexFilterImpl (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbu tokenTup.Token <- token tokenTup.LexbufState <- tokenLexbufState tokenTup.LastTokenPos <- lastTokenEnd + tokenTup //---------------------------------------------------------------------------- diff --git a/src/fsharp/ParseHelpers.fs b/src/fsharp/ParseHelpers.fs index 8d0c6fe367c..d58af7d3378 100644 --- a/src/fsharp/ParseHelpers.fs +++ b/src/fsharp/ParseHelpers.fs @@ -6,6 +6,8 @@ open FSharp.Compiler.AbstractIL open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text open FSharp.Compiler.UnicodeLexing open FSharp.Compiler.Text open FSharp.Compiler.Text.Position @@ -91,28 +93,36 @@ module LexbufLocalXmlDocStore = // The key into the BufferLocalStore used to hold the current accumulated XmlDoc lines let private xmlDocKey = "XmlDoc" + let private getCollector (lexbuf: Lexbuf) = + match lexbuf.BufferLocalStore.TryGetValue xmlDocKey with + | true, collector -> collector + | _ -> + let collector = box (XmlDocCollector()) + lexbuf.BufferLocalStore.[xmlDocKey] <- collector + collector + + |> unbox + let ClearXmlDoc (lexbuf: Lexbuf) = lexbuf.BufferLocalStore.[xmlDocKey] <- box (XmlDocCollector()) /// Called from the lexer to save a single line of XML doc comment. let SaveXmlDocLine (lexbuf: Lexbuf, lineText, range: range) = - let collector = - match lexbuf.BufferLocalStore.TryGetValue xmlDocKey with - | true, collector -> collector - | _ -> - let collector = box (XmlDocCollector()) - lexbuf.BufferLocalStore.[xmlDocKey] <- collector - collector - let collector = unbox(collector) + let collector = getCollector lexbuf collector.AddXmlDocLine(lineText, range) + let AddGrabPoint (lexbuf: Lexbuf) = + let collector = getCollector lexbuf + let startPos = lexbuf.StartPos + collector.AddGrabPoint(mkPos startPos.Line startPos.Column) + /// Called from the parser each time we parse a construct that marks the end of an XML doc comment range, /// e.g. a 'type' declaration. The markerRange is the range of the keyword that delimits the construct. let GrabXmlDocBeforeMarker (lexbuf: Lexbuf, markerRange: range) = match lexbuf.BufferLocalStore.TryGetValue xmlDocKey with | true, collector -> let collector = unbox(collector) - PreXmlDoc.CreateFromGrabPoint(collector, markerRange.End) + PreXmlDoc.CreateFromGrabPoint(collector, markerRange.Start) | _ -> PreXmlDoc.Empty diff --git a/src/fsharp/ParseHelpers.fsi b/src/fsharp/ParseHelpers.fsi index b15011ce716..8403a27eb28 100644 --- a/src/fsharp/ParseHelpers.fsi +++ b/src/fsharp/ParseHelpers.fsi @@ -45,7 +45,9 @@ module LexbufLocalXmlDocStore = val SaveXmlDocLine: lexbuf:UnicodeLexing.Lexbuf * lineText:string * range:range -> unit val GrabXmlDocBeforeMarker: lexbuf:UnicodeLexing.Lexbuf * markerRange:range -> PreXmlDoc - + + val AddGrabPoint: lexbuf:UnicodeLexing.Lexbuf -> unit + type LexerIfdefStackEntry = | IfDefIf | IfDefElse diff --git a/src/fsharp/XmlDoc.fs b/src/fsharp/XmlDoc.fs index 3a30e6033c8..e09624b7036 100644 --- a/src/fsharp/XmlDoc.fs +++ b/src/fsharp/XmlDoc.fs @@ -3,6 +3,7 @@ namespace FSharp.Compiler.Xml open System +open System.Collections.Generic open System.IO open System.Xml open System.Xml.Linq @@ -146,10 +147,10 @@ and XmlDocStatics() = /// Used to collect XML documentation during lexing and parsing. type XmlDocCollector() = let mutable savedLines = ResizeArray() - let mutable savedGrabPoints = ResizeArray() + let mutable savedGrabPoints = Dictionary<_, _>() + let mutable currentGrabPointCommentsCount = 0 + let posCompare p1 p2 = if posGeq p1 p2 then 1 else if posEq p1 p2 then 0 else -1 - let savedGrabPointsAsArray = - lazy (savedGrabPoints.ToArray() |> Array.sortWith posCompare) let savedLinesAsArray = lazy (savedLines.ToArray() |> Array.sortWith (fun (_, p1) (_, p2) -> posCompare p1.End p2.End)) @@ -158,32 +159,26 @@ type XmlDocCollector() = // can't add more XmlDoc elements to XmlDocCollector after extracting first XmlDoc from the overall results assert (not savedLinesAsArray.IsValueCreated) - member x.AddGrabPoint pos = + member x.AddGrabPoint(pos: pos) = check() - savedGrabPoints.Add pos + if currentGrabPointCommentsCount = 0 then () else + let commentsStartEndIndexes = struct(savedLines.Count - currentGrabPointCommentsCount, savedLines.Count - 1) + savedGrabPoints.Add(pos, commentsStartEndIndexes) + currentGrabPointCommentsCount <- 0 member x.AddXmlDocLine(line, range) = check() savedLines.Add(line, range) + currentGrabPointCommentsCount <- currentGrabPointCommentsCount + 1 member x.LinesBefore grabPointPos = - try let lines = savedLinesAsArray.Force() - let grabPoints = savedGrabPointsAsArray.Force() - let firstLineIndexAfterGrabPoint = Array.findFirstIndexWhereTrue lines (fun (_, m) -> posGeq m.End grabPointPos) - let grabPointIndex = Array.findFirstIndexWhereTrue grabPoints (fun pos -> posGeq pos grabPointPos) - assert (posEq grabPoints.[grabPointIndex] grabPointPos) - let firstLineIndexAfterPrevGrabPoint = - if grabPointIndex = 0 then - 0 - else - let prevGrabPointPos = grabPoints.[grabPointIndex-1] - Array.findFirstIndexWhereTrue lines (fun (_, m) -> posGeq m.End prevGrabPointPos) + match savedGrabPoints.TryGetValue grabPointPos with + | true, struct(startIndex, endIndex) -> lines.[startIndex .. endIndex] + | false, _ -> [||] - let lines = lines.[firstLineIndexAfterPrevGrabPoint..firstLineIndexAfterGrabPoint-1] - lines - with e -> - [| |] + member x.HasComments grabPointPos = + savedGrabPoints.TryGetValue grabPointPos |> fst /// Represents the XmlDoc fragments as collected from the lexer during parsing type PreXmlDoc = @@ -209,8 +204,14 @@ type PreXmlDoc = doc.Check(paramNamesOpt) doc + member x.IsEmpty = + match x with + | PreXmlDirect (lines, _) -> lines |> Array.forall String.IsNullOrWhiteSpace + | PreXmlMerge(a, b) -> a.IsEmpty && b.IsEmpty + | PreXmlDocEmpty -> true + | PreXmlDoc (pos, collector) -> not (collector.HasComments pos) + static member CreateFromGrabPoint(collector: XmlDocCollector, grabPointPos) = - collector.AddGrabPoint grabPointPos PreXmlDoc(grabPointPos, collector) static member Empty = PreXmlDocEmpty diff --git a/src/fsharp/XmlDoc.fsi b/src/fsharp/XmlDoc.fsi index e451312f4a5..ed087bd8c1b 100644 --- a/src/fsharp/XmlDoc.fsi +++ b/src/fsharp/XmlDoc.fsi @@ -44,7 +44,9 @@ type internal XmlDocCollector = member AddXmlDocLine: line:string * range:range -> unit member LinesBefore: grabPointPos: pos -> (string * range) [] - + + member HasComments: grabPointPos: pos -> bool + /// Represents the XmlDoc fragments as collected from the lexer during parsing [] type public PreXmlDoc = @@ -57,6 +59,8 @@ type public PreXmlDoc = member ToXmlDoc: check:bool * paramNamesOpt:string list option -> XmlDoc + member IsEmpty: bool + static member Empty: PreXmlDoc [] diff --git a/src/fsharp/lex.fsl b/src/fsharp/lex.fsl index 409e766fd14..0dcdfe3ace9 100644 --- a/src/fsharp/lex.fsl +++ b/src/fsharp/lex.fsl @@ -677,6 +677,7 @@ rule token args skip = parse | "////" op_char* { // 4+ slash are 1-line comments, online 3 slash are XmlDoc let m = lexbuf.LexemeRange + LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) else singleLineComment (None,1,m,args) skip lexbuf } @@ -691,6 +692,7 @@ rule token args skip = parse | "//" op_char* { // Need to read all operator symbols too, otherwise it might be parsed by a rule below let m = lexbuf.LexemeRange + LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) else singleLineComment (None,1,m,args) skip lexbuf } @@ -1454,6 +1456,7 @@ and comment cargs skip = parse | "(*)" { let n, m, args = cargs + LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) else comment cargs skip lexbuf } @@ -1474,6 +1477,7 @@ and comment cargs skip = parse if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n-1, m)) else comment (n-1,m,args) skip lexbuf else + LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) if not skip then COMMENT (LexCont.Token(args.ifdefStack, args.stringNest)) else token args skip lexbuf } diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index c38a484458d..26dd62efe27 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -182,8 +182,12 @@ let checkForMultipleAugmentations m a1 a2 = if not (isNil a1) && not (isNil a2) then raiseParseErrorAt m (FSComp.SR.parsOnlyOneWithAugmentationAllowed()) a1 @ a2 -let grabXmlDoc(parseState:IParseState, elemIdx) = - LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, rhs parseState elemIdx) +let grabXmlDoc(parseState:IParseState, optAttributes: SynAttributeList list, elemIdx) = + let grabPoint = + match optAttributes with + | [] -> rhs parseState elemIdx + | h :: _ -> h.Range + LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, grabPoint) let rangeOfLongIdent(lid:LongIdent) = System.Diagnostics.Debug.Assert(not lid.IsEmpty, "the parser should never produce a long-id that is the empty list") @@ -678,13 +682,13 @@ moduleIntro: | moduleKeyword opt_attributes opt_access opt_rec path { if not (isNil $2) then parseState.LexBuffer.CheckLanguageFeatureErrorRecover LanguageFeature.AttributesToRightOfModuleKeyword <| rhs parseState 4 - $4, $5.Lid, grabXmlDoc(parseState, 1), $3, $2 } + $4, $5.Lid, grabXmlDoc(parseState, [], 1), $3, $2 } /* The start of a namespace declaration */ namespaceIntro: | NAMESPACE opt_rec path - { $2, $3.Lid, grabXmlDoc(parseState, 1) } + { $2, $3.Lid, grabXmlDoc(parseState, [], 1) } /* The contents of a signature file */ @@ -817,12 +821,13 @@ moduleSpfn: match $4 with | [] -> raiseParseErrorAt (rhs2 parseState 3 4) (FSComp.SR.parsUnexpectedEmptyModuleDefn ()) - | SynTypeDefnSig (SynComponentInfo (cas, a, cs, b, c, d, d2, d3), e, f, g) :: tail -> + | SynTypeDefnSig (SynComponentInfo (cas, a, cs, b, _, d, d2, d3), e, f, g) :: tail -> let attrs = $1 @ cas let mTc = let keywordM = rhs parseState 3 (keywordM, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) |> unionRanges g - let tc = (SynTypeDefnSig(SynComponentInfo(attrs, a, cs, b, c, d, d2, d3), e, f, mTc)) + let xmlDoc = grabXmlDoc(parseState, $1, 3) + let tc = (SynTypeDefnSig(SynComponentInfo(attrs, a, cs, b, xmlDoc, d, d2, d3), e, f, mTc)) let m = (mTc, tail) ||> unionRangeWithListBy (fun (a: SynTypeDefnSig) -> a.Range) SynModuleSigDecl.Types (tc :: tail, m) } @@ -839,7 +844,7 @@ moduleSpfn: valSpfn: | opt_attributes opt_declVisibility VAL opt_attributes opt_inline opt_mutable opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints optLiteralValueSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let attr1, attr2, isInline, isMutable, vis2, id, doc, explicitValTyparDecls, (ty, arity), konst = ($1), ($4), ($5), ($6), ($7), ($8), grabXmlDoc(parseState, 3), ($9), ($11), ($12) + let attr1, attr2, isInline, isMutable, vis2, id, doc, explicitValTyparDecls, (ty, arity), konst = ($1), ($4), ($5), ($6), ($7), ($8), grabXmlDoc(parseState, $1, 3), ($9), ($11), ($12) if not (isNil attr2) then errorR(Deprecated(FSComp.SR.parsAttributesMustComeBeforeVal(), rhs parseState 4)) let m = rhs2 parseState 1 11 let valSpfn = SynValSig((attr1@attr2), id, explicitValTyparDecls, ty, arity, isInline, isMutable, doc, vis2, konst, m) @@ -1006,7 +1011,7 @@ classSpfnMembersAtLeastOne: classMemberSpfn: | opt_attributes opt_declVisibility memberSpecFlags opt_inline opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet optLiteralValueSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let isInline, doc, vis2, id, explicitValTyparDecls, (ty, arity), optLiteralValue = $4, grabXmlDoc(parseState, 3), $5, $6, $7, $9, $11 + let isInline, doc, vis2, id, explicitValTyparDecls, (ty, arity), optLiteralValue = $4, grabXmlDoc(parseState, $1, 3), $5, $6, $7, $9, $11 let getSetRangeOpt, getSet = $10 let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet let wholeRange = @@ -1043,7 +1048,7 @@ classMemberSpfn: SynMemberSig.NestedType($5, rhs2 parseState 1 5) } | opt_attributes opt_declVisibility NEW COLON topTypeWithTypeConstraints - { let vis, doc, (ty, valSynInfo) = $2, grabXmlDoc(parseState, 3), $5 + { let vis, doc, (ty, valSynInfo) = $2, grabXmlDoc(parseState, $1, 3), $5 let m = unionRanges (rhs parseState 1) ty.Range let isInline = false let valSpfn = SynValSig ($1, mkSynId (rhs parseState 3) "new", noInferredTypars, ty, valSynInfo, isInline, false, doc, vis, None, m) @@ -1293,10 +1298,11 @@ moduleDefn: /* 'type' definitions */ | opt_attributes opt_declVisibility typeKeyword tyconDefn tyconDefnList { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let (SynTypeDefn(SynComponentInfo(cas, a, cs, b, c, d, d2, d3), e, f, g, h)) = $4 + let xmlDoc = grabXmlDoc(parseState, $1, 3) + let (SynTypeDefn(SynComponentInfo(cas, a, cs, b, _, d, d2, d3), e, f, g, h)) = $4 let attrs = $1@cas let mTc = (h, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) - let tc = (SynTypeDefn(SynComponentInfo(attrs, a, cs, b, c, d, d2, d3), e, f, g, mTc)) + let tc = (SynTypeDefn(SynComponentInfo(attrs, a, cs, b, xmlDoc, d, d2, d3), e, f, g, mTc)) let types = tc :: $5 [ SynModuleDecl.Types(types, (rhs parseState 3, types) ||> unionRangeWithListBy (fun t -> t.Range) ) ] } @@ -1510,13 +1516,19 @@ memberFlags: /* The name of a type in a signature or implementation, possibly with type parameters and constraints */ typeNameInfo: | opt_attributes tyconNameAndTyparDecls opt_typeConstraints - { let typars, lid, fixity, vis, xmlDoc = $2 + { let typars, lid, fixity, vis = $2 + let xmlDoc = grabXmlDoc(parseState, $1, 1) SynComponentInfo ($1, typars, $3, lid, xmlDoc, fixity, vis, rangeOfLid lid) } /* Part of a set of type definitions */ tyconDefnList: | AND tyconDefn tyconDefnList - { $2 :: $3 } + { let xmlDoc = grabXmlDoc(parseState, [], 1) + let tyconDefn = + if xmlDoc.IsEmpty then $2 else + let (SynTypeDefn(SynComponentInfo (a, typars, c, lid, _, fixity, vis, rangeOfLid), typeRepr, members, implicitConstructor, range)) = $2 + SynTypeDefn(SynComponentInfo (a, typars, c, lid, xmlDoc, fixity, vis, rangeOfLid), typeRepr, members, implicitConstructor, range) + tyconDefn :: $3 } | { [] } @@ -1548,7 +1560,7 @@ tyconDefn: let (tcDefRepr, members) = $8 nameRange let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 // Gets the XML doc comments prior to the implicit constructor - let xmlDoc = grabXmlDoc(parseState, 5) + let xmlDoc = grabXmlDoc(parseState, $2, 5) let memberCtorPattern = SynMemberDefn.ImplicitCtor (vis, $2, spats, az, xmlDoc, rangeOfLid lid) let tcDefRepr = match tcDefRepr with @@ -1719,10 +1731,10 @@ memberCore: { let mRhs = $5.Range let optReturnType = $3 let bindingBuilder, mBindLhs = $2 - (fun vis memFlagsBuilder attrs rangeStart -> + (fun xmlDoc vis memFlagsBuilder attrs rangeStart -> let memberFlags = Some (memFlagsBuilder SynMemberKind.Member) let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) - let binding = bindingBuilder (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags) + let binding = (bindingBuilder xmlDoc) (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags) let memberRange = unionRanges rangeStart mRhs [ SynMemberDefn.Member (binding, memberRange) ]) } @@ -1732,7 +1744,7 @@ memberCore: let propertyNameBindingBuilder, _ = $2 let optPropertyType = $3 let isMutable = false - (fun visNoLongerUsed memFlagsBuilder attrs rangeStart -> + (fun xmlDoc visNoLongerUsed memFlagsBuilder attrs rangeStart -> let hasGet = ref false let hasSet = ref false @@ -1747,8 +1759,8 @@ memberCore: { attrList with Attributes = attrList.Attributes |> List.map (fun a -> { a with AppliesToGetterAndSetter = true } ) }) let attrs = attrs @ optAttrs - - let binding = bindingBuilder (visNoLongerUsed, optInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, exprm, [], attrs, Some (memFlagsBuilder SynMemberKind.Member)) + + let binding = (bindingBuilder xmlDoc) (visNoLongerUsed, optInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, exprm, [], attrs, Some (memFlagsBuilder SynMemberKind.Member)) let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, _, _, mBindLhs, spBind)) = binding let memberKind = let getset = @@ -1797,7 +1809,7 @@ memberCore: | _ -> optReturnType // REDO with the correct member kind - let binding = bindingBuilder(vis, isInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder memberKind)) + let binding = (bindingBuilder PreXmlDoc.Empty) (vis, isInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder memberKind)) let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, rhsRetInfo, rhsExpr, mBindLhs, spBind)) = binding let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) @@ -1857,7 +1869,7 @@ memberCore: let bindingPatAdjusted, xmlDocAdjusted = - let bindingOuter = propertyNameBindingBuilder(vis, optInline, isMutable, mWholeBindLhs, spBind, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder SynMemberKind.Member)) + let bindingOuter = (propertyNameBindingBuilder xmlDoc) (vis, optInline, isMutable, mWholeBindLhs, spBind, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder SynMemberKind.Member)) let (SynBinding (_, _, _, _, _, doc2, _, bindingPatOuter, _, _, _, _)) = bindingOuter @@ -1934,7 +1946,8 @@ classDefnMember: if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) let _, flags = $3 - $4 $2 flags $1 rangeStart } + let doc = grabXmlDoc(parseState, $1, 1) + $4 doc $2 flags $1 rangeStart } | opt_attributes opt_declVisibility interfaceMember appType opt_interfaceImplDefn { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(), rhs parseState 1)) @@ -1948,7 +1961,7 @@ classDefnMember: | opt_attributes opt_declVisibility abstractMemberFlags opt_inline nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet opt_ODECLEND { let ty, arity = $8 - let isInline, doc, id, explicitValTyparDecls = $4, grabXmlDoc(parseState, 3), $5, $6 + let isInline, doc, id, explicitValTyparDecls = $4, grabXmlDoc(parseState, $1, 1), $5, $6 let getSetRangeOpt, getSet = $9 let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet let wholeRange = @@ -1964,7 +1977,7 @@ classDefnMember: { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalOnInherit(), rhs parseState 1)) if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityIllegalOnInherit(), rhs parseState 1)) [ $3 ] } - + | opt_attributes opt_declVisibility valDefnDecl opt_ODECLEND { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let rangeStart = rhs parseState 1 @@ -1991,7 +2004,7 @@ classDefnMember: let declPat = SynPat.LongIdent (LongIdentWithDots([mkSynId (rhs parseState 3) "new"], []), None, Some noInferredTypars, SynArgPats.Pats [$4], vis, rhs parseState 3) // Check that 'SynPatForConstructorDecl' matches this correctly assert (match declPat with SynPatForConstructorDecl _ -> true | _ -> false) - [ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, grabXmlDoc(parseState, 3), valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible), m) ] } + [ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, grabXmlDoc(parseState, $1, 3), valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible), m) ] } | opt_attributes opt_declVisibility STATIC typeKeyword tyconDefn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) @@ -2002,7 +2015,7 @@ classDefnMember: valDefnDecl: | VAL opt_mutable opt_access ident COLON typ { let mRhs = rhs2 parseState 4 6 - let doc = grabXmlDoc(parseState, 4) + let doc = grabXmlDoc(parseState, [], 3) let mValDecl = rhs2 parseState 1 6 (fun rangeStart attribs isStatic -> let mValDecl = unionRanges rangeStart mValDecl @@ -2013,7 +2026,7 @@ valDefnDecl: /* An auto-property definition in an object type definition */ autoPropsDefnDecl: | VAL opt_mutable opt_access ident opt_typ EQUALS typedSequentialExprBlock classMemberSpfnGetSet - { let doc = grabXmlDoc(parseState, 5) + { let doc = grabXmlDoc(parseState, [], 5) let mGetSetOpt, getSet = $8 if $2 then errorR (Error (FSComp.SR.parsMutableOnAutoPropertyShouldBeGetSet (), rhs parseState 3)) @@ -2170,7 +2183,8 @@ objectImplementationMembers: objectImplementationMember: | opt_attributes memberOrOverride memberCore opt_ODECLEND { let rangeStart = rhs parseState 1 - $3 None OverrideMemberFlags $1 rangeStart } + let doc = grabXmlDoc(parseState, $1, 1) + $3 doc None OverrideMemberFlags $1 rangeStart } | opt_attributes memberOrOverride autoPropsDefnDecl opt_ODECLEND { let rangeStart = rhs parseState 1 @@ -2282,13 +2296,13 @@ interfaceMember: tyconNameAndTyparDecls: | opt_access path - { None, $2.Lid, false, $1, grabXmlDoc(parseState, 2) } + { None, $2.Lid, false, $1 } | opt_access prefixTyparDecls path - { Some $2, $3.Lid, false, $1, grabXmlDoc(parseState, 2) } + { Some $2, $3.Lid, false, $1 } | opt_access path postfixTyparDecls - { Some $3, $2.Lid, true, $1, grabXmlDoc(parseState, 2) } + { Some $3, $2.Lid, true, $1 } prefixTyparDecls: | typar @@ -2424,7 +2438,7 @@ unionTypeRepr: barAndgrabXmlDoc : | BAR - { grabXmlDoc(parseState, 1) } + { grabXmlDoc(parseState, [], 1) } attrUnionCaseDecls: | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls @@ -2474,20 +2488,20 @@ unionCaseName: firstUnionCaseDeclOfMany: | ident opt_OBLOCKSEP - { Choice2Of2 (SynUnionCase ( [], $1, SynUnionCaseKind.Fields [], PreXmlDoc.Empty, None, rhs parseState 1)) } + { Choice2Of2 (SynUnionCase ( [], $1, SynUnionCaseKind.Fields [], grabXmlDoc(parseState, [], 1), None, rhs parseState 1)) } | ident EQUALS constant opt_OBLOCKSEP - { Choice1Of2 (SynEnumCase ([], $1, fst $3, snd $3, PreXmlDoc.Empty, rhs2 parseState 1 3)) } + { Choice1Of2 (SynEnumCase ([], $1, fst $3, snd $3, grabXmlDoc(parseState, [], 1), rhs2 parseState 1 3)) } | firstUnionCaseDecl opt_OBLOCKSEP { $1 } firstUnionCaseDecl: | ident OF unionCaseRepr - { Choice2Of2 (SynUnionCase ( [], $1, SynUnionCaseKind.Fields $3, PreXmlDoc.Empty, None, rhs2 parseState 1 3)) } + { Choice2Of2 (SynUnionCase ( [], $1, SynUnionCaseKind.Fields $3, grabXmlDoc(parseState, [], 1), None, rhs2 parseState 1 3)) } | ident EQUALS constant opt_OBLOCKSEP - { Choice1Of2 (SynEnumCase ([], $1, fst $3, snd $3, PreXmlDoc.Empty, rhs2 parseState 1 3)) } + { Choice1Of2 (SynEnumCase ([], $1, fst $3, snd $3, grabXmlDoc(parseState, [], 1), rhs2 parseState 1 3)) } unionCaseReprElements: | unionCaseReprElement STAR unionCaseReprElements @@ -2532,7 +2546,7 @@ recdFieldDecl: /* Part of a field or val declaration in a record type or object type */ fieldDecl: | opt_mutable opt_access ident COLON typ - { let xmlDoc = grabXmlDoc (parseState, 3) + { let xmlDoc = grabXmlDoc (parseState, [], 3) fun attrs stat wholeRange -> SynField(attrs, stat, Some $3, $5, $1, xmlDoc, $2, wholeRange) } /* An exception definition */ @@ -2543,7 +2557,7 @@ exconDefn: /* Part of an exception definition */ exceptionAndGrabDoc: | EXCEPTION - { grabXmlDoc(parseState, 1) } + { grabXmlDoc(parseState, [], 1) } /* Part of an exception definition */ exconCore: @@ -2681,7 +2695,7 @@ hardwhiteDefnBindingsTerminator: cPrototype: | EXTERN cRetType opt_access ident opt_HIGH_PRECEDENCE_APP LPAREN cArgs rparen { let rty, vis, nm, args = $2, $3, $4, $7 - let xmlDoc = grabXmlDoc(parseState, 1) + let xmlDoc = grabXmlDoc(parseState, [], 1) let nmm = rhs parseState 3 let argsm = rhs parseState 6 let mBindLhs = lhs parseState @@ -2808,25 +2822,27 @@ localBinding: let optReturnType = $4 let bindingBuilder, mBindLhs = $3 let localBindingRange = unionRanges (rhs2 parseState 1 5) mRhs + let xmlDoc = grabXmlDoc(parseState, [], 1) let localBindingBuilder = (fun attrs vis mLetKwd -> let mWhole = (unionRanges mLetKwd mRhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) let spBind = if IsControlFlowExpression expr then DebugPointAtBinding.NoneAtLet else DebugPointAtBinding.Yes mWhole let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) - bindingBuilder (vis, $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None)) + (bindingBuilder xmlDoc) (vis, $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None)) localBindingRange, localBindingBuilder } | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS error { let mWhole = rhs2 parseState 1 5 let mRhs = rhs parseState 5 let optReturnType = $4 - let bindingBuilder, mBindLhs = $3 + let bindingBuilder, mBindLhs = $3 + let xmlDoc = grabXmlDoc(parseState, [], 1) let localBindingBuilder = (fun attrs vis mLetKwd -> let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs) let eqm = rhs parseState 5 let zeroWidthAtEnd = eqm.EndRange - bindingBuilder (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding1", zeroWidthAtEnd), mRhs, [], attrs, None)) + (bindingBuilder xmlDoc) (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding1", zeroWidthAtEnd), mRhs, [], attrs, None)) mWhole, localBindingBuilder } | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints recover @@ -2838,7 +2854,7 @@ localBinding: let localBindingBuilder = (fun attrs vis mLetKwd -> let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs) - bindingBuilder (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding2", mRhs), mRhs, [], attrs, None)) + (bindingBuilder PreXmlDoc.Empty) (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding2", mRhs), mRhs, [], attrs, None)) mWhole, localBindingBuilder } @@ -2990,13 +3006,7 @@ constant: bindingPattern: | headBindingPattern - - { // Adds a grab point at the start of the binding, so as not to include XML doc comments on the arguments - let xmlDoc = LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, (lhs parseState).StartRange) - // Adds grab point at the end of the binding head, so subsequent types don't erroneously include argument doc comemnts - grabXmlDoc(parseState, 1) |> ignore - - mkSynBinding (xmlDoc, $1), rhs parseState 1 } + { (fun (xmlDoc: PreXmlDoc) -> mkSynBinding (xmlDoc, $1)), rhs parseState 1 } // Subset of patterns allowed to be used in implicit ctors. // For a better error recovery we could replace these rules with the actual SynPat parsing diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index f08d6de964e..2b2505d0d61 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -72,7 +72,10 @@ ParserTests.fs - + + XmlDocTests.fs + + Program.fs diff --git a/tests/service/Common.fs b/tests/service/Common.fs index 27031dbcd16..c4859afc20b 100644 --- a/tests/service/Common.fs +++ b/tests/service/Common.fs @@ -375,6 +375,9 @@ let getParseResultsOfSignatureFile (source: string) = let getParseAndCheckResults (source: string) = parseAndCheckScript("/home/user/Test.fsx", source) +let getParseAndCheckResultsOfSignatureFile (source: string) = + parseAndCheckScript("/home/user/Test.fsi", source) + let getParseAndCheckResultsPreview (source: string) = parseAndCheckScriptPreview("/home/user/Test.fsx", source) diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs new file mode 100644 index 00000000000..3c8443161c7 --- /dev/null +++ b/tests/service/XmlDocTests.fs @@ -0,0 +1,350 @@ +#if INTERACTIVE +#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive +#r "../../artifacts/bin/fcs/net461/nunit.framework.dll" +#load "FsUnit.fs" +#load "Common.fs" +#else +module Tests.XmlDoc +#endif + +open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Symbols +open FsUnit +open NUnit.Framework + +let checkXml symbolName docs checkResults = + let symbol = findSymbolByName symbolName checkResults + let xmlDoc = + match symbol with + | :? FSharpMemberOrFunctionOrValue as v -> v.XmlDoc + | :? FSharpEntity as t -> t.XmlDoc + | :? FSharpUnionCase as u -> u.XmlDoc + | _ -> failwith $"unexpected symbol type {symbol.GetType()}" + match xmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines |> shouldEqual docs + | _ -> failwith "wrong XmlDoc kind" + +let checkXmls data checkResults = + for symbolName, docs in data do checkXml symbolName docs checkResults + +[] +let ``simple type xml doc``() = + let _, checkResults = getParseAndCheckResults """ +///A +type A = class end +""" + checkResults + |> checkXml "A" [|"A"|] + +[] +let ``simple signature type xml doc``() = + let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +///A1 +///A2 +type + ///A3 + internal + ///A4 + A +""" + checkResults + |> checkXml "A" [|"A1"; "A2"|] + +[] +let ``xml doc before/after type name``() = + let _, checkResults = getParseAndCheckResults """ +///A1 +type + ///A2 + [] + A = class end +""" + checkResults + |> checkXml "A" [|"A1"|] + +[] +let ``multiline type xml doc``() = + let _, checkResults = getParseAndCheckResults """ +///A + +///B +type A = class end +""" + checkResults + |> checkXml "A" [|"A"; "B"|] + +[] +let ``separated type xml doc``() = + let _, checkResults = getParseAndCheckResults """ +///A +() +///B +type A = class end +""" + checkResults + |> checkXml "A" [|"B"|] + +[] +let ``separated by simple comment type xml doc``() = + let _, checkResults = getParseAndCheckResults """ +///A +// Simple comment delimiter +///B +type A = class end +""" + checkResults + |> checkXml "A" [|"B"|] + +[] +let ``separated by multiline comment type xml doc``() = + let _, checkResults = getParseAndCheckResults """ +///A +(* Multiline comment +delimiter *) +///B +type A = class end +""" + checkResults + |> checkXml "A" [|"B"|] + +[] +let ``separated by star type xml doc``() = + let _, checkResults = getParseAndCheckResults """ +///A +(*) +///B +type A = class end +""" + checkResults + |> checkXml "A" [|"B"|] + +[] +let Let1() = + let _, checkResults = getParseAndCheckResults """ +///A +1 + 1 +///B +let f x = () +""" + checkResults + |> checkXml "f" [|"B"|] + +[] +let Let2() = + let _, checkResults = getParseAndCheckResults """ +let _ = + ///A + 1 + 1 + ///B + let x = () + () +""" + checkResults + |> checkXml "x" [|"B"|] + +[] +let ``And type xml doc``() = + let _, checkResults = getParseAndCheckResults """ +type A = class end +///B +and B = class end +""" + checkResults + |> checkXml "B" [|"B"|] + +[] +let ``type xml doc after and``() = + let _, checkResults = getParseAndCheckResults """ +type A = class end +and ///B + B = class end +""" + checkResults + |> checkXml "B" [|"B"|] + +[] +let ``type xml docs before/after and``() = + let _, checkResults = getParseAndCheckResults """ +type A = class end +///B1 +and ///B2 + B = class end +""" + checkResults + |> checkXml "B" [|"B1"|] + + +[] +let ``union cases``() = + let _, checkResults = getParseAndCheckResults """ +type A = + ///One + One + ///Two + | Two +""" + checkResults + |> checkXmls [ + "One", [|"One"|] + "Two", [|"Two"|] + ] + +[] +let ``type member multiline xml doc``() = + let _, checkResults = getParseAndCheckResults """ +type A = + member x.A() = ///B1 + () + + ///B2 + ///B3 + member x.B() = () +""" + checkResults + |> checkXml "B" [|"B2"; "B3"|] + +[] +let ``type member with attributes``() = + let _, checkResults = getParseAndCheckResults """ +type A = + ///B1 + ///B2 + [] + ///B3 + member x.B() = () +""" + checkResults + |> checkXml "B" [|"B1"; "B2"|] + +[] +let ``type member xml doc``() = + let _, checkResults = getParseAndCheckResults """ +type A = + ///B1 + member + ///B2 + private x.B() = () +""" + checkResults + |> checkXml "B" [|"B1"|] + +[] +let Test141() = + let _, checkResults = getParseAndCheckResults """ +///A1 +///A2 +[] +///B +type A = class end +""" + checkResults + |> checkXml "A" [|"A1"; "A2"|] + +[] +let Test142() = + let _, checkResults = getParseAndCheckResults """ +type A = class end +and + ///B1 + [] + ///B2 + B = class end +""" + checkResults + |> checkXml "B" [|"B1"|] + +[] +let ``type specifications xml doc``() = + let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +type A +and + ///B1 + [] + ///B2 + B +""" + checkResults + |> checkXml "B" [|"B1"|] + +[] +let ``xml docs after attributes``() = + let _, checkResults = getParseAndCheckResults """ +[] +///A +type A = class end +""" + checkResults + |> checkXml "A" [||] + +[] +let ``abstract member multiline xml doc``() = + let _, checkResults = getParseAndCheckResults """ +type A = + ///M1 + ///M2 + abstract member M: unit +""" + checkResults + |> checkXml "get_M" [|"M1"; "M2"|] + +[] +let ``abstract type member with attributes``() = + let _, checkResults = getParseAndCheckResults """ +type A = + ///M1 + [] + ///M2 + abstract member M: unit +""" + checkResults + |> checkXml "get_M" [|"M1"|] + +[] +let ``signature type member with attributes``() = + let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +type A = + ///M1 + ///M2 + [] + ///M3 + abstract member M: unit +""" + checkResults + |> checkXml "get_M" [|"M1"; "M2"|] + +[] +let ``Property accessors xml doc``() = + let _, checkResults = getParseAndCheckResults """ +type B = + ///A1 + ///A2 + member ///A3 + x.A + ///GET + with get () = 5 + ///SET + and set (_: int) = () + + member x.C = x.set_A(4) +""" + + checkResults + |> checkXmls [ + "get_A", [|"A1"; "A2"|] + "set_A", [|"A1"; "A2"|] + ] + +[] +let ``record multiline xml doc``() = + let _, checkResults = getParseAndCheckResults """ +type A = + { + ///B1 + ///B2 + B: int + } + +{ B = 1 }.B +""" + checkResults + |> checkXml "B" [|"B1"; "B2"|] From 9f6a77e242b752655ac4b800e7e9984be5482097 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Wed, 18 Aug 2021 16:43:30 +0300 Subject: [PATCH 02/25] let bindings and 'extern' support --- src/fsharp/ParseHelpers.fs | 2 - src/fsharp/XmlDoc.fs | 2 +- src/fsharp/pars.fsy | 39 +++++----- tests/service/XmlDocTests.fs | 134 +++++++++++++++++++++++++++++++++-- 4 files changed, 151 insertions(+), 26 deletions(-) diff --git a/src/fsharp/ParseHelpers.fs b/src/fsharp/ParseHelpers.fs index d58af7d3378..369a127014d 100644 --- a/src/fsharp/ParseHelpers.fs +++ b/src/fsharp/ParseHelpers.fs @@ -6,8 +6,6 @@ open FSharp.Compiler.AbstractIL open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features open FSharp.Compiler.SyntaxTreeOps -open FSharp.Compiler.Text -open FSharp.Compiler.Text open FSharp.Compiler.UnicodeLexing open FSharp.Compiler.Text open FSharp.Compiler.Text.Position diff --git a/src/fsharp/XmlDoc.fs b/src/fsharp/XmlDoc.fs index e09624b7036..0ca07c74111 100644 --- a/src/fsharp/XmlDoc.fs +++ b/src/fsharp/XmlDoc.fs @@ -147,7 +147,7 @@ and XmlDocStatics() = /// Used to collect XML documentation during lexing and parsing. type XmlDocCollector() = let mutable savedLines = ResizeArray() - let mutable savedGrabPoints = Dictionary<_, _>() + let mutable savedGrabPoints = Dictionary() let mutable currentGrabPointCommentsCount = 0 let posCompare p1 p2 = if posGeq p1 p2 then 1 else if posEq p1 p2 then 0 else -1 diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 26dd62efe27..a61a268e9e6 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -2601,9 +2601,10 @@ defnBindings: // The first binding swallows any attributes prior to the 'let' BindingSetPreAttrs(mLetKwd, isRec, isUse, - (fun attrs vis -> + (fun attrs vis -> + let xmlDoc = grabXmlDoc(parseState, attrs, 1) // apply the builder - let binds = localBindingsBuilder attrs vis mLetKwd + let binds = localBindingsBuilder xmlDoc attrs vis mLetKwd if not isRec && not (isNilOrSingleton binds) then reportParseErrorAt mLetKwd (FSComp.SR.parsLetAndForNonRecBindings()) [], binds), @@ -2643,7 +2644,8 @@ hardwhiteLetBindings: // the first binding swallow any attributes prior to the 'let' BindingSetPreAttrs(mLetKwd, isRec, isUse, (fun attrs vis -> - let binds = localBindingsBuilder attrs vis mLetKwd + let xmlDoc = grabXmlDoc(parseState, attrs, 1) + let binds = localBindingsBuilder xmlDoc attrs vis mLetKwd if not isRec && not (isNilOrSingleton binds) then reportParseErrorAt mLetKwd (FSComp.SR.parsLetAndForNonRecBindings()) [], binds), @@ -2694,8 +2696,7 @@ hardwhiteDefnBindingsTerminator: /* An 'extern' DllImport function definition in C-style syntax */ cPrototype: | EXTERN cRetType opt_access ident opt_HIGH_PRECEDENCE_APP LPAREN cArgs rparen - { let rty, vis, nm, args = $2, $3, $4, $7 - let xmlDoc = grabXmlDoc(parseState, [], 1) + { let rty, vis, nm, args = $2, $3, $4, $7 let nmm = rhs parseState 3 let argsm = rhs parseState 6 let mBindLhs = lhs parseState @@ -2706,9 +2707,10 @@ cPrototype: SynExpr.Ident (ident("failwith", rhs parseState 6)), SynExpr.Const (SynConst.String("extern was not given a DllImport attribute", SynStringKind.Regular, rhs parseState 8), rhs parseState 8), mRhs) - (fun attrs _ -> + (fun attrs _ -> let bindingId = SynPat.LongIdent (LongIdentWithDots([nm], []), None, Some noInferredTypars, SynArgPats.Pats [SynPat.Tuple(false, args, argsm)], vis, nmm) let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) + let xmlDoc = grabXmlDoc(parseState, attrs, 1) let binding = mkSynBinding (xmlDoc, bindingId) (vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None) @@ -2785,16 +2787,19 @@ localBindings: match moreLocalBindingsLastRange with | None -> localBindingRange | Some m -> m - Some lastRange, (fun attrs vis mLetKwd -> attrLocalBindingBuilder attrs vis mLetKwd true :: moreBindings) + Some lastRange, (fun xmlDoc attrs vis mLetKwd -> attrLocalBindingBuilder xmlDoc attrs vis mLetKwd true :: moreBindings) | None -> - moreLocalBindingsLastRange, (fun _attrs _vis _letm -> moreBindings) } + moreLocalBindingsLastRange, (fun _xmlDoc _attrs _vis _letm -> moreBindings) } moreLocalBindings: | AND attr_localBinding moreLocalBindings { let mLetKwd = rhs parseState 1 (match $2 with - | Some (localBindingRange, attrLocalBindingBuilder) -> (attrLocalBindingBuilder [] None mLetKwd false, localBindingRange) :: $3 + | Some (localBindingRange, attrLocalBindingBuilder) -> + let xmlDoc = grabXmlDoc(parseState, [], 1) + let xmlDoc = if xmlDoc.IsEmpty then grabXmlDoc(parseState, [], 2) else xmlDoc + (attrLocalBindingBuilder xmlDoc [] None mLetKwd false, localBindingRange) :: $3 | None -> $3) } | %prec prec_no_more_attr_bindings @@ -2806,7 +2811,7 @@ attr_localBinding: | opt_attributes localBinding { let attrs2 = $1 let localBindingRange, localBindingBuilder = $2 - let attrLocalBindingBuilder = (fun attrs vis mLetKwd _ -> localBindingBuilder (attrs@attrs2) vis mLetKwd) + let attrLocalBindingBuilder = (fun xmlDoc attrs vis mLetKwd _ -> localBindingBuilder xmlDoc (attrs@attrs2) vis mLetKwd) Some(localBindingRange, attrLocalBindingBuilder) } | error @@ -2822,9 +2827,8 @@ localBinding: let optReturnType = $4 let bindingBuilder, mBindLhs = $3 let localBindingRange = unionRanges (rhs2 parseState 1 5) mRhs - let xmlDoc = grabXmlDoc(parseState, [], 1) let localBindingBuilder = - (fun attrs vis mLetKwd -> + (fun xmlDoc attrs vis mLetKwd -> let mWhole = (unionRanges mLetKwd mRhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) let spBind = if IsControlFlowExpression expr then DebugPointAtBinding.NoneAtLet else DebugPointAtBinding.Yes mWhole let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) @@ -2836,9 +2840,8 @@ localBinding: let mRhs = rhs parseState 5 let optReturnType = $4 let bindingBuilder, mBindLhs = $3 - let xmlDoc = grabXmlDoc(parseState, [], 1) let localBindingBuilder = - (fun attrs vis mLetKwd -> + (fun xmlDoc attrs vis mLetKwd -> let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs) let eqm = rhs parseState 5 let zeroWidthAtEnd = eqm.EndRange @@ -2852,9 +2855,9 @@ localBinding: let mRhs = mWhole.EndRange // zero-width range at end of last good token let bindingBuilder, mBindLhs = $3 let localBindingBuilder = - (fun attrs vis mLetKwd -> + (fun xmlDoc attrs vis mLetKwd -> let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs) - (bindingBuilder PreXmlDoc.Empty) (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding2", mRhs), mRhs, [], attrs, None)) + (bindingBuilder xmlDoc) (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding2", mRhs), mRhs, [], attrs, None)) mWhole, localBindingBuilder } @@ -4739,12 +4742,12 @@ objExprBindings: | WITH localBindings { let mWithKwd = (rhs parseState 1) let _localBindingsLastRange, localBindingsBuilder = $2 - localBindingsBuilder [] None mWithKwd } + localBindingsBuilder PreXmlDoc.Empty [] None mWithKwd } | OWITH localBindings OEND { let mWithKwd = (rhs parseState 1) let _localBindingsLastRange, localBindingsBuilder = $2 - localBindingsBuilder [] None mWithKwd } + localBindingsBuilder PreXmlDoc.Empty [] None mWithKwd } | WITH objectImplementationBlock opt_declEnd { $2 |> diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index 3c8443161c7..c6b8f721841 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -118,8 +118,28 @@ type A = class end checkResults |> checkXml "A" [|"B"|] -[] -let Let1() = +[] +let ``let binding 01 - simple``() = + let _, checkResults = getParseAndCheckResults """ +///f1 +let ///f2 + rec ///f3 + private f x = f x +""" + checkResults + |> checkXml "f" [|"f1"|] + +[] +let ``let binding 02 - let in``() = + let _, checkResults = getParseAndCheckResults """ +///X +let x = 3 in print x +""" + checkResults + |> checkXml "x" [|"X"|] + +[] +let ``let binding 03 - expression delimiter``() = let _, checkResults = getParseAndCheckResults """ ///A 1 + 1 @@ -129,8 +149,8 @@ let f x = () checkResults |> checkXml "f" [|"B"|] -[] -let Let2() = +[] +let ``let binding 04 - local binding``() = let _, checkResults = getParseAndCheckResults """ let _ = ///A @@ -143,7 +163,67 @@ let _ = |> checkXml "x" [|"B"|] [] -let ``And type xml doc``() = +let ``let binding 05 - with attribute``() = + let _, checkResults = getParseAndCheckResults """ +///X +[] +let x = 5 +""" + checkResults + |> checkXml "x" [|"X"|] + +[] +let ``let binding 06 - xml doc after attribute``() = + let _, checkResults = getParseAndCheckResults """ +[] +///X +let x = 5 +""" + checkResults + |> checkXml "x" [||] + +[] +let ``let binding 07 - attribute after 'let'``() = + let _, checkResults = getParseAndCheckResults """ +///X +let [] x = 5 +""" + checkResults + |> checkXml "x" [|"X"|] + +[] +let ``let binding 08 - xml doc before 'and'``() = + let _, checkResults = getParseAndCheckResults """ +let rec f x = g x +///G +and g x = f x +""" + checkResults + |> checkXml "g" [|"G"|] + +[] +let ``let binding 09 - xml doc after 'and'``() = + let _, checkResults = getParseAndCheckResults """ +let rec f x = g x +and ///G + [] g x = f x +""" + checkResults + |> checkXml "g" [|"G"|] + +[] +let ``let binding 010 - xml doc before and after 'and'``() = + let _, checkResults = getParseAndCheckResults """ +let rec f x = g x +///G1 +and ///G2 + g x = f x +""" + checkResults + |> checkXml "g" [|"G1"|] + +[] +let ``and type xml doc``() = let _, checkResults = getParseAndCheckResults """ type A = class end ///B @@ -348,3 +428,47 @@ type A = """ checkResults |> checkXml "B" [|"B1"; "B2"|] + +[] +let ``attributes after type keyword``() = + let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +///A1 +type ///A2 + [] A = class end +""" + checkResults + |> checkXml "A" [|"A1"|] + +[] +let ``module definition``() = + let _, checkResults = getParseAndCheckResults """ +///M1 +module + ///M2 + rec M = + open M +""" + checkResults + |> checkXml "M" [|"M1"|] + +[] +let ``module specification``() = + let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +///M1 +module + ///M2 + rec M +""" + checkResults + |> checkXml "M" [|"M1"|] + +[] +let ``extern``() = + let _, checkResults = getParseAndCheckResults """ +///E +[] +extern void E() +""" + checkResults + |> checkXml "E" [|"E"|] + From 761b9236c1a9d52f31beade6dc766513ea893379 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Thu, 19 Aug 2021 12:53:52 +0300 Subject: [PATCH 03/25] fix SurfaceArea --- .../FSharp.CompilerService.SurfaceArea.netstandard.expected | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected index 05ec57601fd..9abebe4bf11 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -10442,6 +10442,8 @@ FSharp.Compiler.Xml.PreXmlDoc FSharp.Compiler.Xml.PreXmlDoc: Boolean Equals(FSharp.Compiler.Xml.PreXmlDoc) FSharp.Compiler.Xml.PreXmlDoc: Boolean Equals(System.Object) FSharp.Compiler.Xml.PreXmlDoc: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Xml.PreXmlDoc: Boolean IsEmpty +FSharp.Compiler.Xml.PreXmlDoc: Boolean get_IsEmpty() FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.PreXmlDoc Create(System.String[], FSharp.Compiler.Text.Range) FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.PreXmlDoc Empty FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.PreXmlDoc Merge(FSharp.Compiler.Xml.PreXmlDoc, FSharp.Compiler.Xml.PreXmlDoc) From 52a31c3c5a05cf92411ea288ce1b9911df859bef Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Thu, 19 Aug 2021 16:22:49 +0300 Subject: [PATCH 04/25] fix for val & member val --- src/fsharp/pars.fsy | 24 ++++++++++--------- .../fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index a61a268e9e6..2373fbcb8e9 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -1981,19 +1981,22 @@ classDefnMember: | opt_attributes opt_declVisibility valDefnDecl opt_ODECLEND { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let rangeStart = rhs parseState 1 - $3 rangeStart $1 false } + let xmlDoc = grabXmlDoc(parseState, $1, 1) + $3 xmlDoc rangeStart $1 false } | opt_attributes opt_declVisibility STATIC valDefnDecl opt_ODECLEND { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let rangeStart = rhs parseState 1 - $4 rangeStart $1 true } + let xmlDoc = grabXmlDoc(parseState, $1, 1) + $4 xmlDoc rangeStart $1 true } | opt_attributes opt_declVisibility memberFlags autoPropsDefnDecl opt_ODECLEND { let rangeStart = rhs parseState 1 if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let isStatic, flags = $3 - $4 $1 isStatic flags rangeStart } + let xmlDoc = grabXmlDoc(parseState, $1, 1) + $4 xmlDoc $1 isStatic flags rangeStart } | opt_attributes opt_declVisibility NEW atomicPattern optAsSpec EQUALS typedSequentialExprBlock opt_ODECLEND { let mWholeBindLhs = rhs2 parseState 1 (if Option.isSome $5 then 5 else 4) @@ -2015,24 +2018,22 @@ classDefnMember: valDefnDecl: | VAL opt_mutable opt_access ident COLON typ { let mRhs = rhs2 parseState 4 6 - let doc = grabXmlDoc(parseState, [], 3) let mValDecl = rhs2 parseState 1 6 - (fun rangeStart attribs isStatic -> + (fun xmlDoc rangeStart attribs isStatic -> let mValDecl = unionRanges rangeStart mValDecl - let fld = SynField(attribs, isStatic, Some $4, $6, $2, doc, $3, mRhs) + let fld = SynField(attribs, isStatic, Some $4, $6, $2, xmlDoc, $3, mRhs) [ SynMemberDefn.ValField(fld, mValDecl) ]) } /* An auto-property definition in an object type definition */ autoPropsDefnDecl: | VAL opt_mutable opt_access ident opt_typ EQUALS typedSequentialExprBlock classMemberSpfnGetSet - { let doc = grabXmlDoc(parseState, [], 5) - let mGetSetOpt, getSet = $8 + { let mGetSetOpt, getSet = $8 if $2 then errorR (Error (FSComp.SR.parsMutableOnAutoPropertyShouldBeGetSet (), rhs parseState 3)) - (fun attribs isStatic flags rangeStart -> + (fun xmlDoc attribs isStatic flags rangeStart -> let memberRange = unionRanges rangeStart $7.Range - [ SynMemberDefn.AutoProperty(attribs, isStatic, $4, $5, getSet, flags, doc, $3, $7, mGetSetOpt, memberRange) ]) } + [ SynMemberDefn.AutoProperty(attribs, isStatic, $4, $5, getSet, flags, xmlDoc, $3, $7, mGetSetOpt, memberRange) ]) } /* An optional type on an auto-property definition */ @@ -2188,7 +2189,8 @@ objectImplementationMember: | opt_attributes memberOrOverride autoPropsDefnDecl opt_ODECLEND { let rangeStart = rhs parseState 1 - $3 $1 false OverrideMemberFlags rangeStart } + let xmlDoc = grabXmlDoc(parseState, $1, 1) + $3 xmlDoc $1 false OverrideMemberFlags rangeStart } | opt_attributes memberOrOverride error { [] } diff --git a/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs b/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs index f41c9f3198d..842b78b92db 100644 --- a/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs +++ b/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs @@ -5,8 +5,8 @@ #light -/// I'm an xml comment! //// I am NOT an xml comment +/// I'm an xml comment! type e = | A | B From 8d10fa61c33fffd90bc88fe3de46ac2a6c0b17a5 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Fri, 20 Aug 2021 20:40:20 +0300 Subject: [PATCH 05/25] tests + fixes --- src/fsharp/pars.fsy | 95 +-- .../FSharp.Compiler.Service.Tests.fsproj | 2 +- tests/service/XmlDocTests.fs | 550 +++++++++--------- 3 files changed, 340 insertions(+), 307 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 2373fbcb8e9..14cc9dd066b 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -682,7 +682,7 @@ moduleIntro: | moduleKeyword opt_attributes opt_access opt_rec path { if not (isNil $2) then parseState.LexBuffer.CheckLanguageFeatureErrorRecover LanguageFeature.AttributesToRightOfModuleKeyword <| rhs parseState 4 - $4, $5.Lid, grabXmlDoc(parseState, [], 1), $3, $2 } + $4, $5.Lid, $3, $2 } /* The start of a namespace declaration */ @@ -732,11 +732,12 @@ fileModuleSpec: let m2 = rhs parseState 3 let mDeclsAndAttrs = (List.map (fun (a: SynAttributeList) -> a.Range) $1) @ (List.map (fun (d: SynModuleSigDecl) -> d.Range) $4) let m = (m2, mDeclsAndAttrs) ||> unionRangeWithListBy id - let isRec, path2, xml, vis, attribs2 = $3 + let isRec, path2, vis, attribs2 = $3 + let xmlDoc = grabXmlDoc(parseState, $1, 1) (fun (isRec2, path, _) -> if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(), m2)) let lid = path@path2 - ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1 @ attribs2, vis, m))) } + ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xmlDoc, $1 @ attribs2, vis, m))) } | moduleSpfnsPossiblyEmptyBlock { let m = (rhs parseState 1) @@ -797,7 +798,7 @@ moduleSpfn: | opt_attributes opt_declVisibility moduleIntro colonOrEquals namedModuleAbbrevBlock { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let isRec, path, xml, vis, attribs2 = $3 + let isRec, path, vis, attribs2 = $3 if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) if not (isNil $1) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) @@ -807,35 +808,32 @@ moduleSpfn: | _ -> SynModuleSigDecl.ModuleAbbrev(List.head path, $5, rhs2 parseState 1 5) } | opt_attributes opt_declVisibility moduleIntro colonOrEquals moduleSpecBlock - { let isRec, path, xml, vis, attribs2 = $3 + { let isRec, path, vis, attribs2 = $3 + let xmlDoc = grabXmlDoc(parseState, $1, 1) if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleDefnMustBeSimpleName()) if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) - let info = SynComponentInfo($1 @ attribs2, None, [], path, xml, false, vis, rhs parseState 3) + let info = SynComponentInfo($1 @ attribs2, None, [], path, xmlDoc, false, vis, rhs parseState 3) if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let m = (rhs2 parseState 1 4, $5) ||> unionRangeWithListBy (fun (d: SynModuleSigDecl) -> d.Range) SynModuleSigDecl.NestedModule(info, isRec, $5, m) } - | opt_attributes opt_declVisibility typeKeyword tyconSpfnList - { if Option.isSome $2 then - errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) - - match $4 with - | [] -> raiseParseErrorAt (rhs2 parseState 3 4) (FSComp.SR.parsUnexpectedEmptyModuleDefn ()) - | SynTypeDefnSig (SynComponentInfo (cas, a, cs, b, _, d, d2, d3), e, f, g) :: tail -> - let attrs = $1 @ cas - let mTc = - let keywordM = rhs parseState 3 - (keywordM, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) |> unionRanges g - let xmlDoc = grabXmlDoc(parseState, $1, 3) - let tc = (SynTypeDefnSig(SynComponentInfo(attrs, a, cs, b, xmlDoc, d, d2, d3), e, f, mTc)) - let m = (mTc, tail) ||> unionRangeWithListBy (fun (a: SynTypeDefnSig) -> a.Range) - - SynModuleSigDecl.Types (tc :: tail, m) } + | opt_attributes opt_declVisibility typeKeyword tyconSpfn tyconSpfnList + { if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) + let (SynTypeDefnSig (SynComponentInfo (cas, a, cs, b, _, d, d2, d3), e, f, g)) = $4 + let attrs = $1 @ cas + let mTc = + let keywordM = rhs parseState 3 + (keywordM, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) |> unionRanges g + let xmlDoc = grabXmlDoc(parseState, $1, 1) + let tc = (SynTypeDefnSig(SynComponentInfo(attrs, a, cs, b, xmlDoc, d, d2, d3), e, f, mTc)) + let m = (mTc, $5) ||> unionRangeWithListBy (fun (a: SynTypeDefnSig) -> a.Range) + SynModuleSigDecl.Types (tc :: $5, m) } | opt_attributes opt_declVisibility exconSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let (SynExceptionSig(SynExceptionDefnRepr(cas, a, b, c, d, d2), e, f)) = $3 - let ec = SynExceptionSig(SynExceptionDefnRepr($1@cas, a, b, c, d, d2), e, f) + let (SynExceptionSig(SynExceptionDefnRepr(cas, a, b, c, d, d2), e, f)) = $3 + let xmlDoc = grabXmlDoc(parseState, $1, 1) + let ec = SynExceptionSig(SynExceptionDefnRepr($1@cas, a, b, xmlDoc, d, d2), e, f) SynModuleSigDecl.Exception(ec, rhs parseState 3) } | openDecl @@ -844,7 +842,7 @@ moduleSpfn: valSpfn: | opt_attributes opt_declVisibility VAL opt_attributes opt_inline opt_mutable opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints optLiteralValueSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let attr1, attr2, isInline, isMutable, vis2, id, doc, explicitValTyparDecls, (ty, arity), konst = ($1), ($4), ($5), ($6), ($7), ($8), grabXmlDoc(parseState, $1, 3), ($9), ($11), ($12) + let attr1, attr2, isInline, isMutable, vis2, id, doc, explicitValTyparDecls, (ty, arity), konst = ($1), ($4), ($5), ($6), ($7), ($8), grabXmlDoc(parseState, $1, 1), ($9), ($11), ($12) if not (isNil attr2) then errorR(Deprecated(FSComp.SR.parsAttributesMustComeBeforeVal(), rhs parseState 4)) let m = rhs2 parseState 1 11 let valSpfn = SynValSig((attr1@attr2), id, explicitValTyparDecls, ty, arity, isInline, isMutable, doc, vis2, konst, m) @@ -880,11 +878,16 @@ moduleSpecBlock: tyconSpfnList: - | tyconSpfn AND tyconSpfnList - { $1 :: $3 } + | AND tyconSpfn tyconSpfnList + { let xmlDoc = grabXmlDoc(parseState, [], 1) + let tyconSpfn = + if xmlDoc.IsEmpty then $2 else + let (SynTypeDefnSig(SynComponentInfo (a, typars, c, lid, _, fixity, vis, rangeOfLid), typeRepr, members, range)) = $2 + SynTypeDefnSig(SynComponentInfo (a, typars, c, lid, xmlDoc, fixity, vis, rangeOfLid), typeRepr, members, range) + tyconSpfn :: $3 } - | tyconSpfn - { [$1] } + | + { [] } /* A type definition in a signature */ @@ -1035,13 +1038,15 @@ classMemberSpfn: | opt_attributes opt_declVisibility VAL fieldDecl { let wholeRange = rhs2 parseState 1 4 if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) - let fld = $4 $1 false wholeRange + let xmlDoc = grabXmlDoc(parseState, $1, 1) + let fld = $4 xmlDoc $1 false wholeRange SynMemberSig.ValField (fld, wholeRange) } | opt_attributes opt_declVisibility STATIC VAL fieldDecl { let wholeRange = rhs2 parseState 1 5 if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) - SynMemberSig.ValField($5 $1 true wholeRange, wholeRange) } + let xmlDoc = grabXmlDoc(parseState, $1, 1) + SynMemberSig.ValField($5 xmlDoc $1 true wholeRange, wholeRange) } | opt_attributes opt_declVisibility STATIC typeKeyword tyconSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) @@ -1170,11 +1175,12 @@ fileModuleImpl: let m2 = rhs parseState 3 let mDeclsAndAttrs = (List.map (fun (a: SynAttributeList) -> a.Range) $1) @ (List.map (fun (d: SynModuleDecl) -> d.Range) $4) let m = (m2, mDeclsAndAttrs) ||> unionRangeWithListBy id - let isRec2, path2, xml, vis, attribs2 = $3 + let isRec2, path2, vis, attribs2 = $3 + let xmlDoc = grabXmlDoc(parseState, $1, 1) (fun (isRec, path, _) -> if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(), m2)) let lid = path@path2 - ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1@attribs2, vis, m))) } + ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xmlDoc, $1@attribs2, vis, m))) } | moduleDefnsOrExprPossiblyEmptyOrBlock { let m = (rhs parseState 1) @@ -1311,13 +1317,15 @@ moduleDefn: { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let (SynExceptionDefn(SynExceptionDefnRepr(cas, a, b, c, d, d2), e, f)) = $3 let f = (f, $1) ||> unionRangeWithListBy (fun a -> a.Range) - let ec = (SynExceptionDefn(SynExceptionDefnRepr($1@cas, a, b, c, d, d2), e, f)) + let xmlDoc = grabXmlDoc(parseState, $1, 1) + let ec = (SynExceptionDefn(SynExceptionDefnRepr($1@cas, a, b, xmlDoc, d, d2), e, f)) [ SynModuleDecl.Exception(ec, f) ] } /* 'module' definitions */ | opt_attributes opt_declVisibility moduleIntro EQUALS namedModuleDefnBlock { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let attribs, (isRec, path, xml, vis, attribs2) = $1, $3 + let attribs, (isRec, path, vis, attribs2) = $1, $3 + let xmlDoc = grabXmlDoc(parseState, $1, 1) match $5 with | Choice1Of2 eqn -> if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) @@ -1331,7 +1339,7 @@ moduleDefn: [ SynModuleDecl.ModuleAbbrev(List.head path, eqn, (rhs parseState 3, eqn) ||> unionRangeWithListBy (fun id -> id.idRange) ) ] | Choice2Of2 def -> if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) - let info = SynComponentInfo(attribs @ attribs2, None, [], path, xml, false, vis, rhs parseState 3) + let info = SynComponentInfo(attribs @ attribs2, None, [], path, xmlDoc, false, vis, rhs parseState 3) [ SynModuleDecl.NestedModule(info, isRec, def, false, (rhs2 parseState 1 4, def) ||> unionRangeWithListBy (fun d -> d.Range) ) ] } /* unattached custom attributes */ @@ -2540,7 +2548,8 @@ recdFieldDeclList: recdFieldDecl: | opt_attributes fieldDecl { let wholeRange = rhs2 parseState 1 2 - let fld = $2 $1 false wholeRange + let xmlDoc = grabXmlDoc(parseState, $1, 1) + let fld = $2 xmlDoc $1 false wholeRange let (SynField (a, b, c, d, e, f, vis, wholeRange)) = fld if Option.isSome vis then errorR (Error (FSComp.SR.parsRecordFieldsCannotHaveVisibilityDeclarations (), rhs parseState 2)) SynField (a, b, c, d, e, f, None, wholeRange) } @@ -2548,23 +2557,17 @@ recdFieldDecl: /* Part of a field or val declaration in a record type or object type */ fieldDecl: | opt_mutable opt_access ident COLON typ - { let xmlDoc = grabXmlDoc (parseState, [], 3) - fun attrs stat wholeRange -> SynField(attrs, stat, Some $3, $5, $1, xmlDoc, $2, wholeRange) } + { fun xmlDoc attrs stat wholeRange -> SynField(attrs, stat, Some $3, $5, $1, xmlDoc, $2, wholeRange) } /* An exception definition */ exconDefn: | exconCore opt_classDefn { SynExceptionDefn($1, $2, ($1.Range, $2) ||> unionRangeWithListBy (fun cd -> cd.Range) ) } - -/* Part of an exception definition */ -exceptionAndGrabDoc: - | EXCEPTION - { grabXmlDoc(parseState, [], 1) } /* Part of an exception definition */ exconCore: - | exceptionAndGrabDoc opt_attributes opt_access exconIntro exconRepr - { SynExceptionDefnRepr($2, $4, $5, $1, $3, (match $5 with None -> rhs2 parseState 1 4 | Some p -> unionRanges (rangeOfLongIdent p) (rhs2 parseState 1 4))) } + | EXCEPTION opt_attributes opt_access exconIntro exconRepr + { SynExceptionDefnRepr($2, $4, $5, PreXmlDoc.Empty, $3, (match $5 with None -> rhs2 parseState 1 4 | Some p -> unionRanges (rangeOfLongIdent p) (rhs2 parseState 1 4))) } /* Part of an exception definition */ exconIntro: diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 2b2505d0d61..33af688de6e 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -75,7 +75,7 @@ XmlDocTests.fs - + Program.fs diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index c6b8f721841..3ae2ffd6f88 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -12,6 +12,18 @@ open FSharp.Compiler.Symbols open FsUnit open NUnit.Framework +let getFieldXml symbolName fieldName checkResults = + let field = + match findSymbolByName symbolName checkResults with + | :? FSharpEntity as e -> e.FSharpFields |> Seq.find(fun x -> x.DisplayName = fieldName) + | _ -> failwith "Unexpected symbol" + field.XmlDoc + +let compareXml docs xmlDoc = + match xmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines |> shouldEqual docs + | _ -> failwith "wrong XmlDoc kind" + let checkXml symbolName docs checkResults = let symbol = findSymbolByName symbolName checkResults let xmlDoc = @@ -20,64 +32,65 @@ let checkXml symbolName docs checkResults = | :? FSharpEntity as t -> t.XmlDoc | :? FSharpUnionCase as u -> u.XmlDoc | _ -> failwith $"unexpected symbol type {symbol.GetType()}" - match xmlDoc with - | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines |> shouldEqual docs - | _ -> failwith "wrong XmlDoc kind" + compareXml docs xmlDoc let checkXmls data checkResults = for symbolName, docs in data do checkXml symbolName docs checkResults +let checkSignatureAndImplementation code checkAction = + getParseAndCheckResults code |> snd + |> checkAction + + getParseAndCheckResultsOfSignatureFile code |> snd + |> checkAction + [] -let ``simple type xml doc``() = +let ``separated by expression``() = let _, checkResults = getParseAndCheckResults """ ///A -type A = class end +() +///B +type A """ checkResults - |> checkXml "A" [|"A"|] + |> checkXml "A" [|"B"|] [] -let ``simple signature type xml doc``() = - let _, checkResults = getParseAndCheckResultsOfSignatureFile """ -///A1 -///A2 -type - ///A3 - internal - ///A4 - A +let ``separated by // comment``() = + checkSignatureAndImplementation """ +///A +// Simple comment delimiter +///B +type A = class end """ - checkResults - |> checkXml "A" [|"A1"; "A2"|] + (checkXml "A" [|"B"|]) [] -let ``xml doc before/after type name``() = - let _, checkResults = getParseAndCheckResults """ -///A1 -type - ///A2 - [] - A = class end +let ``separated by //// comment``() = + checkSignatureAndImplementation """ +///A +//// Comment delimiter +///B +type A = class end """ - checkResults - |> checkXml "A" [|"A1"|] + (checkXml "A" [|"B"|]) [] -let ``multiline type xml doc``() = - let _, checkResults = getParseAndCheckResults """ +let ``separated by multiline comment``() = + checkSignatureAndImplementation """ ///A - +(* Multiline comment +delimiter *) ///B type A = class end """ - checkResults - |> checkXml "A" [|"A"; "B"|] + (checkXml "A" [|"B"|]) [] -let ``separated type xml doc``() = +let ``separated by (*)``() = let _, checkResults = getParseAndCheckResults """ ///A -() +(*) ///B type A = class end """ @@ -85,95 +98,130 @@ type A = class end |> checkXml "A" [|"B"|] [] -let ``separated by simple comment type xml doc``() = - let _, checkResults = getParseAndCheckResults """ -///A -// Simple comment delimiter -///B +let ``types 01 - xml doc allowed positions``() = + checkSignatureAndImplementation """ +///A1 +///A2 +type + ///A3 + internal + ///A4 + A +""" + (checkXml "A" [|"A1"; "A2"|]) + +[] +let ``types 02 - xml doc before 'and'``() = + checkSignatureAndImplementation """ type A = class end +///B1 +///B2 +and B = class end """ - checkResults - |> checkXml "A" [|"B"|] + (checkXml "B" [|"B1"; "B2"|]) [] -let ``separated by multiline comment type xml doc``() = - let _, checkResults = getParseAndCheckResults """ -///A -(* Multiline comment -delimiter *) -///B +let ``types 03 - xml doc after 'and'``() = + checkSignatureAndImplementation """ type A = class end +and ///B1 + ///B2 + [] + ///B3 + B = class end """ - checkResults - |> checkXml "A" [|"B"|] + (checkXml "B" [|"B1"; "B2"|]) [] -let ``separated by star type xml doc``() = - let _, checkResults = getParseAndCheckResults """ +let ``types 04 - xml doc before/after 'and'``() = + checkSignatureAndImplementation """ +type A = class end +///B1 +and ///B2 + B = class end +""" + (checkXml "B" [|"B1"|]) + +[] +let ``types 05 - attributes after 'type'``() = + checkSignatureAndImplementation """ +///A1 +type ///A2 + [] A = class end +""" + (checkXml "A" [|"A1"|]) + +[] +let ``types 06 - xml doc after attribute``() = + checkSignatureAndImplementation """ +[] ///A -(*) -///B type A = class end """ - checkResults - |> checkXml "A" [|"B"|] + (checkXml "A" [||]) [] -let ``let binding 01 - simple``() = +let ``let bindings 01 - allowed positions``() = let _, checkResults = getParseAndCheckResults """ ///f1 let ///f2 rec ///f3 - private f x = f x + inline ///f4 + private f x = f x """ checkResults |> checkXml "f" [|"f1"|] [] -let ``let binding 02 - let in``() = +let ``let bindings 02``() = let _, checkResults = getParseAndCheckResults """ -///X -let x = 3 in print x +///X1 +///X2 +[] +///X3 +let x = 3 """ checkResults - |> checkXml "x" [|"X"|] + |> checkXml "x" [|"X1"; "X2"|] -[] -let ``let binding 03 - expression delimiter``() = +[] +let ``let bindings 03 - let in``() = let _, checkResults = getParseAndCheckResults """ -///A -1 + 1 -///B -let f x = () +///X1 +///X2 +[] +///X3 +let x = 3 in print x """ checkResults - |> checkXml "f" [|"B"|] + |> checkXml "x" [|"X1"; "X2"|] [] -let ``let binding 04 - local binding``() = +let ``let bindings 04 - local binding``() = let _, checkResults = getParseAndCheckResults """ let _ = - ///A - 1 + 1 - ///B + ///X1 + ///X2 let x = () () """ checkResults - |> checkXml "x" [|"B"|] + |> checkXml "x" [|"X1"; "X2"|] [] -let ``let binding 05 - with attribute``() = +let ``let bindings 05 - use``() = let _, checkResults = getParseAndCheckResults """ -///X -[] -let x = 5 +let _ = + ///X1 + ///X2 + use x = () + () """ checkResults - |> checkXml "x" [|"X"|] + |> checkXml "x" [|"X1"; "X2"|] [] -let ``let binding 06 - xml doc after attribute``() = +let ``let bindings 06 - xml doc after attribute``() = let _, checkResults = getParseAndCheckResults """ [] ///X @@ -183,36 +231,41 @@ let x = 5 |> checkXml "x" [||] [] -let ``let binding 07 - attribute after 'let'``() = +let ``let bindings 07 - attribute after 'let'``() = let _, checkResults = getParseAndCheckResults """ -///X -let [] x = 5 +///X1 +let ///X2 + [] x = 5 """ checkResults - |> checkXml "x" [|"X"|] + |> checkXml "x" [|"X1"|] [] -let ``let binding 08 - xml doc before 'and'``() = +let ``let bindings 08 - xml doc before 'and'``() = let _, checkResults = getParseAndCheckResults """ let rec f x = g x -///G +///G1 +///G2 and g x = f x """ checkResults - |> checkXml "g" [|"G"|] + |> checkXml "g" [|"G1"; "G2"|] [] -let ``let binding 09 - xml doc after 'and'``() = +let ``let bindings 09 - xml doc after 'and'``() = let _, checkResults = getParseAndCheckResults """ let rec f x = g x -and ///G - [] g x = f x +and ///G1 + ///G2 + [] + ///G3 + g x = f x """ checkResults - |> checkXml "g" [|"G"|] + |> checkXml "g" [|"G1"; "G2"|] [] -let ``let binding 010 - xml doc before and after 'and'``() = +let ``let bindings 10 - xml doc before/after 'and'``() = let _, checkResults = getParseAndCheckResults """ let rec f x = g x ///G1 @@ -223,54 +276,29 @@ and ///G2 |> checkXml "g" [|"G1"|] [] -let ``and type xml doc``() = +let ``let bindings 11 - in type``() = let _, checkResults = getParseAndCheckResults """ -type A = class end -///B -and B = class end -""" - checkResults - |> checkXml "B" [|"B"|] - -[] -let ``type xml doc after and``() = - let _, checkResults = getParseAndCheckResults """ -type A = class end -and ///B - B = class end -""" - checkResults - |> checkXml "B" [|"B"|] - -[] -let ``type xml docs before/after and``() = - let _, checkResults = getParseAndCheckResults """ -type A = class end -///B1 -and ///B2 - B = class end +type A() = + ///data + let data = 5 """ checkResults - |> checkXml "B" [|"B1"|] - + |> checkXml "data" [|"data"|] [] -let ``union cases``() = +let ``type members 01 - allowed positions``() = let _, checkResults = getParseAndCheckResults """ type A = - ///One - One - ///Two - | Two + ///B1 + member + ///B2 + private x.B() = () """ checkResults - |> checkXmls [ - "One", [|"One"|] - "Two", [|"Two"|] - ] + |> checkXml "B" [|"B1"|] [] -let ``type member multiline xml doc``() = +let ``type members 02``() = let _, checkResults = getParseAndCheckResults """ type A = member x.A() = ///B1 @@ -278,110 +306,16 @@ type A = ///B2 ///B3 + [] + ///B4 member x.B() = () """ checkResults |> checkXml "B" [|"B2"; "B3"|] [] -let ``type member with attributes``() = - let _, checkResults = getParseAndCheckResults """ -type A = - ///B1 - ///B2 - [] - ///B3 - member x.B() = () -""" - checkResults - |> checkXml "B" [|"B1"; "B2"|] - -[] -let ``type member xml doc``() = - let _, checkResults = getParseAndCheckResults """ -type A = - ///B1 - member - ///B2 - private x.B() = () -""" - checkResults - |> checkXml "B" [|"B1"|] - -[] -let Test141() = - let _, checkResults = getParseAndCheckResults """ -///A1 -///A2 -[] -///B -type A = class end -""" - checkResults - |> checkXml "A" [|"A1"; "A2"|] - -[] -let Test142() = - let _, checkResults = getParseAndCheckResults """ -type A = class end -and - ///B1 - [] - ///B2 - B = class end -""" - checkResults - |> checkXml "B" [|"B1"|] - -[] -let ``type specifications xml doc``() = - let _, checkResults = getParseAndCheckResultsOfSignatureFile """ -type A -and - ///B1 - [] - ///B2 - B -""" - checkResults - |> checkXml "B" [|"B1"|] - -[] -let ``xml docs after attributes``() = - let _, checkResults = getParseAndCheckResults """ -[] -///A -type A = class end -""" - checkResults - |> checkXml "A" [||] - -[] -let ``abstract member multiline xml doc``() = - let _, checkResults = getParseAndCheckResults """ -type A = - ///M1 - ///M2 - abstract member M: unit -""" - checkResults - |> checkXml "get_M" [|"M1"; "M2"|] - -[] -let ``abstract type member with attributes``() = - let _, checkResults = getParseAndCheckResults """ -type A = - ///M1 - [] - ///M2 - abstract member M: unit -""" - checkResults - |> checkXml "get_M" [|"M1"|] - -[] -let ``signature type member with attributes``() = - let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +let ``type members 03 - abstract``() = + checkSignatureAndImplementation """ type A = ///M1 ///M2 @@ -389,11 +323,10 @@ type A = ///M3 abstract member M: unit """ - checkResults - |> checkXml "get_M" [|"M1"; "M2"|] + (checkXml "get_M" [|"M1"; "M2"|]) [] -let ``Property accessors xml doc``() = +let ``type members 04 - property accessors``() = let _, checkResults = getParseAndCheckResults """ type B = ///A1 @@ -407,68 +340,165 @@ type B = member x.C = x.set_A(4) """ - checkResults |> checkXmls [ "get_A", [|"A1"; "A2"|] "set_A", [|"A1"; "A2"|] ] -[] -let ``record multiline xml doc``() = +[] +let ``type members 05 - auto-property``() = let _, checkResults = getParseAndCheckResults """ +type A() = + ///B1 + ///B2 + [] + ///B3 + member val B = 1 with get, set +""" + checkResults + |> checkXml "get_B" [|"B1"; "B2"|] + +[] +let ``record``() = + checkSignatureAndImplementation """ type A = { ///B1 ///B2 + [] + ///B3 B: int } - -{ B = 1 }.B """ - checkResults - |> checkXml "B" [|"B1"; "B2"|] + (getFieldXml "A" "B" >> + compareXml [|"B1"; "B2"|]) [] -let ``attributes after type keyword``() = - let _, checkResults = getParseAndCheckResultsOfSignatureFile """ -///A1 -type ///A2 - [] A = class end -""" - checkResults - |> checkXml "A" [|"A1"|] - -[] -let ``module definition``() = - let _, checkResults = getParseAndCheckResults """ +let ``module 01``() = + checkSignatureAndImplementation """ ///M1 +///M2 +[] +///M3 module - ///M2 - rec M = - open M + ///M4 + rec M """ - checkResults - |> checkXml "M" [|"M1"|] + (checkXml "M" [|"M1"; "M2"|]) [] -let ``module specification``() = - let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +let ``module 02 - attributes after 'module'``() = + checkSignatureAndImplementation """ ///M1 -module - ///M2 +module ///M2 + [] rec M """ - checkResults - |> checkXml "M" [|"M1"|] + (checkXml "M" [|"M1"|]) + +[] +let ``union cases 01 - without bar``() = + checkSignatureAndImplementation """ +type A = + ///One1 + ///One2 + One + ///Two1 + ///Two2 + | Two +""" + (checkXmls [ + "One", [|"One1"; "One2"|] + "Two", [|"Two1"; "Two2"|] + ]) + +[] +let ``union cases 02``() = + checkSignatureAndImplementation """ +type A = + ///One1 + ///One2 + | One + ///Two1 + ///Two2 + | Two +""" + (checkXmls [ + "One", [|"One1"; "One2"|] + "Two", [|"Two1"; "Two2"|] + ]) [] let ``extern``() = let _, checkResults = getParseAndCheckResults """ -///E +///E1 +///E2 [] +///E3 extern void E() """ checkResults - |> checkXml "E" [|"E"|] + |> checkXml "E" [|"E1"; "E2"|] + +[] +let ``exception 01 - allowed positions``() = + checkSignatureAndImplementation """ +///E1 +///E2 +[] +///E3 +exception ///E4 + E of string +""" + (checkXml "E" [|"E1"; "E2"|]) + +[] +let ``exception 02 - attribute after 'exception'``() = + checkSignatureAndImplementation """ +exception ///E + [] + E of string +""" + (checkXml "E" [||]) + +[] +let ``val 01 - type``() = + checkSignatureAndImplementation """ +type A = + ///B1 + ///B2 + [] + ///B3 + val mutable private B: int +""" + (getFieldXml "A" "B" >> + compareXml [|"B1"; "B2"|]) + +[] +let ``val 02 - struct``() = + let _, checkResults = getParseAndCheckResults """ +type Point = + struct + ///X1 + ///X2 + [] + ///X3 + val x: float + end +""" + checkResults + |> getFieldXml "Point" "x" + |> compareXml [|"X1"; "X2"|] +[] +let ``val 03 - module``() = + let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +///A1 +///A2 +[] +///A3 +val a: int +""" + checkResults + |> checkXml "a" [|"A1"; "A2"|] From 41cf202dcf0e58860dc48d7f7b8f05b709650a77 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Sun, 22 Aug 2021 15:49:46 +0300 Subject: [PATCH 06/25] yet another tests --- tests/service/XmlDocTests.fs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index 3ae2ffd6f88..d11a3632570 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -184,17 +184,35 @@ let x = 3 checkResults |> checkXml "x" [|"X1"; "X2"|] -[] -let ``let bindings 03 - let in``() = +[] +let ``let bindings 03 - 'let in'``() = let _, checkResults = getParseAndCheckResults """ ///X1 ///X2 [] ///X3 -let x = 3 in print x +let x = 3 in + +///Y1 +///Y2 +[] +///Y3 +let y = x """ checkResults - |> checkXml "x" [|"X1"; "X2"|] + |> checkXmls [ + "x", [|"X1"; "X2"|] + "y", [|"Y1"; "Y2"|] + ] + +[] +let ``let bindings 03 - 'let in' with attributes after 'let'``() = + let _, checkResults = getParseAndCheckResults """ +let ///X + [] x = 3 in print x +""" + checkResults + |> checkXml "x" [||] [] let ``let bindings 04 - local binding``() = From 614d152be5ee938b5175340962ec564b6908fac6 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Sun, 22 Aug 2021 15:53:36 +0300 Subject: [PATCH 07/25] _ --- src/fsharp/LexFilter.fs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs index fe30bc9912a..a9b8da1d06f 100644 --- a/src/fsharp/LexFilter.fs +++ b/src/fsharp/LexFilter.fs @@ -651,7 +651,6 @@ type LexFilterImpl (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbu tokenTup.Token <- token tokenTup.LexbufState <- tokenLexbufState tokenTup.LastTokenPos <- lastTokenEnd - tokenTup //---------------------------------------------------------------------------- From 0c7bc4d322510e903cd1fd2e001a7905a2a23ba2 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Sun, 22 Aug 2021 18:40:02 +0300 Subject: [PATCH 08/25] simplify --- src/fsharp/pars.fsy | 62 ++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 14cc9dd066b..e661db8c443 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -182,13 +182,16 @@ let checkForMultipleAugmentations m a1 a2 = if not (isNil a1) && not (isNil a2) then raiseParseErrorAt m (FSComp.SR.parsOnlyOneWithAugmentationAllowed()) a1 @ a2 -let grabXmlDoc(parseState:IParseState, optAttributes: SynAttributeList list, elemIdx) = +let grabXmlDocAtRangeStart(parseState: IParseState, optAttributes: SynAttributeList list, range: range) = let grabPoint = match optAttributes with - | [] -> rhs parseState elemIdx + | [] -> range | h :: _ -> h.Range LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, grabPoint) +let grabXmlDoc(parseState: IParseState, optAttributes: SynAttributeList list, elemIdx) = + grabXmlDocAtRangeStart(parseState, optAttributes, rhs parseState elemIdx) + let rangeOfLongIdent(lid:LongIdent) = System.Diagnostics.Debug.Assert(not lid.IsEmpty, "the parser should never produce a long-id that is the empty list") (lid.Head.idRange, lid) ||> unionRangeWithListBy (fun id -> id.idRange) @@ -1014,7 +1017,7 @@ classSpfnMembersAtLeastOne: classMemberSpfn: | opt_attributes opt_declVisibility memberSpecFlags opt_inline opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet optLiteralValueSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let isInline, doc, vis2, id, explicitValTyparDecls, (ty, arity), optLiteralValue = $4, grabXmlDoc(parseState, $1, 3), $5, $6, $7, $9, $11 + let isInline, doc, vis2, id, explicitValTyparDecls, (ty, arity), optLiteralValue = $4, grabXmlDoc(parseState, $1, 1), $5, $6, $7, $9, $11 let getSetRangeOpt, getSet = $10 let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet let wholeRange = @@ -1038,22 +1041,20 @@ classMemberSpfn: | opt_attributes opt_declVisibility VAL fieldDecl { let wholeRange = rhs2 parseState 1 4 if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) - let xmlDoc = grabXmlDoc(parseState, $1, 1) - let fld = $4 xmlDoc $1 false wholeRange + let fld = $4 $1 false wholeRange SynMemberSig.ValField (fld, wholeRange) } | opt_attributes opt_declVisibility STATIC VAL fieldDecl { let wholeRange = rhs2 parseState 1 5 if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) - let xmlDoc = grabXmlDoc(parseState, $1, 1) - SynMemberSig.ValField($5 xmlDoc $1 true wholeRange, wholeRange) } + SynMemberSig.ValField($5 $1 true wholeRange, wholeRange) } | opt_attributes opt_declVisibility STATIC typeKeyword tyconSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) SynMemberSig.NestedType($5, rhs2 parseState 1 5) } | opt_attributes opt_declVisibility NEW COLON topTypeWithTypeConstraints - { let vis, doc, (ty, valSynInfo) = $2, grabXmlDoc(parseState, $1, 3), $5 + { let vis, doc, (ty, valSynInfo) = $2, grabXmlDoc(parseState, $1, 1), $5 let m = unionRanges (rhs parseState 1) ty.Range let isInline = false let valSpfn = SynValSig ($1, mkSynId (rhs parseState 3) "new", noInferredTypars, ty, valSynInfo, isInline, false, doc, vis, None, m) @@ -1304,7 +1305,7 @@ moduleDefn: /* 'type' definitions */ | opt_attributes opt_declVisibility typeKeyword tyconDefn tyconDefnList { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let xmlDoc = grabXmlDoc(parseState, $1, 3) + let xmlDoc = grabXmlDoc(parseState, $1, 1) let (SynTypeDefn(SynComponentInfo(cas, a, cs, b, _, d, d2, d3), e, f, g, h)) = $4 let attrs = $1@cas let mTc = (h, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) @@ -1566,9 +1567,9 @@ tyconDefn: { let vis, spats, az = $3, $5, $6 let nameRange = rhs parseState 1 let (tcDefRepr, members) = $8 nameRange - let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 + let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 // Gets the XML doc comments prior to the implicit constructor - let xmlDoc = grabXmlDoc(parseState, $2, 5) + let xmlDoc = grabXmlDoc(parseState, $2, 2) let memberCtorPattern = SynMemberDefn.ImplicitCtor (vis, $2, spats, az, xmlDoc, rangeOfLid lid) let tcDefRepr = match tcDefRepr with @@ -1739,7 +1740,8 @@ memberCore: { let mRhs = $5.Range let optReturnType = $3 let bindingBuilder, mBindLhs = $2 - (fun xmlDoc vis memFlagsBuilder attrs rangeStart -> + (fun vis memFlagsBuilder attrs rangeStart -> + let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, rangeStart) let memberFlags = Some (memFlagsBuilder SynMemberKind.Member) let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) let binding = (bindingBuilder xmlDoc) (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags) @@ -1752,9 +1754,10 @@ memberCore: let propertyNameBindingBuilder, _ = $2 let optPropertyType = $3 let isMutable = false - (fun xmlDoc visNoLongerUsed memFlagsBuilder attrs rangeStart -> + (fun visNoLongerUsed memFlagsBuilder attrs rangeStart -> let hasGet = ref false let hasSet = ref false + let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, rangeStart) // Iterate over 1 or 2 'get'/'set' entries $4 |> List.choose (fun (optInline, optAttrs, (bindingBuilder, mBindLhs), optReturnType, expr, exprm) -> @@ -1954,8 +1957,7 @@ classDefnMember: if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) let _, flags = $3 - let doc = grabXmlDoc(parseState, $1, 1) - $4 doc $2 flags $1 rangeStart } + $4 $2 flags $1 rangeStart } | opt_attributes opt_declVisibility interfaceMember appType opt_interfaceImplDefn { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(), rhs parseState 1)) @@ -1989,22 +1991,19 @@ classDefnMember: | opt_attributes opt_declVisibility valDefnDecl opt_ODECLEND { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let rangeStart = rhs parseState 1 - let xmlDoc = grabXmlDoc(parseState, $1, 1) - $3 xmlDoc rangeStart $1 false } + $3 rangeStart $1 false } | opt_attributes opt_declVisibility STATIC valDefnDecl opt_ODECLEND { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let rangeStart = rhs parseState 1 - let xmlDoc = grabXmlDoc(parseState, $1, 1) - $4 xmlDoc rangeStart $1 true } + $4 rangeStart $1 true } | opt_attributes opt_declVisibility memberFlags autoPropsDefnDecl opt_ODECLEND { let rangeStart = rhs parseState 1 if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let isStatic, flags = $3 - let xmlDoc = grabXmlDoc(parseState, $1, 1) - $4 xmlDoc $1 isStatic flags rangeStart } + $4 $1 isStatic flags rangeStart } | opt_attributes opt_declVisibility NEW atomicPattern optAsSpec EQUALS typedSequentialExprBlock opt_ODECLEND { let mWholeBindLhs = rhs2 parseState 1 (if Option.isSome $5 then 5 else 4) @@ -2015,7 +2014,7 @@ classDefnMember: let declPat = SynPat.LongIdent (LongIdentWithDots([mkSynId (rhs parseState 3) "new"], []), None, Some noInferredTypars, SynArgPats.Pats [$4], vis, rhs parseState 3) // Check that 'SynPatForConstructorDecl' matches this correctly assert (match declPat with SynPatForConstructorDecl _ -> true | _ -> false) - [ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, grabXmlDoc(parseState, $1, 3), valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible), m) ] } + [ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, grabXmlDoc(parseState, $1, 1), valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible), m) ] } | opt_attributes opt_declVisibility STATIC typeKeyword tyconDefn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) @@ -2027,7 +2026,8 @@ valDefnDecl: | VAL opt_mutable opt_access ident COLON typ { let mRhs = rhs2 parseState 4 6 let mValDecl = rhs2 parseState 1 6 - (fun xmlDoc rangeStart attribs isStatic -> + (fun rangeStart attribs isStatic -> + let xmlDoc = grabXmlDocAtRangeStart(parseState, attribs, rangeStart) let mValDecl = unionRanges rangeStart mValDecl let fld = SynField(attribs, isStatic, Some $4, $6, $2, xmlDoc, $3, mRhs) [ SynMemberDefn.ValField(fld, mValDecl) ]) } @@ -2039,7 +2039,8 @@ autoPropsDefnDecl: { let mGetSetOpt, getSet = $8 if $2 then errorR (Error (FSComp.SR.parsMutableOnAutoPropertyShouldBeGetSet (), rhs parseState 3)) - (fun xmlDoc attribs isStatic flags rangeStart -> + (fun attribs isStatic flags rangeStart -> + let xmlDoc = grabXmlDocAtRangeStart(parseState, attribs, rangeStart) let memberRange = unionRanges rangeStart $7.Range [ SynMemberDefn.AutoProperty(attribs, isStatic, $4, $5, getSet, flags, xmlDoc, $3, $7, mGetSetOpt, memberRange) ]) } @@ -2192,13 +2193,11 @@ objectImplementationMembers: objectImplementationMember: | opt_attributes memberOrOverride memberCore opt_ODECLEND { let rangeStart = rhs parseState 1 - let doc = grabXmlDoc(parseState, $1, 1) - $3 doc None OverrideMemberFlags $1 rangeStart } + $3 None OverrideMemberFlags $1 rangeStart } | opt_attributes memberOrOverride autoPropsDefnDecl opt_ODECLEND { let rangeStart = rhs parseState 1 - let xmlDoc = grabXmlDoc(parseState, $1, 1) - $3 xmlDoc $1 false OverrideMemberFlags rangeStart } + $3 $1 false OverrideMemberFlags rangeStart } | opt_attributes memberOrOverride error { [] } @@ -2548,8 +2547,7 @@ recdFieldDeclList: recdFieldDecl: | opt_attributes fieldDecl { let wholeRange = rhs2 parseState 1 2 - let xmlDoc = grabXmlDoc(parseState, $1, 1) - let fld = $2 xmlDoc $1 false wholeRange + let fld = $2 $1 false wholeRange let (SynField (a, b, c, d, e, f, vis, wholeRange)) = fld if Option.isSome vis then errorR (Error (FSComp.SR.parsRecordFieldsCannotHaveVisibilityDeclarations (), rhs parseState 2)) SynField (a, b, c, d, e, f, None, wholeRange) } @@ -2557,7 +2555,9 @@ recdFieldDecl: /* Part of a field or val declaration in a record type or object type */ fieldDecl: | opt_mutable opt_access ident COLON typ - { fun xmlDoc attrs stat wholeRange -> SynField(attrs, stat, Some $3, $5, $1, xmlDoc, $2, wholeRange) } + { fun attrs stat wholeRange -> + let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, wholeRange) + SynField(attrs, stat, Some $3, $5, $1, xmlDoc, $2, wholeRange) } /* An exception definition */ exconDefn: From 10c15369d4a3b9cf84247183357f36da78ffa518 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Sun, 22 Aug 2021 18:51:02 +0300 Subject: [PATCH 09/25] test for implicit ctor --- tests/service/XmlDocTests.fs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index d11a3632570..05e4441b57a 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -377,6 +377,18 @@ type A() = checkResults |> checkXml "get_B" [|"B1"; "B2"|] +[] +let ``type members 06 - implicit ctor``() = + let _, checkResults = getParseAndCheckResults """ +type A ///CTOR + () = +""" + checkResults + |> checkXmls [ + "A", [||] + ".ctor", [|"CTOR"|] + ] + [] let ``record``() = checkSignatureAndImplementation """ From 0e9f61f259b3ab7d29cb668925b8d47fbb9aaab9 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Sun, 22 Aug 2021 18:53:18 +0300 Subject: [PATCH 10/25] fix --- tests/service/XmlDocTests.fs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index 05e4441b57a..7cf79ff9c78 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -380,13 +380,16 @@ type A() = [] let ``type members 06 - implicit ctor``() = let _, checkResults = getParseAndCheckResults """ -type A ///CTOR +type A ///CTOR1 + ///CTOR2 + [] + ///CTOR3 () = """ checkResults |> checkXmls [ "A", [||] - ".ctor", [|"CTOR"|] + ".ctor", [|"CTOR1"; "CTOR2"|] ] [] From 5f44b7812ac2d76abd4ec450e03af8a924c9ef8d Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Sun, 22 Aug 2021 22:33:43 +0300 Subject: [PATCH 11/25] improve test --- tests/service/XmlDocTests.fs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index 7cf79ff9c78..aea1bcb96f7 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -452,10 +452,14 @@ let ``union cases 02``() = type A = ///One1 ///One2 - | One + | [] + ///One3 + One ///Two1 ///Two2 - | Two + | [] + ///Two3 + Two """ (checkXmls [ "One", [|"One1"; "One2"|] From ddc86d6a4126011b5153bf1f33e6981d1ae46150 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Tue, 31 Aug 2021 15:13:53 +0300 Subject: [PATCH 12/25] move grabXmlDoc to the ParseHelpers --- src/fsharp/ParseHelpers.fs | 10 ++++++++++ src/fsharp/ParseHelpers.fsi | 5 +++++ src/fsharp/pars.fsy | 10 ---------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/fsharp/ParseHelpers.fs b/src/fsharp/ParseHelpers.fs index 369a127014d..b67c3e0e887 100644 --- a/src/fsharp/ParseHelpers.fs +++ b/src/fsharp/ParseHelpers.fs @@ -5,6 +5,7 @@ module FSharp.Compiler.ParseHelpers open FSharp.Compiler.AbstractIL open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features +open FSharp.Compiler.Syntax open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.UnicodeLexing open FSharp.Compiler.Text @@ -264,3 +265,12 @@ let ParseAssemblyCodeType s reportLibraryOnlyFeatures (isFeatureSupported: Langu IL.PrimaryAssemblyILGlobals.typ_Object #endif +let grabXmlDocAtRangeStart(parseState: IParseState, optAttributes: SynAttributeList list, range: range) = + let grabPoint = + match optAttributes with + | [] -> range + | h :: _ -> h.Range + LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, grabPoint) + +let grabXmlDoc(parseState: IParseState, optAttributes: SynAttributeList list, elemIdx) = + grabXmlDocAtRangeStart(parseState, optAttributes, rhs parseState elemIdx) diff --git a/src/fsharp/ParseHelpers.fsi b/src/fsharp/ParseHelpers.fsi index 8403a27eb28..1e2a866163f 100644 --- a/src/fsharp/ParseHelpers.fsi +++ b/src/fsharp/ParseHelpers.fsi @@ -3,6 +3,7 @@ module internal FSharp.Compiler.ParseHelpers open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.Syntax open FSharp.Compiler.Text open FSharp.Compiler.Xml open Internal.Utilities.Text.Lexing @@ -113,3 +114,7 @@ and LexCont = LexerContinuation val ParseAssemblyCodeInstructions: s:string -> reportLibraryOnlyFeatures: bool -> isFeatureSupported:(Features.LanguageFeature -> bool) -> checkLanguageFeatureErrorRecover:(Features.LanguageFeature -> range -> unit) -> m:range -> ILInstr[] val ParseAssemblyCodeType: s:string -> reportLibraryOnlyFeatures: bool -> isFeatureSupported:(Features.LanguageFeature -> bool) -> checkLanguageFeatureErrorRecover:(Features.LanguageFeature -> range -> unit) -> m:range -> ILType + +val grabXmlDocAtRangeStart: parseState: IParseState * optAttributes: SynAttributeList list * range: range -> PreXmlDoc + +val grabXmlDoc: parseState: IParseState * optAttributes: SynAttributeList list * elemIdx: int -> PreXmlDoc diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index e661db8c443..1a5e2cf4a51 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -182,16 +182,6 @@ let checkForMultipleAugmentations m a1 a2 = if not (isNil a1) && not (isNil a2) then raiseParseErrorAt m (FSComp.SR.parsOnlyOneWithAugmentationAllowed()) a1 @ a2 -let grabXmlDocAtRangeStart(parseState: IParseState, optAttributes: SynAttributeList list, range: range) = - let grabPoint = - match optAttributes with - | [] -> range - | h :: _ -> h.Range - LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, grabPoint) - -let grabXmlDoc(parseState: IParseState, optAttributes: SynAttributeList list, elemIdx) = - grabXmlDocAtRangeStart(parseState, optAttributes, rhs parseState elemIdx) - let rangeOfLongIdent(lid:LongIdent) = System.Diagnostics.Debug.Assert(not lid.IsEmpty, "the parser should never produce a long-id that is the empty list") (lid.Head.idRange, lid) ||> unionRangeWithListBy (fun id -> id.idRange) From 5050baca1b13e07803f69be31adf309d366ddead Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Thu, 2 Sep 2021 14:26:44 +0300 Subject: [PATCH 13/25] diagnostic --- src/fsharp/FSComp.txt | 1 + src/fsharp/FSharp.Core/FSharp.Core.fsproj | 2 + src/fsharp/ParseAndCheckInputs.fs | 2 + src/fsharp/ParseHelpers.fs | 18 ++ src/fsharp/ParseHelpers.fsi | 4 + src/fsharp/XmlDoc.fs | 49 +++- src/fsharp/XmlDoc.fsi | 6 + src/fsharp/lex.fsl | 6 +- src/fsharp/pars.fsy | 12 +- src/fsharp/xlf/FSComp.txt.cs.xlf | 5 + src/fsharp/xlf/FSComp.txt.de.xlf | 5 + src/fsharp/xlf/FSComp.txt.es.xlf | 5 + src/fsharp/xlf/FSComp.txt.fr.xlf | 5 + src/fsharp/xlf/FSComp.txt.it.xlf | 5 + src/fsharp/xlf/FSComp.txt.ja.xlf | 5 + src/fsharp/xlf/FSComp.txt.ko.xlf | 5 + src/fsharp/xlf/FSComp.txt.pl.xlf | 5 + src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 5 + src/fsharp/xlf/FSComp.txt.ru.xlf | 5 + src/fsharp/xlf/FSComp.txt.tr.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 5 + tests/service/XmlDocTests.fs | 312 +++++++++++++++++----- 23 files changed, 390 insertions(+), 87 deletions(-) diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 9bf9937c1e7..2a18a72566c 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1618,3 +1618,4 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3517,optFailedToInlineSuggestedValue,"The value '%s' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only." 3518,implMissingInlineIfLambda,"The 'InlineIfLambda' attribute is present in the signature but not the implementation." 3519,tcInlineIfLambdaUsedOnNonInlineFunctionOrMethod,"The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type." +3520,invalidXmlDocPosition,"XML comment is not placed on a valid language element." diff --git a/src/fsharp/FSharp.Core/FSharp.Core.fsproj b/src/fsharp/FSharp.Core/FSharp.Core.fsproj index 4fafe661c48..26184d32edf 100644 --- a/src/fsharp/FSharp.Core/FSharp.Core.fsproj +++ b/src/fsharp/FSharp.Core/FSharp.Core.fsproj @@ -15,6 +15,8 @@ $(OtherFlags) --warnon:1182 $(OtherFlags) --warnon:3390 + + $(OtherFlags) --warnon:3520 $(OtherFlags) --nowarn:57 diff --git a/src/fsharp/ParseAndCheckInputs.fs b/src/fsharp/ParseAndCheckInputs.fs index 9c633e880de..30ce3ffbdd7 100644 --- a/src/fsharp/ParseAndCheckInputs.fs +++ b/src/fsharp/ParseAndCheckInputs.fs @@ -274,9 +274,11 @@ let ParseInput (lexer, errorLogger: ErrorLogger, lexbuf: UnicodeLexing.Lexbuf, d // Call the appropriate parser - for signature files or implementation files if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then let impl = Parser.implementationFile lexer lexbuf + LexbufLocalXmlDocStore.CheckInvalidXmlDocPositions(lexbuf) PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, impl) elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then let intfs = Parser.signatureFile lexer lexbuf + LexbufLocalXmlDocStore.CheckInvalidXmlDocPositions(lexbuf) PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, intfs) else delayLogger.Error(Error(FSComp.SR.buildInvalidSourceFileExtension filename, rangeStartup)) diff --git a/src/fsharp/ParseHelpers.fs b/src/fsharp/ParseHelpers.fs index b67c3e0e887..b1ad0131fdf 100644 --- a/src/fsharp/ParseHelpers.fs +++ b/src/fsharp/ParseHelpers.fs @@ -115,6 +115,21 @@ module LexbufLocalXmlDocStore = let startPos = lexbuf.StartPos collector.AddGrabPoint(mkPos startPos.Line startPos.Column) + /// Allowed cases when there are comments after XmlDoc + /// + /// /// X xmlDoc + /// // comment + /// //// comment + /// (* multiline comment *) + /// let x = ... // X xmlDoc + /// + /// Remember the first position when a comment (//, (* *), ////) is encountered after the XmlDoc block + /// then add a grab point if a new XmlDoc block follows the comments + let AddGrabPointDelayed (lexbuf: Lexbuf) = + let collector = getCollector lexbuf + let startPos = lexbuf.StartPos + collector.AddGrabPointDelayed(mkPos startPos.Line startPos.Column) + /// Called from the parser each time we parse a construct that marks the end of an XML doc comment range, /// e.g. a 'type' declaration. The markerRange is the range of the keyword that delimits the construct. let GrabXmlDocBeforeMarker (lexbuf: Lexbuf, markerRange: range) = @@ -125,6 +140,9 @@ module LexbufLocalXmlDocStore = | _ -> PreXmlDoc.Empty + let CheckInvalidXmlDocPositions (lexbuf: Lexbuf) = + let collector = getCollector lexbuf + collector.CheckInvalidXmlDocPositions() //------------------------------------------------------------------------ // Parsing/lexing: status of #if/#endif processing in lexing, used for continutations diff --git a/src/fsharp/ParseHelpers.fsi b/src/fsharp/ParseHelpers.fsi index 1e2a866163f..bc44bf8b3bf 100644 --- a/src/fsharp/ParseHelpers.fsi +++ b/src/fsharp/ParseHelpers.fsi @@ -49,6 +49,10 @@ module LexbufLocalXmlDocStore = val AddGrabPoint: lexbuf:UnicodeLexing.Lexbuf -> unit + val AddGrabPointDelayed: lexbuf:UnicodeLexing.Lexbuf -> unit + + val CheckInvalidXmlDocPositions: lexbuf:UnicodeLexing.Lexbuf -> unit + type LexerIfdefStackEntry = | IfDefIf | IfDefElse diff --git a/src/fsharp/XmlDoc.fs b/src/fsharp/XmlDoc.fs index 0ca07c74111..374d1c0eb54 100644 --- a/src/fsharp/XmlDoc.fs +++ b/src/fsharp/XmlDoc.fs @@ -12,7 +12,6 @@ open Internal.Utilities.Collections open FSharp.Compiler.ErrorLogger open FSharp.Compiler.IO open FSharp.Compiler.Text -open FSharp.Compiler.Text.Position open FSharp.Compiler.Text.Range open FSharp.Compiler.AbstractIL.IL @@ -147,13 +146,10 @@ and XmlDocStatics() = /// Used to collect XML documentation during lexing and parsing. type XmlDocCollector() = let mutable savedLines = ResizeArray() - let mutable savedGrabPoints = Dictionary() + let mutable savedGrabPoints = Dictionary() let mutable currentGrabPointCommentsCount = 0 - - let posCompare p1 p2 = if posGeq p1 p2 then 1 else if posEq p1 p2 then 0 else -1 - - let savedLinesAsArray = - lazy (savedLines.ToArray() |> Array.sortWith (fun (_, p1) (_, p2) -> posCompare p1.End p2.End)) + let mutable delayedGrabPoint = ValueNone + let savedLinesAsArray = lazy (savedLines.ToArray()) let check() = // can't add more XmlDoc elements to XmlDocCollector after extracting first XmlDoc from the overall results @@ -162,24 +158,51 @@ type XmlDocCollector() = member x.AddGrabPoint(pos: pos) = check() if currentGrabPointCommentsCount = 0 then () else - let commentsStartEndIndexes = struct(savedLines.Count - currentGrabPointCommentsCount, savedLines.Count - 1) - savedGrabPoints.Add(pos, commentsStartEndIndexes) + let xmlDocBlock = struct(savedLines.Count - currentGrabPointCommentsCount, savedLines.Count - 1, false) + savedGrabPoints.Add(pos, xmlDocBlock) currentGrabPointCommentsCount <- 0 + delayedGrabPoint <- ValueNone + + member x.AddGrabPointDelayed(pos: pos) = + check() + if currentGrabPointCommentsCount = 0 then () else + match delayedGrabPoint with + | ValueNone -> delayedGrabPoint <- ValueSome(pos) + | _ -> () member x.AddXmlDocLine(line, range) = check() + match delayedGrabPoint with + | ValueNone -> () + | ValueSome pos -> x.AddGrabPoint(pos) // Commit delayed grab point + savedLines.Add(line, range) currentGrabPointCommentsCount <- currentGrabPointCommentsCount + 1 member x.LinesBefore grabPointPos = let lines = savedLinesAsArray.Force() match savedGrabPoints.TryGetValue grabPointPos with - | true, struct(startIndex, endIndex) -> lines.[startIndex .. endIndex] + | true, struct(startIndex, endIndex, _) -> lines.[startIndex .. endIndex] | false, _ -> [||] + member x.SetXmlDocValidity(grabPointPos, isValid) = + match savedGrabPoints.TryGetValue grabPointPos with + | true, struct(startIndex, endIndex, _) -> + savedGrabPoints.[grabPointPos] <- struct(startIndex, endIndex, isValid) + | _ -> () + member x.HasComments grabPointPos = savedGrabPoints.TryGetValue grabPointPos |> fst + member x.CheckInvalidXmlDocPositions() = + let lines = savedLinesAsArray.Force() + for startIndex, endIndex, isValid in savedGrabPoints.Values do + if isValid then () else + let _, startRange = lines.[startIndex] + let _, endRange = lines.[endIndex] + let range = unionRanges startRange endRange + informationalWarning (Error(FSComp.SR.invalidXmlDocPosition(), range)) + /// Represents the XmlDoc fragments as collected from the lexer during parsing type PreXmlDoc = | PreXmlDirect of unprocessedLines: string[] * range: range @@ -211,7 +234,13 @@ type PreXmlDoc = | PreXmlDocEmpty -> true | PreXmlDoc (pos, collector) -> not (collector.HasComments pos) + member x.MarkAsInvalid() = + match x with + | PreXmlDoc (pos, collector) -> collector.SetXmlDocValidity(pos, false) + | _ -> () + static member CreateFromGrabPoint(collector: XmlDocCollector, grabPointPos) = + collector.SetXmlDocValidity(grabPointPos, true) PreXmlDoc(grabPointPos, collector) static member Empty = PreXmlDocEmpty diff --git a/src/fsharp/XmlDoc.fsi b/src/fsharp/XmlDoc.fsi index ed087bd8c1b..00faec7ddbe 100644 --- a/src/fsharp/XmlDoc.fsi +++ b/src/fsharp/XmlDoc.fsi @@ -41,12 +41,16 @@ type internal XmlDocCollector = member AddGrabPoint: pos: pos -> unit + member AddGrabPointDelayed: pos: pos -> unit + member AddXmlDocLine: line:string * range:range -> unit member LinesBefore: grabPointPos: pos -> (string * range) [] member HasComments: grabPointPos: pos -> bool + member CheckInvalidXmlDocPositions: unit -> unit + /// Represents the XmlDoc fragments as collected from the lexer during parsing [] type public PreXmlDoc = @@ -61,6 +65,8 @@ type public PreXmlDoc = member IsEmpty: bool + member internal MarkAsInvalid: unit -> unit + static member Empty: PreXmlDoc [] diff --git a/src/fsharp/lex.fsl b/src/fsharp/lex.fsl index 0dcdfe3ace9..2e3f3c5b111 100644 --- a/src/fsharp/lex.fsl +++ b/src/fsharp/lex.fsl @@ -677,7 +677,7 @@ rule token args skip = parse | "////" op_char* { // 4+ slash are 1-line comments, online 3 slash are XmlDoc let m = lexbuf.LexemeRange - LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) + LexbufLocalXmlDocStore.AddGrabPointDelayed(lexbuf) if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) else singleLineComment (None,1,m,args) skip lexbuf } @@ -692,7 +692,7 @@ rule token args skip = parse | "//" op_char* { // Need to read all operator symbols too, otherwise it might be parsed by a rule below let m = lexbuf.LexemeRange - LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) + LexbufLocalXmlDocStore.AddGrabPointDelayed(lexbuf) if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) else singleLineComment (None,1,m,args) skip lexbuf } @@ -1477,7 +1477,7 @@ and comment cargs skip = parse if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n-1, m)) else comment (n-1,m,args) skip lexbuf else - LexbufLocalXmlDocStore.AddGrabPoint(lexbuf) + LexbufLocalXmlDocStore.AddGrabPointDelayed(lexbuf) if not skip then COMMENT (LexCont.Token(args.ifdefStack, args.stringNest)) else token args skip lexbuf } diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 1a5e2cf4a51..786c3b9ba36 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -812,7 +812,8 @@ moduleSpfn: | opt_attributes opt_declVisibility typeKeyword tyconSpfn tyconSpfnList { if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) - let (SynTypeDefnSig (SynComponentInfo (cas, a, cs, b, _, d, d2, d3), e, f, g)) = $4 + let (SynTypeDefnSig (SynComponentInfo (cas, a, cs, b, _xmlDoc, d, d2, d3), e, f, g)) = $4 + _xmlDoc.MarkAsInvalid() let attrs = $1 @ cas let mTc = let keywordM = rhs parseState 3 @@ -875,7 +876,8 @@ tyconSpfnList: { let xmlDoc = grabXmlDoc(parseState, [], 1) let tyconSpfn = if xmlDoc.IsEmpty then $2 else - let (SynTypeDefnSig(SynComponentInfo (a, typars, c, lid, _, fixity, vis, rangeOfLid), typeRepr, members, range)) = $2 + let (SynTypeDefnSig(SynComponentInfo (a, typars, c, lid, _xmlDoc, fixity, vis, rangeOfLid), typeRepr, members, range)) = $2 + _xmlDoc.MarkAsInvalid() SynTypeDefnSig(SynComponentInfo (a, typars, c, lid, xmlDoc, fixity, vis, rangeOfLid), typeRepr, members, range) tyconSpfn :: $3 } @@ -1296,7 +1298,8 @@ moduleDefn: | opt_attributes opt_declVisibility typeKeyword tyconDefn tyconDefnList { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let xmlDoc = grabXmlDoc(parseState, $1, 1) - let (SynTypeDefn(SynComponentInfo(cas, a, cs, b, _, d, d2, d3), e, f, g, h)) = $4 + let (SynTypeDefn(SynComponentInfo(cas, a, cs, b, _xmlDoc, d, d2, d3), e, f, g, h)) = $4 + _xmlDoc.MarkAsInvalid() let attrs = $1@cas let mTc = (h, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) let tc = (SynTypeDefn(SynComponentInfo(attrs, a, cs, b, xmlDoc, d, d2, d3), e, f, g, mTc)) @@ -1525,7 +1528,8 @@ tyconDefnList: { let xmlDoc = grabXmlDoc(parseState, [], 1) let tyconDefn = if xmlDoc.IsEmpty then $2 else - let (SynTypeDefn(SynComponentInfo (a, typars, c, lid, _, fixity, vis, rangeOfLid), typeRepr, members, implicitConstructor, range)) = $2 + let (SynTypeDefn(SynComponentInfo (a, typars, c, lid, _xmlDoc, fixity, vis, rangeOfLid), typeRepr, members, implicitConstructor, range)) = $2 + _xmlDoc.MarkAsInvalid() SynTypeDefn(SynComponentInfo (a, typars, c, lid, xmlDoc, fixity, vis, rangeOfLid), typeRepr, members, implicitConstructor, range) tyconDefn :: $3 } | diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 4f1068a61e0..ae3283da2d0 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -292,6 +292,11 @@ Atribut InlineIfLambda se nachází v signatuře, ale ne v implementaci. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Klíčové slovo, které specifikuje konstantní literál jako argument parametru typu v poskytovatelích typů diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index c87da1eb799..5054fb26300 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -292,6 +292,11 @@ Das Attribut "InlineIfLambda" ist in der Signatur vorhanden, jedoch nicht in der Implementierung. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Schlüsselwort, um ein konstantes Literal als Typparameterargument in Typanbietern anzugeben. diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index ba20897d6d6..59c4fdc5d53 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -292,6 +292,11 @@ El atributo "InlineIfLambda" está presente en la firma, pero no en la implementación. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Palabra clave para especificar un literal de constante como argumento de parámetro de tipo en los proveedores de tipo. diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index d1dbb5a3228..f7cbd72eaa3 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -292,6 +292,11 @@ L’attribut « InlineIfLambda » est présent dans la signature, mais pas dans l’implémentation. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Mot clé permettant de spécifier une constante littérale en tant qu'argument de paramètre de type dans les fournisseurs de types. diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index c2efb639371..8b451c11fd1 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -292,6 +292,11 @@ L'attributo 'InlineIfLambda' è presente nella firma, ma non nell'implementazione. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Parola chiave per specificare un valore letterale di costante come argomento del parametro di tipo in Provider di tipi. diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 423870b1b3f..da348d15227 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -292,6 +292,11 @@ 'InlineIfLambda' 属性はシグネチャに存在しますが、実装はありません。 + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. 定数リテラルを型プロバイダーの型パラメーター引数として指定するキーワード。 diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 3a1e807667e..dd43dee3eda 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -292,6 +292,11 @@ 'InlineIfLambda' 특성이 서명에 있지만 구현에는 없습니다. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. 상수 리터럴을 형식 공급자의 형식 매개 변수 인수로 지정하는 키워드입니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 4b05380fb6a..4ff423e11d1 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -292,6 +292,11 @@ Atrybut "InlineIfLambda" jest obecny w sygnaturze, ale nie w implementacji. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Słowo kluczowe na potrzeby określania literału stałej jako argumentu parametru typu w przypadku dostawców typów. diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index e78da3a8260..555a8f2cec4 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -292,6 +292,11 @@ O atributo 'InlineIfLambda' está presente na assinatura, mas não na implementação. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Palavra-chave para especificar um literal constante como um argumento de parâmetro de tipo nos Provedores de Tipo. diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 8ae8c73c007..3a5429f3fb2 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -292,6 +292,11 @@ Атрибут "InlineIfLambda" присутствует в сигнатуре, но отсутствует в реализации. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Ключевое слово для указания константного литерала в качестве аргумента параметра типа в поставщиках типов. diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 3a24dcb76c4..ad318a8407b 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -292,6 +292,11 @@ 'InlineIfLambda' özniteliği imzada var ama uygulamada yok. + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. Tür Sağlayıcılarında tür parametresi bağımsız değişkeni olarak sabit değişmez değeri belirtmek için anahtar sözcük. diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 3d8521964f9..6d2e1e56ea5 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -292,6 +292,11 @@ "InlineIfLambda" 属性存在于签名中,但实现中不存在。 + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. 用于将常量文本指定为类型提供程序中的类型形参实参的关键字。 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 3b48511cf78..e96d2e8501f 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -292,6 +292,11 @@ 'InlineIfLambda' 屬性存在於簽章中,但不存在於實作中。 + + XML comment is not placed on a valid language element. + XML comment is not placed on a valid language element. + + Keyword to specify a constant literal as a type parameter argument in Type Providers. 用於在型別提供者中,將常數常值指定為型別參數引數的關鍵字。 diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index aea1bcb96f7..9df4cfe6708 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -7,8 +7,10 @@ module Tests.XmlDoc #endif +open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Symbols +open FSharp.Test.Compiler open FsUnit open NUnit.Framework @@ -37,16 +39,41 @@ let checkXml symbolName docs checkResults = let checkXmls data checkResults = for symbolName, docs in data do checkXml symbolName docs checkResults -let checkSignatureAndImplementation code checkAction = - getParseAndCheckResults code |> snd - |> checkAction +let checkSignatureAndImplementation code checkResultsAction parseResultsAction = + let checkCode getResultsFunc = + let parseResults, checkResults = getResultsFunc code + checkResultsAction checkResults + parseResultsAction parseResults - getParseAndCheckResultsOfSignatureFile code |> snd - |> checkAction + checkCode getParseAndCheckResults + checkCode getParseAndCheckResultsOfSignatureFile + +let checkParsingErrors expected (parseResults: FSharpParseFileResults) = + parseResults.Diagnostics |> Array.map (fun x -> + let range = x.Range + Error x.ErrorNumber, Line range.StartLine, Col range.StartColumn, Line range.EndLine, Col range.EndColumn, x.Message) + + |> shouldEqual expected [] -let ``separated by expression``() = - let _, checkResults = getParseAndCheckResults """ +let ``comments after xml-doc``(): unit = + checkSignatureAndImplementation """ +module Test + +// b +///A +// b +//// b +(* + b *) +type A = class end +""" + (checkXml "A" [|"A"|]) + (checkParsingErrors [||]) + +[] +let ``separated by expression``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ ///A () ///B @@ -55,29 +82,40 @@ type A checkResults |> checkXml "A" [|"B"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 2, Col 0, Line 2, Col 4, "XML comment is not placed on a valid language element."|] + [] -let ``separated by // comment``() = +let ``separated by // comment``(): unit = checkSignatureAndImplementation """ +module Test + ///A // Simple comment delimiter ///B type A = class end """ (checkXml "A" [|"B"|]) + (checkParsingErrors [|Error 3520, Line 4, Col 0, Line 4, Col 4, "XML comment is not placed on a valid language element."|]) [] -let ``separated by //// comment``() = +let ``separated by //// comment``(): unit = checkSignatureAndImplementation """ +module Test + ///A //// Comment delimiter ///B type A = class end """ (checkXml "A" [|"B"|]) + (checkParsingErrors [|Error 3520, Line 4, Col 0, Line 4, Col 4, "XML comment is not placed on a valid language element."|]) [] -let ``separated by multiline comment``() = +let ``separated by multiline comment``(): unit = checkSignatureAndImplementation """ +module Test + ///A (* Multiline comment delimiter *) @@ -85,10 +123,11 @@ delimiter *) type A = class end """ (checkXml "A" [|"B"|]) + (checkParsingErrors [|Error 3520, Line 4, Col 0, Line 4, Col 4, "XML comment is not placed on a valid language element."|]) [] -let ``separated by (*)``() = - let _, checkResults = getParseAndCheckResults """ +let ``separated by (*)``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ ///A (*) ///B @@ -97,9 +136,14 @@ type A = class end checkResults |> checkXml "A" [|"B"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 2, Col 0, Line 2, Col 4, "XML comment is not placed on a valid language element."|] + [] -let ``types 01 - xml doc allowed positions``() = +let ``types 01 - xml doc allowed positions``(): unit = checkSignatureAndImplementation """ +module Test + ///A1 ///A2 type @@ -109,20 +153,29 @@ type A """ (checkXml "A" [|"A1"; "A2"|]) + (checkParsingErrors [| + Error 3520, Line 7, Col 4, Line 7, Col 9, "XML comment is not placed on a valid language element." + Error 3520, Line 9, Col 13, Line 9, Col 18, "XML comment is not placed on a valid language element." + |]) [] -let ``types 02 - xml doc before 'and'``() = +let ``types 02 - xml doc before 'and'``(): unit = checkSignatureAndImplementation """ +module Test + type A = class end ///B1 ///B2 and B = class end """ (checkXml "B" [|"B1"; "B2"|]) + (checkParsingErrors [||]) [] -let ``types 03 - xml doc after 'and'``() = +let ``types 03 - xml doc after 'and'``(): unit = checkSignatureAndImplementation """ +module Test + type A = class end and ///B1 ///B2 @@ -131,38 +184,48 @@ and ///B1 B = class end """ (checkXml "B" [|"B1"; "B2"|]) + (checkParsingErrors [|Error 3520, Line 8, Col 4, Line 8, Col 9, "XML comment is not placed on a valid language element."|]) [] -let ``types 04 - xml doc before/after 'and'``() = +let ``types 04 - xml doc before/after 'and'``(): unit = checkSignatureAndImplementation """ +module Test + type A = class end ///B1 and ///B2 B = class end """ (checkXml "B" [|"B1"|]) + (checkParsingErrors [|Error 3520, Line 6, Col 4, Line 6, Col 9, "XML comment is not placed on a valid language element."|]) [] -let ``types 05 - attributes after 'type'``() = +let ``types 05 - attributes after 'type'``(): unit = checkSignatureAndImplementation """ +module Test + ///A1 type ///A2 [] A = class end """ (checkXml "A" [|"A1"|]) + (checkParsingErrors [|Error 3520, Line 5, Col 5, Line 5, Col 10, "XML comment is not placed on a valid language element."|]) [] -let ``types 06 - xml doc after attribute``() = +let ``types 06 - xml doc after attribute``(): unit = checkSignatureAndImplementation """ +module Test + [] ///A type A = class end """ (checkXml "A" [||]) + (checkParsingErrors [|Error 3520, Line 5, Col 0, Line 5, Col 4, "XML comment is not placed on a valid language element."|]) [] -let ``let bindings 01 - allowed positions``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 01 - allowed positions``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ ///f1 let ///f2 rec ///f3 @@ -172,9 +235,16 @@ let ///f2 checkResults |> checkXml "f" [|"f1"|] + parseResults + |> checkParsingErrors [| + Error 3520, Line 3, Col 4, Line 3, Col 9, "XML comment is not placed on a valid language element." + Error 3520, Line 4, Col 8, Line 4, Col 13, "XML comment is not placed on a valid language element." + Error 3520, Line 5, Col 15, Line 5, Col 20, "XML comment is not placed on a valid language element." + |] + [] -let ``let bindings 02``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 02``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ ///X1 ///X2 [] @@ -184,9 +254,12 @@ let x = 3 checkResults |> checkXml "x" [|"X1"; "X2"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 5, Col 0, Line 5, Col 5, "XML comment is not placed on a valid language element."|] + [] -let ``let bindings 03 - 'let in'``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 03 - 'let in'``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ ///X1 ///X2 [] @@ -205,18 +278,27 @@ let y = x "y", [|"Y1"; "Y2"|] ] + parseResults + |> checkParsingErrors [| + Error 3520, Line 5, Col 0, Line 5, Col 5, "XML comment is not placed on a valid language element." + Error 3520, Line 11, Col 0, Line 11, Col 5, "XML comment is not placed on a valid language element." + |] + [] -let ``let bindings 03 - 'let in' with attributes after 'let'``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 03 - 'let in' with attributes after 'let'``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ let ///X [] x = 3 in print x """ checkResults |> checkXml "x" [||] + parseResults + |> checkParsingErrors [|Error 3520, Line 2, Col 4, Line 2, Col 8, "XML comment is not placed on a valid language element."|] + [] -let ``let bindings 04 - local binding``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 04 - local binding``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ let _ = ///X1 ///X2 @@ -226,9 +308,12 @@ let _ = checkResults |> checkXml "x" [|"X1"; "X2"|] + parseResults + |> checkParsingErrors [||] + [] -let ``let bindings 05 - use``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 05 - use``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ let _ = ///X1 ///X2 @@ -238,9 +323,12 @@ let _ = checkResults |> checkXml "x" [|"X1"; "X2"|] + parseResults + |> checkParsingErrors [||] + [] -let ``let bindings 06 - xml doc after attribute``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 06 - xml doc after attribute``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ [] ///X let x = 5 @@ -248,9 +336,12 @@ let x = 5 checkResults |> checkXml "x" [||] + parseResults + |> checkParsingErrors [|Error 3520, Line 3, Col 0, Line 3, Col 4, "XML comment is not placed on a valid language element."|] + [] -let ``let bindings 07 - attribute after 'let'``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 07 - attribute after 'let'``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ ///X1 let ///X2 [] x = 5 @@ -258,9 +349,12 @@ let ///X2 checkResults |> checkXml "x" [|"X1"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 3, Col 4, Line 3, Col 9, "XML comment is not placed on a valid language element."|] + [] -let ``let bindings 08 - xml doc before 'and'``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 08 - xml doc before 'and'``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ let rec f x = g x ///G1 ///G2 @@ -269,9 +363,12 @@ and g x = f x checkResults |> checkXml "g" [|"G1"; "G2"|] + parseResults + |> checkParsingErrors [||] + [] -let ``let bindings 09 - xml doc after 'and'``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 09 - xml doc after 'and'``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ let rec f x = g x and ///G1 ///G2 @@ -282,9 +379,12 @@ and ///G1 checkResults |> checkXml "g" [|"G1"; "G2"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 6, Col 4, Line 6, Col 9, "XML comment is not placed on a valid language element."|] + [] -let ``let bindings 10 - xml doc before/after 'and'``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 10 - xml doc before/after 'and'``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ let rec f x = g x ///G1 and ///G2 @@ -293,9 +393,12 @@ and ///G2 checkResults |> checkXml "g" [|"G1"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 4, Col 4, Line 4, Col 9, "XML comment is not placed on a valid language element."|] + [] -let ``let bindings 11 - in type``() = - let _, checkResults = getParseAndCheckResults """ +let ``let bindings 11 - in type``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ type A() = ///data let data = 5 @@ -303,21 +406,27 @@ type A() = checkResults |> checkXml "data" [|"data"|] + parseResults + |> checkParsingErrors [||] + [] -let ``type members 01 - allowed positions``() = - let _, checkResults = getParseAndCheckResults """ +let ``type members 01 - allowed positions``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ type A = ///B1 member ///B2 - private x.B() = () + private x.B(): unit = () """ checkResults |> checkXml "B" [|"B1"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 5, Col 11, Line 5, Col 16, "XML comment is not placed on a valid language element."|] + [] -let ``type members 02``() = - let _, checkResults = getParseAndCheckResults """ +let ``type members 02``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ type A = member x.A() = ///B1 () @@ -331,9 +440,17 @@ type A = checkResults |> checkXml "B" [|"B2"; "B3"|] + parseResults + |> checkParsingErrors [| + Error 3520, Line 3, Col 19, Line 3, Col 24, "XML comment is not placed on a valid language element." + Error 3520, Line 9, Col 4, Line 9, Col 9, "XML comment is not placed on a valid language element." + |] + [] -let ``type members 03 - abstract``() = +let ``type members 03 - abstract``(): unit = checkSignatureAndImplementation """ +module Test + type A = ///M1 ///M2 @@ -342,17 +459,18 @@ type A = abstract member M: unit """ (checkXml "get_M" [|"M1"; "M2"|]) + (checkParsingErrors [|Error 3520, Line 8, Col 4, Line 8, Col 9, "XML comment is not placed on a valid language element."|]) [] -let ``type members 04 - property accessors``() = - let _, checkResults = getParseAndCheckResults """ +let ``type members 04 - property accessors``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ type B = ///A1 ///A2 member ///A3 x.A ///GET - with get () = 5 + with get (): unit = 5 ///SET and set (_: int) = () @@ -364,9 +482,16 @@ type B = "set_A", [|"A1"; "A2"|] ] + parseResults + |> checkParsingErrors [| + Error 3520, Line 5, Col 11, Line 5, Col 16, "XML comment is not placed on a valid language element." + Error 3520, Line 7, Col 16, Line 7, Col 22, "XML comment is not placed on a valid language element." + Error 3520, Line 9, Col 16, Line 9, Col 22, "XML comment is not placed on a valid language element." + |] + [] -let ``type members 05 - auto-property``() = - let _, checkResults = getParseAndCheckResults """ +let ``type members 05 - auto-property``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ type A() = ///B1 ///B2 @@ -377,14 +502,17 @@ type A() = checkResults |> checkXml "get_B" [|"B1"; "B2"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 6, Col 4, Line 6, Col 9, "XML comment is not placed on a valid language element."|] + [] -let ``type members 06 - implicit ctor``() = - let _, checkResults = getParseAndCheckResults """ +let ``type members 06 - implicit ctor``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ type A ///CTOR1 ///CTOR2 [] ///CTOR3 - () = + () = class end """ checkResults |> checkXmls [ @@ -392,9 +520,14 @@ type A ///CTOR1 ".ctor", [|"CTOR1"; "CTOR2"|] ] + parseResults + |> checkParsingErrors [|Error 3520, Line 5, Col 7, Line 5, Col 15, "XML comment is not placed on a valid language element."|] + [] -let ``record``() = +let ``record``(): unit = checkSignatureAndImplementation """ +module Test + type A = { ///B1 @@ -406,9 +539,10 @@ type A = """ (getFieldXml "A" "B" >> compareXml [|"B1"; "B2"|]) + (checkParsingErrors [|Error 3520, Line 9, Col 8, Line 9, Col 13, "XML comment is not placed on a valid language element."|]) [] -let ``module 01``() = +let ``module 01``(): unit = checkSignatureAndImplementation """ ///M1 ///M2 @@ -419,9 +553,13 @@ module rec M """ (checkXml "M" [|"M1"; "M2"|]) + (checkParsingErrors [| + Error 3520, Line 5, Col 0, Line 5, Col 5, "XML comment is not placed on a valid language element." + Error 3520, Line 7, Col 7, Line 7, Col 12, "XML comment is not placed on a valid language element." + |]) [] -let ``module 02 - attributes after 'module'``() = +let ``module 02 - attributes after 'module'``(): unit = checkSignatureAndImplementation """ ///M1 module ///M2 @@ -429,10 +567,13 @@ module ///M2 rec M """ (checkXml "M" [|"M1"|]) + (checkParsingErrors [|Error 3520, Line 3, Col 7, Line 3, Col 12, "XML comment is not placed on a valid language element."|]) [] -let ``union cases 01 - without bar``() = +let ``union cases 01 - without bar``(): unit = checkSignatureAndImplementation """ +module Test + type A = ///One1 ///One2 @@ -445,10 +586,13 @@ type A = "One", [|"One1"; "One2"|] "Two", [|"Two1"; "Two2"|] ]) + (checkParsingErrors [||]) [] -let ``union cases 02``() = +let ``union cases 02``(): unit = checkSignatureAndImplementation """ +module Test + type A = ///One1 ///One2 @@ -465,10 +609,14 @@ type A = "One", [|"One1"; "One2"|] "Two", [|"Two1"; "Two2"|] ]) + (checkParsingErrors [| + Error 3520, Line 8, Col 6, Line 8, Col 13, "XML comment is not placed on a valid language element." + Error 3520, Line 13, Col 6, Line 13, Col 13, "XML comment is not placed on a valid language element." + |]) [] -let ``extern``() = - let _, checkResults = getParseAndCheckResults """ +let ``extern``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ ///E1 ///E2 [] @@ -478,9 +626,14 @@ extern void E() checkResults |> checkXml "E" [|"E1"; "E2"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 5, Col 0, Line 5, Col 5, "XML comment is not placed on a valid language element."|] + [] -let ``exception 01 - allowed positions``() = +let ``exception 01 - allowed positions``(): unit = checkSignatureAndImplementation """ +module Test + ///E1 ///E2 [] @@ -489,32 +642,43 @@ exception ///E4 E of string """ (checkXml "E" [|"E1"; "E2"|]) + (checkParsingErrors [| + Error 3520, Line 7, Col 0, Line 7, Col 5, "XML comment is not placed on a valid language element." + Error 3520, Line 8, Col 10, Line 8, Col 15, "XML comment is not placed on a valid language element." + |]) [] -let ``exception 02 - attribute after 'exception'``() = +let ``exception 02 - attribute after 'exception'``(): unit = checkSignatureAndImplementation """ +module Test + exception ///E [] E of string """ (checkXml "E" [||]) + (checkParsingErrors [|Error 3520, Line 4, Col 10, Line 4, Col 14, "XML comment is not placed on a valid language element."|]) [] -let ``val 01 - type``() = +let ``val 01 - type``(): unit = checkSignatureAndImplementation """ +module Test + type A = ///B1 ///B2 [] ///B3 + ///B4 val mutable private B: int """ (getFieldXml "A" "B" >> compareXml [|"B1"; "B2"|]) + (checkParsingErrors [|Error 3520, Line 8, Col 4, Line 9, Col 9, "XML comment is not placed on a valid language element."|]) [] -let ``val 02 - struct``() = - let _, checkResults = getParseAndCheckResults """ +let ``val 02 - struct``(): unit = + let parseResults, checkResults = getParseAndCheckResults """ type Point = struct ///X1 @@ -528,9 +692,14 @@ type Point = |> getFieldXml "Point" "x" |> compareXml [|"X1"; "X2"|] + parseResults + |> checkParsingErrors [|Error 3520, Line 7, Col 8, Line 7, Col 13, "XML comment is not placed on a valid language element."|] + [] -let ``val 03 - module``() = - let _, checkResults = getParseAndCheckResultsOfSignatureFile """ +let ``val 03 - module``(): unit = + let parseResults, checkResults = getParseAndCheckResultsOfSignatureFile """ +module Test + ///A1 ///A2 [] @@ -539,3 +708,6 @@ val a: int """ checkResults |> checkXml "a" [|"A1"; "A2"|] + + parseResults + |> checkParsingErrors [|Error 3520, Line 7, Col 0, Line 7, Col 5, "XML comment is not placed on a valid language element."|] From 3661e90778fc00b485018c27cdd91d39410d1996 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 8 Jan 2021 16:22:58 -0600 Subject: [PATCH 14/25] initial impl # Conflicts: # src/fsharp/SyntaxTreeOps.fs # src/fsharp/SyntaxTreeOps.fsi # src/fsharp/fsi/fsi.fs # src/fsharp/pars.fsy --- src/fsharp/SyntaxTreeOps.fs | 2 +- src/fsharp/SyntaxTreeOps.fsi | 2 +- src/fsharp/pars.fsy | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fsharp/SyntaxTreeOps.fs b/src/fsharp/SyntaxTreeOps.fs index 207a122ed9c..33a82472186 100644 --- a/src/fsharp/SyntaxTreeOps.fs +++ b/src/fsharp/SyntaxTreeOps.fs @@ -91,7 +91,7 @@ let rec IsControlFlowExpression e = let mkSynAnonField (ty: SynType) = SynField([], false, None, ty, false, PreXmlDoc.Empty, None, ty.Range) -let mkSynNamedField (ident, ty: SynType, m) = SynField([], false, Some ident, ty, false, PreXmlDoc.Empty, None, m) +let mkSynNamedField (ident, ty: SynType, xmlDoc, m) = SynField([], false, Some ident, ty, false, xmlDoc, None, m) let mkSynPatVar vis (id: Ident) = SynPat.Named (id, false, vis, id.idRange) diff --git a/src/fsharp/SyntaxTreeOps.fsi b/src/fsharp/SyntaxTreeOps.fsi index c4274fb9584..f7f7d51421e 100644 --- a/src/fsharp/SyntaxTreeOps.fsi +++ b/src/fsharp/SyntaxTreeOps.fsi @@ -50,7 +50,7 @@ val IsControlFlowExpression: e:SynExpr -> bool val mkSynAnonField: ty:SynType -> SynField -val mkSynNamedField: ident:Ident * ty:SynType * m:range -> SynField +val mkSynNamedField: ident:Ident * ty:SynType * xmlDoc:PreXmlDoc * m:range -> SynField val mkSynPatVar: vis:SynAccess option -> id:Ident -> SynPat diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 786c3b9ba36..26578a89c47 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -2515,8 +2515,9 @@ unionCaseReprElements: unionCaseReprElement: | ident COLON appType - { let wholeRange = rhs2 parseState 1 3 - mkSynNamedField($1, $3, wholeRange) } + { let xmlDoc = grabXmlDoc(parseState, [], 1) + let wholeRange = rhs2 parseState 1 3 + mkSynNamedField($1, $3, xmlDoc, wholeRange) } | appType { mkSynAnonField $1 } From f869a0c39b194b28ca0e44643b82675ee70f8376 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 8 Jan 2021 17:23:06 -0600 Subject: [PATCH 15/25] add in test that verifies the SyntaxTree representation # Conflicts: # tests/service/Symbols.fs --- tests/service/Symbols.fs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index 85df60c7af4..931a38a7a8a 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -1583,3 +1583,43 @@ else (* some long comment here *) if c then assertRange (4, 34) (4, 36) mIf2 | _ -> Assert.Fail "Could not get valid AST" + + +module UnionCaseComments = + [] + let ``Union Case fields can have comments`` () = + let ast = """ +type Foo = +/// docs for Thing +| Thing of + /// docs for first + first: string * + /// docs for second + second: bool +""" + |> getParseResults + + match ast with + | ParsedInput.ImplFile(ParsedImplFileInput(modules = [ + SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types ([ + SynTypeDefn.SynTypeDefn (typeRepr = SynTypeDefnRepr.Simple (simpleRepr = SynTypeDefnSimpleRepr.Union(unionCases = [ + SynUnionCase.SynUnionCase (caseType = SynUnionCaseKind.Fields [ + SynField.SynField(xmlDoc = firstXml) + SynField.SynField(xmlDoc = anonXml) + ]) + ]))) + ], _) + ]) + ])) -> + let firstDocs = firstXml.ToXmlDoc(false, None).GetXmlText() + let anonDocs = anonXml.ToXmlDoc(false, None).GetXmlText() + + Assert.AreEqual(""" + docs for first +""", firstDocs) + Assert.AreEqual(""" + docs for anon field +""", anonDocs) + | _ -> + failwith "Could not find SynExpr.Do" From 81912bda34447d4992ae7847bae8d9b490b13ab9 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 8 Jan 2021 17:57:54 -0600 Subject: [PATCH 16/25] generate sigs and write docs for union case properties # Conflicts: # src/fsharp/XmlDocFileWriter.fs --- src/fsharp/CheckDeclarations.fs | 6 +++--- src/fsharp/XmlDocFileWriter.fs | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/fsharp/CheckDeclarations.fs b/src/fsharp/CheckDeclarations.fs index ed895304059..a9e312a43ed 100644 --- a/src/fsharp/CheckDeclarations.fs +++ b/src/fsharp/CheckDeclarations.fs @@ -483,9 +483,9 @@ module TcRecdUnionAndEnumDeclarations = | Some fieldId, Parent tcref -> let item = Item.UnionCaseField (UnionCaseInfo (thisTyInst, UnionCaseRef (tcref, id.idText)), i) CallNameResolutionSink cenv.tcSink (fieldId.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights) - | _ -> () - - TcAnonFieldDecl cenv env parent tpenv (mkUnionCaseFieldName nFields i) fld) + TcNamedFieldDecl cenv env parent false tpenv fld + | _ -> + TcAnonFieldDecl cenv env parent tpenv (mkUnionCaseFieldName nFields i) fld) ValidateFieldNames(flds, rfields) rfields, thisTy diff --git a/src/fsharp/XmlDocFileWriter.fs b/src/fsharp/XmlDocFileWriter.fs index 60ec69d07ac..26fa5b01327 100644 --- a/src/fsharp/XmlDocFileWriter.fs +++ b/src/fsharp/XmlDocFileWriter.fs @@ -23,8 +23,15 @@ module XmlDocWriter = if (hasDoc tc.XmlDoc) then tc.XmlDocSig <- XmlDocSigOfTycon [ptext; tc.CompiledName] for vref in tc.MembersOfFSharpTyconSorted do doValSig ptext vref.Deref + for uc in tc.UnionCasesArray do - if (hasDoc uc.XmlDoc) then uc.XmlDocSig <- XmlDocSigOfUnionCase [ptext; tc.CompiledName; uc.Id.idText] + if (hasDoc uc.XmlDoc) then + uc.XmlDocSig <- XmlDocSigOfUnionCase [ptext; tc.CompiledName; uc.Id.idText] + for field in uc.RecdFieldsArray do + if (hasDoc field.XmlDoc) then + // union case fields are exposed as properties + field.XmlDocSig <- XmlDocSigOfProperty [ptext; tc.CompiledName; uc.Id.idText; field.Id.idText] + for rf in tc.AllFieldsArray do if (hasDoc rf.XmlDoc) then rf.XmlDocSig <- @@ -68,9 +75,12 @@ module XmlDocWriter = let doc = xmlDoc.GetXmlText() members <- (id, doc) :: members let doVal (v: Val) = addMember v.XmlDocSig v.XmlDoc - let doUnionCase (uc: UnionCase) = addMember uc.XmlDocSig uc.XmlDoc let doField (rf: RecdField) = addMember rf.XmlDocSig rf.XmlDoc - let doTycon (tc: Tycon) = + let doUnionCase (uc: UnionCase) = + addMember uc.XmlDocSig uc.XmlDoc + for field in uc.RecdFieldsArray do + addMember field.XmlDocSig field.XmlDoc + let doTycon (tc: Tycon) = addMember tc.XmlDocSig tc.XmlDoc for vref in tc.MembersOfFSharpTyconSorted do doVal vref.Deref From 36424af373774a552bc2795bfff04f34dee5a10c Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Sat, 9 Jan 2021 12:19:50 -0600 Subject: [PATCH 17/25] implement xmldocs for anon fields as well # Conflicts: # src/fsharp/SyntaxTreeOps.fs # src/fsharp/SyntaxTreeOps.fsi # src/fsharp/XmlDocFileWriter.fs # src/fsharp/pars.fsy # tests/service/Symbols.fs --- src/fsharp/SyntaxTreeOps.fs | 2 +- src/fsharp/SyntaxTreeOps.fsi | 2 +- src/fsharp/pars.fsy | 5 +++-- tests/service/Symbols.fs | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/fsharp/SyntaxTreeOps.fs b/src/fsharp/SyntaxTreeOps.fs index 33a82472186..938fb418018 100644 --- a/src/fsharp/SyntaxTreeOps.fs +++ b/src/fsharp/SyntaxTreeOps.fs @@ -89,7 +89,7 @@ let rec IsControlFlowExpression e = | SynExpr.Typed (e, _, _) -> IsControlFlowExpression e | _ -> false -let mkSynAnonField (ty: SynType) = SynField([], false, None, ty, false, PreXmlDoc.Empty, None, ty.Range) +let mkSynAnonField (ty: SynType, xmlDoc) = SynField([], false, None, ty, false, xmlDoc, None, ty.Range) let mkSynNamedField (ident, ty: SynType, xmlDoc, m) = SynField([], false, Some ident, ty, false, xmlDoc, None, m) diff --git a/src/fsharp/SyntaxTreeOps.fsi b/src/fsharp/SyntaxTreeOps.fsi index f7f7d51421e..3183c9cb819 100644 --- a/src/fsharp/SyntaxTreeOps.fsi +++ b/src/fsharp/SyntaxTreeOps.fsi @@ -48,7 +48,7 @@ val (|SingleIdent|_|): inp:SynExpr -> Ident option /// This affects placement of sequence points val IsControlFlowExpression: e:SynExpr -> bool -val mkSynAnonField: ty:SynType -> SynField +val mkSynAnonField: ty:SynType * xmlDoc:PreXmlDoc -> SynField val mkSynNamedField: ident:Ident * ty:SynType * xmlDoc:PreXmlDoc * m:range -> SynField diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 26578a89c47..4444bda3836 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -2517,10 +2517,11 @@ unionCaseReprElement: | ident COLON appType { let xmlDoc = grabXmlDoc(parseState, [], 1) let wholeRange = rhs2 parseState 1 3 - mkSynNamedField($1, $3, xmlDoc, wholeRange) } + mkSynNamedField ($1, $3, xmlDoc, wholeRange) } | appType - { mkSynAnonField $1 } + { let xmlDoc = grabXmlDoc(parseState, [], 1) + mkSynAnonField ($1, xmlDoc) } unionCaseRepr: | braceFieldDeclList diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index 931a38a7a8a..29c73c0280d 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -1594,8 +1594,8 @@ type Foo = | Thing of /// docs for first first: string * - /// docs for second - second: bool + /// docs for anon field + bool """ |> getParseResults From d67fd9f369bfb17a28cbd8030e8cd6b20b6e9314 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Fri, 3 Sep 2021 15:37:14 +0300 Subject: [PATCH 18/25] minor fixes --- src/fsharp/ParseAndCheckInputs.fs | 4 ++-- src/fsharp/ParseHelpers.fs | 2 +- src/fsharp/ParseHelpers.fsi | 2 +- tests/service/Symbols.fs | 12 ++++++------ tests/service/XmlDocTests.fs | 24 ++++++++++++++++++++++++ 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/fsharp/ParseAndCheckInputs.fs b/src/fsharp/ParseAndCheckInputs.fs index 30ce3ffbdd7..d664cd58412 100644 --- a/src/fsharp/ParseAndCheckInputs.fs +++ b/src/fsharp/ParseAndCheckInputs.fs @@ -274,11 +274,11 @@ let ParseInput (lexer, errorLogger: ErrorLogger, lexbuf: UnicodeLexing.Lexbuf, d // Call the appropriate parser - for signature files or implementation files if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then let impl = Parser.implementationFile lexer lexbuf - LexbufLocalXmlDocStore.CheckInvalidXmlDocPositions(lexbuf) + LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf) PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, impl) elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then let intfs = Parser.signatureFile lexer lexbuf - LexbufLocalXmlDocStore.CheckInvalidXmlDocPositions(lexbuf) + LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf) PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, intfs) else delayLogger.Error(Error(FSComp.SR.buildInvalidSourceFileExtension filename, rangeStartup)) diff --git a/src/fsharp/ParseHelpers.fs b/src/fsharp/ParseHelpers.fs index b1ad0131fdf..b70103fcde5 100644 --- a/src/fsharp/ParseHelpers.fs +++ b/src/fsharp/ParseHelpers.fs @@ -140,7 +140,7 @@ module LexbufLocalXmlDocStore = | _ -> PreXmlDoc.Empty - let CheckInvalidXmlDocPositions (lexbuf: Lexbuf) = + let ReportInvalidXmlDocPositions (lexbuf: Lexbuf) = let collector = getCollector lexbuf collector.CheckInvalidXmlDocPositions() diff --git a/src/fsharp/ParseHelpers.fsi b/src/fsharp/ParseHelpers.fsi index bc44bf8b3bf..d27f3710ddb 100644 --- a/src/fsharp/ParseHelpers.fsi +++ b/src/fsharp/ParseHelpers.fsi @@ -51,7 +51,7 @@ module LexbufLocalXmlDocStore = val AddGrabPointDelayed: lexbuf:UnicodeLexing.Lexbuf -> unit - val CheckInvalidXmlDocPositions: lexbuf:UnicodeLexing.Lexbuf -> unit + val ReportInvalidXmlDocPositions: lexbuf:UnicodeLexing.Lexbuf -> unit type LexerIfdefStackEntry = | IfDefIf diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index 29c73c0280d..788170c65a4 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -7,6 +7,7 @@ module Tests.Service.Symbols #endif +open System open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Symbols open FSharp.Compiler.Syntax @@ -1615,11 +1616,10 @@ type Foo = let firstDocs = firstXml.ToXmlDoc(false, None).GetXmlText() let anonDocs = anonXml.ToXmlDoc(false, None).GetXmlText() - Assert.AreEqual(""" - docs for first -""", firstDocs) - Assert.AreEqual(""" - docs for anon field -""", anonDocs) + let nl = Environment.NewLine + + Assert.AreEqual($"{nl} docs for first{nl}", firstDocs) + Assert.AreEqual($"{nl} docs for anon field{nl}", anonDocs) + | _ -> failwith "Could not find SynExpr.Do" diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index 9df4cfe6708..67a2e85dcb6 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -18,6 +18,7 @@ let getFieldXml symbolName fieldName checkResults = let field = match findSymbolByName symbolName checkResults with | :? FSharpEntity as e -> e.FSharpFields |> Seq.find(fun x -> x.DisplayName = fieldName) + | :? FSharpUnionCase as c -> c.Fields |> Seq.find(fun x -> x.DisplayName = fieldName) | _ -> failwith "Unexpected symbol" field.XmlDoc @@ -614,6 +615,29 @@ type A = Error 3520, Line 13, Col 6, Line 13, Col 13, "XML comment is not placed on a valid language element." |]) +[] +let ``union cases 03 - union case fields``(): unit = + checkSignatureAndImplementation """ +module Test + +type Foo = +| Thing of + ///A1 + ///A2 + a: string * + ///B1 + ///B2 + bool +""" + (fun checkResults -> + getFieldXml "Thing" "a" checkResults + |> compareXml [|"A1"; "A2"|] + + getFieldXml "Thing" "Item2" checkResults + |> compareXml [|"B1"; "B2"|]) + + (checkParsingErrors [||]) + [] let ``extern``(): unit = let parseResults, checkResults = getParseAndCheckResults """ From 407fc1f170fd87596af8f80892f7b8f962eb2e88 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Wed, 8 Sep 2021 13:26:25 +0300 Subject: [PATCH 19/25] fix xml-doc in FSharp.Core --- src/fsharp/FSharp.Core/Linq.fs | 2 +- src/fsharp/FSharp.Core/Query.fsi | 8 +- src/fsharp/FSharp.Core/SI.fs | 106 ++++++------ src/fsharp/FSharp.Core/array2.fsi | 4 +- src/fsharp/FSharp.Core/array3.fsi | 6 +- src/fsharp/FSharp.Core/async.fs | 8 +- src/fsharp/FSharp.Core/async.fsi | 10 +- src/fsharp/FSharp.Core/eventmodule.fsi | 8 +- .../FSharp.Core/fslib-extra-pervasives.fsi | 4 +- src/fsharp/FSharp.Core/mailbox.fsi | 2 +- src/fsharp/FSharp.Core/math/z.fsi | 2 +- src/fsharp/FSharp.Core/nativeptr.fsi | 74 ++++---- src/fsharp/FSharp.Core/observable.fsi | 4 +- src/fsharp/FSharp.Core/option.fsi | 2 +- src/fsharp/FSharp.Core/prim-types.fsi | 158 +++++++++--------- src/fsharp/FSharp.Core/printf.fs | 2 +- src/fsharp/FSharp.Core/quotations.fsi | 4 +- src/fsharp/FSharp.Core/reflect.fsi | 6 +- src/fsharp/FSharp.Core/result.fsi | 2 +- src/fsharp/FSharp.Core/seq.fsi | 4 +- src/fsharp/FSharp.Core/seqcore.fsi | 4 +- src/fsharp/FSharp.Core/set.fsi | 3 +- src/fsharp/FSharp.Core/string.fs | 2 +- src/fsharp/FSharp.Core/tasks.fsi | 6 +- 24 files changed, 215 insertions(+), 216 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 8bc7fcf5615..d46d9eedb56 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -497,7 +497,7 @@ module LeafExpressionConverter = // or type T to an argument expecting Expression. | ImplicitExpressionConversionHelperQ (_, [_], [x1]) -> ConvExprToLinqInContext env x1 - /// Use witnesses if they are available + // Use witnesses if they are available | CallWithWitnesses (objArgOpt, _, minfo2, witnessArgs, args) -> let fullArgs = witnessArgs @ args let replacementExpr = diff --git a/src/fsharp/FSharp.Core/Query.fsi b/src/fsharp/FSharp.Core/Query.fsi index 7017fe693e8..13dd7e1fbc7 100644 --- a/src/fsharp/FSharp.Core/Query.fsi +++ b/src/fsharp/FSharp.Core/Query.fsi @@ -10,15 +10,15 @@ namespace Microsoft.FSharp.Linq open System.Collections open System.Collections.Generic - [] /// /// A partial input or result in an F# query. This type is used to support the F# query syntax. /// /// /// - /// Library functionality for F# query syntax and interoperability with .NET LINQ Expressions. See + /// Library functionality for F# query syntax and interoperability with .NET LINQ Expressions. See /// also F# Query Expressions in the F# Language Guide. /// + [] type QuerySource<'T, 'Q> = /// /// A method used to support the F# query syntax. @@ -30,9 +30,9 @@ namespace Microsoft.FSharp.Linq /// member Source : seq<'T> - [] - /// The type used to support the F# query syntax. Use 'query { ... }' to use the query syntax. See + /// The type used to support the F# query syntax. Use 'query { ... }' to use the query syntax. See /// also F# Query Expressions in the F# Language Guide. + [] type QueryBuilder = /// Create an instance of this builder. Use 'query { ... }' to use the query syntax. new : unit -> QueryBuilder diff --git a/src/fsharp/FSharp.Core/SI.fs b/src/fsharp/FSharp.Core/SI.fs index b0ec79e91f9..10a0798445c 100644 --- a/src/fsharp/FSharp.Core/SI.fs +++ b/src/fsharp/FSharp.Core/SI.fs @@ -4,112 +4,112 @@ namespace Microsoft.FSharp.Data.UnitSystems.SI.UnitNames open Microsoft.FSharp.Core - [] /// The SI unit of length + [] type metre - [] /// The SI unit of length + [] type meter = metre - [] /// The SI unit of mass + [] type kilogram - [] /// The SI unit of time + [] type second - [] /// The SI unit of electric current + [] type ampere - [] /// The SI unit of thermodynamic temperature + [] type kelvin - [] /// The SI unit of amount of substance + [] type mole - [] /// The SI unit of luminous intensity + [] type candela - [] /// The SI unit of frequency + [] type hertz = / second - [] /// The SI unit of force + [] type newton = kilogram metre / second^2 - [] /// The SI unit of pressure, stress + [] type pascal = newton / metre^2 - [] /// The SI unit of energy, work, amount of heat + [] type joule = newton metre - [] /// The SI unit of power, radiant flux + [] type watt = joule / second - [] /// The SI unit of electric charge, amount of electricity + [] type coulomb = second ampere - [] /// The SI unit of electric potential difference, electromotive force + [] type volt = watt/ampere - [] /// The SI unit of capacitance + [] type farad = coulomb/volt - [] /// The SI unit of electric resistance + [] type ohm = volt/ampere - [] /// The SI unit of electric conductance + [] type siemens = ampere/volt - [] /// The SI unit of magnetic flux + [] type weber = volt second - [] /// The SI unit of magnetic flux density + [] type tesla = weber/metre^2 - [] /// The SI unit of inductance + [] type henry = weber/ampere - [] /// The SI unit of luminous flux + [] type lumen = candela - [] /// The SI unit of illuminance + [] type lux = lumen/metre^2 - [] /// The SI unit of activity referred to a radionuclide + [] type becquerel = second^-1 - [] /// The SI unit of absorbed dose + [] type gray = joule/kilogram - [] /// The SI unit of does equivalent + [] type sievert = joule/kilogram - [] /// The SI unit of catalytic activity + [] type katal = mole/second @@ -118,106 +118,106 @@ namespace Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols open Microsoft.FSharp.Core open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames - [] /// A synonym for Metre, the SI unit of length + [] type m = metre - [] /// A synonym for kilogram, the SI unit of mass + [] type kg = kilogram - [] /// A synonym for second, the SI unit of time + [] type s = second - [] /// A synonym for ampere, the SI unit of electric current + [] type A = ampere - [] /// A synonym for kelvin, the SI unit of thermodynamic temperature + [] type K = kelvin - [] /// A synonym for mole, the SI unit of amount of substance + [] type mol = mole - [] /// A synonym for candela, the SI unit of luminous intensity + [] type cd = candela - [] /// A synonym for hertz, the SI unit of frequency + [] type Hz = hertz - [] /// A synonym for newton, the SI unit of force + [] type N = newton - [] /// A synonym for pascal, the SI unit of pressure, stress + [] type Pa = pascal - [] /// A synonym for joule, the SI unit of energy, work, amount of heat + [] type J = joule - [] /// A synonym for watt, the SI unit of power, radiant flux + [] type W = watt - [] /// A synonym for coulomb, the SI unit of electric charge, amount of electricity + [] type C = coulomb - [] /// A synonym for volt, the SI unit of electric potential difference, electromotive force + [] type V = volt - [] /// A synonym for farad, the SI unit of capacitance + [] type F = farad - [] /// A synonym for siemens, the SI unit of electric conductance + [] type S = siemens - [] /// A synonym for UnitNames.ohm, the SI unit of electric resistance. + [] type ohm = Microsoft.FSharp.Data.UnitSystems.SI.UnitNames.ohm - [] /// A synonym for weber, the SI unit of magnetic flux + [] type Wb = weber - [] /// A synonym for tesla, the SI unit of magnetic flux density + [] type T = tesla - [] /// A synonym for lumen, the SI unit of luminous flux + [] type lm = lumen - [] /// A synonym for lux, the SI unit of illuminance + [] type lx = lux - [] /// A synonym for becquerel, the SI unit of activity referred to a radionuclide + [] type Bq = becquerel - [] /// A synonym for gray, the SI unit of absorbed dose + [] type Gy = gray - [] /// A synonym for sievert, the SI unit of does equivalent + [] type Sv = sievert - [] /// A synonym for katal, the SI unit of catalytic activity + [] type kat = katal - [] /// A synonym for henry, the SI unit of inductance + [] type H = henry diff --git a/src/fsharp/FSharp.Core/array2.fsi b/src/fsharp/FSharp.Core/array2.fsi index 372bc131419..586023c8f8e 100644 --- a/src/fsharp/FSharp.Core/array2.fsi +++ b/src/fsharp/FSharp.Core/array2.fsi @@ -6,8 +6,6 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Collections open Microsoft.FSharp.Core - [] - [] /// Contains operations for working with 2-dimensional arrays. /// /// @@ -23,6 +21,8 @@ namespace Microsoft.FSharp.Collections /// Non-zero-based arrays can also be created using Array2D.zeroCreateBased, /// Array2D.createBased and Array2D.initBased. /// + [] + [] module Array2D = /// Fetches the base-index for the first dimension of the array. diff --git a/src/fsharp/FSharp.Core/array3.fsi b/src/fsharp/FSharp.Core/array3.fsi index 60be384d0d8..fc77ce4913f 100644 --- a/src/fsharp/FSharp.Core/array3.fsi +++ b/src/fsharp/FSharp.Core/array3.fsi @@ -7,13 +7,13 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Core open Microsoft.FSharp.Core.Operators - [] - [] /// Contains operations for working with rank 3 arrays. /// /// /// See also F# Language Guide - Arrays. /// + [] + [] module Array3D = /// Creates an array whose elements are all initially the given value. @@ -135,9 +135,9 @@ namespace Microsoft.FSharp.Collections + /// Contains operations for working with rank 4 arrays. [] [] - /// Contains operations for working with rank 4 arrays. module Array4D = /// Creates an array whose elements are all initially the given value diff --git a/src/fsharp/FSharp.Core/async.fs b/src/fsharp/FSharp.Core/async.fs index 6afa26489de..f7e41125e9f 100644 --- a/src/fsharp/FSharp.Core/async.fs +++ b/src/fsharp/FSharp.Core/async.fs @@ -233,9 +233,9 @@ namespace Microsoft.FSharp.Control // NOTE: this must be a tailcall cont res + /// Represents rarely changing components of an in-flight async computation [] [] - /// Represents rarely changing components of an in-flight async computation type AsyncActivationAux = { /// The active cancellation token token: CancellationToken @@ -249,9 +249,9 @@ namespace Microsoft.FSharp.Control /// Holds some commonly-allocated callbacks and a mutable location to use for a trampoline trampolineHolder: TrampolineHolder } + /// Represents context for an in-flight async computation [] [] - /// Represents context for an in-flight async computation type AsyncActivationContents<'T> = { /// The success continuation cont: cont<'T> @@ -305,7 +305,7 @@ namespace Microsoft.FSharp.Control contents.aux.ccont (OperationCanceledException (contents.aux.token)) /// Check for trampoline hijacking. - // Note, this must make tailcalls, so may not be an instance member taking a byref argument, + /// Note, this must make tailcalls, so may not be an instance member taking a byref argument, /// nor call any members taking byref arguments. static member inline HijackCheckThenCall (ctxt: AsyncActivation<'T>) cont arg = ctxt.aux.trampolineHolder.HijackCheckThenCall cont arg @@ -756,7 +756,7 @@ namespace Microsoft.FSharp.Control /// - Hijack check after 'entering' the implied try/finally and after MoveNext call /// - Do not apply 'GetEnumerator' with exception protection. However for an 'async' /// in an 'async { ... }' the exception protection will be provided by the enclosing - // Delay or Bind or similar construct. + /// Delay or Bind or similar construct. /// - Apply 'MoveNext' with exception protection /// - Apply 'Current' with exception protection diff --git a/src/fsharp/FSharp.Core/async.fsi b/src/fsharp/FSharp.Core/async.fsi index 4f9f765bf6f..c5ff4be3876 100644 --- a/src/fsharp/FSharp.Core/async.fsi +++ b/src/fsharp/FSharp.Core/async.fsi @@ -609,9 +609,9 @@ namespace Microsoft.FSharp.Control type AsyncReturn /// The F# compiler emits references to this type to implement F# async expressions. - [] /// /// Async Internals + [] type AsyncActivation<'T> = /// The F# compiler emits calls to this function to implement F# async expressions. @@ -649,10 +649,10 @@ namespace Microsoft.FSharp.Control | Error of ExceptionDispatchInfo | Canceled of OperationCanceledException - [] /// Entry points for generated code /// /// Async Internals + [] module AsyncPrimitives = /// The F# compiler emits calls to this function to implement F# async expressions. @@ -722,11 +722,11 @@ namespace Microsoft.FSharp.Control // Internals used by MailboxProcessor val internal CreateAsyncResultAsync : AsyncResult<'T> -> Async<'T> - [] - [] /// The type of the async operator, used to build workflows for asynchronous computations. /// /// Async Programming + [] + [] type AsyncBuilder = /// Creates an asynchronous computation that enumerates the sequence seq /// on demand and runs body for each element. @@ -884,10 +884,10 @@ namespace Microsoft.FSharp.Control /// A cancellation check is performed when the computation is executed. internal new : unit -> AsyncBuilder - [] /// A module of extension members providing asynchronous operations for some basic CLI types related to concurrency and I/O. /// /// Async Programming + [] module CommonExtensions = type System.IO.Stream with diff --git a/src/fsharp/FSharp.Core/eventmodule.fsi b/src/fsharp/FSharp.Core/eventmodule.fsi index 4e520b559f6..6dcd33f5d35 100644 --- a/src/fsharp/FSharp.Core/eventmodule.fsi +++ b/src/fsharp/FSharp.Core/eventmodule.fsi @@ -5,11 +5,11 @@ namespace Microsoft.FSharp.Control open Microsoft.FSharp.Core open Microsoft.FSharp.Control - [] - [] /// Contains operations for working with values of type . /// /// Events and Observables + [] + [] module Event = /// Fires the output event when either of the input events fire. @@ -73,11 +73,10 @@ namespace Microsoft.FSharp.Control [] val choose: chooser:('T -> 'U option) -> sourceEvent:IEvent<'Del,'T> -> IEvent<'U> - [] /// Returns a new event consisting of the results of applying the given accumulating function /// to successive values triggered on the input event. An item of internal state /// records the current value of the state parameter. The internal state is not locked during the - /// execution of the accumulation function, so care should be taken that the + /// execution of the accumulation function, so care should be taken that the /// input IEvent not triggered by multiple threads simultaneously. /// /// The function to update the state with each event value. @@ -85,6 +84,7 @@ namespace Microsoft.FSharp.Control /// The input event. /// /// An event that fires on the updated state values. + [] val scan: collector:('U -> 'T -> 'U) -> state:'U -> sourceEvent:IEvent<'Del,'T> -> IEvent<'U> /// Runs the given function each time the given event is triggered. diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi index c7ae3fc6cf1..7fca5d59537 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi @@ -3,10 +3,10 @@ /// Pervasives: Additional bindings available at the top level namespace Microsoft.FSharp.Core -[] /// A set of extra operators and functions. This module is automatically opened in all F# code. /// /// Basic Operators +[] module ExtraTopLevelOperators = open System @@ -235,8 +235,8 @@ namespace Microsoft.FSharp.Core.CompilerServices member Line : int with get, set member Column : int with get, set - [] /// Indicates that a code editor should hide all System.Object methods from the intellisense menus for instances of a provided type + [] type TypeProviderEditorHideMethodsAttribute = inherit System.Attribute /// Creates an instance of the attribute diff --git a/src/fsharp/FSharp.Core/mailbox.fsi b/src/fsharp/FSharp.Core/mailbox.fsi index 3f36a6f9def..067c68048e9 100644 --- a/src/fsharp/FSharp.Core/mailbox.fsi +++ b/src/fsharp/FSharp.Core/mailbox.fsi @@ -7,10 +7,10 @@ namespace Microsoft.FSharp.Control open Microsoft.FSharp.Core open Microsoft.FSharp.Control - [] /// A handle to a capability to reply to a PostAndReply message. /// /// Agents + [] type AsyncReplyChannel<'Reply> = /// Sends a reply to a PostAndReply message. /// The value to send. diff --git a/src/fsharp/FSharp.Core/math/z.fsi b/src/fsharp/FSharp.Core/math/z.fsi index 463d57f3db0..a8c52f5703a 100644 --- a/src/fsharp/FSharp.Core/math/z.fsi +++ b/src/fsharp/FSharp.Core/math/z.fsi @@ -17,10 +17,10 @@ namespace Microsoft.FSharp.Core /// Basic Types type bigint = System.Numerics.BigInteger - [] /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' /// /// Language Primitives + [] module NumericLiterals = /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' diff --git a/src/fsharp/FSharp.Core/nativeptr.fsi b/src/fsharp/FSharp.Core/nativeptr.fsi index cc2d7b0fc75..9d5c634ab88 100644 --- a/src/fsharp/FSharp.Core/nativeptr.fsi +++ b/src/fsharp/FSharp.Core/nativeptr.fsi @@ -5,70 +5,70 @@ namespace Microsoft.FSharp.NativeInterop open Microsoft.FSharp.Core open Microsoft.FSharp.Collections - [] - [] /// Contains operations on native pointers. Use of these operators may /// result in the generation of unverifiable code. /// /// - /// Library functionality for native interopability. See - /// also F# External Functions in + /// Library functionality for native interopability. See + /// also F# External Functions in /// the F# Language Guide. /// + [] + [] module NativePtr = - [] - [] /// Returns a typed native pointer for a given machine address. /// /// The machine address. /// /// A typed native pointer. + [] + [] val inline ofNativeInt : address: nativeint -> nativeptr<'T> - [] - [] /// Returns a machine address for a given typed native pointer. /// /// The typed native pointer. /// /// The machine address. + [] + [] val inline toNativeInt : address: nativeptr<'T> -> nativeint - [] - [] /// Returns a typed native pointer for a untyped native pointer. /// /// The untyped native pointer. /// /// A typed native pointer. + [] + [] val inline ofVoidPtr : address: voidptr -> nativeptr<'T> - [] - [] /// Returns an untyped native pointer for a given typed native pointer. /// /// The typed native pointer. /// /// An untyped native pointer. + [] + [] val inline toVoidPtr : address: nativeptr<'T> -> voidptr - [] - [] /// Returns a typed native pointer for a Common IL (Intermediate Language) signature pointer. /// /// The Common IL signature pointer. /// /// A typed native pointer. + [] + [] val inline ofILSigPtr : address: ilsigptr<'T> -> nativeptr<'T> - [] - [] /// Returns a Common IL (Intermediate Language) signature pointer for a given typed native pointer. /// /// The typed native pointer. /// /// A Common IL signature pointer. + [] + [] val inline toILSigPtr : address: nativeptr<'T> -> ilsigptr<'T> /// Converts a given typed native pointer to a managed pointer. @@ -80,53 +80,53 @@ namespace Microsoft.FSharp.NativeInterop [] val inline toByRef: address: nativeptr<'T> -> byref<'T> - [] - [] - /// Returns a typed native pointer by adding index * sizeof<'T> to the + /// Returns a typed native pointer by adding index * sizeof<'T> to the /// given input pointer. /// /// The input pointer. /// The index by which to offset the pointer. /// /// A typed pointer. + [] + [] val inline add : address: nativeptr<'T> -> index: int -> nativeptr<'T> - [] - [] - /// Dereferences the typed native pointer computed by adding index * sizeof<'T> to the + /// Dereferences the typed native pointer computed by adding index * sizeof<'T> to the /// given input pointer. /// /// The input pointer. /// The index by which to offset the pointer. /// /// The value at the pointer address. + [] + [] val inline get : address: nativeptr<'T> -> index: int -> 'T - [] - [] /// Dereferences the given typed native pointer. /// /// The input pointer. /// /// The value at the pointer address. + [] + [] val inline read : address: nativeptr<'T> -> 'T - [] - [] /// Assigns the value into the memory location referenced by the given typed native pointer. /// /// The input pointer. /// The value to assign. + [] + [] val inline write : address: nativeptr<'T> -> value: 'T -> unit - [] - [] - /// Assigns the value into the memory location referenced by the typed native + /// Assigns the value into the memory location referenced by the typed native /// pointer computed by adding index * sizeof<'T> to the given input pointer. /// /// The input pointer. /// The index by which to offset the pointer. /// The value to assign. + [] + [] val inline set : address: nativeptr<'T> -> index: int -> value: 'T -> unit /// Allocates a region of memory on the stack. @@ -155,35 +155,35 @@ namespace Microsoft.FSharp.NativeInterop [] val inline isNullPtr: address: nativeptr<'T> -> bool - [] - [] /// Clears the value stored at the location of a given native pointer. /// /// The input pointer. + [] + [] val inline clear : address: nativeptr<'T> -> unit - [] - [] /// Initializes a specified block of memory starting at a specific address to a given byte count and initial byte value. /// /// The input pointer. /// The initial byte value. /// The total repeat count of the byte value. + [] + [] val inline initBlock : address: nativeptr<'T> -> value: byte -> count: uint32 -> unit - [] - [] /// Copies a value to a specified destination address from a specified source address. /// /// The destination pointer. /// The source pointer. + [] + [] val inline copy : destination: nativeptr<'T> -> source: nativeptr<'T> -> unit - [] - [] /// Copies a block of memory to a specified destination address starting from a specified source address until a specified byte count of (count * sizeof<'T>). /// /// The destination pointer. /// The source pointer. /// The source pointer. + [] + [] val inline copyBlock : destination: nativeptr<'T> -> source: nativeptr<'T> -> count: int -> unit diff --git a/src/fsharp/FSharp.Core/observable.fsi b/src/fsharp/FSharp.Core/observable.fsi index bf3c218de57..3384fe4f149 100644 --- a/src/fsharp/FSharp.Core/observable.fsi +++ b/src/fsharp/FSharp.Core/observable.fsi @@ -5,11 +5,11 @@ namespace Microsoft.FSharp.Control open System open Microsoft.FSharp.Core - [] - [] /// Contains operations for working with first class event and other observable objects. /// /// Events and Observables + [] + [] module Observable = /// Returns an observable for the merged observations from the sources. diff --git a/src/fsharp/FSharp.Core/option.fsi b/src/fsharp/FSharp.Core/option.fsi index 1c4c74f78a8..86e1a2e5b39 100644 --- a/src/fsharp/FSharp.Core/option.fsi +++ b/src/fsharp/FSharp.Core/option.fsi @@ -7,10 +7,10 @@ open Microsoft.FSharp.Core open Microsoft.FSharp.Collections -[] /// Contains operations for working with options. /// /// Options +[] module Option = /// Returns true if the option is not None. /// The input option. diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 917abe58298..1cb2deb7186 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -66,10 +66,10 @@ namespace Microsoft.FSharp.Core /// Indicates that the compiled entity had private or internal representation in F# source code. | NonPublicRepresentation = 32 - [] /// Indicates one or more adjustments to the compiled representation of an F# type or member. /// /// Attributes + [] type CompilationRepresentationFlags = /// No special compilation representation. @@ -407,12 +407,12 @@ namespace Microsoft.FSharp.Core /// StructuralComparisonAttribute new : unit -> StructuralComparisonAttribute - [] - [] /// Indicates that a member on a computation builder type is a custom query operator, /// and indicates the name of that operator. /// /// Attributes + [] + [] type CustomOperationAttribute = inherit Attribute @@ -444,12 +444,12 @@ namespace Microsoft.FSharp.Core /// Indicates if the custom operation maintains the variable space of the query of computation expression through the use of a bind operation member MaintainsVariableSpaceUsingBind : bool with get,set - [] - [] /// Indicates that, when a custom operator is used in a computation expression, /// a parameter is automatically parameterized by the variable space of the computation expression /// /// Attributes + [] + [] type ProjectionParameterAttribute = /// Creates an instance of the attribute @@ -936,191 +936,191 @@ namespace Microsoft.FSharp.Core /// or an enclosing module opened. member Path: string - [] - /// The type of double-precision floating point numbers, annotated with a unit of measure. + /// The type of double-precision floating point numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type float<[] 'Measure> = float - [] - /// The type of single-precision floating point numbers, annotated with a unit of measure. + /// The type of single-precision floating point numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// /// Basic Types with Units of Measure + [] type float32<[] 'Measure> = float32 - [] /// The type of decimal numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type decimal<[] 'Measure> = decimal - [] /// The type of 32-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type int<[] 'Measure> = int - [] /// The type of 8-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type sbyte<[] 'Measure> = sbyte - [] /// The type of 16-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type int16<[] 'Measure> = int16 - [] /// The type of 64-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type int64<[] 'Measure> = int64 - [] - [] /// The type of machine-sized signed integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] + [] type nativeint<[] 'Measure> = nativeint - [] - [] /// The type of 32-bit unsigned integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] + [] type uint<[] 'Measure> = uint - - [] - [] + /// The type of 8-bit unsigned integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] + [] type byte<[] 'Measure> = byte - [] - [] - /// The type of 16-bit unsigned integer numbers, annotated with a unit of measure. + /// The type of 16-bit unsigned integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] + [] type uint16<[] 'Measure> = uint16 - [] - [] - /// The type of 64-bit unsigned integer numbers, annotated with a unit of measure. + /// The type of 64-bit unsigned integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] + [] type uint64<[] 'Measure> = uint64 - [] - [] - /// The type of machine-sized unsigned integer numbers, annotated with a unit of measure. + /// The type of machine-sized unsigned integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] + [] type unativeint<[] 'Measure> = unativeint - [] - /// The type of double-precision floating point numbers, annotated with a unit of measure. + /// The type of double-precision floating point numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type double<[] 'Measure> = float<'Measure> - [] - /// The type of single-precision floating point numbers, annotated with a unit of measure. + /// The type of single-precision floating point numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type single<[] 'Measure> = float32<'Measure> - [] - /// The type of 8-bit signed integer numbers, annotated with a unit of measure. + /// The type of 8-bit signed integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type int8<[] 'Measure> = sbyte<'Measure> - [] - /// The type of 32-bit signed integer numbers, annotated with a unit of measure. + /// The type of 32-bit signed integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type int32<[] 'Measure> = int<'Measure> - [] - /// The type of 8-bit unsigned integer numbers, annotated with a unit of measure. + /// The type of 8-bit unsigned integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type uint8<[] 'Measure> = byte<'Measure> - [] - /// The type of 32-bit unsigned integer numbers, annotated with a unit of measure. + /// The type of 32-bit unsigned integer numbers, annotated with a unit of measure. /// The unit of measure is erased in compiled code and when values of this type - /// are analyzed using reflection. The type is representationally equivalent to + /// are analyzed using reflection. The type is representationally equivalent to /// . /// /// Basic Types with Units of Measure + [] type uint32<[] 'Measure> = uint<'Measure> /// Represents a managed pointer in F# code. + /// ByRef and Pointer Types #if BUILDING_WITH_LKG || BUILD_FROM_SOURCE [] #else [] #endif - /// ByRef and Pointer Types type byref<'T, 'Kind> = (# "!0&" #) /// Represents a managed pointer in F# code. For F# 4.5+ this is considered equivalent to byref<'T, ByRefKinds.InOut> @@ -1128,12 +1128,12 @@ namespace Microsoft.FSharp.Core type byref<'T> = (# "!0&" #) /// Represents the types of byrefs in F# 4.5+ + /// ByRef and Pointer Types #if BUILDING_WITH_LKG || BUILD_FROM_SOURCE [] #else [] #endif - /// ByRef and Pointer Types module ByRefKinds = /// Represents a byref that can be written @@ -1316,8 +1316,8 @@ namespace Microsoft.FSharp.Core [] val FastGenericEqualityComparerFromTable<'T> : System.Collections.Generic.IEqualityComparer<'T> when 'T : equality - [] /// Make an F# comparer object for the given type + [] val FastGenericComparerFromTable<'T> : System.Collections.Generic.IComparer<'T> when 'T : comparison /// Hash a value according to its structure. This hash is not limited by an overall node count when hashing F# @@ -1408,52 +1408,52 @@ namespace Microsoft.FSharp.Core /// The sbyte with units-of-measure. val inline SByteWithMeasure : input: sbyte -> sbyte<'Measure> - [] /// Creates a nativeint value with units-of-measure /// /// The input nativeint. /// /// The nativeint with units-of-measure. + [] val inline IntPtrWithMeasure : input: nativeint -> nativeint<'Measure> - [] /// Creates a uint value with units-of-measure /// /// The input uint. /// /// The uint with units-of-measure. + [] val inline UInt32WithMeasure : input: uint -> uint<'Measure> - [] /// Creates a uint64 value with units-of-measure /// /// The input uint64. /// /// The uint64 with units-of-measure. + [] val inline UInt64WithMeasure : input: uint64 -> uint64<'Measure> - [] /// Creates a uint16 value with units-of-measure /// /// The input uint16. /// /// The uint16 with units-of-measure. + [] val inline UInt16WithMeasure : input: uint16 -> uint16<'Measure> - [] /// Creates a byte value with units-of-measure /// /// The input byte. /// /// The byte with units-of-measure. + [] val inline ByteWithMeasure : input: byte -> byte<'Measure> - [] /// Creates a unativeint value with units-of-measure /// /// The input unativeint. /// /// The unativeint with units-of-measure. + [] val inline UIntPtrWithMeasure : input: unativeint -> unativeint<'Measure> /// Parse an int32 according to the rules used by the overloaded 'int32' conversion operator when applied to strings @@ -2086,12 +2086,12 @@ namespace Microsoft.FSharp.Core /// The function result. static member InvokeFast : func: FSharpFunc<'T,('U -> 'V)> * arg1:'T * arg2:'U -> 'V - [] - [] /// Helper functions for converting F# first class function values to and from CLI representations /// of functions using delegates. /// Language Primitives - type FuncConvert = + [] + [] + type FuncConvert = /// Convert the given Action delegate object to an F# function value /// @@ -2416,8 +2416,8 @@ namespace Microsoft.FSharp.Core /// static member op_Implicit : value:'T -> 'T option - [] /// Get the value of a 'Some' option. A NullReferenceException is raised if the option is 'None'. + [] member Value : 'T /// Return 'true' if the option is a 'Some' value. @@ -3611,10 +3611,10 @@ namespace Microsoft.FSharp.Core [] val ( |KeyValue| ): keyValuePair:KeyValuePair<'Key,'Value> -> 'Key * 'Value - [] - [] /// Contains extension methods to allow the use of F# indexer notation with arrays. /// This module is automatically opened in all F# code. + [] + [] module ArrayExtensions = type ``[,,,]``<'T> with /// Get the index for the element offset elements away from the end of the collection. @@ -4534,22 +4534,22 @@ namespace Microsoft.FSharp.Core [] val inline defaultof<'T> : 'T - [] - /// Perform generic comparison on two values where the type of the values is not + /// Perform generic comparison on two values where the type of the values is not /// statically required to have the 'comparison' constraint. /// The result of the comparison. + [] val inline compare : 'T -> 'T -> int - [] - /// Perform generic equality on two values where the type of the values is not + /// Perform generic equality on two values where the type of the values is not /// statically required to satisfy the 'equality' constraint. /// The result of the comparison. + [] val inline equals : 'T -> 'T -> bool - [] - /// Perform generic hashing on a value where the type of the value is not + /// Perform generic hashing on a value where the type of the value is not /// statically required to satisfy the 'equality' constraint. /// The computed hash value. + [] val inline hash : 'T -> int /// A module of comparison and equality operators that are statically resolved, but which are not fully generic and do not make structural comparison. Opening this diff --git a/src/fsharp/FSharp.Core/printf.fs b/src/fsharp/FSharp.Core/printf.fs index 0dbdb801c88..9d4d69e6664 100644 --- a/src/fsharp/FSharp.Core/printf.fs +++ b/src/fsharp/FSharp.Core/printf.fs @@ -253,8 +253,8 @@ module internal PrintfImpl = i <- i + 1 buf.ToString() - [] /// Represents one step in the execution of a format string + [] type Step = | StepWithArg of prefix: string * conv: (obj -> string) | StepWithTypedArg of prefix: string * conv: (obj -> Type -> string) diff --git a/src/fsharp/FSharp.Core/quotations.fsi b/src/fsharp/FSharp.Core/quotations.fsi index 01d8b1c4ebc..98400eb4a0e 100644 --- a/src/fsharp/FSharp.Core/quotations.fsi +++ b/src/fsharp/FSharp.Core/quotations.fsi @@ -563,8 +563,8 @@ and [] member Raw : Expr -[] /// Contains a set of primitive F# active patterns to analyze F# expression objects +[] module Patterns = /// An active pattern to recognize expressions that represent getting the address of a value @@ -872,8 +872,8 @@ module Patterns = [] val (|VarSet|_|) : input:Expr -> (Var * Expr) option -[] /// Contains a set of derived F# active patterns to analyze F# expression objects +[] module DerivedPatterns = /// An active pattern to recognize expressions that represent a (possibly curried or tupled) first class function value diff --git a/src/fsharp/FSharp.Core/reflect.fsi b/src/fsharp/FSharp.Core/reflect.fsi index 948e778aace..c2132c385ac 100644 --- a/src/fsharp/FSharp.Core/reflect.fsi +++ b/src/fsharp/FSharp.Core/reflect.fsi @@ -44,9 +44,9 @@ type UnionCaseInfo = member Tag: int -[] /// Contains operations associated with constructing and analyzing values associated with F# types /// such as records, unions and tuples. +[] type FSharpValue = /// Reads a field from a record value. @@ -312,8 +312,8 @@ type FSharpValue = /// A typed function from the given dynamic implementation. static member MakeFunction : functionType:Type * implementation:(obj -> obj) -> obj -[] /// Contains operations associated with constructing and analyzing F# types such as records, unions and tuples +[] type FSharpType = /// Reads all the fields from a record value, in declaration order @@ -442,8 +442,8 @@ type FSharpType = /// A tuple of the domain and range types of the input function. static member GetFunctionElements : functionType:Type -> Type * Type -[] /// Defines further accessing additional information about F# types and F# values at runtime. +[] module FSharpReflectionExtensions = type FSharpValue with /// Creates an instance of a record type. diff --git a/src/fsharp/FSharp.Core/result.fsi b/src/fsharp/FSharp.Core/result.fsi index 52e23db5d13..9723bb4ecf8 100644 --- a/src/fsharp/FSharp.Core/result.fsi +++ b/src/fsharp/FSharp.Core/result.fsi @@ -4,10 +4,10 @@ namespace Microsoft.FSharp.Core open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators - [] /// Contains operations for working with values of type . /// /// Choices and Results + [] module Result = /// map f inp evaluates to match inp with Error e -> Error e | Ok x -> Ok (f x). diff --git a/src/fsharp/FSharp.Core/seq.fsi b/src/fsharp/FSharp.Core/seq.fsi index 4b875355d3f..73578dfe44e 100644 --- a/src/fsharp/FSharp.Core/seq.fsi +++ b/src/fsharp/FSharp.Core/seq.fsi @@ -878,7 +878,6 @@ namespace Microsoft.FSharp.Collections [] val nth: index:int -> source:seq<'T> -> 'T - [] /// Views the given array as a sequence. /// /// The input array. @@ -886,14 +885,15 @@ namespace Microsoft.FSharp.Collections /// The result sequence. /// /// Thrown when the input sequence is null. + [] val ofArray: source:'T[] -> seq<'T> - [] /// Views the given list as a sequence. /// /// The input list. /// /// The result sequence. + [] val ofList: source:'T list -> seq<'T> /// Returns a sequence of each element in the input sequence and its predecessor, with the diff --git a/src/fsharp/FSharp.Core/seqcore.fsi b/src/fsharp/FSharp.Core/seqcore.fsi index cce9b5dbb3e..1e29d377411 100644 --- a/src/fsharp/FSharp.Core/seqcore.fsi +++ b/src/fsharp/FSharp.Core/seqcore.fsi @@ -64,8 +64,8 @@ namespace Microsoft.FSharp.Core.CompilerServices open Microsoft.FSharp.Core open Microsoft.FSharp.Collections - [] /// A group of functions used as part of the compiled representation of F# sequence expressions. + [] module RuntimeHelpers = [] @@ -122,8 +122,8 @@ namespace Microsoft.FSharp.Core.CompilerServices /// The initialized event. val CreateEvent : addHandler : ('Delegate -> unit) -> removeHandler : ('Delegate -> unit) -> createHandler : ((obj -> 'Args -> unit) -> 'Delegate) -> Microsoft.FSharp.Control.IEvent<'Delegate,'Args> - [] /// The F# compiler emits implementations of this type for compiled sequence expressions. + [] type GeneratedSequenceBase<'T> = /// The F# compiler emits implementations of this type for compiled sequence expressions. /// diff --git a/src/fsharp/FSharp.Core/set.fsi b/src/fsharp/FSharp.Core/set.fsi index 53f1d725abb..a2e540d92de 100644 --- a/src/fsharp/FSharp.Core/set.fsi +++ b/src/fsharp/FSharp.Core/set.fsi @@ -123,10 +123,9 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Core open Microsoft.FSharp.Collections + /// Contains operations for working with values of type . [] [] - - /// Contains operations for working with values of type . module Set = /// The empty set for the type 'T. diff --git a/src/fsharp/FSharp.Core/string.fs b/src/fsharp/FSharp.Core/string.fs index 37e8fcd7d68..4ed8b4e9183 100644 --- a/src/fsharp/FSharp.Core/string.fs +++ b/src/fsharp/FSharp.Core/string.fs @@ -13,9 +13,9 @@ namespace Microsoft.FSharp.Core [] [] module String = - [] /// LOH threshold is calculated from Internal.Utilities.Library.LOH_SIZE_THRESHOLD_BYTES, /// and is equal to 80_000 / sizeof + [] let LOH_CHAR_THRESHOLD = 40_000 [] diff --git a/src/fsharp/FSharp.Core/tasks.fsi b/src/fsharp/FSharp.Core/tasks.fsi index e5ad31910ce..93b2079207b 100644 --- a/src/fsharp/FSharp.Core/tasks.fsi +++ b/src/fsharp/FSharp.Core/tasks.fsi @@ -12,12 +12,12 @@ namespace Microsoft.FSharp.Control open Microsoft.FSharp.Core.CompilerServices open Microsoft.FSharp.Collections - [] - [] - [] /// /// The extra data stored in ResumableStateMachine for tasks /// + [] + [] + [] type TaskStateMachineData<'T> = /// From 40154696868de3ebe7e57e948e17364b0992c44b Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Wed, 8 Sep 2021 15:02:43 +0300 Subject: [PATCH 20/25] fix tests --- tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs | 2 +- tests/service/XmlDocTests.fs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs b/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs index 842b78b92db..f41c9f3198d 100644 --- a/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs +++ b/tests/fsharpqa/Source/XmlDoc/Basic/xmlDoc002.fs @@ -5,8 +5,8 @@ #light -//// I am NOT an xml comment /// I'm an xml comment! +//// I am NOT an xml comment type e = | A | B diff --git a/tests/service/XmlDocTests.fs b/tests/service/XmlDocTests.fs index 67a2e85dcb6..b07ffacaf2e 100644 --- a/tests/service/XmlDocTests.fs +++ b/tests/service/XmlDocTests.fs @@ -568,7 +568,10 @@ module ///M2 rec M """ (checkXml "M" [|"M1"|]) - (checkParsingErrors [|Error 3520, Line 3, Col 7, Line 3, Col 12, "XML comment is not placed on a valid language element."|]) + (checkParsingErrors [| + Error 3350, Line 5, Col 7, Line 5, Col 10, "Feature 'attributes to the right of the 'module' keyword' is not available in F# 5.0. Please use language version 'preview' or greater." + Error 3520, Line 3, Col 7, Line 3, Col 12, "XML comment is not placed on a valid language element." + |]) [] let ``union cases 01 - without bar``(): unit = From 81a4f999588b6dd307246eda996053a94696c357 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Wed, 8 Sep 2021 15:47:47 +0300 Subject: [PATCH 21/25] fix docs in FSharp.Compiler.Service --- src/fsharp/CheckDeclarations.fs | 61 ++++++++++++------- src/fsharp/CheckExpressions.fs | 10 +-- src/fsharp/CheckExpressions.fsi | 2 +- src/fsharp/CompilerConfig.fs | 2 +- src/fsharp/CompilerImports.fsi | 2 +- src/fsharp/ConstraintSolver.fs | 2 +- src/fsharp/ConstraintSolver.fsi | 2 +- src/fsharp/IlxGen.fs | 4 +- src/fsharp/InfoReader.fs | 24 ++++---- src/fsharp/InnerLambdasToTopLevelFuncs.fs | 8 +-- src/fsharp/MethodCalls.fs | 29 +++++---- src/fsharp/MethodOverrides.fs | 2 +- src/fsharp/NameResolution.fs | 16 ++--- src/fsharp/NameResolution.fsi | 11 ++-- src/fsharp/Optimizer.fs | 8 +-- src/fsharp/ParseAndCheckInputs.fsi | 2 +- src/fsharp/QueueList.fs | 2 +- src/fsharp/ScriptClosure.fs | 2 +- src/fsharp/ScriptClosure.fsi | 4 +- src/fsharp/TypedTree.fs | 36 +++++------ src/fsharp/TypedTreeOps.fs | 2 +- src/fsharp/absil/illib.fs | 6 +- src/fsharp/absil/ilread.fs | 4 +- src/fsharp/absil/ilread.fsi | 2 +- src/fsharp/absil/ilwrite.fs | 2 +- src/fsharp/fsi/fsi.fs | 6 +- src/fsharp/fsi/fsi.fsi | 6 +- src/fsharp/infos.fs | 6 +- src/fsharp/service/FSharpCheckerResults.fs | 2 +- src/fsharp/service/FSharpParseFileResults.fsi | 2 +- src/fsharp/service/IncrementalBuild.fs | 4 +- src/fsharp/service/ServiceDeclarationLists.fs | 2 +- .../service/ServiceDeclarationLists.fsi | 8 +-- src/fsharp/service/service.fsi | 2 +- src/fsharp/utils/ResizeArray.fsi | 2 +- src/fsharp/utils/prim-lexing.fsi | 2 +- src/fsharp/utils/prim-parsing.fs | 2 +- src/fsharp/utils/prim-parsing.fsi | 2 +- 38 files changed, 155 insertions(+), 136 deletions(-) diff --git a/src/fsharp/CheckDeclarations.fs b/src/fsharp/CheckDeclarations.fs index 9291da043ef..a09734f0c54 100644 --- a/src/fsharp/CheckDeclarations.fs +++ b/src/fsharp/CheckDeclarations.fs @@ -878,12 +878,21 @@ module IncrClassChecking = not arity.HasNoArgs && not v.IsMutable + /// /// Choose how a binding is represented - member localRep.ChooseRepresentation (cenv: cenv, env: TcEnv, isStatic, isCtorArg, - ctorInfo: IncrClassCtorLhs, - /// The vars forced to be fields due to static member bindings, instance initialization expressions or instance member bindings - staticForcedFieldVars: FreeLocals, - /// The vars forced to be fields due to instance member bindings + /// + /// + /// + /// + /// + /// + /// The vars forced to be fields due to static member bindings, instance initialization expressions or instance member bindings + /// The vars forced to be fields due to instance member bindings + /// + /// + member localRep.ChooseRepresentation (cenv: cenv, env: TcEnv, isStatic, isCtorArg, + ctorInfo: IncrClassCtorLhs, + staticForcedFieldVars: FreeLocals, instanceForcedFieldVars: FreeLocals, takenFieldNames: Set, bind: Binding) = @@ -1091,9 +1100,9 @@ module IncrClassChecking = /// Given localRep saying how locals have been represented, e.g. as fields. /// Given an expr under a given thisVal context. // - /// Fix up the references to the locals, e.g. - /// v -> this.fieldv - /// f x -> this.method x + // Fix up the references to the locals, e.g. + // v -> this.fieldv + // f x -> this.method x member localRep.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo (thisTyInst: TypeInst) expr = // fixup: intercept and expr rewrite let FixupExprNode rw e = @@ -1143,21 +1152,27 @@ module IncrClassChecking = | Phase2CCtorJustAfterSuperInit | Phase2CCtorJustAfterLastLet - /// Given a set of 'let' bindings (static or not, recursive or not) that make up a class, - /// generate their initialization expression(s). - let MakeCtorForIncrClassConstructionPhase2C + /// + /// Given a set of 'let' bindings (static or not, recursive or not) that make up a class, + /// generate their initialization expression(s). + /// + /// + /// + /// The lhs information about the implicit constructor + /// The call to the super class constructor + /// Should we place a sequence point at the 'inheritedTys call? + /// The declarations + /// + /// Record any unconstrained type parameters generalized for the outer members as "free choices" in the let bindings + /// + let MakeCtorForIncrClassConstructionPhase2C (cenv: cenv, - env: TcEnv, - /// The lhs information about the implicit constructor - ctorInfo: IncrClassCtorLhs, - /// The call to the super class constructor - inheritsExpr, - /// Should we place a sequence point at the 'inheritedTys call? - inheritsIsVisible, - /// The declarations + env: TcEnv, + ctorInfo: IncrClassCtorLhs, + inheritsExpr, + inheritsIsVisible, decs: IncrClassConstructionBindingsPhase2C list, - memberBinds: Binding list, - /// Record any unconstrained type parameters generalized for the outer members as "free choices" in the let bindings + memberBinds: Binding list, generalizedTyparsForRecursiveBlock, safeStaticInitInfo: SafeInitData) = @@ -1459,7 +1474,7 @@ module IncrClassChecking = ctorBody let cctorBodyOpt = - /// Omit the .cctor if it's empty + // Omit the .cctor if it's empty match cctorInitActions with | [] -> None | _ -> @@ -3586,7 +3601,7 @@ module EstablishTypeDefinitionCores = /// Note that for /// type PairOfInts = int * int /// then after running this phase and checking for cycles, operations - // such as 'isRefTupleTy' will return reliable results, e.g. isRefTupleTy on the + /// such as 'isRefTupleTy' will return reliable results, e.g. isRefTupleTy on the /// TAST type for 'PairOfInts' will report 'true' // let private TcTyconDefnCore_Phase1C_Phase1E_EstablishAbbreviations (cenv: cenv) envinner inSig tpenv pass (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, _, _, _, _)) (tycon: Tycon) (attrs: Attribs) = diff --git a/src/fsharp/CheckExpressions.fs b/src/fsharp/CheckExpressions.fs index 48e93649a01..6986de51694 100644 --- a/src/fsharp/CheckExpressions.fs +++ b/src/fsharp/CheckExpressions.fs @@ -1029,8 +1029,8 @@ let noArgOrRetAttribs = ArgAndRetAttribs ([], []) /// shares the same code paths (e.g. TcLetBinding and TcLetrec) as processing expression bindings (such as "let x = 1 in ...") /// Member bindings also use this path. // -/// However there are differences in how different bindings get processed, -/// i.e. module bindings get published to the implicitly accumulated module type, but expression 'let' bindings don't. +// However there are differences in how different bindings get processed, +// i.e. module bindings get published to the implicitly accumulated module type, but expression 'let' bindings don't. type DeclKind = | ModuleOrMemberBinding @@ -5963,7 +5963,7 @@ and TcExprUndelayed cenv (overallTy: OverallTy) env tpenv (synExpr: SynExpr) = let e3', tpenv = TcExpr cenv overallTy env tpenv e3 Expr.StaticOptimization (constraints', e2', e3', m), tpenv - /// e1.longId <- e2 + // e1.longId <- e2 | SynExpr.DotSet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, mStmt) -> if lidwd.ThereIsAnExtraDotAtTheEnd then // just drop rhs on the floor @@ -5973,11 +5973,11 @@ and TcExprUndelayed cenv (overallTy: OverallTy) env tpenv (synExpr: SynExpr) = let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) TcExprThen cenv overallTy env tpenv false e1 [DelayedDotLookup(longId, mExprAndDotLookup); MakeDelayedSet(e2, mStmt)] - /// e1 <- e2 + // e1 <- e2 | SynExpr.Set (e1, e2, mStmt) -> TcExprThen cenv overallTy env tpenv false e1 [MakeDelayedSet(e2, mStmt)] - /// e1.longId(e2) <- e3, very rarely used named property setters + // e1.longId(e2) <- e3, very rarely used named property setters | SynExpr.DotNamedIndexedPropertySet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, e3, mStmt) -> if lidwd.ThereIsAnExtraDotAtTheEnd then // just drop rhs on the floor diff --git a/src/fsharp/CheckExpressions.fsi b/src/fsharp/CheckExpressions.fsi index e430ce66fa0..765ecd35c93 100644 --- a/src/fsharp/CheckExpressions.fsi +++ b/src/fsharp/CheckExpressions.fsi @@ -46,10 +46,10 @@ val InitialImplicitCtorInfo: unit -> CtorInfo [] type UngeneralizableItem -[] /// Represents the type environment at a particular scope. Includes the name /// resolution environment, the ungeneralizable items from earlier in the scope /// and other information about the scope. +[] type TcEnv = { /// Name resolution information eNameResEnv: NameResolutionEnv diff --git a/src/fsharp/CompilerConfig.fs b/src/fsharp/CompilerConfig.fs index f93653b1d8c..dae491a9d44 100644 --- a/src/fsharp/CompilerConfig.fs +++ b/src/fsharp/CompilerConfig.fs @@ -860,8 +860,8 @@ type TcConfigBuilder = // TcConfig //-------------------------------------------------------------------------- -[] /// This type is immutable and must be kept as such. Do not extract or mutate the underlying data except by cloning it. +[] type TcConfig private (data: TcConfigBuilder, validate: bool) = // Validate the inputs - this helps ensure errors in options are shown in visual studio rather than only when built diff --git a/src/fsharp/CompilerImports.fsi b/src/fsharp/CompilerImports.fsi index 4b91bb7c52d..0eeb5e23c29 100644 --- a/src/fsharp/CompilerImports.fsi +++ b/src/fsharp/CompilerImports.fsi @@ -117,8 +117,8 @@ type ImportedAssembly = } -[] /// Tables of assembly resolutions +[] type TcAssemblyResolutions = member GetAssemblyResolutions: unit -> AssemblyResolution list diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 34f20beda0c..d178d9b23a2 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -143,8 +143,8 @@ let FreshenMethInfo m (minfo: MethInfo) = // Subsumption of types: solve/record subtyping constraints //------------------------------------------------------------------------- -[] /// Information about the context of a type equation. +[] type ContextInfo = /// No context was given. diff --git a/src/fsharp/ConstraintSolver.fsi b/src/fsharp/ConstraintSolver.fsi index fb0d76a2b4e..dee696470e5 100644 --- a/src/fsharp/ConstraintSolver.fsi +++ b/src/fsharp/ConstraintSolver.fsi @@ -43,8 +43,8 @@ val FreshenTypars: range -> Typars -> TType list val FreshenMethInfo: range -> MethInfo -> TType list -[] /// Information about the context of a type equation. +[] type ContextInfo = /// No context was given. diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 01c780049c9..033f2ac8cdf 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -1472,7 +1472,7 @@ let AddIncrementalLocalAssemblyFragmentToIlxGenEnv (amap: ImportMap, isIncrement let GenILSourceMarker (g: TcGlobals) (m: range) = ILDebugPoint.Create(document=g.memoize_file m.FileIndex, line=m.StartLine, - /// NOTE: .NET && VS measure first column as column 1 + // NOTE: .NET && VS measure first column as column 1 column= m.StartColumn+1, endLine= m.EndLine, endColumn=m.EndColumn+1) @@ -5131,7 +5131,7 @@ and GenSequenceExpr GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloWitnessInfos for fv in cloFreeVars do - /// State variables always get zero-initialized + // State variables always get zero-initialized if stateVarsSet.Contains fv then GenDefaultValue cenv cgbuf eenvouter (fv.Type, m) else diff --git a/src/fsharp/InfoReader.fs b/src/fsharp/InfoReader.fs index cd5f95eb116..1abbb388202 100644 --- a/src/fsharp/InfoReader.fs +++ b/src/fsharp/InfoReader.fs @@ -537,7 +537,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this = // Remove any virtuals that are signature-equivalent to virtuals in subtypes, except for newslots // That is, keep if it's - /// (a) not virtual + // (a) not virtual // (b) is a new slot or // (c) not equivalent // We keep virtual finals around for error detection later on @@ -939,18 +939,18 @@ let TryDestStandardDelegateType (infoReader: InfoReader) m ad delTy = /// Indicates if an event info is associated with a delegate type that is a "standard" .NET delegate type /// with a sender parameter. // -/// In the F# design, we take advantage of the following idiom to simplify away the bogus "object" parameter of the -/// of the "Add" methods associated with events. If you want to access it you -/// can use AddHandler instead. +// In the F# design, we take advantage of the following idiom to simplify away the bogus "object" parameter of the +// of the "Add" methods associated with events. If you want to access it you +// can use AddHandler instead. -/// The .NET Framework guidelines indicate that the delegate type used for -/// an event should take two parameters, an "object source" parameter -/// indicating the source of the event, and an "e" parameter that -/// encapsulates any additional information about the event. The type of -/// the "e" parameter should derive from the EventArgs class. For events -/// that do not use any additional information, the .NET Framework has -/// already defined an appropriate delegate type: EventHandler. -/// (from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcwlkEventsTutorial.asp) +// The .NET Framework guidelines indicate that the delegate type used for +// an event should take two parameters, an "object source" parameter +// indicating the source of the event, and an "e" parameter that +// encapsulates any additional information about the event. The type of +// the "e" parameter should derive from the EventArgs class. For events +// that do not use any additional information, the .NET Framework has +// already defined an appropriate delegate type: EventHandler. +// (from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcwlkEventsTutorial.asp) let IsStandardEventInfo (infoReader: InfoReader) m ad (einfo: EventInfo) = let dty = einfo.GetDelegateType(infoReader.amap, m) match TryDestStandardDelegateType infoReader m ad dty with diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs index 209900ce333..2388de90d9f 100644 --- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs +++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs @@ -250,8 +250,8 @@ module Pass1_DetermineTLRAndArities = // pass2: determine reqdTypars(f) and envreq(f) - notes //------------------------------------------------------------------------- -/// What are the closing types/values for {f1, f2...} mutually defined? -/// +// What are the closing types/values for {f1, f2...} mutually defined? +// // Note: arity-met g-applications (g TLR) will translated as: // [[g @ tps ` args]] -> gHAT @ reqdTypars(g) tps ` env(g) args // so they require availability of closing types/values for g. @@ -1157,8 +1157,8 @@ module Pass4_RewriteAssembly = let pds, z = ExtractPreDecs z MakePreDecs m pds (mkTypeLambda m argtyvs (body, rty)), z - /// Lifting TLR out over constructs (disabled) - /// Lift minimally to ensure the defn is not lifted up and over defns on which it depends (disabled) + // Lifting TLR out over constructs (disabled) + // Lift minimally to ensure the defn is not lifted up and over defns on which it depends (disabled) | Expr.Match (spBind, exprm, dtree, targets, m, ty) -> let targets = Array.toList targets let dtree, z = TransDecisionTree penv z dtree diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 3367224af9d..8ae27687210 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -466,37 +466,42 @@ let MakeCalledArgs amap m (minfo: MethInfo) minst = NameOpt=nmOpt CalledArgumentType=typeOfCalledArg }) +/// /// Represents the syntactic matching between a caller of a method and the called method. /// /// The constructor takes all the information about the caller and called side of a method, match up named arguments, property setters etc., /// and returns a CalledMeth object for further analysis. +/// +/// +/// +/// +/// A function to help generate fresh type variables the property setters methods in generic classes +/// Range +/// The access domain of the place where the call is taking place +/// The method we're attempting to call +/// The 'called type arguments', i.e. the fresh generic instantiation of the method we're attempting to call +/// The 'caller type arguments', i.e. user-given generic instantiation of the method we're attempting to call +/// The property related to the method we're attempting to call, if any +/// The 'caller method arguments', i.e. a list of user-given parameter expressions, split between unnamed and named arguments +/// A function to help generate fresh type variables the property setters methods in generic classes +/// Do we allow the use of a param args method in its "expanded" form? +/// Do we allow the use of the transformation that converts out arguments as tuple returns? +/// Method parameters type CalledMeth<'T> (infoReader: InfoReader, nameEnv: NameResolutionEnv option, isCheckingAttributeCall, - /// A function to help generate fresh type variables the property setters methods in generic classes freshenMethInfo, - /// Range m, - /// The access domain of the place where the call is taking place ad, - /// The method we're attempting to call minfo: MethInfo, - /// The 'called type arguments', i.e. the fresh generic instantiation of the method we're attempting to call calledTyArgs, - /// The 'caller type arguments', i.e. user-given generic instantiation of the method we're attempting to call callerTyArgs: TType list, - /// The property related to the method we're attempting to call, if any pinfoOpt: PropInfo option, - /// The types of the actual object argument, if any callerObjArgTys: TType list, - /// The 'caller method arguments', i.e. a list of user-given parameter expressions, split between unnamed and named arguments callerArgs: CallerArgs<'T>, - /// Do we allow the use of a param args method in its "expanded" form? allowParamArgs: bool, - /// Do we allow the use of the transformation that converts out arguments as tuple returns? allowOutAndOptArgs: bool, - /// Method parameters tyargsOpt: TType option) = let g = infoReader.g diff --git a/src/fsharp/MethodOverrides.fs b/src/fsharp/MethodOverrides.fs index 9acba857687..421630da530 100644 --- a/src/fsharp/MethodOverrides.fs +++ b/src/fsharp/MethodOverrides.fs @@ -682,7 +682,7 @@ module DispatchSlotChecking = if not minfo.IsAbstract then yield GetInheritedMemberOverrideInfo g amap reqdTyRange CanImplementAnyClassHierarchySlot minfo ] - /// Check that no interface type is implied twice + // Check that no interface type is implied twice for j, _, _, impliedTys2 in reqdTyInfos do if i > j then for ty, dispatchSlots in dispatchSlotSet do diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 4785453d27c..d82b0655df7 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -135,8 +135,8 @@ let (|AbbrevOrAppTy|_|) (ty: TType) = | TType_app (tcref, _) -> Some tcref | _ -> None -[] /// Represents the item with which a named argument is associated. +[] type ArgumentContainer = /// The named argument is an argument of a method | Method of MethInfo @@ -151,8 +151,8 @@ let emptyTypeInst : TypeInst = [] type EnclosingTypeInst = TypeInst let emptyEnclosingTypeInst : EnclosingTypeInst = emptyTypeInst -[] /// Represents an item that results from name resolution +[] type Item = /// Represents the resolution of a name to an F# value or function. @@ -294,9 +294,9 @@ let valRefHash (vref: ValRef) = | ValueNone -> 0 | ValueSome v -> LanguagePrimitives.PhysicalHash v -[] /// Pairs an Item with a TyparInst showing how generic type variables of the item are instantiated at /// a particular usage point. +[] type ItemWithInst = { Item: Item TyparInst: TyparInst } @@ -353,8 +353,8 @@ type FullyQualifiedFlag = type UnqualifiedItems = LayeredMap -[] /// The environment of information used to resolve names +[] type NameResolutionEnv = { /// Display environment information for output eDisplayEnv: DisplayEnv @@ -830,12 +830,12 @@ type TypeNameResolutionFlag = | ResolveTypeNamesToCtors | ResolveTypeNamesToTypeRefs -[] -[] /// Represents information about the generic argument count of a type name when resolving it. /// /// In some situations we resolve "List" to any type definition with that name regardless of the number /// of generic arguments. In others, we know precisely how many generic arguments are needed. +[] +[] type TypeNameResolutionStaticArgsInfo = /// Indicates indefinite knowledge of type arguments | Indefinite @@ -856,8 +856,8 @@ type TypeNameResolutionStaticArgsInfo = if x.NumStaticArgs = 0 || TryDemangleGenericNameAndPos nm <> ValueNone then nm else nm + "`" + string x.NumStaticArgs -[] /// Represents information which guides name resolution of types. +[] type TypeNameResolutionInfo = | TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo @@ -4907,7 +4907,7 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a | [] -> - /// Include all the entries in the eUnqualifiedItems table. + // Include all the entries in the eUnqualifiedItems table. for uitem in nenv.eUnqualifiedItems.Values do match uitem with | Item.UnqualifiedType _ -> () diff --git a/src/fsharp/NameResolution.fsi b/src/fsharp/NameResolution.fsi index ec2f3186af0..0b96de1fac1 100755 --- a/src/fsharp/NameResolution.fsi +++ b/src/fsharp/NameResolution.fsi @@ -30,8 +30,8 @@ type NameResolver = /// Get the active pattern elements defined in a module, if any. Cache in the slot in the module type. val ActivePatternElemsOfModuleOrNamespace: g: TcGlobals -> ModuleOrNamespaceRef -> NameMap -[] /// Represents the item with which a named argument is associated. +[] type ArgumentContainer = /// The named argument is an argument of a method | Method of MethInfo @@ -45,8 +45,8 @@ val (|AbbrevOrAppTy|_|): TType -> TyconRef option type EnclosingTypeInst = TypeInst -[] /// Represents an item that results from name resolution +[] type Item = /// Represents the resolution of a name to an F# value or function. | Value of ValRef @@ -138,9 +138,9 @@ type Item = /// This includes backticks, parens etc. member DisplayName: string -[] -/// Pairs an Item with a TyparInst showing how generic type variables of the item are instantiated at +/// Pairs an Item with a TyparInst showing how generic type variables of the item are instantiated at /// a particular usage point. +[] type ItemWithInst = { Item: Item TyparInst: TyparInst } @@ -383,8 +383,8 @@ type TcSymbolUseData = DisplayEnv: DisplayEnv Range: range } -[] /// Represents container for all name resolutions that were met so far when typechecking some particular file +[] type internal TcSymbolUses = /// Get all the uses of a particular item within the file @@ -608,4 +608,3 @@ val GetVisibleNamespacesAndModulesAtPoint: NameResolver -> NameResolutionEnv -> val IsItemResolvable: NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> Item -> bool val TrySelectExtensionMethInfoOfILExtMem: range -> ImportMap -> TType -> TyconRef * MethInfo * ExtensionMethodPriority -> MethInfo option - \ No newline at end of file diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index c051e137939..72266c6bf1f 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1388,7 +1388,7 @@ let rec ExprHasEffect g expr = | Expr.Lambda _ | Expr.TyLambda _ | Expr.Const _ -> false - /// type applications do not have effects, with the exception of type functions + // type applications do not have effects, with the exception of type functions | Expr.App (f0, _, _, [], _) -> (IsTyFuncValRefExpr f0) || ExprHasEffect g f0 | Expr.Op (op, _, args, m) -> ExprsHaveEffect g args || OpHasEffect g m op | Expr.LetRec (binds, body, _, _) -> BindingsHaveEffect g binds || ExprHasEffect g body @@ -3383,9 +3383,9 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety = let arities = if isNil tps then arities else 1+arities let bsize = bodyinfo.TotalSize - /// Set the flag on the value indicating that direct calls can avoid a tailcall (which are expensive on .NET x86) - /// MightMakeCriticalTailcall is true whenever the body of the method may itself do a useful tailcall, e.g. has - /// an application in the last position. + // Set the flag on the value indicating that direct calls can avoid a tailcall (which are expensive on .NET x86) + // MightMakeCriticalTailcall is true whenever the body of the method may itself do a useful tailcall, e.g. has + // an application in the last position. match vspec with | Some v -> if not bodyinfo.MightMakeCriticalTailcall then diff --git a/src/fsharp/ParseAndCheckInputs.fsi b/src/fsharp/ParseAndCheckInputs.fsi index dce7ab03f95..d1074191899 100644 --- a/src/fsharp/ParseAndCheckInputs.fsi +++ b/src/fsharp/ParseAndCheckInputs.fsi @@ -56,8 +56,8 @@ val ParseInputFiles: TcConfig * Lexhelp.LexResourceManager * conditionalCompilat /// applying the InternalsVisibleTo in referenced assemblies and opening 'Checked' if requested. val GetInitialTcEnv: assemblyName: string * range * TcConfig * TcImports * TcGlobals -> TcEnv * OpenDeclaration list -[] /// Represents the incremental type checking state for a set of inputs +[] type TcState = member NiceNameGenerator: NiceNameGenerator diff --git a/src/fsharp/QueueList.fs b/src/fsharp/QueueList.fs index 49015631dfb..cb823d0bd87 100644 --- a/src/fsharp/QueueList.fs +++ b/src/fsharp/QueueList.fs @@ -44,7 +44,7 @@ type internal QueueList<'T>(firstElementsIn:'T list, lastElementsRevIn: 'T list, let lastElementsRevIn = List.rev newElements @ lastElementsRev QueueList(firstElements, lastElementsRevIn, numLastElementsIn + newLength) - /// This operation is O(n) anyway, so executing ToList() here is OK + // This operation is O(n) anyway, so executing ToList() here is OK interface IEnumerable<'T> with member x.GetEnumerator() : IEnumerator<'T> = (x.ToList() :> IEnumerable<_>).GetEnumerator() diff --git a/src/fsharp/ScriptClosure.fs b/src/fsharp/ScriptClosure.fs index dd06780ce3c..8bf4de50d9e 100644 --- a/src/fsharp/ScriptClosure.fs +++ b/src/fsharp/ScriptClosure.fs @@ -471,7 +471,7 @@ module ScriptPreprocessClosure = type LoadClosure with /// Analyze a script text and find the closure of its references. /// Used from FCS, when editing a script file. - // + /// /// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the /// same arguments as the rest of the application. static member ComputeClosureOfScriptText diff --git a/src/fsharp/ScriptClosure.fsi b/src/fsharp/ScriptClosure.fsi index 8831b0f49ab..29957edb3be 100644 --- a/src/fsharp/ScriptClosure.fsi +++ b/src/fsharp/ScriptClosure.fsi @@ -73,8 +73,8 @@ type LoadClosure = /// Analyze a script text and find the closure of its references. /// Used from FCS, when editing a script file. // - /// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the - /// same arguments as the rest of the application. + // A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the + // same arguments as the rest of the application. static member ComputeClosureOfScriptText: legacyReferenceResolver: LegacyReferenceResolver * defaultFSharpBinariesDir: string * diff --git a/src/fsharp/TypedTree.fs b/src/fsharp/TypedTree.fs index cc4545ee69c..75b9073f9a9 100644 --- a/src/fsharp/TypedTree.fs +++ b/src/fsharp/TypedTree.fs @@ -67,8 +67,8 @@ type ValMutability = | Immutable | Mutable -[] /// Indicates if a type parameter is needed at runtime and may not be eliminated +[] type TyparDynamicReq = /// Indicates the type parameter is not needed at runtime and may be eliminated @@ -92,8 +92,8 @@ type ValBaseOrThisInfo = /// Indicates the 'this' value specified in a memberm e.g. 'x' in 'member x.M() = 1' | MemberThisVal -[] /// Flags on values +[] type ValFlags(flags: int64) = new (recValInfo, baseOrThis, isCompGen, inlineInfo, isMutable, isModuleOrMemberBinding, isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst, isGeneratedEventVal) = @@ -5259,22 +5259,22 @@ type CcuReference = string // ILAssemblyRef /// A relinkable handle to the contents of a compilation unit. Relinking is performed by mutation. // -/// A compilation unit is, more or less, the new material created in one -/// invocation of the compiler. Due to static linking assemblies may hold more -/// than one compilation unit (i.e. when two assemblies are merged into a compilation -/// the resulting assembly will contain 3 CUs). Compilation units are also created for referenced -/// .NET assemblies. -/// -/// References to items such as type constructors are via -/// cross-compilation-unit thunks, which directly reference the data structures that define -/// these modules. Thus, when saving out values to disk we only wish -/// to save out the "current" part of the term graph. When reading values -/// back in we "fixup" the links to previously referenced modules. -/// -/// All non-local accesses to the data structures are mediated -/// by ccu-thunks. Ultimately, a ccu-thunk is either a (named) element of -/// the data structure, or it is a delayed fixup, i.e. an invalid dangling -/// reference that has not had an appropriate fixup applied. +// A compilation unit is, more or less, the new material created in one +// invocation of the compiler. Due to static linking assemblies may hold more +// than one compilation unit (i.e. when two assemblies are merged into a compilation +// the resulting assembly will contain 3 CUs). Compilation units are also created for referenced +// .NET assemblies. +// +// References to items such as type constructors are via +// cross-compilation-unit thunks, which directly reference the data structures that define +// these modules. Thus, when saving out values to disk we only wish +// to save out the "current" part of the term graph. When reading values +// back in we "fixup" the links to previously referenced modules. +// +// All non-local accesses to the data structures are mediated +// by ccu-thunks. Ultimately, a ccu-thunk is either a (named) element of +// the data structure, or it is a delayed fixup, i.e. an invalid dangling +// reference that has not had an appropriate fixup applied. [] type CcuThunk = { diff --git a/src/fsharp/TypedTreeOps.fs b/src/fsharp/TypedTreeOps.fs index 4996150ed88..b93c31f7fe2 100644 --- a/src/fsharp/TypedTreeOps.fs +++ b/src/fsharp/TypedTreeOps.fs @@ -1976,7 +1976,7 @@ let unionFreeTypars s1 s2 = let emptyFreeTyvars = { FreeTycons = emptyFreeTycons - /// The summary of values used as trait solutions + // The summary of values used as trait solutions FreeTraitSolutions = emptyFreeLocals FreeTypars = emptyFreeTypars} diff --git a/src/fsharp/absil/illib.fs b/src/fsharp/absil/illib.fs index 2cd1f328f82..26e99a0ce6f 100644 --- a/src/fsharp/absil/illib.fs +++ b/src/fsharp/absil/illib.fs @@ -100,8 +100,8 @@ module internal PervasiveAutoOpens = cancellationToken) task.Result -[] /// An efficient lazy for inline storage in a class type. Results in fewer thunks. +[] type InlineDelayInit<'T when 'T : not struct> = new (f: unit -> 'T) = {store = Unchecked.defaultof<'T>; func = Func<_>(f) } val mutable store : 'T @@ -504,8 +504,8 @@ module ResizeArray = // rounding down here is good because it ensures we don't go over let maxArrayItemCount = LOH_SIZE_THRESHOLD_BYTES / itemSizeBytes - /// chunk the provided input into arrays that are smaller than the LOH limit - /// in order to prevent long-term storage of those values + // chunk the provided input into arrays that are smaller than the LOH limit + // in order to prevent long-term storage of those values chunkBySize maxArrayItemCount f inp module ValueOptionInternal = diff --git a/src/fsharp/absil/ilread.fs b/src/fsharp/absil/ilread.fs index 33882f26276..444f11aedf2 100644 --- a/src/fsharp/absil/ilread.fs +++ b/src/fsharp/absil/ilread.fs @@ -193,7 +193,7 @@ type WeakByteFile(fileName: string, chunk: (int * int) option) = member _.FileName = fileName - /// Get the bytes for the file + // Get the bytes for the file interface BinaryFile with override this.GetView() = @@ -3877,7 +3877,7 @@ type ILModuleReader = abstract ILModuleDef: ILModuleDef abstract ILAssemblyRefs: ILAssemblyRef list - /// ILModuleReader objects only need to be explicitly disposed if memory mapping is used, i.e. reduceMemoryUsage = false + // ILModuleReader objects only need to be explicitly disposed if memory mapping is used, i.e. reduceMemoryUsage = false inherit IDisposable [] diff --git a/src/fsharp/absil/ilread.fsi b/src/fsharp/absil/ilread.fsi index a9cc50ad0c1..09c1a1bca91 100644 --- a/src/fsharp/absil/ilread.fsi +++ b/src/fsharp/absil/ilread.fsi @@ -65,7 +65,7 @@ type public ILModuleReader = abstract ILModuleDef: ILModuleDef abstract ILAssemblyRefs: ILAssemblyRef list - /// ILModuleReader objects only need to be explicitly disposed if memory mapping is used, i.e. reduceMemoryUsage = false + // ILModuleReader objects only need to be explicitly disposed if memory mapping is used, i.e. reduceMemoryUsage = false inherit System.IDisposable diff --git a/src/fsharp/absil/ilwrite.fs b/src/fsharp/absil/ilwrite.fs index 1697acc5b4c..d28319054d5 100644 --- a/src/fsharp/absil/ilwrite.fs +++ b/src/fsharp/absil/ilwrite.fs @@ -4331,7 +4331,7 @@ and writePdb (dumpDebugInfo, showTimes, portablePDB, embeddedPDB, pdbfile, outfi end reportTime showTimes "Finalize PDB" - /// Sign the binary. No further changes to binary allowed past this point! + // Sign the binary. No further changes to binary allowed past this point! match signer with | None -> () | Some s -> diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs index ee962657ad1..730f582d29d 100644 --- a/src/fsharp/fsi/fsi.fs +++ b/src/fsharp/fsi/fsi.fs @@ -234,9 +234,9 @@ type EvaluationEventArgs(fsivalue : FsiValue option, symbolUse : FSharpSymbolUse member x.Symbol = symbolUse.Symbol member x.ImplementationDeclaration = decl -[] /// User-configurable information that changes how F# Interactive operates, stored in the 'fsi' object /// and accessible via the programming model +[] type FsiEvaluationSessionHostConfig () = let evaluationEvent = Event() /// Called by the evaluation session to ask the host for parameters to format text for output @@ -940,7 +940,7 @@ type internal FsiConsoleInput(fsi: FsiEvaluationSessionHostConfig, fsiOptions: F /// When using a key-reading console this holds the first line after it is read let mutable firstLine = None - /// Peek on the standard input so that the user can type into it from a console window. + // Peek on the standard input so that the user can type into it from a console window. do if fsiOptions.Interact then if fsiOptions.PeekAheadOnConsoleToPermitTyping then (Thread(fun () -> @@ -1416,7 +1416,7 @@ type internal FsiDynamicCompiler let infoReader = InfoReader(istate.tcGlobals, istate.tcImports.GetImportMap()) valuePrinter.InvokeExprPrinter (istate.tcState.TcEnvFromImpls.DisplayEnv, infoReader, istate.emEnv, istate.ilxGenerator, vref) - /// Clear the value held in the previous "it" binding, if any, as long as it has never been referenced. + // Clear the value held in the previous "it" binding, if any, as long as it has never been referenced. match prevIt with | Some prevVal when not prevVal.Deref.HasBeenReferenced -> istate.ilxGenerator.ClearGeneratedValue (valuePrinter.GetEvaluationContext istate.emEnv, prevVal.Deref) diff --git a/src/fsharp/fsi/fsi.fsi b/src/fsharp/fsi/fsi.fsi index 63f8d980c71..30c11444556 100644 --- a/src/fsharp/fsi/fsi.fsi +++ b/src/fsharp/fsi/fsi.fsi @@ -9,8 +9,8 @@ open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Diagnostics open FSharp.Compiler.Symbols -[] /// Represents an evaluated F# value +[] type FsiValue = /// The value, as an object @@ -22,8 +22,8 @@ type FsiValue = /// The type of the value, from the point of view of the F# type system member FSharpType: FSharpType -[] /// Represents an evaluated F# value that is bound to an identifier +[] type FsiBoundValue = /// The identifier of the value @@ -307,8 +307,8 @@ module Settings = /// Schedule a restart for the event loop. abstract ScheduleRestart: unit -> unit - [] /// Operations supported by the currently executing F# Interactive session. + [] type InteractiveSettings = /// Get or set the floating point format used in the output of the interactive session. member FloatingPointFormat: string with get,set diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 3c60e70ddbd..a1f2b836e2d 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -98,8 +98,8 @@ let GetSuperTypeOfType g amap m ty = /// Make a type for System.Collections.Generic.IList let mkSystemCollectionsGenericIListTy (g: TcGlobals) ty = TType_app(g.tcref_System_Collections_Generic_IList, [ty]) -[] /// Indicates whether we can skip interface types that lie outside the reference set +[] type SkipUnrefInterfaces = Yes | No /// Collect the set of immediate declared interface types for an F# type, but do not @@ -600,8 +600,8 @@ type ReflectedArgInfo = //------------------------------------------------------------------------- // ParamNameAndType, ParamData -[] /// Partial information about a parameter returned for use by the Language Service +[] type ParamNameAndType = | ParamNameAndType of Ident option * TType @@ -610,8 +610,8 @@ type ParamNameAndType = static member Instantiate inst p = let (ParamNameAndType(nm, ty)) = p in ParamNameAndType(nm, instType inst ty) static member InstantiateCurried inst paramTypes = paramTypes |> List.mapSquared (ParamNameAndType.Instantiate inst) -[] /// Full information about a parameter returned for use by the type checker and language service. +[] type ParamData = ParamData of isParamArray: bool * diff --git a/src/fsharp/service/FSharpCheckerResults.fs b/src/fsharp/service/FSharpCheckerResults.fs index ca208b7201b..c3fd629bd63 100644 --- a/src/fsharp/service/FSharpCheckerResults.fs +++ b/src/fsharp/service/FSharpCheckerResults.fs @@ -1917,10 +1917,10 @@ type FSharpProjectContext(thisCcu: CcuThunk, assemblies: FSharpAssembly list, ad member _.AccessibilityRights = FSharpAccessibilityRights(thisCcu, ad) -[] /// A live object of this type keeps the background corresponding background builder (and type providers) alive (through reference-counting). // // Note: objects returned by the methods of this type do not require the corresponding background builder to be alive. +[] type FSharpCheckFileResults (filename: string, errors: FSharpDiagnostic[], diff --git a/src/fsharp/service/FSharpParseFileResults.fsi b/src/fsharp/service/FSharpParseFileResults.fsi index 9d3378a7b9a..e5048aa4700 100644 --- a/src/fsharp/service/FSharpParseFileResults.fsi +++ b/src/fsharp/service/FSharpParseFileResults.fsi @@ -7,8 +7,8 @@ open FSharp.Compiler.EditorServices open FSharp.Compiler.Syntax open FSharp.Compiler.Text -[] /// Represents the results of parsing an F# file and a set of analysis operations based on the parse tree alone. +[] type public FSharpParseFileResults = /// The syntax tree resulting from the parse diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs index 8909575da24..ebb94f18398 100644 --- a/src/fsharp/service/IncrementalBuild.fs +++ b/src/fsharp/service/IncrementalBuild.fs @@ -535,7 +535,7 @@ type BoundModel private (tcConfig: TcConfig, let tcInfoExtras = { - /// Only keep the typed interface files when doing a "full" build for fsc.exe, otherwise just throw them away + // Only keep the typed interface files when doing a "full" build for fsc.exe, otherwise just throw them away latestImplFile = if keepAssemblyContents then implFile else None tcResolutions = (if keepAllBackgroundResolutions then sink.GetResolutions() else TcResolutions.Empty) tcSymbolUses = (if keepAllBackgroundSymbolUses then sink.GetSymbolUses() else TcSymbolUses.Empty) @@ -668,7 +668,7 @@ module Utilities = | _ -> None /// The implementation of the information needed by TcImports in CompileOps.fs for an F# assembly reference. -// +/// /// Constructs the build data (IRawFSharpAssemblyData) representing the assembly when used /// as a cross-assembly reference. Note the assembly has not been generated on disk, so this is /// a virtualized view of the assembly contents as computed by background checking. diff --git a/src/fsharp/service/ServiceDeclarationLists.fs b/src/fsharp/service/ServiceDeclarationLists.fs index 3ea07d55545..a077a1fe444 100644 --- a/src/fsharp/service/ServiceDeclarationLists.fs +++ b/src/fsharp/service/ServiceDeclarationLists.fs @@ -456,8 +456,8 @@ module DeclarationListHelpers = (fun () -> FormatItemDescriptionToToolTipElement isDecl infoReader ad m denv item) (fun err -> ToolTipElement.CompositionError err) +/// Represents one parameter for one method (or other item) in a group. [] -/// Represents one parameter for one method (or other item) in a group. type MethodGroupItemParameter(name: string, canonicalTypeTextForSorting: string, display: TaggedText[], isOptional: bool) = /// The name of the parameter. diff --git a/src/fsharp/service/ServiceDeclarationLists.fsi b/src/fsharp/service/ServiceDeclarationLists.fsi index d8a302cef94..508e7297529 100644 --- a/src/fsharp/service/ServiceDeclarationLists.fsi +++ b/src/fsharp/service/ServiceDeclarationLists.fsi @@ -88,11 +88,11 @@ type internal CompletionItem = } member Item: Item -[] /// Represents a declaration in F# source code, with information attached ready for display by an editor. /// Returned by GetDeclarations. // -// Note: this type holds a weak reference to compiler resources. +// Note: this type holds a weak reference to compiler resources. +[] type public DeclarationListItem = /// Get the text to display in the declaration list for the declaration. member Name: string @@ -123,11 +123,11 @@ type public DeclarationListItem = member NamespaceToOpen: string option -[] /// Represents a set of declarations in F# source code, with information attached ready for display by an editor. /// Returned by GetDeclarations. // -// Note: this type holds a weak reference to compiler resources. +// Note: this type holds a weak reference to compiler resources. +[] type public DeclarationListInfo = member Items: DeclarationListItem[] diff --git a/src/fsharp/service/service.fsi b/src/fsharp/service/service.fsi index 97b6f9f7983..018fca15317 100644 --- a/src/fsharp/service/service.fsi +++ b/src/fsharp/service/service.fsi @@ -15,8 +15,8 @@ open FSharp.Compiler.Syntax open FSharp.Compiler.Text open FSharp.Compiler.Tokenization -[] /// Used to parse and check F# source code. +[] type public FSharpChecker = /// /// Create an instance of an FSharpChecker. diff --git a/src/fsharp/utils/ResizeArray.fsi b/src/fsharp/utils/ResizeArray.fsi index cdc216aaab9..400f38e4b4c 100644 --- a/src/fsharp/utils/ResizeArray.fsi +++ b/src/fsharp/utils/ResizeArray.fsi @@ -2,8 +2,8 @@ namespace Internal.Utilities -[] /// Generic operations on the type System.Collections.Generic.List, which is called ResizeArray in the F# libraries. +[] module internal ResizeArray = /// Return the length of the collection. You can also use property arr.Length. diff --git a/src/fsharp/utils/prim-lexing.fsi b/src/fsharp/utils/prim-lexing.fsi index 23ad8cbefa6..24577606320 100644 --- a/src/fsharp/utils/prim-lexing.fsi +++ b/src/fsharp/utils/prim-lexing.fsi @@ -95,10 +95,10 @@ type internal Position = static member FirstLine: fileIdx:int -> Position -[] /// Input buffers consumed by lexers generated by fslex.exe. /// The type must be generic to match the code generated by FsLex and FsYacc (if you would like to /// fix this, please submit a PR to the FsLexYacc repository allowing for optional emit of a non-generic type reference). +[] type internal LexBuffer<'Char> = /// The start position for the lexeme. member StartPos: Position with get,set diff --git a/src/fsharp/utils/prim-parsing.fs b/src/fsharp/utils/prim-parsing.fs index 444113f939b..c7214456a2a 100644 --- a/src/fsharp/utils/prim-parsing.fs +++ b/src/fsharp/utils/prim-parsing.fs @@ -34,8 +34,8 @@ type internal IParseState(ruleStartPoss:Position[], ruleEndPoss:Position[], lhsP member p.RaiseError() = raise RecoverableParseError -[] /// This context is passed to the error reporter when a syntax error occurs +[] type internal ParseErrorContext<'tok> (//lexbuf: LexBuffer<_>, stateStack:int list, diff --git a/src/fsharp/utils/prim-parsing.fsi b/src/fsharp/utils/prim-parsing.fsi index c4d5475273e..e34181709e8 100644 --- a/src/fsharp/utils/prim-parsing.fsi +++ b/src/fsharp/utils/prim-parsing.fsi @@ -37,8 +37,8 @@ type internal IParseState = member LexBuffer : LexBuffer -[] /// The context provided when a parse error occurs. +[] type internal ParseErrorContext<'tok> = /// The stack of state indexes active at the parse error . member StateStack : int list From 2298a6fbdf2de7c670362505e16a3116c6af2c94 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Wed, 8 Sep 2021 16:35:26 +0300 Subject: [PATCH 22/25] yet another comment fix --- src/fsharp/FSharp.Core/async.fs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/async.fs b/src/fsharp/FSharp.Core/async.fs index f7e41125e9f..6578233e762 100644 --- a/src/fsharp/FSharp.Core/async.fs +++ b/src/fsharp/FSharp.Core/async.fs @@ -305,8 +305,9 @@ namespace Microsoft.FSharp.Control contents.aux.ccont (OperationCanceledException (contents.aux.token)) /// Check for trampoline hijacking. - /// Note, this must make tailcalls, so may not be an instance member taking a byref argument, - /// nor call any members taking byref arguments. + // + // Note, this must make tailcalls, so may not be an instance member taking a byref argument, + // nor call any members taking byref arguments. static member inline HijackCheckThenCall (ctxt: AsyncActivation<'T>) cont arg = ctxt.aux.trampolineHolder.HijackCheckThenCall cont arg From 7c4cab7448b5a47e3ae1dbbb976c5fb1af8ec9d0 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Wed, 8 Sep 2021 20:52:26 +0300 Subject: [PATCH 23/25] try to fix tests --- tests/fsharp/typecheck/sigs/neg25.fs | 2 +- tests/fsharp/typecheck/sigs/neg66.fsx | 2 +- tests/fsharp/typecheck/sigs/neg67.fsx | 2 +- tests/fsharp/typecheck/sigs/neg69.fsx | 2 +- tests/fsharp/typecheck/sigs/neg71.bsl | 2 ++ tests/fsharp/typecheck/sigs/neg71.vsbsl | 2 ++ 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg25.fs b/tests/fsharp/typecheck/sigs/neg25.fs index 87b1d5c81df..f12074effb6 100644 --- a/tests/fsharp/typecheck/sigs/neg25.fs +++ b/tests/fsharp/typecheck/sigs/neg25.fs @@ -67,7 +67,7 @@ module NegativeTestsActualRepro1 = override this.MaximumStrength = 9u // Stub - type TestVariableLevelEnumeratorFactory (levels: seq) = /// THis should give an error + type TestVariableLevelEnumeratorFactory (levels: seq) = // THis should give an error inherit TestCaseEnumeratorFactoryCommonImplementation () let node = TestVariableNode levels diff --git a/tests/fsharp/typecheck/sigs/neg66.fsx b/tests/fsharp/typecheck/sigs/neg66.fsx index 5d4dc729639..fc1ef247684 100644 --- a/tests/fsharp/typecheck/sigs/neg66.fsx +++ b/tests/fsharp/typecheck/sigs/neg66.fsx @@ -125,7 +125,7 @@ type Simulator() = let ay = (dy / d) * g / obj.Mass ax,ay - /// Find all the gravitational objects in the system except the given object + // Find all the gravitational objects in the system except the given object let FindObjects(obj) = [ for paintObject in paintObjects do match paintObject with diff --git a/tests/fsharp/typecheck/sigs/neg67.fsx b/tests/fsharp/typecheck/sigs/neg67.fsx index caab46acada..bda04dcdcb1 100644 --- a/tests/fsharp/typecheck/sigs/neg67.fsx +++ b/tests/fsharp/typecheck/sigs/neg67.fsx @@ -125,7 +125,7 @@ type Simulator() = let ay = (dy / d) * g / obj.Mass ax,ay - /// Find all the gravitational objects in the system except the given object + // Find all the gravitational objects in the system except the given object let FindObjects(obj) = [ for paintObject in paintObjects do match paintObject with diff --git a/tests/fsharp/typecheck/sigs/neg69.fsx b/tests/fsharp/typecheck/sigs/neg69.fsx index 9e0c51770cf..cc0cf21086c 100644 --- a/tests/fsharp/typecheck/sigs/neg69.fsx +++ b/tests/fsharp/typecheck/sigs/neg69.fsx @@ -125,7 +125,7 @@ type Simulator() = let ay = (dy / d) * g / obj.Mass ax,ay - /// Find all the gravitational objects in the system except the given object + // Find all the gravitational objects in the system except the given object let FindObjects(obj) = [ for paintObject in paintObjects do match paintObject with diff --git a/tests/fsharp/typecheck/sigs/neg71.bsl b/tests/fsharp/typecheck/sigs/neg71.bsl index dd572143c38..c41a93b8bcf 100644 --- a/tests/fsharp/typecheck/sigs/neg71.bsl +++ b/tests/fsharp/typecheck/sigs/neg71.bsl @@ -4,3 +4,5 @@ neg71.fsx(110,43,110,44): parse error FS0010: Unexpected symbol ')' in expressio neg71.fsx(166,24,168,1): parse error FS0010: Incomplete structured construct at or before this point in member definition. Expected incomplete structured construct at or before this point, 'end' or other token. neg71.fsx(230,1,230,13): parse error FS0010: Unexpected identifier in member definition + +neg71.fsx(128,5,128,81): parse info FS3520: XML comment is not placed on a valid language element. diff --git a/tests/fsharp/typecheck/sigs/neg71.vsbsl b/tests/fsharp/typecheck/sigs/neg71.vsbsl index 87e679bcc92..c1dc656ab1d 100644 --- a/tests/fsharp/typecheck/sigs/neg71.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg71.vsbsl @@ -11,6 +11,8 @@ neg71.fsx(166,24,168,1): parse error FS0010: Incomplete structured construct at neg71.fsx(230,1,230,13): parse error FS0010: Unexpected identifier in member definition +neg71.fsx(128,5,128,81): parse info FS3520: XML comment is not placed on a valid language element. + neg71.fsx(168,1,168,28): typecheck error FS0960: 'let' and 'do' bindings must come before member and interface definitions in type definitions neg71.fsx(168,9,168,18): typecheck error FS0039: The value or constructor 'Simulator' is not defined. From 889c2f99802048bafe3b15cd48a9ccddd1da3d13 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Thu, 9 Sep 2021 00:09:50 +0300 Subject: [PATCH 24/25] yet another test fix --- tests/fsharp/typecheck/sigs/neg71.vsbsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/fsharp/typecheck/sigs/neg71.vsbsl b/tests/fsharp/typecheck/sigs/neg71.vsbsl index c1dc656ab1d..bbdad6e76ff 100644 --- a/tests/fsharp/typecheck/sigs/neg71.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg71.vsbsl @@ -5,6 +5,8 @@ neg71.fsx(166,24,168,1): parse error FS0010: Incomplete structured construct at neg71.fsx(230,1,230,13): parse error FS0010: Unexpected identifier in member definition +neg71.fsx(128,5,128,81): parse info FS3520: XML comment is not placed on a valid language element. + neg71.fsx(110,43,110,44): parse error FS0010: Unexpected symbol ')' in expression. Expected incomplete structured construct at or before this point or other token. neg71.fsx(166,24,168,1): parse error FS0010: Incomplete structured construct at or before this point in member definition. Expected incomplete structured construct at or before this point, 'end' or other token. From 79e9afa4210c00ca151518ab032391065b36547a Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Fri, 17 Sep 2021 00:23:36 +0300 Subject: [PATCH 25/25] compilation fix --- src/fsharp/FSharp.Core/array.fsi | 4 ++-- src/fsharp/FSharp.Core/quotations.fsi | 4 ++-- src/fsharp/FSharp.Core/seq.fsi | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/fsharp/FSharp.Core/array.fsi b/src/fsharp/FSharp.Core/array.fsi index 0950c5e9a80..1dc582d5c95 100644 --- a/src/fsharp/FSharp.Core/array.fsi +++ b/src/fsharp/FSharp.Core/array.fsi @@ -345,10 +345,10 @@ module Array = /// Returns an empty array of the given type. /// The empty array. - [] /// /// - /// + /// + [] [] val empty<'T> : 'T[] diff --git a/src/fsharp/FSharp.Core/quotations.fsi b/src/fsharp/FSharp.Core/quotations.fsi index 1713a7405a0..28f349f3578 100644 --- a/src/fsharp/FSharp.Core/quotations.fsi +++ b/src/fsharp/FSharp.Core/quotations.fsi @@ -409,9 +409,9 @@ type Expr = /// The expression being quoted. /// /// The resulting expression. - [] - /// + /// /// + [] static member Quote: inner:Expr -> Expr /// Builds an expression that represents a nested raw quotation literal diff --git a/src/fsharp/FSharp.Core/seq.fsi b/src/fsharp/FSharp.Core/seq.fsi index 7a948e91ac3..0812402517c 100644 --- a/src/fsharp/FSharp.Core/seq.fsi +++ b/src/fsharp/FSharp.Core/seq.fsi @@ -1162,9 +1162,6 @@ module Seq = [] val nth: index:int -> source:seq<'T> -> 'T - /// - /// - [] /// Views the given array as a sequence. /// /// The input array. @@ -1172,16 +1169,19 @@ module Seq = /// The result sequence. /// /// Thrown when the input sequence is null. + /// + /// + [] val ofArray: source:'T[] -> seq<'T> - /// - /// - [] /// Views the given list as a sequence. /// /// The input list. /// /// The result sequence. + /// + /// + [] val ofList: source:'T list -> seq<'T> /// Returns a sequence of each element in the input sequence and its predecessor, with the