Skip to content

Commit

Permalink
Merge main to feature/nullness (#16366)
Browse files Browse the repository at this point in the history
* Fixes #16359 - correctly handle imports with 0 length public key tokens (#16363)

* Parser: recover on unfinished record decls, fix field ranges (#16357)

* Parser: recover on unfinished record decls, fix field ranges

* Fantomas

* Better diagnostic ranges for fields

* More parser tests

* Update surface area

* Fix xml doc test

* Update baselines

* Update src/Compiler/SyntaxTree/SyntaxTree.fsi

Co-authored-by: Edgar Gonzalez <edgargonzalez.info@gmail.com>

* Add MutableKeyword to SynFieldTrivia. (#11)

* Simplify

* Fantomas

---------

Co-authored-by: Edgar Gonzalez <edgargonzalez.info@gmail.com>
Co-authored-by: Florian Verdonck <florian.verdonck@outlook.com>

---------

Co-authored-by: Kevin Ransom (msft) <codecutter@hotmail.com>
Co-authored-by: Eugene Auduchinok <eugene.auduchinok@jetbrains.com>
Co-authored-by: Edgar Gonzalez <edgargonzalez.info@gmail.com>
Co-authored-by: Florian Verdonck <florian.verdonck@outlook.com>
Co-authored-by: Tomas Grosup <tomasgrosup@microsoft.com>
  • Loading branch information
6 people authored Dec 4, 2023
1 parent dec61d6 commit 91429b4
Show file tree
Hide file tree
Showing 109 changed files with 1,167 additions and 203 deletions.
3 changes: 2 additions & 1 deletion docs/release-notes/FSharp.Compiler.Service/8.0.200.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- Miscellaneous fixes to parens analysis - https://github.com/dotnet/fsharp/pull/16262
- Miscellaneous fixes to parens analysis - https://github.com/dotnet/fsharp/pull/16262
- Fixes #16359 - correctly handle imports with 0 length public key tokens - https://github.com/dotnet/fsharp/pull/16363
7 changes: 6 additions & 1 deletion src/Compiler/AbstractIL/ilread.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1946,7 +1946,12 @@ and seekReadAssemblyManifest (ctxt: ILMetadataReader) pectxt idx =
Name = name
AuxModuleHashAlgorithm = hash
SecurityDeclsStored = ctxt.securityDeclsReader_Assembly
PublicKey = pubkey
PublicKey =
// The runtime and C# treat a 0 length publicKey as an unsigned assembly, so if a public record exists with a length of 0
// treat it as unsigned
match pubkey with
| Some pkBytes when pkBytes.Length > 0 -> pubkey
| _ -> None
Version = Some(ILVersionInfo(v1, v2, v3, v4))
Locale = readStringHeapOption ctxt localeIdx
CustomAttrsStored = ctxt.customAttrsReader_Assembly
Expand Down
34 changes: 21 additions & 13 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,9 @@ module TcRecdUnionAndEnumDeclarations =
let vis = CombineReprAccess parent vis
Construct.NewRecdField isStatic konst id nameGenerated tyR isMutable vol attrsForProperty attrsForField xmldoc vis false

let TcFieldDecl (cenv: cenv) env parent isIncrClass tpenv (isStatic, synAttrs, id, nameGenerated, ty, isMutable, xmldoc, vis, m) =
let TcFieldDecl (cenv: cenv) env parent isIncrClass tpenv (isStatic, synAttrs, id: Ident, nameGenerated, ty, isMutable, xmldoc, vis) =
let g = cenv.g
let m = id.idRange
let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDecl synAttrs
let attrsForProperty, attrsForField = attrs |> List.partition (fun (attrTargets, _) -> (attrTargets &&& AttributeTargets.Property) <> enum 0)
let attrsForProperty = (List.map snd attrsForProperty)
Expand Down Expand Up @@ -458,18 +459,20 @@ module TcRecdUnionAndEnumDeclarations =

let checkXmlDocs = cenv.diagnosticOptions.CheckXmlDocs
let xmlDoc = xmldoc.ToXmlDoc(checkXmlDocs, Some [])
TcFieldDecl cenv env parent false tpenv (isStatic, attribs, id, idOpt.IsNone, ty, isMutable, xmlDoc, vis, m)
TcFieldDecl cenv env parent false tpenv (isStatic, attribs, id, idOpt.IsNone, ty, isMutable, xmlDoc, vis)

let TcNamedFieldDecl cenv env parent isIncrClass tpenv (SynField(Attributes attribs, isStatic, id, ty, isMutable, xmldoc, vis, m, _)) =
match id with
| None -> error (Error(FSComp.SR.tcFieldRequiresName(), m))
| None ->
errorR (Error(FSComp.SR.tcFieldRequiresName(), m))
None
| Some id ->
let checkXmlDocs = cenv.diagnosticOptions.CheckXmlDocs
let xmlDoc = xmldoc.ToXmlDoc(checkXmlDocs, Some [])
TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, attribs, id, false, ty, isMutable, xmlDoc, vis, m)
Some(TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, attribs, id, false, ty, isMutable, xmlDoc, vis))

let TcNamedFieldDecls cenv env parent isIncrClass tpenv fields =
fields |> List.map (TcNamedFieldDecl cenv env parent isIncrClass tpenv)
fields |> List.choose (TcNamedFieldDecl cenv env parent isIncrClass tpenv)

//-------------------------------------------------------------------------
// Bind other elements of type definitions (constructors etc.)
Expand Down Expand Up @@ -518,14 +521,19 @@ module TcRecdUnionAndEnumDeclarations =
match args with
| SynUnionCaseKind.Fields flds ->
let nFields = flds.Length
let rfields = flds |> List.mapi (fun i (SynField (idOpt = idOpt) as fld) ->
match idOpt, parent with
| 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)
TcNamedFieldDecl cenv env parent false tpenv fld
| _ ->
TcAnonFieldDecl cenv env parent tpenv (mkUnionCaseFieldName nFields i) fld)
let rfields =
flds
|> List.mapi (fun i (SynField (idOpt = idOpt) as fld) ->
match idOpt, parent with
| 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)
TcNamedFieldDecl cenv env parent false tpenv fld
| _ ->
Some(TcAnonFieldDecl cenv env parent tpenv (mkUnionCaseFieldName nFields i) fld)
)
|> List.choose (fun x -> x)

