BaseCompiler.cs :  » 2.6.4-mono-.net-core » System.Web » System » Web » Compilation » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Web 
System.Web » System » Web » Compilation » BaseCompiler.cs
//
// System.Web.Compilation.BaseCompiler
//
// Authors:
//  Gonzalo Paniagua Javier (gonzalo@ximian.com)
//
// (c) Copyright 2002,2003 Ximian, Inc (http://www.ximian.com)
//

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.Text;
using System.Web.UI;
using System.Web.Configuration;
using System.IO;

namespace System.Web.Compilation{
  abstract class BaseCompiler
  {
    const string DEFAULT_NAMESPACE = "ASP";
    internal static Guid HashMD5 = new Guid(0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99);
    static BindingFlags replaceableFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

    TemplateParser parser;
    CodeDomProvider provider;
    ICodeCompiler compiler;
    CodeCompileUnit unit;
    CodeNamespace mainNS;
    CompilerParameters compilerParameters;
    bool isRebuilding = false;
    protected Hashtable partialNameOverride = new Hashtable();
    protected CodeTypeDeclaration partialClass;
    protected CodeTypeReferenceExpression partialClassExpr;
    protected CodeTypeDeclaration mainClass;
    protected CodeTypeReferenceExpression mainClassExpr;
    protected static CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression ();

    VirtualPath inputVirtualPath;
    
    public VirtualPath InputVirtualPath {
      get {
        if (inputVirtualPath == null)
          inputVirtualPath = new VirtualPath (VirtualPathUtility.Combine (parser.BaseVirtualDir, Path.GetFileName (parser.InputFile)));

        return inputVirtualPath;
      }
    }
    
    protected BaseCompiler (TemplateParser parser)
    {
      this.parser = parser;
    }

    protected void AddReferencedAssembly (Assembly asm)
    {
      if (unit == null || asm == null)
        return;

      StringCollection refAsm = unit.ReferencedAssemblies;
      string asmLocation = asm.Location;
      if (!refAsm.Contains (asmLocation))
        refAsm.Add (asmLocation);
    }
    
    internal CodeStatement AddLinePragma (CodeExpression expression, ControlBuilder builder)
    {
      return AddLinePragma (new CodeExpressionStatement (expression), builder);
    }
    
    internal CodeStatement AddLinePragma (CodeStatement statement, ControlBuilder builder)
    {
      if (builder == null || statement == null)
        return statement;

      ILocation location = null;

      if (!(builder is CodeRenderBuilder))
        location = builder.Location;
      
      if (location != null)
        return AddLinePragma (statement, location);
      else
        return AddLinePragma (statement, builder.Line, builder.FileName);
    }

    internal CodeStatement AddLinePragma (CodeStatement statement, ILocation location)
    {
      if (location == null || statement == null)
        return statement;
      
      return AddLinePragma (statement, location.BeginLine, location.Filename);
    }

    bool IgnoreFile (string fileName)
    {
      if (parser != null && !parser.LinePragmasOn)
        return true;
      
      return String.Compare (fileName, "@@inner_string@@", StringComparison.OrdinalIgnoreCase) == 0;
    }
    
    internal CodeStatement AddLinePragma (CodeStatement statement, int line, string fileName)
    {
      if (statement == null || IgnoreFile (fileName))
        return statement;
      
      statement.LinePragma = new CodeLinePragma (fileName, line);
      return statement;      
    }

    internal CodeTypeMember AddLinePragma (CodeTypeMember member, ControlBuilder builder)
    {
      if (builder == null || member == null)
        return member;

      ILocation location = builder.Location;
      
      if (location != null)
        return AddLinePragma (member, location);
      else
        return AddLinePragma (member, builder.Line, builder.FileName);
    }
    
    internal CodeTypeMember AddLinePragma (CodeTypeMember member, ILocation location)
    {
      if (location == null || member == null)
        return member;

      return AddLinePragma (member, location.BeginLine, location.Filename);
    }
    
    internal CodeTypeMember AddLinePragma (CodeTypeMember member, int line, string fileName)
    {
      if (member == null || IgnoreFile (fileName))
        return member;
      
      member.LinePragma = new CodeLinePragma (fileName, line);
      return member;
    }
    
