未验证 提交 be5b58c6 编写于 作者: K Kevin Ransom (msft) 提交者: GitHub

Merge pull request #4225 from auduchinok/record-fields-name-generated

Symbols API: add IsNameGenerated to FSharpField
......@@ -1953,6 +1953,7 @@ and u_recdfield_spec st =
rfield_xmldoc= defaultArg xmldoc XmlDoc.Empty
rfield_xmldocsig=f
rfield_access=g
rfield_name_generated = false
rfield_other_range = None }
and u_rfield_table st = MakeRecdFieldsTable (u_list u_recdfield_spec st)
......
......@@ -1583,7 +1583,7 @@ let InstanceMembersNeedSafeInitCheck cenv m thisTy =
let MakeSafeInitField (g: TcGlobals) env m isStatic =
let id = ident(globalNng.FreshCompilerGeneratedName("init", m), m)
let taccess = TAccess [env.eAccessPath]
NewRecdField isStatic None id g.int_ty true true [] [] XmlDoc.Empty taccess true
NewRecdField isStatic None id false g.int_ty true true [] [] XmlDoc.Empty taccess true
// Make the "delayed reference" boolean value recording the safe initialization of a type in a hierarchy where there is a HasSelfReferentialConstructor
let ComputeInstanceSafeInitInfo cenv env m thisTy =
......@@ -11897,12 +11897,12 @@ module TcRecdUnionAndEnumDeclarations = begin
| ParentNone -> vis
| Parent tcref -> combineAccess vis tcref.TypeReprAccessibility
let MakeRecdFieldSpec _cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, isMutable, vol, xmldoc, vis, m) =
let MakeRecdFieldSpec _cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, nameGenerated, isMutable, vol, xmldoc, vis, m) =
let vis, _ = ComputeAccessAndCompPath env None m vis None parent
let vis = CombineReprAccess parent vis
NewRecdField isStatic konst id ty' isMutable vol attrsForProperty attrsForField xmldoc vis false
NewRecdField isStatic konst id nameGenerated ty' isMutable vol attrsForProperty attrsForField xmldoc vis false
let TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, synAttrs, id, ty, isMutable, xmldoc, vis, m) =
let TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, synAttrs, id, nameGenerated, ty, isMutable, xmldoc, vis, m) =
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)
......@@ -11921,7 +11921,7 @@ module TcRecdUnionAndEnumDeclarations = begin
if isIncrClass && (not zeroInit || not isMutable) then errorR(Error(FSComp.SR.tcUninitializedValFieldsMustBeMutable(), m))
if isStatic && (not zeroInit || not isMutable || vis <> Some SynAccess.Private ) then errorR(Error(FSComp.SR.tcStaticValFieldsMustBeMutableAndPrivate(), m))
let konst = if zeroInit then Some Const.Zero else None
let rfspec = MakeRecdFieldSpec cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, isMutable, isVolatile, xmldoc, vis, m)
let rfspec = MakeRecdFieldSpec cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, nameGenerated, isMutable, isVolatile, xmldoc, vis, m)
match parent with
| Parent tcref when useGenuineField tcref.Deref rfspec ->
// Recheck the attributes for errors if the definition only generates a field
......@@ -11932,7 +11932,7 @@ module TcRecdUnionAndEnumDeclarations = begin
let TcAnonFieldDecl cenv env parent tpenv nm (Field(attribs, isStatic, idOpt, ty, isMutable, xmldoc, vis, m)) =
let id = (match idOpt with None -> mkSynId m nm | Some id -> id)
let f = TcFieldDecl cenv env parent false tpenv (isStatic, attribs, id, ty, isMutable, xmldoc.ToXmlDoc(), vis, m)
let f = TcFieldDecl cenv env parent false tpenv (isStatic, attribs, id, idOpt.IsNone, ty, isMutable, xmldoc.ToXmlDoc(), vis, m)
match idOpt with
| None -> ()
| Some id ->
......@@ -11944,7 +11944,7 @@ module TcRecdUnionAndEnumDeclarations = begin
let TcNamedFieldDecl cenv env parent isIncrClass tpenv (Field(attribs, isStatic, id, ty, isMutable, xmldoc, vis, m)) =
match id with
| None -> error (Error(FSComp.SR.tcFieldRequiresName(), m))
| Some(id) -> TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, attribs, id, ty, isMutable, xmldoc.ToXmlDoc(), vis, m)
| Some(id) -> TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, attribs, id, false, ty, isMutable, xmldoc.ToXmlDoc(), vis, m)
let TcNamedFieldDecls cenv env parent isIncrClass tpenv fields =
fields |> List.map (TcNamedFieldDecl cenv env parent isIncrClass tpenv)
......@@ -12007,7 +12007,7 @@ module TcRecdUnionAndEnumDeclarations = begin
let rfields =
argtys |> List.mapi (fun i (argty, argInfo) ->
let id = (match argInfo.Name with Some id -> id | None -> mkSynId m (mkName nFields i))
MakeRecdFieldSpec cenv env parent (false, None, argty, [], [], id, false, false, XmlDoc.Empty, None, m))
MakeRecdFieldSpec cenv env parent (false, None, argty, [], [], id, argInfo.Name.IsNone, false, false, XmlDoc.Empty, None, m))
if not (typeEquiv cenv.g recordTy thisTy) then
error(Error(FSComp.SR.tcReturnTypesForUnionMustBeSameAsType(), m))
rfields, recordTy
......@@ -12029,7 +12029,7 @@ module TcRecdUnionAndEnumDeclarations = begin
let vis, _ = ComputeAccessAndCompPath env None m None None parent
let vis = CombineReprAccess parent vis
if id.idText = "value__" then errorR(Error(FSComp.SR.tcNotValidEnumCaseName(), id.idRange))
NewRecdField true (Some v) id thisTy false false [] attrs (xmldoc.ToXmlDoc()) vis false
NewRecdField true (Some v) id false thisTy false false [] attrs (xmldoc.ToXmlDoc()) vis false
let TcEnumDecls cenv env parent thisTy enumCases =
let fieldTy = NewInferenceType ()
......@@ -12284,7 +12284,7 @@ module IncrClassChecking =
let taccess = TAccess [cpath]
let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute v.Attribs
NewRecdField isStatic None id ty v.IsMutable isVolatile [(*no property attributes*)] v.Attribs v.XmlDoc taccess (*compiler generated:*)true
NewRecdField isStatic None id false ty v.IsMutable isVolatile [(*no property attributes*)] v.Attribs v.XmlDoc taccess (*compiler generated:*)true
/// Indicates how is a 'let' bound value in a class with implicit construction is represented in
/// the TAST ultimately produced by type checking.
......@@ -15289,7 +15289,7 @@ module EstablishTypeDefinitionCores =
let ty = names.[arg].Type
let id = names.[arg].Ident
let taccess = TAccess [envinner.eAccessPath]
yield NewRecdField false None id ty false false [(*no property attributes*)] [(*no field attributes *)] XmlDoc.Empty taccess (*compiler generated:*)true ]
yield NewRecdField false None id false ty false false [(*no property attributes*)] [(*no field attributes *)] XmlDoc.Empty taccess (*compiler generated:*)true ]
(userFields @ implicitStructFields) |> CheckDuplicates (fun f -> f.Id) "field" |> ignore
writeFakeRecordFieldsToSink userFields
......@@ -15404,7 +15404,7 @@ module EstablishTypeDefinitionCores =
noCLIMutableAttributeCheck()
noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedEnum
noAllowNullLiteralAttributeCheck()
let vfld = NewRecdField false None (ident("value__", m)) fieldTy false false [] [] XmlDoc.Empty taccessPublic true
let vfld = NewRecdField false None (ident("value__", m)) false fieldTy false false [] [] XmlDoc.Empty taccessPublic true
if not (ListSet.contains (typeEquiv cenv.g) fieldTy [ cenv.g.int32_ty; cenv.g.int16_ty; cenv.g.sbyte_ty; cenv.g.int64_ty; cenv.g.char_ty; cenv.g.bool_ty; cenv.g.uint32_ty; cenv.g.uint16_ty; cenv.g.byte_ty; cenv.g.uint64_ty ]) then
errorR(Error(FSComp.SR.tcInvalidTypeForLiteralEnumeration(), m))
......
......@@ -853,6 +853,12 @@ and FSharpField(cenv: cenv, d: FSharpFieldData) =
| Choice1Of2 r -> r.IsCompilerGenerated
| Choice2Of2 _ -> false
member __.IsNameGenerated =
if isUnresolved() then false else
match d.TryRecdField with
| Choice1Of2 r -> r.rfield_name_generated
| _ -> false
member __.DeclarationLocation =
checkIsResolved()
match d.TryRecdField with
......
......@@ -425,6 +425,10 @@ and [<Class>] public FSharpField =
/// Indicates a compiler generated field, not visible to Intellisense or name resolution
member IsCompilerGenerated: bool
/// Indicates if the field name was generated by compiler (e.g. ItemN names in union cases and DataN in exceptions).
/// This API returns true for source defined symbols only.
member IsNameGenerated: bool
/// Get the in-memory XML documentation for the field, used when code is checked in-memory
member XmlDoc: IList<string>
......
......@@ -1469,7 +1469,9 @@ and
mutable rfield_fattribs: Attribs
/// Name/declaration-location of the field
rfield_id: Ident
rfield_id: Ident
rfield_name_generated: bool
/// If this field is populated, this is the implementation range for an item in a signature, otherwise it is
/// the signature range for an item in an implementation
......@@ -4920,7 +4922,7 @@ let NewExn cpath (id:Ident) access repr attribs doc =
entity_il_repr_cache= newCache() }
/// Create a new TAST RecdField node for an F# class, struct or record field
let NewRecdField stat konst id ty isMutable isVolatile pattribs fattribs docOption access secret =
let NewRecdField stat konst id nameGenerated ty isMutable isVolatile pattribs fattribs docOption access secret =
{ rfield_mutable=isMutable
rfield_pattribs=pattribs
rfield_fattribs=fattribs
......@@ -4932,7 +4934,8 @@ let NewRecdField stat konst id ty isMutable isVolatile pattribs fattribs docOpt
rfield_secret = secret
rfield_xmldoc = docOption
rfield_xmldocsig = ""
rfield_id=id
rfield_id=id
rfield_name_generated = nameGenerated
rfield_other_range = None }
......
......@@ -968,3 +968,34 @@ let ``Test TPProject param info`` () =
``Basic cancellation test`` ()
``Intro test`` ()
#endif
[<Test>]
let ``FSharpField.IsNameGenerated`` () =
let checkFields source =
let file = "/home/user/Test.fsx"
let _, typeCheckResults = parseAndCheckScript(file, source)
let symbols =
typeCheckResults.GetAllUsesOfAllSymbolsInFile()
|> Async.RunSynchronously
symbols
|> Array.choose (fun su ->
match su.Symbol with
| :? FSharpEntity as entity -> Some entity.FSharpFields
| :? FSharpUnionCase as unionCase -> Some unionCase.UnionCaseFields
| _ -> None)
|> Seq.concat
|> Seq.map (fun (field: FSharpField) -> field.Name, field.IsNameGenerated)
|> List.ofSeq
["exception E of string", ["Data0", true]
"exception E of Data0: string", ["Data0", false]
"exception E of Name: string", ["Name", false]
"exception E of string * Data2: string * Data1: string * Name: string * Data4: string",
["Data0", true; "Data2", false; "Data1", false; "Name", false; "Data4", false]
"type U = Case of string", ["Item", true]
"type U = Case of Item: string", ["Item", false]
"type U = Case of Name: string", ["Name", false]
"type U = Case of string * Item2: string * string * Name: string",
["Item1", true; "Item2", false; "Item3", true; "Name", false]]
|> List.iter (fun (source, expected) -> checkFields source |> shouldEqual expected)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册