提交 4385bb76 编写于 作者: D Don Syme 提交者: latkin

fix for 82 - Scope of types for named attribute values

Scope of types for named values in attributes improperly set as assembly where attribute is defined

fixes https://github.com/Microsoft/visualfsharp/issues/82
closes https://github.com/Microsoft/visualfsharp/pull/568

commit a7e74c8cba301d39bb5b1d07f448dc4bcef88967
Author: latkin <latkin@microsoft.com>
Date:   Thu Aug 13 16:55:32 2015 -0700

    Add tests

commit 6c6cb0e0ebae07c1e55847e2ddbab72bdcffef54
Merge: d2a25c8 01dc5083
Author: Don Syme <donsyme@fastmail.fm>
Date:   Tue Aug 4 20:05:22 2015 +0100

    update

commit d2a25c8db9c55d1ee0bd78c140355ccaa9130fee
Author: Don Syme <donsyme@fastmail.fm>
Date:   Mon May 11 12:44:15 2015 +0100

    updates to fix (3)

commit 1097c068a457585c1e303e788d6bbb792a71e32d
Author: Don Syme <donsyme@fastmail.fm>
Date:   Mon May 11 12:42:43 2015 +0100

    updates to fix (2)

commit 27c926891d1671edc6c174ee676eece370cbdc78
Author: Don Syme <donsyme@fastmail.fm>
Date:   Mon May 11 12:40:47 2015 +0100

    updates to fix

commit fb3a470b9ec90bc81f4c2289d0c0c7a6c7e3cebe
Author: Don Syme <donsyme@fastmail.fm>
Date:   Mon May 11 12:36:13 2015 +0100

    fix for 82