    internal void ConstructType ()
    {
      unit = new CodeCompileUnit ();
      byte[] md5checksum = parser.MD5Checksum;

      if (md5checksum != null) {
        CodeChecksumPragma pragma = new CodeChecksumPragma ();
        pragma.FileName = parser.InputFile;
        pragma.ChecksumAlgorithmId = HashMD5;
        pragma.ChecksumData = md5checksum;

        unit.StartDirectives.Add (pragma);
      }

      if (parser.IsPartial) {
        string partialns = null;
        string partialclasstype = parser.PartialClassName;

        int partialdot = partialclasstype.LastIndexOf ('.');
        if (partialdot != -1) {
          partialns = partialclasstype.Substring (0, partialdot);
          partialclasstype = partialclasstype.Substring (partialdot + 1);
        }
        
        CodeNamespace partialNS = new CodeNamespace (partialns);
        partialClass = new CodeTypeDeclaration (partialclasstype);
        partialClass.IsPartial = true;
        partialClassExpr = new CodeTypeReferenceExpression (parser.PartialClassName);
        
        unit.Namespaces.Add (partialNS);
        partialClass.TypeAttributes = TypeAttributes.Public;
        partialNS.Types.Add (partialClass);
      }

      string mainclasstype = parser.ClassName;
      string mainns = DEFAULT_NAMESPACE;
      int maindot = mainclasstype.LastIndexOf ('.');
      if (maindot != -1) {
        mainns = mainclasstype.Substring (0, maindot);
        mainclasstype = mainclasstype.Substring (maindot + 1);
      }

      mainNS = new CodeNamespace (mainns);
      mainClass = new CodeTypeDeclaration (mainclasstype);
      CodeTypeReference baseTypeRef;
      if (partialClass != null) {
        baseTypeRef = new CodeTypeReference (parser.PartialClassName);
        baseTypeRef.Options |= CodeTypeReferenceOptions.GlobalReference;
      } else {
        baseTypeRef = new CodeTypeReference (parser.BaseType.FullName);
        if (parser.BaseTypeIsGlobal)
          baseTypeRef.Options |= CodeTypeReferenceOptions.GlobalReference;
      }
      mainClass.BaseTypes.Add (baseTypeRef);

      mainClassExpr = new CodeTypeReferenceExpression (mainns + "." + mainclasstype);

      unit.Namespaces.Add (mainNS);
      mainClass.TypeAttributes = TypeAttributes.Public;
      mainNS.Types.Add (mainClass);

      foreach (object o in parser.Imports.Keys) {
        if (o is string)
          mainNS.Imports.Add (new CodeNamespaceImport ((string) o));
      }

      // StringCollection.Contains has O(n) complexity, but
      // considering the number of comparisons we make on
      // average and the fact that using an intermediate array
      // would be even more costly, this is fine here.
      StringCollection refAsm = unit.ReferencedAssemblies;
      string asmName;
      if (parser.Assemblies != null) {
        foreach (object o in parser.Assemblies) {
          asmName = o as string;
          if (asmName != null && !refAsm.Contains (asmName))
            refAsm.Add (asmName);
        }
      }

      ArrayList al = WebConfigurationManager.ExtraAssemblies;
      if (al != null && al.Count > 0) {
        foreach (object o in al) {
          asmName = o as string;
          if (asmName != null && !refAsm.Contains (asmName))
            refAsm.Add (asmName);
        }
      }

      IList list = BuildManager.CodeAssemblies;
      if (list != null && list.Count > 0) {
        Assembly asm;
        foreach (object o in list) {
          asm = o as Assembly;
          if (o == null)
            continue;
          asmName = asm.Location;
          if (asmName != null && !refAsm.Contains (asmName))
            refAsm.Add (asmName);
        }
      }

      // Late-bound generators specifics (as for MonoBASIC/VB.NET)
      unit.UserData["RequireVariableDeclaration"] = parser.ExplicitOn;
      unit.UserData["AllowLateBound"] = !parser.StrictOn;

      InitializeType ();
      AddInterfaces ();
      AddClassAttributes ();
      CreateStaticFields ();
      AddApplicationAndSessionObjects ();
      AddScripts ();
      CreateMethods ();
      CreateConstructor (null, null);
    }

