예제 #1
0
        /// <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="StarkPlatform.Compiler.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(CSharpCompilation 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);
        }