上级 e6593d2f
......@@ -4685,7 +4685,7 @@ type ILTypeSigParser(tstring : string) =
let ilty = x.ParseType()
ILAttribElem.Type(Some(ilty))
let decodeILAttribData ilg (ca: ILAttribute) scope =
let decodeILAttribData ilg (ca: ILAttribute) =
let bytes = ca.Data
let sigptr = 0
let bb0,sigptr = sigptr_get_byte bytes sigptr
......@@ -4779,15 +4779,19 @@ let decodeILAttribData ilg (ca: ILAttribute) scope =
let et,sigptr = sigptr_get_u8 bytes sigptr
// We have a named value
let ty,sigptr =
// REVIEW: Post-M3, consider removing the restriction for scope - it's unnecessary
// because you can reconstruct scope using the qualified name from the CA Blob
if (0x50 = (int et) || 0x55 = (int et)) && Option.isSome scope then
if (0x50 = (int et) || 0x55 = (int et)) then
let qualified_tname,sigptr = sigptr_get_serstring bytes sigptr
// we're already getting the qualified name from the binary blob
// if we don't split out the unqualified name from the qualified name,
// we'll write the qualified assembly reference string twice to the binary blob
let unqualified_tname = qualified_tname.Split([|','|]).[0]
let scoref = Option.get scope
let unqualified_tname, rest =
let pieces = qualified_tname.Split(',')
if pieces.Length > 1 then
pieces.[0], Some (String.concat "," pieces.[1..])
else
pieces.[0], None
let scoref =
match rest with
| Some aname -> ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(aname)))
| None -> ilg.traits.ScopeRef
let tref = mkILTyRef (scoref,unqualified_tname)
let tspec = mkILNonGenericTySpec tref
ILType.Value(tspec),sigptr
......
......@@ -1797,11 +1797,9 @@ val destTypeDefsWithGlobalFunctionsFirst: ILGlobals -> ILTypeDefs -> ILTypeDef l
/// Note: not all custom attribute data can be decoded without binding types. In particular
/// enums must be bound in order to discover the size of the underlying integer.
/// The following assumes enums have size int32.
/// It also does not completely decode System.Type attributes
val decodeILAttribData:
ILGlobals ->
ILAttribute ->
ILScopeRef option ->
ILAttribElem list * (* fixed args *)
ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *)
......
......@@ -292,7 +292,7 @@ let cattr_typ2typ ilg f c =
// dev11 M3 defensive coding: if anything goes wrong with attribute decoding or encoding, then back out.
if morphCustomAttributeData then
try
let elems,namedArgs = IL.decodeILAttribData ilg c (Some(meth.MethodRef.EnclosingTypeRef.Scope))
let elems,namedArgs = IL.decodeILAttribData ilg c
let elems = elems |> List.map (celem_typ2typ f)
let namedArgs = namedArgs |> List.map (cnamedarg_typ2typ f)
IL.mkILCustomAttribMethRef ilg (meth, elems, namedArgs)
......
......@@ -5796,7 +5796,7 @@ and CreatePermissionSets g amap eenv (securityAttributes : Attrib list) =
let tref = tcref.CompiledRepresentationForNamedType
let ilattr = GenAttr amap g eenv attr
let _, ilNamedArgs =
match TryDecodeILAttribute g tref (Some(tref.Scope)) (mkILCustomAttrs [ilattr]) with
match TryDecodeILAttribute g tref (mkILCustomAttrs [ilattr]) with
| Some(ae,na) -> ae, na
| _ -> [],[]
let setArgs = ilNamedArgs |> List.map (fun (n,ilt,_,ilae) -> (n,ilt,ilae))
......
......@@ -2522,8 +2522,8 @@ let isILAttrib (tref:ILTypeRef) (attr: ILAttribute) =
// results of attribute lookups in the TAST
let HasILAttribute tref (attrs: ILAttributes) = List.exists (isILAttrib tref) attrs.AsList
let TryDecodeILAttribute g tref scope (attrs: ILAttributes) =
attrs.AsList |> List.tryPick(fun x -> if isILAttrib tref x then Some(decodeILAttribData g.ilg x scope) else None)
let TryDecodeILAttribute g tref (attrs: ILAttributes) =
attrs.AsList |> List.tryPick(fun x -> if isILAttrib tref x then Some(decodeILAttribData g.ilg x) else None)
// This one is done by name to ensure the compiler doesn't take a dependency on dereferencing a type that only exists in .NET 3.5
let ILThingHasExtensionAttribute (attrs : ILAttributes) =
......@@ -2590,7 +2590,7 @@ let TryBindTyconRefAttribute g (m:range) (AttribInfo (atref,_) as args) (tcref:T
| None -> None
#endif
| ILTypeMetadata (_,tdef) ->
match TryDecodeILAttribute g atref (Some(atref.Scope)) tdef.CustomAttrs with
match TryDecodeILAttribute g atref tdef.CustomAttrs with
| Some attr -> f1 attr
| _ -> None
| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
......@@ -6111,8 +6111,7 @@ let isTypeProviderAssemblyAttr (cattr:ILAttribute) =
let TryDecodeTypeProviderAssemblyAttr ilg (cattr:ILAttribute) =
if isTypeProviderAssemblyAttr cattr then
// ok to use ecmaILGlobals here since we're querying metadata, not making it
let parms, _args = decodeILAttribData ilg cattr None
let parms, _args = decodeILAttribData ilg cattr
match parms with // The first parameter to the attribute is the name of the assembly with the compiler extensions.
| (ILAttribElem.String (Some assemblyName))::_ -> Some assemblyName
| (ILAttribElem.String None)::_ -> Some null
......@@ -6144,8 +6143,7 @@ let tref_AutoOpenAttr () = mkILTyRef(IlxSettings.ilxFsharpCoreLibScopeRef (), tn
let IsSignatureDataVersionAttr cattr = isILAttrib (tref_SignatureDataVersionAttr ()) cattr
let TryFindAutoOpenAttr (ilg : IL.ILGlobals) cattr =
if isILAttrib (tref_AutoOpenAttr ()) cattr then
// ok to use ecmaILGlobals here since we're querying metadata, not making it
match decodeILAttribData ilg cattr None with
match decodeILAttribData ilg cattr with
| [ILAttribElem.String s],_ -> s
| [],_ -> None
| _ ->
......@@ -6159,8 +6157,7 @@ let tref_InternalsVisibleToAttr (ilg : IL.ILGlobals) =
let TryFindInternalsVisibleToAttr ilg cattr =
if isILAttrib (tref_InternalsVisibleToAttr ilg) cattr then
// ok to use ecmaILGlobals here since we're querying metadata, not making it
match decodeILAttribData ilg cattr None with
match decodeILAttribData ilg cattr with
| [ILAttribElem.String s],_ -> s
| [],_ -> None
| _ ->
......@@ -6171,8 +6168,7 @@ let TryFindInternalsVisibleToAttr ilg cattr =
let IsMatchingSignatureDataVersionAttr ilg ((v1,v2,v3,_) : ILVersionInfo) cattr =
IsSignatureDataVersionAttr cattr &&
// ok to use ecmaILGlobals here since we're querying metadata, not making it
match decodeILAttribData ilg cattr None with
match decodeILAttribData ilg cattr with
| [ILAttribElem.Int32 u1; ILAttribElem.Int32 u2;ILAttribElem.Int32 u3 ],_ ->
(v1 = uint16 u1) && (v2 = uint16 u2) && (v3 = uint16 u3)
| _ ->
......
......@@ -1197,7 +1197,7 @@ val mkLdelem : TcGlobals -> range -> TType -> Expr -> Expr -> Expr
// Analyze attribute sets
//-------------------------------------------------------------------------
val TryDecodeILAttribute : TcGlobals -> ILTypeRef -> ILScopeRef option -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option
val TryDecodeILAttribute : TcGlobals -> ILTypeRef -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option
val TryFindILAttribute : BuiltinAttribInfo -> ILAttributes -> bool
val TryFindILAttributeOpt : BuiltinAttribInfo option -> ILAttributes -> bool
......
......@@ -9722,7 +9722,7 @@ and TcAttribute cenv (env: TcEnv) attrTgt (synAttr: SynAttribute) =
let tdef = tcref.ILTyconRawMetadata
let tref = cenv.g.attrib_AttributeUsageAttribute.TypeRef
match TryDecodeILAttribute cenv.g tref (Some(tref.Scope)) tdef.CustomAttrs with
match TryDecodeILAttribute cenv.g tref tdef.CustomAttrs with
| Some ([ILAttribElem.Int32 validOn ],named) ->
let inherited =
match List.tryPick (function ("Inherited",_,_,ILAttribElem.Bool res) -> Some res | _ -> None) named with
......
......@@ -753,7 +753,7 @@ type ILMethInfo =
member x.IsDllImport g =
match g.attrib_DllImportAttribute with
| None -> false
| Some (AttribInfo(tref,_)) ->x.RawMetadata.CustomAttrs |> TryDecodeILAttribute g tref (Some tref.Scope) |> isSome
| Some (AttribInfo(tref,_)) ->x.RawMetadata.CustomAttrs |> TryDecodeILAttribute g tref |> isSome
/// Get the (zero or one) 'self'/'this'/'object' arguments associated with an IL method.
/// An instance extension method returns one object argument.
......@@ -1233,7 +1233,7 @@ type MethInfo =
[ [ for p in ilMethInfo.ParamMetadata do
let isParamArrayArg = TryFindILAttribute g.attrib_ParamArrayAttribute p.CustomAttrs
let reflArgInfo =
match TryDecodeILAttribute g g.attrib_ReflectedDefinitionAttribute.TypeRef (Some(g.attrib_ReflectedDefinitionAttribute.TypeRef.Scope)) p.CustomAttrs with
match TryDecodeILAttribute g g.attrib_ReflectedDefinitionAttribute.TypeRef p.CustomAttrs with
| Some ([ILAttribElem.Bool b ],_) -> ReflectedArgInfo.Quote b
| Some _ -> ReflectedArgInfo.Quote false
| _ -> ReflectedArgInfo.None
......@@ -2558,7 +2558,7 @@ module AttributeChecking =
ignore f3
#endif
BindMethInfoAttributes m minfo
(fun ilAttribs -> TryDecodeILAttribute g atref (Some(atref.Scope)) ilAttribs |> Option.bind f1)
(fun ilAttribs -> TryDecodeILAttribute g atref ilAttribs |> Option.bind f1)
(fun fsAttribs -> TryFindFSharpAttribute g attribSpec fsAttribs |> Option.bind f2)
#if EXTENSIONTYPING
(fun provAttribs ->
......@@ -2591,7 +2591,7 @@ module AttributeChecking =
/// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data
let private CheckILAttributes g cattrs m =
let (AttribInfo(tref,_)) = g.attrib_SystemObsolete
match TryDecodeILAttribute g tref (Some(tref.Scope)) cattrs with
match TryDecodeILAttribute g tref cattrs with
| Some ([ILAttribElem.String (Some msg) ],_) ->
WarnD(ObsoleteWarning(msg,m))
| Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ],_) ->
......@@ -2676,7 +2676,7 @@ module AttributeChecking =
/// Indicate if a list of IL attributes contains 'ObsoleteAttribute'. Used to suppress the item in intellisense.
let CheckILAttributesForUnseen g cattrs _m =
let (AttribInfo(tref,_)) = g.attrib_SystemObsolete
isSome (TryDecodeILAttribute g tref (Some(tref.Scope)) cattrs)
isSome (TryDecodeILAttribute g tref cattrs)
/// Checks the attributes for CompilerMessageAttribute, which has an IsHidden argument that allows
/// items to be suppressed from intellisense.
......
type T = Top.Repro.C
T.Run()
let attrs = typeof<T>.GetMethod("Run").GetCustomAttributes(false)
let attr = attrs.[0] :?> System.ServiceModel.FaultContractAttribute
printfn "%A" (attr.ProtectionLevel.ToString())
\ No newline at end of file
NoMT SOURCE=mirror.fs SCFLAGS="-a ..\\providedtypes.fs" PRECMD="\$CSC_PIPE /target:library library.cs" # Attribute_Arg_Type_Scope_Setup
NoMT SOURCE=client.fs SCFLAGS="-r:mirror.dll -r:System.ServiceModel.dll" # Attribute_Arg_Type_Scope_Test
mirror.dll
library.dll
\ No newline at end of file
using System;
using System.Net.Security;
using System.ServiceModel;
public class C {
[FaultContract(typeof(Exception), ProtectionLevel = ProtectionLevel.Sign)]
public static void Run() { Console.WriteLine("In run");}
}
\ No newline at end of file
// compile as: fsc --target:library ProvidedTypes.fsi ProvidedTypes.fs Mirror.fs
namespace Repro
open System.IO
open System.Reflection
open ProviderImplementation.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices
[<assembly : TypeProviderAssembly>]
do()
[<TypeProvider>]
type Mirror() as this =
inherit TypeProviderForNamespaces()
let thisAssembly = typeof<Mirror>.Assembly
let topType = ProvidedTypeDefinition(thisAssembly, "Top", "Repro", Some typeof<obj>, IsErased = true)
let csAssembly =
let location = Path.GetDirectoryName(thisAssembly.Location)
System.Reflection.Assembly.LoadFrom(Path.Combine(location, "library.dll"))
do topType.AddAssemblyTypesAsNestedTypesDelayed(fun() -> csAssembly)
do this.AddNamespace("Top", [topType])
\ No newline at end of file
此差异已折叠。
......@@ -238,6 +238,7 @@ Conformance08 Conformance\UnitsOfMeasure\WithOOP
NoHostedCompiler,TypeProviders01 TypeProviders\Arrays
NoHostedCompiler,TypeProviders01 TypeProviders\Attributes
NoHostedCompiler,TypeProviders01 ..\..\..\testsprivate\fsharpqa\Source\TypeProviders\BuiltIn\EdmxFile
NoHostedCompiler,TypeProviders01 TypeProviders\BuiltIn\OdataService\Diagnostics
NoHostedCompiler,TypeProviders01 TypeProviders\BuiltIn\OdataService\StaticParam
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册