ValidateFieldNames(flds, rfields)

rfields, thisTy
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1748,4 +1748,5 @@ featureReuseSameFieldsInStructUnions,"Share underlying fields in a [<Struct>] di
3859,tcNoStaticPropertyFoundForOverride,"No static abstract property was found that corresponds to this override"
3860,chkStaticMembersOnObjectExpressions,"Object expressions cannot implement interfaces with static abstract members or declare static members."
3861,chkTailCallAttrOnNonRec,"The TailCall attribute should only be applied to recursive functions."
3862,parsStaticMemberImcompleteSyntax,"Incomplete declaration of a static construct. Use 'static let','static do','static member' or 'static val' for declaration."
3862,parsStaticMemberImcompleteSyntax,"Incomplete declaration of a static construct. Use 'static let','static do','static member' or 'static val' for declaration."
3863,parsExpectingField,"Expecting record field"
71 changes: 61 additions & 10 deletions src/Compiler/SyntaxTree/ParseHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,20 +1140,71 @@ let mkAutoPropDefn mVal access ident typ mEquals (expr: SynExpr) accessors xmlDo
trivia
)

let mkValField mVal mRhs mut access ident (typ: SynType) xmlDoc rangeStart attribs mStaticOpt =
let isStatic = Option.isSome mStaticOpt
let mValDecl = unionRanges rangeStart typ.Range |> unionRangeWithXmlDoc xmlDoc
let mkSynField
parseState
(idOpt: Ident option)
(t: SynType option)
(isMutable: range option)
(vis: SynAccess option)
(attributes: SynAttributes)
(mStatic: range option)
(rangeStart: range)
(leadingKeyword: SynLeadingKeyword option)
=

let t, mStart =
match t with
| Some value -> value, rangeStart
| None ->

