未验证 提交 142c0345 编写于 作者: C Chet Husk 提交者: GitHub

Implement walking of Attribute super types to check AttributeUsage (#10834)

上级 83a0acb6
......@@ -3013,6 +3013,11 @@ let superOfTycon (g: TcGlobals) (tycon: Tycon) =
| None -> g.obj_ty
| Some ty -> ty
/// walk a TyconRef's inheritance tree, yielding any parent types as an array
let supersOfTyconRef (tcref: TyconRef) =
Array.unfold (fun (tcref: TyconRef) -> match tcref.TypeContents.tcaug_super with Some (TType_app(sup, _)) -> Some(sup, sup) | _ -> None) tcref
//----------------------------------------------------------------------------
// Detect attributes
//----------------------------------------------------------------------------
......@@ -3119,12 +3124,16 @@ let TryFindTyconRefBoolAttribute g m attribSpec tcref =
| ([ Some ((:? bool as v) : obj) ], _) -> Some v
| _ -> None)
/// Try to find the resolved attributeusage for an type by walking its inheritance tree and picking the correct attribute usage value
let TryFindAttributeUsageAttribute g m tcref =
TryBindTyconRefAttribute g m g.attrib_AttributeUsageAttribute tcref
[| yield tcref
yield! supersOfTyconRef tcref |]
|> Array.tryPick (fun tcref ->
TryBindTyconRefAttribute g m g.attrib_AttributeUsageAttribute tcref
(fun (_, named) -> named |> List.tryPick (function ("AllowMultiple", _, _, ILAttribElem.Bool res) -> Some res | _ -> None))
(fun (Attrib(_, _, _, named, _, _, _)) -> named |> List.tryPick (function AttribNamedArg("AllowMultiple", _, _, AttribBoolArg res ) -> Some res | _ -> None))
(fun (_, named) -> named |> List.tryPick (function ("AllowMultiple", Some ((:? bool as res) : obj)) -> Some res | _ -> None))
)
/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument.
///
......
......@@ -43,6 +43,7 @@
<Compile Include="ErrorMessages\WrongSyntaxInForLoop.fs" />
<Compile Include="ErrorMessages\ConfusingTypeName.fs" />
<Compile Include="Language\RegressionTests.fs" />
<Compile Include="Language\AttributeCheckingTests.fs" />
<Compile Include="Language\XmlComments.fs" />
<Compile Include="Language\CompilerDirectiveTests.fs" />
<Compile Include="Language\CodeQuotationTests.fs" />
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.ComponentTests.AttributeChecking
open Xunit
open FSharp.Test.Utilities.Compiler
module AttributeCheckingTests =
[<Fact>]
let ``attributes check inherited AllowMultiple`` () =
Fsx """
open System
[<AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)>]
type HttpMethodAttribute() = inherit Attribute()
type HttpGetAttribute() = inherit HttpMethodAttribute()
[<HttpGet; HttpGet>] // this shouldn't error like
[<HttpMethod; HttpMethod>] // this doesn't
type C() =
member _.M() = ()
"""
|> ignoreWarnings
|> compile
|> shouldSucceed
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册