    internal CodeFieldReferenceExpression GetMainClassFieldReferenceExpression (string fieldName)
    {
      CodeTypeReference mainClassTypeRef;
      mainClassTypeRef = new CodeTypeReference (mainNS.Name + "." + mainClass.Name);
      mainClassTypeRef.Options |= CodeTypeReferenceOptions.GlobalReference;

      return new CodeFieldReferenceExpression (
        new CodeTypeReferenceExpression (mainClassTypeRef), fieldName);
    }

    protected virtual void InitializeType ()
    {}
    
    protected virtual void CreateStaticFields ()
    {
      CodeMemberField fld = new CodeMemberField (typeof (bool), "__initialized");
      fld.Attributes = MemberAttributes.Private | MemberAttributes.Static;
      fld.InitExpression = new CodePrimitiveExpression (false);
      mainClass.Members.Add (fld);
    }

    void AssignAppRelativeVirtualPath (CodeConstructor ctor)
    {
      if (String.IsNullOrEmpty (parser.InputFile))
        return;
      
      Type baseType = parser.CodeFileBaseClassType;
      if (baseType == null)
        baseType = parser.BaseType;
      if (baseType == null)
        return;
      if (!baseType.IsSubclassOf (typeof (System.Web.UI.TemplateControl)))
        return;
      
      CodeTypeReference baseTypeRef = new CodeTypeReference (baseType.FullName);
      if (parser.BaseTypeIsGlobal)
        baseTypeRef.Options |= CodeTypeReferenceOptions.GlobalReference;
      
      CodeExpression cast = new CodeCastExpression (baseTypeRef, new CodeThisReferenceExpression ());
      CodePropertyReferenceExpression arvpProp = new CodePropertyReferenceExpression (cast, "AppRelativeVirtualPath");
      CodeAssignStatement arvpAssign = new CodeAssignStatement ();
      arvpAssign.Left = arvpProp;
      arvpAssign.Right = new CodePrimitiveExpression (VirtualPathUtility.RemoveTrailingSlash (InputVirtualPath.AppRelative));
      ctor.Statements.Add (arvpAssign);
    }
    
    protected virtual void CreateConstructor (CodeStatementCollection localVars,
                CodeStatementCollection trueStmt)
    {
      CodeConstructor ctor = new CodeConstructor ();
      ctor.Attributes = MemberAttributes.Public;
      mainClass.Members.Add (ctor);

      if (localVars != null)
        ctor.Statements.AddRange (localVars);

      AssignAppRelativeVirtualPath (ctor);

      CodeFieldReferenceExpression initialized = GetMainClassFieldReferenceExpression ("__initialized");
      
      CodeBinaryOperatorExpression bin;
      bin = new CodeBinaryOperatorExpression (initialized,
                CodeBinaryOperatorType.ValueEquality,
                new CodePrimitiveExpression (false));

      CodeAssignStatement assign = new CodeAssignStatement (initialized,
                        new CodePrimitiveExpression (true));

      CodeConditionStatement cond = new CodeConditionStatement ();
      cond.Condition = bin;
      
      if (trueStmt != null)
        cond.TrueStatements.AddRange (trueStmt);
      cond.TrueStatements.Add (assign);
      ctor.Statements.Add (cond);
      AddStatementsToConstructor (ctor);
    }

    protected virtual void AddStatementsToConstructor (CodeConstructor ctor)
    {
    }
    
    void AddScripts ()
    {
      if (parser.Scripts == null || parser.Scripts.Count == 0)
        return;

      ServerSideScript sss;
      
      foreach (object o in parser.Scripts) {
        sss = o as ServerSideScript;

        if (sss == null)
          continue;
        
        mainClass.Members.Add (AddLinePragma (new CodeSnippetTypeMember (sss.Script), sss.Location));
      }
    }
    
    protected internal virtual void CreateMethods ()
    {
    }

    void InternalCreatePageProperty (string retType, string name, string contextProperty)
    {
      CodeMemberProperty property = new CodeMemberProperty ();
      property.Name = name;
      property.Type = new CodeTypeReference (retType);
      property.Attributes = MemberAttributes.Family | MemberAttributes.Final;

      CodeMethodReturnStatement ret = new CodeMethodReturnStatement ();
      CodeCastExpression cast = new CodeCastExpression ();
      ret.Expression = cast;
      
      CodePropertyReferenceExpression refexp = new CodePropertyReferenceExpression ();
      refexp.TargetObject = new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "Context");
      refexp.PropertyName = contextProperty;
      
