示例#1
0
        protected internal override void ProcessExternalResource(
            IResourceBuildHelper helper,
            string url,
            out string preProcessed,
            out string compacted,
            List <ParseException> errors)
        {
            compacted = preProcessed = String.Empty;

            Uri uri;

            if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
            {
                throw new ArgumentException("Invalid external URL");
            }

            string       ext      = Path.GetExtension(uri.AbsolutePath).Trim('.');
            CompilerType compiler = helper.GetDefaultCompilerTypeForLanguage(ext);

            if (!typeof(ResourceCodeProvider).IsAssignableFrom(compiler.CodeDomProviderType))
            {
                // don't know how to process any further
                return;
            }

            ResourceCodeProvider provider = (ResourceCodeProvider)Activator.CreateInstance(compiler.CodeDomProviderType);

            try
            {
                // concatenate the preprocessed source for current merge phase
                provider.ProcessExternalResource(
                    helper,
                    url,
                    out preProcessed,
                    out compacted,
                    errors);
            }
            catch (ParseException ex)
            {
                errors.Add(ex);
            }
            catch (Exception ex)
            {
                errors.Add(new ParseError(ex.Message, url, 0, 0, ex));
            }

            if (!this.isMimeSet &&
                !String.IsNullOrEmpty(provider.ContentType) &&
                !String.IsNullOrEmpty(provider.FileExtension))
            {
                this.contentType   = provider.ContentType;
                this.fileExtension = provider.FileExtension;
                this.isMimeSet     = true;
            }
        }
        public override void GenerateCode(AssemblyBuilder assemblyBuilder)
        {
            string contentType, fileExtension;
            string originalSource, prettyPrintResource, compactedResource;

            ResourceCodeProvider provider = assemblyBuilder.CodeDomProvider as ResourceCodeProvider;

            if (provider != null)
            {
                originalSource = provider.CompileResource(
                    this,
                    base.VirtualPath,
                    out prettyPrintResource,
                    out compactedResource);

                contentType   = provider.ContentType;
                fileExtension = provider.FileExtension;
            }
            else
            {
                // read the resource contents
                using (TextReader reader = this.OpenReader())
                {
                    originalSource = compactedResource = prettyPrintResource = reader.ReadToEnd();
                }

                contentType   = "text/plain";
                fileExtension = "txt";
            }

            IResourceNameGenerator nameGenerator = assemblyBuilder.CodeDomProvider as IResourceNameGenerator;

            if (nameGenerator != null)
            {
                this.ResourceFullName = nameGenerator.GenerateResourceName(base.VirtualPath);
            }
            else
            {
                this.ResourceFullName = ResourceBuildProvider.GenerateTypeNameFromPath(base.VirtualPath);
            }

            byte[] gzippedBytes, deflatedBytes;
            ResourceBuildProvider.Compress(compactedResource, out gzippedBytes, out deflatedBytes);
            string hash = ResourceBuildProvider.ComputeHash(compactedResource);

            // generate a resource container
            CodeCompileUnit generatedUnit = new CodeCompileUnit();

            #region namespace ResourceNamespace

            CodeNamespace ns = new CodeNamespace(this.ResourceNamespace);
            generatedUnit.Namespaces.Add(ns);

            #endregion namespace ResourceNamespace

            #region public sealed class ResourceTypeName

            CodeTypeDeclaration resourceType = new CodeTypeDeclaration();
            resourceType.IsClass    = true;
            resourceType.Name       = this.ResourceTypeName;
            resourceType.Attributes = MemberAttributes.Public | MemberAttributes.Final;

            provider.SetBaseClass(resourceType);

            resourceType.BaseTypes.Add(typeof(IOptimizedResult));
            ns.Types.Add(resourceType);

            #endregion public sealed class ResourceTypeName

            #region [BuildPath(virtualPath)]

            string virtualPath = base.VirtualPath;
            if (HttpRuntime.AppDomainAppVirtualPath.Length > 1)
            {
                virtualPath = virtualPath.Substring(HttpRuntime.AppDomainAppVirtualPath.Length);
            }
            virtualPath = "~" + virtualPath;

            CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(
                new CodeTypeReference(typeof(BuildPathAttribute)),
                new CodeAttributeArgument(new CodePrimitiveExpression(virtualPath)));
            resourceType.CustomAttributes.Add(attribute);

            #endregion [BuildPath(virtualPath)]

            #region private static readonly byte[] GzippedBytes

            CodeMemberField field = new CodeMemberField();
            field.Name       = "GzippedBytes";
            field.Type       = new CodeTypeReference(typeof(byte[]));
            field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

            CodeArrayCreateExpression arrayInit = new CodeArrayCreateExpression(field.Type, gzippedBytes.Length);
            foreach (byte b in gzippedBytes)
            {
                arrayInit.Initializers.Add(new CodePrimitiveExpression(b));
            }
            field.InitExpression = arrayInit;

            resourceType.Members.Add(field);

            #endregion private static static readonly byte[] GzippedBytes

            #region private static readonly byte[] DeflatedBytes;

            field            = new CodeMemberField();
            field.Name       = "DeflatedBytes";
            field.Type       = new CodeTypeReference(typeof(byte[]));
            field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

            arrayInit = new CodeArrayCreateExpression(field.Type, deflatedBytes.Length);
            foreach (byte b in deflatedBytes)
            {
                arrayInit.Initializers.Add(new CodePrimitiveExpression(b));
            }
            field.InitExpression = arrayInit;

            resourceType.Members.Add(field);

            #endregion private static readonly byte[] DeflatedBytes;

            #region string IOptimizedResult.Source { get; }

            // add a readonly property with the original resource source
            CodeMemberProperty property = new CodeMemberProperty();
            property.Name = "Source";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return originalSource; }
            if (originalSource == null || originalSource.Length <= 0x5DC)
            {
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(originalSource)));
            }
            else
            {
                string escaped = ResourceBuildProvider.QuoteSnippetStringCStyle(originalSource);
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(escaped)));
            }
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.Source { get; }

            #region string IOptimizedResult.PrettyPrinted { get; }

            // add a readonly property with the resource data
            property      = new CodeMemberProperty();
            property.Name = "PrettyPrinted";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;

            if (String.Equals(originalSource, prettyPrintResource))
            {
                // get { return ((IOptimizedResult)this).Source; }
                CodeExpression thisRef = new CodeCastExpression(typeof(IOptimizedResult), new CodeThisReferenceExpression());
                CodePropertyReferenceExpression sourceProperty = new CodePropertyReferenceExpression(thisRef, "Source");
                property.GetStatements.Add(new CodeMethodReturnStatement(sourceProperty));
            }
            else
            {
                // get { return prettyPrintResource; }
                if (prettyPrintResource == null || prettyPrintResource.Length <= 0x5DC)
                {
                    property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(prettyPrintResource)));
                }
                else
                {
                    string escaped = ResourceBuildProvider.QuoteSnippetStringCStyle(prettyPrintResource);
                    property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(escaped)));
                }
            }
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.PrettyPrinted { get; }

            #region string IOptimizedResult.Compacted { get; }

            // add a readonly property with the compacted resource data
            property      = new CodeMemberProperty();
            property.Name = "Compacted";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return compactedResource; }
            if (compactedResource == null || compactedResource.Length <= 0x5DC)
            {
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(compactedResource)));
            }
            else
            {
                string escaped = ResourceBuildProvider.QuoteSnippetStringCStyle(compactedResource);
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(escaped)));
            }
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.Compacted { get; }

            #region byte[] IOptimizedResult.Gzipped { get; }

            // add a readonly property with the gzipped resource data
            property      = new CodeMemberProperty();
            property.Name = "Gzipped";
            property.Type = new CodeTypeReference(typeof(byte[]));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return GzippedBytes; }
            property.GetStatements.Add(new CodeMethodReturnStatement(
                                           new CodeFieldReferenceExpression(
                                               new CodeTypeReferenceExpression(this.ResourceTypeName),
                                               "GzippedBytes")));
            resourceType.Members.Add(property);

            #endregion byte[] IOptimizedResult.Gzipped { get; }

            #region byte[] IOptimizedResult.Deflated { get; }

            // add a readonly property with the deflated resource data
            property      = new CodeMemberProperty();
            property.Name = "Deflated";
            property.Type = new CodeTypeReference(typeof(byte[]));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return DeflatedBytes; }
            property.GetStatements.Add(new CodeMethodReturnStatement(
                                           new CodeFieldReferenceExpression(
                                               new CodeTypeReferenceExpression(this.ResourceTypeName),
                                               "DeflatedBytes")));
            resourceType.Members.Add(property);

            #endregion byte[] IOptimizedResult.Deflated { get; }

            #region string IBuildResultMeta.ContentType { get; }

            // add a readonly property with the MIME type
            property      = new CodeMemberProperty();
            property.Name = "ContentType";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return contentType; }
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(contentType)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.ContentType { get; }

            #region string IBuildResultMeta.FileExtension { get; }

            // add a readonly property with the MIME type
            property      = new CodeMemberProperty();
            property.Name = "FileExtension";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return fileExtension; }
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(fileExtension)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.FileExtension { get; }

            #region string IBuildResultMeta.Hash { get; }

            // add a readonly property with the resource data
            property      = new CodeMemberProperty();
            property.Name = "Hash";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return hash); }

            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(hash)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.Hash { get; }

            if (this.VirtualPathDependencies.Count > 0)
            {
                resourceType.BaseTypes.Add(typeof(IDependentResult));

                #region private static readonly string[] Dependencies

                field            = new CodeMemberField();
                field.Name       = "Dependencies";
                field.Type       = new CodeTypeReference(typeof(string[]));
                field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

                arrayInit = new CodeArrayCreateExpression(field.Type, this.VirtualPathDependencies.Count);
                foreach (string key in this.VirtualPathDependencies)
                {
                    arrayInit.Initializers.Add(new CodePrimitiveExpression(key));
                }
                field.InitExpression = arrayInit;

                resourceType.Members.Add(field);

                #endregion private static readonly string[] Dependencies

                #region IEnumerable<string> IDependentResult.VirtualPathDependencies { get; }

                // add a readonly property returning the static data
                property      = new CodeMemberProperty();
                property.Name = "VirtualPathDependencies";
                property.Type = new CodeTypeReference(typeof(IEnumerable <string>));
                property.PrivateImplementationType = new CodeTypeReference(typeof(IDependentResult));
                property.HasGet = true;
                // get { return Dependencies; }
                property.GetStatements.Add(new CodeMethodReturnStatement(
                                               new CodeFieldReferenceExpression(
                                                   new CodeTypeReferenceExpression(resourceType.Name),
                                                   "Dependencies")));
                resourceType.Members.Add(property);

                #endregion IEnumerable<string> IDependentResult.VirtualPathDependencies { get; }
            }

            // allow the code provider to extend with additional properties
            provider.GenerateCodeExtensions(this, resourceType);

            // Generate _ASP FastObjectFactory
            assemblyBuilder.GenerateTypeFactory(this.ResourceFullName);

            assemblyBuilder.AddCodeCompileUnit(this, generatedUnit);
        }