let mType, mStart =
idOpt
|> Option.map _.idRange
|> Option.orElseWith (fun _ -> vis |> Option.map (fun v -> v.Range))
|> Option.orElse isMutable
|> Option.orElseWith (fun _ -> leadingKeyword |> Option.map (fun k -> k.Range))
|> Option.orElseWith (fun _ -> attributes |> List.tryLast |> Option.map (fun l -> l.Range))
|> Option.map (fun m -> m, rangeStart)
|> Option.defaultWith (fun _ -> rangeStart.StartRange, rangeStart.StartRange)

SynType.FromParseError(mType.EndRange), mStart

let mWhole = unionRanges mStart t.Range
let xmlDoc = grabXmlDocAtRangeStart (parseState, attributes, mWhole)
let mWhole = unionRangeWithXmlDoc xmlDoc mWhole

SynField(
attributes,
Option.isSome mStatic,
idOpt,
t,
Option.isSome isMutable,
xmlDoc,
vis,
mWhole,
{
LeadingKeyword = leadingKeyword
MutableKeyword = isMutable
}
)

let mkValField
parseState
mVal
(isMutable: range option)
access
(idOpt: Ident option)
(typ: SynType option)
(rangeStart: range)
attribs
mStaticOpt
=
let leadingKeyword =
match mStaticOpt with
| None -> SynLeadingKeyword.Val mVal
| Some mStatic -> SynLeadingKeyword.StaticVal(mStatic, mVal)

let fld =
SynField(attribs, isStatic, Some ident, typ, mut, xmlDoc, access, mRhs, { LeadingKeyword = Some leadingKeyword })
let field =
mkSynField parseState idOpt typ isMutable access attribs mStaticOpt rangeStart (Some leadingKeyword)

SynMemberDefn.ValField(fld, mValDecl)

let mkSynField parseState idOpt t isMutable vis attributes isStatic mWhole leadingKeyword =
let xmlDoc = grabXmlDocAtRangeStart (parseState, attributes, mWhole)
SynField(attributes, isStatic, idOpt, t, isMutable, xmlDoc, vis, mWhole, { LeadingKeyword = leadingKeyword })
SynMemberDefn.ValField(field, field.Range)
19 changes: 9 additions & 10 deletions src/Compiler/SyntaxTree/ParseHelpers.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -280,26 +280,25 @@ val mkAutoPropDefn:
SynMemberDefn

val mkValField:
parseState: IParseState ->
mVal: range ->
mRhs: range ->
mut: bool ->
isMutable: range option ->
access: SynAccess option ->
ident: Ident ->
typ: SynType ->
xmlDoc: PreXmlDoc ->
range ->
idOpt: Ident option ->
typ: SynType option ->
rangeStart: range ->
SynAttributes ->
range option ->
SynMemberDefn

val mkSynField:
parseState: IParseState ->
idOpt: Ident option ->
t: SynType ->
isMutable: bool ->
t: SynType option ->
isMutable: range option ->
vis: SynAccess option ->
attributes: SynAttributeList list ->
isStatic: bool ->
mWhole: range ->
mStatic: range option ->
rangeStart: range ->
leadingKeyword: SynLeadingKeyword option ->
SynField
4 changes: 4 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,10 @@ type SynField =
range: range *
trivia: SynFieldTrivia

member this.Range =
match this with
| SynField(range = range) -> range

[<NoEquality; NoComparison>]
type SynComponentInfo =
| SynComponentInfo of
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,9 @@ type SynField =
range: range *
trivia: SynFieldTrivia

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

/// Represents the syntax tree associated with the name of a type definition or module
/// in signature or implementation.
///
Expand Down
7 changes: 6 additions & 1 deletion src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,14 @@ type SynMemberDefnAbstractSlotTrivia =
type SynFieldTrivia =
{
LeadingKeyword: SynLeadingKeyword option
MutableKeyword: range option
}

static member Zero: SynFieldTrivia = { LeadingKeyword = None }
static member Zero: SynFieldTrivia =
{
LeadingKeyword = None
MutableKeyword = None
}

[<NoEquality; NoComparison>]
type SynTypeOrTrivia = { OrKeyword: range }
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ type SynFieldTrivia =
{
/// Used leading keyword of SynField
LeadingKeyword: SynLeadingKeyword option
/// The syntax range of the `mutable` keyword
MutableKeyword: range option
}

static member Zero: SynFieldTrivia
Expand Down
Loading

0 comments on commit 91429b4

Please sign in to comment.