      cast.TargetType = new CodeTypeReference (retType);
      cast.Expression = refexp;
      
      property.GetStatements.Add (ret);
      if (partialClass == null)
        mainClass.Members.Add (property);
      else
        partialClass.Members.Add (property);
    }
    
    protected void CreateProfileProperty ()
    {
      string retType;
      if (AppCodeCompiler.HaveCustomProfile (WebConfigurationManager.GetWebApplicationSection ("system.web/profile") as ProfileSection))
        retType = "ProfileCommon";
      else
        retType = "System.Web.Profile.DefaultProfile";
      InternalCreatePageProperty (retType, "Profile", "Profile");
    }
    
    protected virtual void AddInterfaces ()
    {
      if (parser.Interfaces == null)
        return;

      foreach (object o in parser.Interfaces) {
        if (o is string)
          mainClass.BaseTypes.Add (new CodeTypeReference ((string) o));
      }
    }

    protected virtual void AddClassAttributes ()
    {
    }
    
    protected virtual void AddApplicationAndSessionObjects ()
    {
    }

    /* Utility methods for <object> stuff */
    protected void CreateApplicationOrSessionPropertyForObject (Type type,
                      string propName,
                      bool isApplication,
                      bool isPublic)
    {
      /* if isApplication this generates (the 'cachedapp' field is created earlier):
      private MyNS.MyClass app {
        get {
          if ((this.cachedapp == null)) {
            this.cachedapp = ((MyNS.MyClass)
              (this.Application.StaticObjects.GetObject("app")));
          }
          return this.cachedapp;
        }
      }

      else, this is for Session:
      private MyNS.MyClass ses {
        get {
          return ((MyNS.MyClass) (this.Session.StaticObjects.GetObject("ses")));
        }
      }

      */

      CodeExpression result = null;

      CodeMemberProperty prop = new CodeMemberProperty ();
      prop.Type = new CodeTypeReference (type);
      prop.Name = propName;
      if (isPublic)
        prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
      else
        prop.Attributes = MemberAttributes.Private | MemberAttributes.Final;

      CodePropertyReferenceExpression p1;
      if (isApplication)
        p1 = new CodePropertyReferenceExpression (thisRef, "Application");
      else
        p1 = new CodePropertyReferenceExpression (thisRef, "Session");

      CodePropertyReferenceExpression p2;
      p2 = new CodePropertyReferenceExpression (p1, "StaticObjects");

      CodeMethodReferenceExpression getobject;
      getobject = new CodeMethodReferenceExpression (p2, "GetObject");

      CodeMethodInvokeExpression invoker;
      invoker = new CodeMethodInvokeExpression (getobject,
            new CodePrimitiveExpression (propName));

      CodeCastExpression cast = new CodeCastExpression (prop.Type, invoker);

      if (isApplication) {
        CodeFieldReferenceExpression field;
        field = new CodeFieldReferenceExpression (thisRef, "cached" + propName);

        CodeConditionStatement stmt = new CodeConditionStatement();
        stmt.Condition = new CodeBinaryOperatorExpression (field,
              CodeBinaryOperatorType.IdentityEquality,
              new CodePrimitiveExpression (null));

        CodeAssignStatement assign = new CodeAssignStatement ();
        assign.Left = field;
        assign.Right = cast;
        stmt.TrueStatements.Add (assign);
        prop.GetStatements.Add (stmt);
        result = field;
      } else {
        result = cast;
      }
            
      prop.GetStatements.Add (new CodeMethodReturnStatement (result));
      mainClass.Members.Add (prop);
    }

    protected string CreateFieldForObject (Type type, string name)
    {
      string fieldName = "cached" + name;
      CodeMemberField f = new CodeMemberField (type, fieldName);
      f.Attributes = MemberAttributes.Private;
      mainClass.Members.Add (f);
      return fieldName;
    }