示例#3
0
        private void ProcessEmbeddedResource(
            IResourceBuildHelper helper,
            string source,
            out string preProcessed,
            out string compacted,
            List <ParseException> errors)
        {
            preProcessed = source.Replace(" ", "");
            string[] parts = preProcessed.Split(TypeDelims, 2, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length < 2 ||
                String.IsNullOrEmpty(parts[0]) ||
                String.IsNullOrEmpty(parts[1]))
            {
                compacted = preProcessed = null;
                return;
            }

            parts[0] = MergeResourceCodeProvider.ScrubResourceName(parts[0]);

            // load resources from Assembly
            Assembly assembly = Assembly.Load(parts[1]);

            helper.AddAssemblyDependency(assembly);

            ManifestResourceInfo info = assembly.GetManifestResourceInfo(parts[0]);

            if (info == null)
            {
                compacted = preProcessed = null;
                return;
            }

            using (Stream stream = assembly.GetManifestResourceStream(parts[0]))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    preProcessed = reader.ReadToEnd();
                    compacted    = null;
                }
            }

            string       ext      = Path.GetExtension(parts[0]).Trim('.');
            CompilerType compiler = helper.GetDefaultCompilerTypeForLanguage(ext);

            if (!typeof(ResourceCodeProvider).IsAssignableFrom(compiler.CodeDomProviderType))
            {
                // don't know how to process any further
                compacted = preProcessed;
                return;
            }

            ResourceCodeProvider provider = (ResourceCodeProvider)Activator.CreateInstance(compiler.CodeDomProviderType);

            try
            {
                // concatenate the preprocessed source for current merge phase
                provider.ProcessResource(
                    helper,
                    parts[0],
                    preProcessed,
                    out preProcessed,
                    out compacted,
                    errors);
            }
            catch (ParseException ex)
            {
                errors.Add(ex);
            }
            catch (Exception ex)
            {
                errors.Add(new ParseError(ex.Message, parts[0], 0, 0, ex));
            }

            if (!this.isMimeSet &&
                !String.IsNullOrEmpty(provider.ContentType) &&
                !String.IsNullOrEmpty(provider.FileExtension))
            {
                this.contentType   = provider.ContentType;
                this.fileExtension = provider.FileExtension;
                this.isMimeSet     = true;
            }
        }