//internal void DecodeSecurityAttribute<T>(Symbol targetSymbol, PhpCompilation compilation, ref DecodeWellKnownAttributeArguments<AttributeSyntax, BaseAttributeData, AttributeLocation> arguments)
        //    where T : WellKnownAttributeData, ISecurityAttributeTarget, new()
        //{
        //    Debug.Assert(!this.HasErrors);

        //    bool hasErrors;
        //    DeclarativeSecurityAction action = DecodeSecurityAttributeAction(targetSymbol, compilation, arguments.AttributeSyntaxOpt, out hasErrors, arguments.Diagnostics);

        //    if (!hasErrors)
        //    {
        //        T data = arguments.GetOrCreateData<T>();
        //        SecurityWellKnownAttributeData securityData = data.GetOrCreateData();
        //        securityData.SetSecurityAttribute(arguments.Index, action, arguments.AttributesCount);

        //        if (this.IsTargetAttribute(targetSymbol, AttributeDescription.PermissionSetAttribute))
        //        {
        //            string resolvedPathForFixup = DecodePermissionSetAttribute(compilation, arguments.AttributeSyntaxOpt, arguments.Diagnostics);
        //            if (resolvedPathForFixup != null)
        //            {
        //                securityData.SetPathForPermissionSetAttributeFixup(arguments.Index, resolvedPathForFixup, arguments.AttributesCount);
        //            }
        //        }
        //    }
        //}

        //private DeclarativeSecurityAction DecodeSecurityAttributeAction(Symbol targetSymbol, PhpCompilation compilation, AttributeSyntax nodeOpt, out bool hasErrors, DiagnosticBag diagnostics)
        //{
        //    Debug.Assert((object)targetSymbol != null);
        //    Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method);
        //    Debug.Assert(this.IsSecurityAttribute(compilation));

        //    var ctorArgs = this.CommonConstructorArguments;
        //    if (!ctorArgs.Any())
        //    {
        //        // NOTE:    Security custom attributes must have a valid SecurityAction as its first argument, we have none here.
        //        // NOTE:    Ideally, we should always generate 'CS7048: First argument to a security attribute must be a valid SecurityAction' for this case.
        //        // NOTE:    However, native compiler allows applying System.Security.Permissions.HostProtectionAttribute attribute without any argument and uses
        //        // NOTE:    SecurityAction.LinkDemand as the default SecurityAction in this case. We maintain compatibility with the native compiler for this case.

        //        // BREAKING CHANGE: Even though the native compiler intends to allow only HostProtectionAttribute to be applied without any arguments,
        //        //                  it doesn't quite do this correctly

        //        // The implementation issue leads to the native compiler allowing any user defined security attribute with a parameterless constructor and a named property argument as the first
        //        // attribute argument to have the above mentioned behavior, even though the comment clearly mentions that this behavior was intended only for the HostProtectionAttribute.
        //        // We currently allow this case only for the HostProtectionAttribute. In future if need arises, we can exactly match native compiler's behavior.

        //        if (this.IsTargetAttribute(targetSymbol, AttributeDescription.HostProtectionAttribute))
        //        {
        //            hasErrors = false;
        //            return DeclarativeSecurityAction.LinkDemand;
        //        }
        //    }
        //    else
        //    {
        //        TypedConstant firstArg = ctorArgs.First();
        //        TypeSymbol firstArgType = (TypeSymbol)firstArg.Type;
        //        if ((object)firstArgType != null && firstArgType.Equals(compilation.GetWellKnownType(WellKnownType.System_Security_Permissions_SecurityAction)))
        //        {
        //            return DecodeSecurityAction(firstArg, targetSymbol, nodeOpt, diagnostics, out hasErrors);
        //        }
        //    }

        //    // CS7048: First argument to a security attribute must be a valid SecurityAction
        //    diagnostics.Add(ErrorCode.ERR_SecurityAttributeMissingAction, nodeOpt != null ? nodeOpt.Name.Location : NoLocation.Singleton);
        //    hasErrors = true;
        //    return DeclarativeSecurityAction.None;
        //}

        //private DeclarativeSecurityAction DecodeSecurityAction(TypedConstant typedValue, Symbol targetSymbol, AttributeSyntax nodeOpt, DiagnosticBag diagnostics, out bool hasErrors)
        //{
        //    Debug.Assert((object)targetSymbol != null);
        //    Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method);

        //    int securityAction = (int)typedValue.Value;
        //    bool isPermissionRequestAction;

        //    switch (securityAction)
        //    {
        //        case (int)DeclarativeSecurityAction.InheritanceDemand:
        //        case (int)DeclarativeSecurityAction.LinkDemand:
        //            if (this.IsTargetAttribute(targetSymbol, AttributeDescription.PrincipalPermissionAttribute))
        //            {
        //                // CS7052: SecurityAction value '{0}' is invalid for PrincipalPermission attribute
        //                string displayString;
        //                Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //                diagnostics.Add(ErrorCode.ERR_PrincipalPermissionInvalidAction, syntaxLocation, displayString);
        //                hasErrors = true;
        //                return DeclarativeSecurityAction.None;
        //            }

        //            isPermissionRequestAction = false;
        //            break;

        //        case 1:
        //        // Native compiler allows security action value 1 for security attributes on types/methods, even though there is no corresponding field in System.Security.Permissions.SecurityAction enum.
        //        // We will maintain compatibility.

        //        case (int)DeclarativeSecurityAction.Assert:
        //        case (int)DeclarativeSecurityAction.Demand:
        //        case (int)DeclarativeSecurityAction.PermitOnly:
        //        case (int)DeclarativeSecurityAction.Deny:
        //            isPermissionRequestAction = false;
        //            break;

        //        case (int)DeclarativeSecurityAction.RequestMinimum:
        //        case (int)DeclarativeSecurityAction.RequestOptional:
        //        case (int)DeclarativeSecurityAction.RequestRefuse:
        //            isPermissionRequestAction = true;
        //            break;

        //        default:
        //            {
        //                // CS7049: Security attribute '{0}' has an invalid SecurityAction value '{1}'
        //                string displayString;
        //                Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //                diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidAction, syntaxLocation, nodeOpt != null ? nodeOpt.GetErrorDisplayName() : "", displayString);
        //                hasErrors = true;
        //                return DeclarativeSecurityAction.None;
        //            }
        //    }

        //    // Validate security action for symbol kind
        //    if (isPermissionRequestAction)
        //    {
        //        if (targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method)
        //        {
        //            // Types and methods cannot take permission requests.

        //            // CS7051: SecurityAction value '{0}' is invalid for security attributes applied to a type or a method
        //            string displayString;
        //            Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //            diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionTypeOrMethod, syntaxLocation, displayString);
        //            hasErrors = true;
        //            return DeclarativeSecurityAction.None;
        //        }
        //    }
        //    else
        //    {
        //        if (targetSymbol.Kind == SymbolKind.Assembly)
        //        {
        //            // Assemblies cannot take declarative security.

        //            // CS7050: SecurityAction value '{0}' is invalid for security attributes applied to an assembly
        //            string displayString;
        //            Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //            diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionAssembly, syntaxLocation, displayString);
        //            hasErrors = true;
        //            return DeclarativeSecurityAction.None;
        //        }
        //    }

        //    hasErrors = false;
        //    return (DeclarativeSecurityAction)securityAction;
        //}

        //private static Location GetSecurityAttributeActionSyntaxLocation(AttributeSyntax nodeOpt, TypedConstant typedValue, out string displayString)
        //{
        //    if (nodeOpt == null)
        //    {
        //        displayString = "";
        //        return NoLocation.Singleton;
        //    }

        //    var argList = nodeOpt.ArgumentList;
        //    if (argList == null || argList.Arguments.IsEmpty())
        //    {
        //        // Optional SecurityAction parameter with default value.
        //        displayString = typedValue.Value.ToString();
        //        return nodeOpt.Location;
        //    }

        //    AttributeArgumentSyntax argSyntax = argList.Arguments[0];
        //    displayString = argSyntax.ToString();
        //    return argSyntax.Location;
        //}

        ///// <summary>
        ///// Decodes PermissionSetAttribute applied in source to determine if it needs any fixup during codegen.
        ///// </summary>
        ///// <remarks>
        ///// PermissionSetAttribute needs fixup when it contains an assignment to the 'File' property as a single named attribute argument.
        ///// Fixup performed is ported from SecurityAttributes::FixUpPermissionSetAttribute.
        ///// It involves following steps:
        /////  1) Verifying that the specified file name resolves to a valid path.
        /////  2) Reading the contents of the file into a byte array.
        /////  3) Convert each byte in the file content into two bytes containing hexadecimal characters.
        /////  4) Replacing the 'File = fileName' named argument with 'Hex = hexFileContent' argument, where hexFileContent is the converted output from step 3) above.
        /////
        ///// Step 1) is performed in this method, i.e. during binding.
        ///// Remaining steps are performed during serialization as we want to avoid retaining the entire file contents throughout the binding/codegen pass.
        ///// See <see cref="Microsoft.CodeAnalysis.CodeGen.PermissionSetAttributeWithFileReference"/> for remaining fixup steps.
        ///// </remarks>
        ///// <returns>String containing the resolved file path if PermissionSetAttribute needs fixup during codegen, null otherwise.</returns>
        //private string DecodePermissionSetAttribute(PhpCompilation compilation, AttributeSyntax nodeOpt, DiagnosticBag diagnostics)
        //{
        //    Debug.Assert(!this.HasErrors);

        //    string resolvedFilePath = null;
        //    var namedArgs = this.CommonNamedArguments;

        //    if (namedArgs.Length == 1)
        //    {
        //        var namedArg = namedArgs[0];
        //        NamedTypeSymbol attrType = this.AttributeClass;
        //        string filePropName = PermissionSetAttributeWithFileReference.FilePropertyName;
        //        string hexPropName = PermissionSetAttributeWithFileReference.HexPropertyName;

        //        if (namedArg.Key == filePropName &&
        //            PermissionSetAttributeTypeHasRequiredProperty(attrType, filePropName))
        //        {
        //            // resolve file prop path
        //            var fileName = (string)namedArg.Value.Value;
        //            var resolver = compilation.Options.XmlReferenceResolver;

        //            resolvedFilePath = (resolver != null) ? resolver.ResolveReference(fileName, baseFilePath: null) : null;

        //            if (resolvedFilePath == null)
        //            {
        //                // CS7053: Unable to resolve file path '{0}' specified for the named argument '{1}' for PermissionSet attribute
        //                Location argSyntaxLocation = nodeOpt != null ? nodeOpt.GetNamedArgumentSyntax(filePropName).Location : NoLocation.Singleton;
        //                diagnostics.Add(ErrorCode.ERR_PermissionSetAttributeInvalidFile, argSyntaxLocation, fileName ?? "<null>", filePropName);
        //            }
        //            else if (!PermissionSetAttributeTypeHasRequiredProperty(attrType, hexPropName))
        //            {
        //                // PermissionSetAttribute was defined in user source, but doesn't have the required Hex property.
        //                // Native compiler still emits the file content as named assignment to 'Hex' property, but this leads to a runtime exception.
        //                // We instead skip the fixup and emit the file property.

        //                // CONSIDER: We may want to consider taking a breaking change and generating an error here.

        //                return null;
        //            }
        //        }
        //    }

        //    return resolvedFilePath;
        //}

        // This method checks if the given PermissionSetAttribute type has a property member with the given propName which is writable, non-generic, public and of string type.
        private static bool PermissionSetAttributeTypeHasRequiredProperty(NamedTypeSymbol permissionSetType, string propName)
        {
            var members = permissionSetType.GetMembers(propName);

            if (members.Length == 1 && members[0].Kind == SymbolKind.Property)
            {
                var property = (PropertySymbol)members[0];
                if ((object)property.Type != null && property.Type.SpecialType == SpecialType.System_String &&
                    property.DeclaredAccessibility == Accessibility.Public && property.GetMemberArity() == 0 &&
                    (object)property.SetMethod != null && property.SetMethod.DeclaredAccessibility == Accessibility.Public)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#2
0
        public static MethodSymbol ResolveMethodImplementation(MethodSymbol method, NamedTypeSymbol type)
        {
            while (type != null)
            {
                var candidates = type.GetMembers(method.RoutineName).OfType <MethodSymbol>().Where(CanOverride);
                var resolved   = ResolveMethodImplementation(method, candidates);
                if (resolved != null)
                {
                    return(resolved);
                }

                //
                type = type.BaseType;
            }

            //
            return(null);
        }
        public static MethodSymbol ResolveMethodImplementation(MethodSymbol method, NamedTypeSymbol type)
        {
            for (; type != null; type = type.BaseType)
            {
                var members = type.GetMembersByPhpName(method.RoutineName).OfType <MethodSymbol>().Where(CanOverride);
                if (method.ContainingType.IsInterface)
                {
                    // check explicit interface override
                    members = members.Concat(type.GetMembers(method.ContainingType.GetFullName() + "." + method.RoutineName).OfType <MethodSymbol>());
                }

                var resolved = ResolveMethodImplementation(method, members);
                if (resolved != null)
                {
                    return(resolved);
                }
            }

            //
            return(null);
        }
示例#4
0
        public static MethodSymbol ResolveMethodImplementation(MethodSymbol method, NamedTypeSymbol type)
        {
            // ignoring System.Object (we don't override its methods from PHP)
            bool ignoreSystemObject = method.ContainingType.IsPhpType();

            for (; type != null; type = type.BaseType)
            {
                if (ignoreSystemObject && type.SpecialType == SpecialType.System_Object)
                {
                    break;
                }

                var resolved = ResolveMethodImplementation(method, type.GetMembers());
                if (resolved != null)
                {
                    return(resolved);
                }
            }

            //
            return(null);
        }
示例#5
0
        public static MethodSymbol ResolveMethodImplementation(MethodSymbol method, NamedTypeSymbol type)
        {
            // ignoring System.Object (we don't override its methods from PHP)

            for (; type != null && type.SpecialType != SpecialType.System_Object; type = type.BaseType)
            {
                var members = type.GetMembersByPhpName(method.RoutineName).OfType <MethodSymbol>().Where(CanOverride);
                if (method.ContainingType.IsInterface)
                {
                    // check explicit interface override
                    members = members.Concat(type.GetMembers(method.ContainingType.GetFullName() + "." + method.RoutineName).OfType <MethodSymbol>());
                }

                var resolved = ResolveMethodImplementation(method, members);
                if (resolved != null)
                {
                    return(resolved);
                }
            }

            //
            return(null);
        }
示例#6
0
        //internal void DecodeSecurityAttribute<T>(Symbol targetSymbol, PhpCompilation compilation, ref DecodeWellKnownAttributeArguments<AttributeSyntax, BaseAttributeData, AttributeLocation> arguments)
        //    where T : WellKnownAttributeData, ISecurityAttributeTarget, new()
        //{
        //    Debug.Assert(!this.HasErrors);

        //    bool hasErrors;
        //    DeclarativeSecurityAction action = DecodeSecurityAttributeAction(targetSymbol, compilation, arguments.AttributeSyntaxOpt, out hasErrors, arguments.Diagnostics);

        //    if (!hasErrors)
        //    {
        //        T data = arguments.GetOrCreateData<T>();
        //        SecurityWellKnownAttributeData securityData = data.GetOrCreateData();
        //        securityData.SetSecurityAttribute(arguments.Index, action, arguments.AttributesCount);

        //        if (this.IsTargetAttribute(targetSymbol, AttributeDescription.PermissionSetAttribute))
        //        {
        //            string resolvedPathForFixup = DecodePermissionSetAttribute(compilation, arguments.AttributeSyntaxOpt, arguments.Diagnostics);
        //            if (resolvedPathForFixup != null)
        //            {
        //                securityData.SetPathForPermissionSetAttributeFixup(arguments.Index, resolvedPathForFixup, arguments.AttributesCount);
        //            }
        //        }
        //    }
        //}

        //private DeclarativeSecurityAction DecodeSecurityAttributeAction(Symbol targetSymbol, PhpCompilation compilation, AttributeSyntax nodeOpt, out bool hasErrors, DiagnosticBag diagnostics)
        //{
        //    Debug.Assert((object)targetSymbol != null);
        //    Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method);
        //    Debug.Assert(this.IsSecurityAttribute(compilation));

        //    var ctorArgs = this.CommonConstructorArguments;
        //    if (!ctorArgs.Any())
        //    {
        //        // NOTE:    Security custom attributes must have a valid SecurityAction as its first argument, we have none here.
        //        // NOTE:    Ideally, we should always generate 'CS7048: First argument to a security attribute must be a valid SecurityAction' for this case.
        //        // NOTE:    However, native compiler allows applying System.Security.Permissions.HostProtectionAttribute attribute without any argument and uses 
        //        // NOTE:    SecurityAction.LinkDemand as the default SecurityAction in this case. We maintain compatibility with the native compiler for this case.

        //        // BREAKING CHANGE: Even though the native compiler intends to allow only HostProtectionAttribute to be applied without any arguments,
        //        //                  it doesn't quite do this correctly 

        //        // The implementation issue leads to the native compiler allowing any user defined security attribute with a parameterless constructor and a named property argument as the first
        //        // attribute argument to have the above mentioned behavior, even though the comment clearly mentions that this behavior was intended only for the HostProtectionAttribute.
        //        // We currently allow this case only for the HostProtectionAttribute. In future if need arises, we can exactly match native compiler's behavior.

        //        if (this.IsTargetAttribute(targetSymbol, AttributeDescription.HostProtectionAttribute))
        //        {
        //            hasErrors = false;
        //            return DeclarativeSecurityAction.LinkDemand;
        //        }
        //    }
        //    else
        //    {
        //        TypedConstant firstArg = ctorArgs.First();
        //        TypeSymbol firstArgType = (TypeSymbol)firstArg.Type;
        //        if ((object)firstArgType != null && firstArgType.Equals(compilation.GetWellKnownType(WellKnownType.System_Security_Permissions_SecurityAction)))
        //        {
        //            return DecodeSecurityAction(firstArg, targetSymbol, nodeOpt, diagnostics, out hasErrors);
        //        }
        //    }

        //    // CS7048: First argument to a security attribute must be a valid SecurityAction
        //    diagnostics.Add(ErrorCode.ERR_SecurityAttributeMissingAction, nodeOpt != null ? nodeOpt.Name.Location : NoLocation.Singleton);
        //    hasErrors = true;
        //    return DeclarativeSecurityAction.None;
        //}

        //private DeclarativeSecurityAction DecodeSecurityAction(TypedConstant typedValue, Symbol targetSymbol, AttributeSyntax nodeOpt, DiagnosticBag diagnostics, out bool hasErrors)
        //{
        //    Debug.Assert((object)targetSymbol != null);
        //    Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method);

        //    int securityAction = (int)typedValue.Value;
        //    bool isPermissionRequestAction;

        //    switch (securityAction)
        //    {
        //        case (int)DeclarativeSecurityAction.InheritanceDemand:
        //        case (int)DeclarativeSecurityAction.LinkDemand:
        //            if (this.IsTargetAttribute(targetSymbol, AttributeDescription.PrincipalPermissionAttribute))
        //            {
        //                // CS7052: SecurityAction value '{0}' is invalid for PrincipalPermission attribute
        //                string displayString;
        //                Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //                diagnostics.Add(ErrorCode.ERR_PrincipalPermissionInvalidAction, syntaxLocation, displayString);
        //                hasErrors = true;
        //                return DeclarativeSecurityAction.None;
        //            }

        //            isPermissionRequestAction = false;
        //            break;

        //        case 1:
        //        // Native compiler allows security action value 1 for security attributes on types/methods, even though there is no corresponding field in System.Security.Permissions.SecurityAction enum.
        //        // We will maintain compatibility.

        //        case (int)DeclarativeSecurityAction.Assert:
        //        case (int)DeclarativeSecurityAction.Demand:
        //        case (int)DeclarativeSecurityAction.PermitOnly:
        //        case (int)DeclarativeSecurityAction.Deny:
        //            isPermissionRequestAction = false;
        //            break;

        //        case (int)DeclarativeSecurityAction.RequestMinimum:
        //        case (int)DeclarativeSecurityAction.RequestOptional:
        //        case (int)DeclarativeSecurityAction.RequestRefuse:
        //            isPermissionRequestAction = true;
        //            break;

        //        default:
        //            {
        //                // CS7049: Security attribute '{0}' has an invalid SecurityAction value '{1}'
        //                string displayString;
        //                Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //                diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidAction, syntaxLocation, nodeOpt != null ? nodeOpt.GetErrorDisplayName() : "", displayString);
        //                hasErrors = true;
        //                return DeclarativeSecurityAction.None;
        //            }
        //    }

        //    // Validate security action for symbol kind
        //    if (isPermissionRequestAction)
        //    {
        //        if (targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method)
        //        {
        //            // Types and methods cannot take permission requests.

        //            // CS7051: SecurityAction value '{0}' is invalid for security attributes applied to a type or a method
        //            string displayString;
        //            Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //            diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionTypeOrMethod, syntaxLocation, displayString);
        //            hasErrors = true;
        //            return DeclarativeSecurityAction.None;
        //        }
        //    }
        //    else
        //    {
        //        if (targetSymbol.Kind == SymbolKind.Assembly)
        //        {
        //            // Assemblies cannot take declarative security.

        //            // CS7050: SecurityAction value '{0}' is invalid for security attributes applied to an assembly
        //            string displayString;
        //            Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString);
        //            diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionAssembly, syntaxLocation, displayString);
        //            hasErrors = true;
        //            return DeclarativeSecurityAction.None;
        //        }
        //    }

        //    hasErrors = false;
        //    return (DeclarativeSecurityAction)securityAction;
        //}

        //private static Location GetSecurityAttributeActionSyntaxLocation(AttributeSyntax nodeOpt, TypedConstant typedValue, out string displayString)
        //{
        //    if (nodeOpt == null)
        //    {
        //        displayString = "";
        //        return NoLocation.Singleton;
        //    }

        //    var argList = nodeOpt.ArgumentList;
        //    if (argList == null || argList.Arguments.IsEmpty())
        //    {
        //        // Optional SecurityAction parameter with default value.
        //        displayString = typedValue.Value.ToString();
        //        return nodeOpt.Location;
        //    }

        //    AttributeArgumentSyntax argSyntax = argList.Arguments[0];
        //    displayString = argSyntax.ToString();
        //    return argSyntax.Location;
        //}

        ///// <summary>
        ///// Decodes PermissionSetAttribute applied in source to determine if it needs any fixup during codegen.
        ///// </summary>
        ///// <remarks>
        ///// PermissionSetAttribute needs fixup when it contains an assignment to the 'File' property as a single named attribute argument.
        ///// Fixup performed is ported from SecurityAttributes::FixUpPermissionSetAttribute.
        ///// It involves following steps:
        /////  1) Verifying that the specified file name resolves to a valid path.
        /////  2) Reading the contents of the file into a byte array.
        /////  3) Convert each byte in the file content into two bytes containing hexadecimal characters.
        /////  4) Replacing the 'File = fileName' named argument with 'Hex = hexFileContent' argument, where hexFileContent is the converted output from step 3) above.
        /////
        ///// Step 1) is performed in this method, i.e. during binding.
        ///// Remaining steps are performed during serialization as we want to avoid retaining the entire file contents throughout the binding/codegen pass.
        ///// See <see cref="Microsoft.CodeAnalysis.CodeGen.PermissionSetAttributeWithFileReference"/> for remaining fixup steps.
        ///// </remarks>
        ///// <returns>String containing the resolved file path if PermissionSetAttribute needs fixup during codegen, null otherwise.</returns>
        //private string DecodePermissionSetAttribute(PhpCompilation compilation, AttributeSyntax nodeOpt, DiagnosticBag diagnostics)
        //{
        //    Debug.Assert(!this.HasErrors);

        //    string resolvedFilePath = null;
        //    var namedArgs = this.CommonNamedArguments;

        //    if (namedArgs.Length == 1)
        //    {
        //        var namedArg = namedArgs[0];
        //        NamedTypeSymbol attrType = this.AttributeClass;
        //        string filePropName = PermissionSetAttributeWithFileReference.FilePropertyName;
        //        string hexPropName = PermissionSetAttributeWithFileReference.HexPropertyName;

        //        if (namedArg.Key == filePropName &&
        //            PermissionSetAttributeTypeHasRequiredProperty(attrType, filePropName))
        //        {
        //            // resolve file prop path
        //            var fileName = (string)namedArg.Value.Value;
        //            var resolver = compilation.Options.XmlReferenceResolver;

        //            resolvedFilePath = (resolver != null) ? resolver.ResolveReference(fileName, baseFilePath: null) : null;

        //            if (resolvedFilePath == null)
        //            {
        //                // CS7053: Unable to resolve file path '{0}' specified for the named argument '{1}' for PermissionSet attribute
        //                Location argSyntaxLocation = nodeOpt != null ? nodeOpt.GetNamedArgumentSyntax(filePropName).Location : NoLocation.Singleton;
        //                diagnostics.Add(ErrorCode.ERR_PermissionSetAttributeInvalidFile, argSyntaxLocation, fileName ?? "<null>", filePropName);
        //            }
        //            else if (!PermissionSetAttributeTypeHasRequiredProperty(attrType, hexPropName))
        //            {
        //                // PermissionSetAttribute was defined in user source, but doesn't have the required Hex property.
        //                // Native compiler still emits the file content as named assignment to 'Hex' property, but this leads to a runtime exception.
        //                // We instead skip the fixup and emit the file property.

        //                // CONSIDER: We may want to consider taking a breaking change and generating an error here.

        //                return null;
        //            }
        //        }
        //    }

        //    return resolvedFilePath;
        //}

        // This method checks if the given PermissionSetAttribute type has a property member with the given propName which is writable, non-generic, public and of string type.
        private static bool PermissionSetAttributeTypeHasRequiredProperty(NamedTypeSymbol permissionSetType, string propName)
        {
            var members = permissionSetType.GetMembers(propName);
            if (members.Length == 1 && members[0].Kind == SymbolKind.Property)
            {
                var property = (PropertySymbol)members[0];
                if ((object)property.Type != null && property.Type.SpecialType == SpecialType.System_String &&
                    property.DeclaredAccessibility == Accessibility.Public && property.GetMemberArity() == 0 &&
                    (object)property.SetMethod != null && property.SetMethod.DeclaredAccessibility == Accessibility.Public)
                {
                    return true;
                }
            }

            return false;
        }