    protected void CreatePropertyForObject (Type type, string propName, string fieldName, bool isPublic)
    {
      CodeFieldReferenceExpression field = new CodeFieldReferenceExpression (thisRef, fieldName);
      CodeMemberProperty prop = new CodeMemberProperty ();
      prop.Type = new CodeTypeReference (type);
      prop.Name = propName;
      if (isPublic)
        prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
      else
        prop.Attributes = MemberAttributes.Private | MemberAttributes.Final;

      CodeConditionStatement stmt = new CodeConditionStatement();
      stmt.Condition = new CodeBinaryOperatorExpression (field,
            CodeBinaryOperatorType.IdentityEquality,
            new CodePrimitiveExpression (null));

      CodeObjectCreateExpression create = new CodeObjectCreateExpression (prop.Type);  
      stmt.TrueStatements.Add (new CodeAssignStatement (field, create));
      prop.GetStatements.Add (stmt);
      prop.GetStatements.Add (new CodeMethodReturnStatement (field));

      mainClass.Members.Add (prop);
    }
    /******/

    void CheckCompilerErrors (CompilerResults results)
    {
      if (results.NativeCompilerReturnValue == 0)
        return;

      string fileText = null;
      CompilerErrorCollection errors = results.Errors;
      CompilerError ce = (errors != null && errors.Count > 0) ? errors [0] : null;
      string inFile = (ce != null) ? ce.FileName : null;
      
      if (inFile != null && File.Exists (inFile)) {
        using (StreamReader sr = File.OpenText (inFile)) {
          fileText = sr.ReadToEnd ();
        }
      } else {
        StringWriter writer = new StringWriter();
        provider.CreateGenerator().GenerateCodeFromCompileUnit (unit, writer, null);
        fileText = writer.ToString ();
      }
      throw new CompilationException (parser.InputFile, errors, fileText);
    }

    protected string DynamicDir ()
    {
      return AppDomain.CurrentDomain.SetupInformation.DynamicBase;
    }

    internal static CodeDomProvider CreateProvider (string lang)
    {
      CompilerParameters par;
      string tempdir;
      
      return CreateProvider (HttpContext.Current, lang, out par, out tempdir);
    }
    
    internal static CodeDomProvider CreateProvider (string lang, out string compilerOptions, out int warningLevel, out string tempdir)
    {
      return CreateProvider (HttpContext.Current, lang, out compilerOptions, out warningLevel, out tempdir);
    }
    
    internal static CodeDomProvider CreateProvider (HttpContext context, string lang, out string compilerOptions, out int warningLevel, out string tempdir)
    {
      CodeDomProvider ret;
      CompilerParameters par;

      ret = CreateProvider (context, lang, out par, out tempdir);
      if (par != null){
        warningLevel = par.WarningLevel;
        compilerOptions = par.CompilerOptions;
      } else {
        warningLevel = 2;
        compilerOptions = String.Empty;
      }

      return ret;
    }

    internal static CodeDomProvider CreateProvider (HttpContext context, string lang, out CompilerParameters par, out string tempdir)
    {
      CodeDomProvider ret = null;
      par = null;
      
      CompilationSection config = (CompilationSection) WebConfigurationManager.GetWebApplicationSection ("system.web/compilation");
      Compiler comp = config.Compilers[lang];
      
      if (comp == null) {
        CompilerInfo info = CodeDomProvider.GetCompilerInfo (lang);
        if (info != null && info.IsCodeDomProviderTypeValid) {
          ret = info.CreateProvider ();
          par = info.CreateDefaultCompilerParameters ();
        }
      } else {
        Type t = HttpApplication.LoadType (comp.Type, true);
        ret = Activator.CreateInstance (t) as CodeDomProvider;

        par = new CompilerParameters ();
        par.CompilerOptions = comp.CompilerOptions;
        par.WarningLevel = comp.WarningLevel;
      }
      tempdir = config.TempDirectory;

      return ret;
    }
    
