﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Compilation.ObjectFactoryCodeDomTreeGenerator
// Assembly: System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// MVID: 7E68A73E-4066-4F24-AB0A-F147209F50EC
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Web.dll

using System;
using System.CodeDom;
using System.Globalization;
using System.Reflection;
using System.Runtime;
using System.Security.Permissions;
using System.Web.UI;

namespace System.Web.Compilation
{
  internal class ObjectFactoryCodeDomTreeGenerator
  {
    private CodeCompileUnit _codeCompileUnit;
    private CodeTypeDeclaration _factoryClass;
    private const string factoryClassNameBase = "FastObjectFactory_";
    private const string factoryFullClassNameBase = "__ASP.FastObjectFactory_";

    internal CodeCompileUnit CodeCompileUnit
    {
      [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
      {
        return this._codeCompileUnit;
      }
    }

    internal ObjectFactoryCodeDomTreeGenerator(string outputAssemblyName)
    {
      this._codeCompileUnit = new CodeCompileUnit();
      CodeNamespace codeNamespace = new CodeNamespace("__ASP");
      this._codeCompileUnit.Namespaces.Add(codeNamespace);
      this._factoryClass = new CodeTypeDeclaration("FastObjectFactory_" + Util.MakeValidTypeNameFromString(outputAssemblyName).ToLower(CultureInfo.InvariantCulture));
      this._factoryClass.TypeAttributes &= ~TypeAttributes.Public;
      CodeSnippetTypeMember snippetTypeMember = new CodeSnippetTypeMember(string.Empty);
      snippetTypeMember.LinePragma = new CodeLinePragma("c:\\\\dummy.txt", 1);
      this._factoryClass.Members.Add((CodeTypeMember) snippetTypeMember);
      CodeConstructor codeConstructor = new CodeConstructor();
      codeConstructor.Attributes |= MemberAttributes.Private;
      this._factoryClass.Members.Add((CodeTypeMember) codeConstructor);
      codeNamespace.Types.Add(this._factoryClass);
    }

    internal void AddFactoryMethod(string typeToCreate)
    {
      CodeMemberMethod codeMemberMethod = new CodeMemberMethod();
      codeMemberMethod.Name = ObjectFactoryCodeDomTreeGenerator.GetCreateMethodNameForType(typeToCreate);
      codeMemberMethod.ReturnType = new CodeTypeReference(typeof (object));
      codeMemberMethod.Attributes = MemberAttributes.Static;
      CodeMethodReturnStatement methodReturnStatement = new CodeMethodReturnStatement((CodeExpression) new CodeObjectCreateExpression(typeToCreate, new CodeExpression[0]));
      codeMemberMethod.Statements.Add((CodeStatement) methodReturnStatement);
      this._factoryClass.Members.Add((CodeTypeMember) codeMemberMethod);
    }

    [ReflectionPermission(SecurityAction.Assert, Flags = ReflectionPermissionFlag.MemberAccess)]
    internal static InstantiateObject GetFastObjectCreationDelegate(Type t)
    {
      Type type = t.Assembly.GetType("__ASP.FastObjectFactory_" + Util.MakeValidTypeNameFromString(Util.GetAssemblyShortName(t.Assembly).ToLower(CultureInfo.InvariantCulture)));
      if (type == (Type) null)
        return (InstantiateObject) null;
      string methodNameForType = ObjectFactoryCodeDomTreeGenerator.GetCreateMethodNameForType(t.FullName);
      try
      {
        return (InstantiateObject) Delegate.CreateDelegate(typeof (InstantiateObject), type, methodNameForType);
      }
      catch
      {
        return (InstantiateObject) null;
      }
    }

    private static string GetCreateMethodNameForType(string typeToCreate)
    {
      return "Create_" + Util.MakeValidTypeNameFromString(typeToCreate);
    }
  }
}