    [MonoTODO ("find out how to extract the warningLevel and compilerOptions in the <system.codedom> case")]
    public virtual Type GetCompiledType () 
    {
      Type type = CachingCompiler.GetTypeFromCache (parser.InputFile);
      if (type != null)
        return type;

      ConstructType ();
      string lang = parser.Language;
      string tempdir;
      string compilerOptions;
      int warningLevel;

      Provider = CreateProvider (parser.Context, lang, out compilerOptions, out warningLevel, out tempdir);
      if (Provider == null)
        throw new HttpException ("Configuration error. Language not supported: " +
                lang, 500);

      CompilerParameters parameters = CompilerParameters;
      parameters.IncludeDebugInformation = parser.Debug;
      parameters.CompilerOptions = compilerOptions + " " + parser.CompilerOptions;
      parameters.WarningLevel = warningLevel;
      
      bool keepFiles = (Environment.GetEnvironmentVariable ("MONO_ASPNET_NODELETE") != null);

      if (tempdir == null || tempdir == "")
        tempdir = DynamicDir ();
        
      TempFileCollection tempcoll = new TempFileCollection (tempdir, keepFiles);
      parameters.TempFiles = tempcoll;
      string dllfilename = Path.GetFileName (tempcoll.AddExtension ("dll", true));
      parameters.OutputAssembly = Path.Combine (DynamicDir (), dllfilename);

      CompilerResults results = CachingCompiler.Compile (this);
      CheckCompilerErrors (results);
      Assembly assembly = results.CompiledAssembly;
      if (assembly == null) {
        if (!File.Exists (parameters.OutputAssembly)) {
          results.TempFiles.Delete ();
          throw new CompilationException (parser.InputFile, results.Errors,
            "No assembly returned after compilation!?");
        }

        assembly = Assembly.LoadFrom (parameters.OutputAssembly);
      }

      results.TempFiles.Delete ();
      Type mainClassType = assembly.GetType (MainClassType, true);

      if (parser.IsPartial) {
        // With the partial classes, we need to make sure we
        // don't have any methods that should have not been
        // created (because they are accessible from the base
        // types). We cannot do this normally because the
        // codebehind file is actually a partial class and we
        // have no way of identifying the partial class' base
        // type until now.
        if (!isRebuilding && CheckPartialBaseType (mainClassType)) {
          isRebuilding = true;
          parser.RootBuilder.ResetState ();
          return GetCompiledType ();
        }
      }

      return mainClassType;
    }

    internal string MainClassType {
      get {
        if (mainClassExpr == null)
          return null;

        return mainClassExpr.Type.BaseType;
      }
    }
    
    internal bool IsRebuildingPartial
    {
      get { return isRebuilding; }
    }

    internal bool CheckPartialBaseType (Type type)
    {
      // Get the base type. If we don't have any (bad thing), we
      // don't need to replace ourselves. Also check for the
      // core file, since that won't have any either.
      Type baseType = type.BaseType;
      if (baseType == null || baseType == typeof(System.Web.UI.Page))
        return false;

      bool rebuild = false;

      if (CheckPartialBaseFields (type, baseType))
        rebuild = true;

      if (CheckPartialBaseProperties (type, baseType))
        rebuild = true;

      return rebuild;
    }

    internal bool CheckPartialBaseFields (Type type, Type baseType)
    {
      bool rebuild = false;

      foreach (FieldInfo baseInfo in baseType.GetFields (replaceableFlags)) {
        if (baseInfo.IsPrivate)
          continue;

        FieldInfo typeInfo = type.GetField (baseInfo.Name, replaceableFlags);

        if (typeInfo != null && typeInfo.DeclaringType == type) {
          partialNameOverride [typeInfo.Name] = true;
          rebuild = true;
        }
      }

      return rebuild;
    }

    internal bool CheckPartialBaseProperties (Type type, Type baseType)
    {
      bool rebuild = false;

      foreach (PropertyInfo baseInfo in baseType.GetProperties ()) {
        PropertyInfo typeInfo = type.GetProperty (baseInfo.Name);

        if (typeInfo != null && typeInfo.DeclaringType == type) {
          partialNameOverride [typeInfo.Name] = true;
          rebuild = true;
        }
      }

      return rebuild;
    }

    internal CodeDomProvider Provider {
      get { return provider; }
      set { provider = value; }
    }

    internal ICodeCompiler Compiler {
      get { return compiler; }
      set { compiler = value; }
    }    

    internal CompilerParameters CompilerParameters {
      get {
        if (compilerParameters == null)
          compilerParameters = new CompilerParameters ();
        
        return compilerParameters;
      }
      
      set { compilerParameters = value; }
    }

    internal CodeCompileUnit CompileUnit {
      get { return unit; }
    }

    internal CodeTypeDeclaration DerivedType {
      get { return mainClass; }
    }

    internal CodeTypeDeclaration BaseType {
      get {
        if (partialClass == null)
          return DerivedType;
        return partialClass;
      }
    }

    internal TemplateParser Parser {
      get { return parser; }
    }
  }
}

www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.