The Labs \ Source Viewer \ SSCLI \ System.CodeDom.Compiler \ HandlerBase

  1. //------------------------------------------------------------------------------
  2. // <copyright file="CodeDomCompilationConfiguration.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. /*
  16. * Code related to the <assemblies> config section
  17. *
  18. * Copyright (c) 1999 Microsoft Corporation
  19. */
  20. namespace System.CodeDom.Compiler
  21. {
  22.    
  23.     using System;
  24.     using System.CodeDom;
  25.     using System.Collections;
  26.     using System.Collections.Specialized;
  27.     using System.Configuration;
  28.     using System.IO;
  29.     using System.Reflection;
  30.     using System.Runtime.Serialization.Formatters;
  31.     using System.Xml;
  32.     using System.Globalization;
  33.    
  34.     internal class CodeDomCompilationConfiguration
  35.     {
  36.        
  37.         internal const string sectionName = "system.codedom";
  38.        
  39.         static readonly char[] s_fieldSeparators = new char[] {';'};
  40.        
  41.         // _compilerLanguages : Hashtable <string, CompilerInfo>
  42.         internal Hashtable _compilerLanguages;
  43.        
  44.         // _compilerExtensions : Hashtable <string, CompilerInfo>
  45.         internal Hashtable _compilerExtensions;
  46.         internal ArrayList _allCompilerInfo;
  47.        
  48.         private static CodeDomCompilationConfiguration defaultInstance = new CodeDomCompilationConfiguration();
  49.        
  50.         static internal CodeDomCompilationConfiguration Default {
  51.             get { return defaultInstance; }
  52.         }
  53.        
  54.         internal CodeDomCompilationConfiguration()
  55.         {
  56.             // First time initialization. This must be kept consistent with machine.config.comments in that it
  57.             // must initialize the config system as if that block was present.
  58.            
  59.             _compilerLanguages = new Hashtable(StringComparer.OrdinalIgnoreCase);
  60.             _compilerExtensions = new Hashtable(StringComparer.OrdinalIgnoreCase);
  61.             _allCompilerInfo = new ArrayList();
  62.            
  63.             CompilerInfo compilerInfo;
  64.             CompilerParameters compilerParameters;
  65.             string typeName;
  66.            
  67.             // C#
  68.             compilerParameters = new CompilerParameters();
  69.             compilerParameters.WarningLevel = 4;
  70.             typeName = "Microsoft.CSharp.CSharpCodeProvider, " + AssemblyRef.System;
  71.             compilerInfo = new CompilerInfo(compilerParameters, typeName);
  72.             compilerInfo._compilerLanguages = new string[] {"c#", "cs", "csharp"};
  73.             compilerInfo._compilerExtensions = new string[] {".cs", "cs"};
  74.             AddCompilerInfo(compilerInfo);
  75.            
  76.            
  77.             // JScript
  78.             compilerParameters = new CompilerParameters();
  79.             compilerParameters.WarningLevel = 4;
  80.             typeName = "Microsoft.JScript.JScriptCodeProvider, " + AssemblyRef.MicrosoftJScript;
  81.             compilerInfo = new CompilerInfo(compilerParameters, typeName);
  82.             compilerInfo._compilerLanguages = new string[] {"js", "jscript", "javascript"};
  83.             compilerInfo._compilerExtensions = new string[] {".js", "js"};
  84.             AddCompilerInfo(compilerInfo);
  85.            
  86.            
  87.         }
  88.        
  89.         private CodeDomCompilationConfiguration(CodeDomCompilationConfiguration original)
  90.         {
  91.             if (original._compilerLanguages != null)
  92.                 _compilerLanguages = (Hashtable)original._compilerLanguages.Clone();
  93.            
  94.             if (original._compilerExtensions != null)
  95.                 _compilerExtensions = (Hashtable)original._compilerExtensions.Clone();
  96.            
  97.             if (original._allCompilerInfo != null)
  98.                 _allCompilerInfo = (ArrayList)original._allCompilerInfo.Clone();
  99.         }
  100.        
  101.         private void AddCompilerInfo(CompilerInfo compilerInfo)
  102.         {
  103.            
  104.             foreach (string language in compilerInfo._compilerLanguages) {
  105.                 _compilerLanguages[language] = compilerInfo;
  106.             }
  107.            
  108.             foreach (string extension in compilerInfo._compilerExtensions) {
  109.                 _compilerExtensions[extension] = compilerInfo;
  110.             }
  111.            
  112.             _allCompilerInfo.Add(compilerInfo);
  113.         }
  114.        
  115.         private void RemoveUnmapped()
  116.         {
  117.             // Allow config compilers to replace redundant compiler entries
  118.            
  119.             // clear out the mapped marker
  120.             for (int i = 0; i < _allCompilerInfo.Count; i++) {
  121.                 ((CompilerInfo)_allCompilerInfo[i])._mapped = false;
  122.             }
  123.            
  124.             // Re-mark only the ones that still have a mapping
  125.             foreach (CompilerInfo destinationCompilerInfo in _compilerLanguages.Values) {
  126.                 destinationCompilerInfo._mapped = true;
  127.             }
  128.             foreach (CompilerInfo destinationCompilerInfo in _compilerExtensions.Values) {
  129.                 destinationCompilerInfo._mapped = true;
  130.             }
  131.            
  132.             // Remove the ones that were not marked
  133.             for (int i = _allCompilerInfo.Count - 1; i >= 0; i--) {
  134.                 if (!((CompilerInfo)_allCompilerInfo[i])._mapped) {
  135.                     _allCompilerInfo.RemoveAt(i);
  136.                 }
  137.             }
  138.         }
  139.        
  140.        
  141.         internal class SectionHandler
  142.         {
  143.             private SectionHandler()
  144.             {
  145.             }
  146.            
  147.             static internal object CreateStatic(object inheritedObject, XmlNode node)
  148.             {
  149.                 CodeDomCompilationConfiguration inherited = (CodeDomCompilationConfiguration)inheritedObject;
  150.                 CodeDomCompilationConfiguration result;
  151.                
  152.                 if (inherited == null)
  153.                     result = new CodeDomCompilationConfiguration();
  154.                 else
  155.                     result = new CodeDomCompilationConfiguration(inherited);
  156.                
  157.                 HandlerBase.CheckForUnrecognizedAttributes(node);
  158.                
  159.                 //
  160.                 // Handle child elements (if they exist)
  161.                 // - compilers
  162.                 //
  163.                 foreach (XmlNode child in node.ChildNodes) {
  164.                    
  165.                     // skip whitespace and comments
  166.                     // reject nonelements
  167.                     if (HandlerBase.IsIgnorableAlsoCheckForNonElement(child))
  168.                         continue;
  169.                    
  170.                     // handle <compilers>
  171.                     if (child.Name == "compilers") {
  172.                         ProcessCompilersElement(result, child);
  173.                     }
  174.                     else {
  175.                         HandlerBase.ThrowUnrecognizedElement(child);
  176.                     }
  177.                 }
  178.                
  179.                 return result;
  180.             }
  181.            
  182.             private static void ProcessCompilersElement(CodeDomCompilationConfiguration result, XmlNode node)
  183.             {
  184.                
  185.                 // reject attributes
  186.                 HandlerBase.CheckForUnrecognizedAttributes(node);
  187.                
  188.                 string configFile = ConfigurationErrorsException.GetFilename(node);
  189.                
  190.                 foreach (XmlNode child in node.ChildNodes) {
  191.                     int configLineNumber = ConfigurationErrorsException.GetLineNumber(child);
  192.                    
  193.                     // skip whitespace and comments
  194.                     // reject nonelements
  195.                     if (HandlerBase.IsIgnorableAlsoCheckForNonElement(child))
  196.                         continue;
  197.                    
  198.                     if (child.Name != "compiler") {
  199.                         HandlerBase.ThrowUnrecognizedElement(child);
  200.                     }
  201.                    
  202.                     string languages = String.Empty;
  203.                     XmlNode languageNode = HandlerBase.GetAndRemoveRequiredNonEmptyStringAttribute(child, "language", ref languages);
  204.                     string extensions = String.Empty;
  205.                     HandlerBase.GetAndRemoveRequiredNonEmptyStringAttribute(child, "extension", ref extensions);
  206.                     string compilerTypeName = null;
  207.                     HandlerBase.GetAndRemoveRequiredNonEmptyStringAttribute(child, "type", ref compilerTypeName);
  208.                    
  209.                     // Create a CompilerParameters for this compiler.
  210.                     CompilerParameters compilerParams = new CompilerParameters();
  211.                    
  212.                     int warningLevel = 0;
  213.                     if (HandlerBase.GetAndRemoveNonNegativeIntegerAttribute(child, "warningLevel", ref warningLevel) != null) {
  214.                         compilerParams.WarningLevel = warningLevel;
  215.                        
  216.                         // Need to be false if the warning level is 0
  217.                         compilerParams.TreatWarningsAsErrors = (warningLevel > 0);
  218.                     }
  219.                     string compilerOptions = null;
  220.                     if (HandlerBase.GetAndRemoveStringAttribute(child, "compilerOptions", ref compilerOptions) != null) {
  221.                         compilerParams.CompilerOptions = compilerOptions;
  222.                     }
  223.                    
  224.                     HandlerBase.CheckForUnrecognizedAttributes(child);
  225.                     HandlerBase.CheckForChildNodes(child);
  226.                    
  227.                     // Create a CompilerInfo structure for this compiler
  228.                     CompilerInfo compilerInfo = new CompilerInfo(compilerParams, compilerTypeName);
  229.                     compilerInfo.configFileName = configFile;
  230.                     compilerInfo.configFileLineNumber = configLineNumber;
  231.                    
  232.                     // Parse the semicolon separated lists
  233.                     string[] languageList = languages.Split(s_fieldSeparators);
  234.                     string[] extensionList = extensions.Split(s_fieldSeparators);
  235.                    
  236.                     for (int i = 0; i < languageList.Length; i++) {
  237.                         languageList[i] = languageList[i].Trim();
  238.                     }
  239.                    
  240.                     for (int i = 0; i < extensionList.Length; i++) {
  241.                         extensionList[i] = extensionList[i].Trim();
  242.                     }
  243.                    
  244.                    
  245.                     // Validate language names, language names must have length and extensions must start with a period.
  246.                     foreach (string language in languageList) {
  247.                         if (language.Length == 0)
  248.                             throw new ConfigurationErrorsException(SR.GetString(SR.Language_Names_Cannot_Be_Empty));
  249.                     }
  250.                    
  251.                     foreach (string extension in extensionList) {
  252.                         if (extension.Length == 0 || extension[0] != '.')
  253.                             throw new ConfigurationErrorsException(SR.GetString(SR.Extension_Names_Cannot_Be_Empty_Or_Non_Period_Based));
  254.                     }
  255.                    
  256.                    
  257.                     compilerInfo._compilerLanguages = languageList;
  258.                     compilerInfo._compilerExtensions = extensionList;
  259.                    
  260.                     result.AddCompilerInfo(compilerInfo);
  261.                 }
  262.                 // Allow config options to replace redundant compiler entries
  263.                 result.RemoveUnmapped();
  264.             }
  265.         }
  266.     }
  267.    
  268.     internal class CodeDomConfigurationHandler : IConfigurationSectionHandler
  269.     {
  270.         internal CodeDomConfigurationHandler()
  271.         {
  272.         }
  273.        
  274.         public virtual object Create(object inheritedObject, object configContextObj, XmlNode node)
  275.         {
  276.             return CodeDomCompilationConfiguration.SectionHandler.CreateStatic(inheritedObject, node);
  277.         }
  278.     }
  279.    
  280.    
  281.    
  282.    
  283.     static internal class HandlerBase
  284.     {
  285.        
  286.         //
  287.         // XML Attribute Helpers
  288.         //
  289.        
  290.         private static XmlNode GetAndRemoveAttribute(XmlNode node, string attrib, bool fRequired)
  291.         {
  292.             XmlNode a = node.Attributes.RemoveNamedItem(attrib);
  293.            
  294.             // If the attribute is required and was not present, throw
  295.             if (fRequired && a == null) {
  296.                 throw new ConfigurationErrorsException(SR.GetString(SR.Config_missing_required_attribute, attrib, node.Name), node);
  297.             }
  298.            
  299.             return a;
  300.         }
  301.        
  302.         private static XmlNode GetAndRemoveStringAttributeInternal(XmlNode node, string attrib, bool fRequired, ref string val)
  303.         {
  304.             XmlNode a = GetAndRemoveAttribute(node, attrib, fRequired);
  305.             if (a != null)
  306.                 val = a.Value;
  307.            
  308.             return a;
  309.         }
  310.        
  311.         static internal XmlNode GetAndRemoveStringAttribute(XmlNode node, string attrib, ref string val)
  312.         {
  313.                 /*fRequired*/            return GetAndRemoveStringAttributeInternal(node, attrib, false, ref val);
  314.         }
  315.        
  316.         static internal XmlNode GetAndRemoveRequiredNonEmptyStringAttribute(XmlNode node, string attrib, ref string val)
  317.         {
  318.                 /*fRequired*/            return GetAndRemoveNonEmptyStringAttributeInternal(node, attrib, true, ref val);
  319.         }
  320.        
  321.         private static XmlNode GetAndRemoveNonEmptyStringAttributeInternal(XmlNode node, string attrib, bool fRequired, ref string val)
  322.         {
  323.             XmlNode a = GetAndRemoveStringAttributeInternal(node, attrib, fRequired, ref val);
  324.             if (a != null && val.Length == 0) {
  325.                 throw new ConfigurationErrorsException(SR.GetString(SR.Empty_attribute, attrib), a);
  326.             }
  327.            
  328.             return a;
  329.         }
  330.        
  331.         private static XmlNode GetAndRemoveIntegerAttributeInternal(XmlNode node, string attrib, bool fRequired, ref int val)
  332.         {
  333.             XmlNode a = GetAndRemoveAttribute(node, attrib, fRequired);
  334.             if (a != null) {
  335.                 if (a.Value.Trim() != a.Value) {
  336.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_invalid_integer_attribute, a.Name), a);
  337.                 }
  338.                
  339.                 try {
  340.                     val = int.Parse(a.Value, CultureInfo.InvariantCulture);
  341.                 }
  342.                 catch (Exception e) {
  343.                     throw new ConfigurationErrorsException(SR.GetString(SR.Config_invalid_integer_attribute, a.Name), e, a);
  344.                 }
  345.             }
  346.            
  347.             return a;
  348.         }
  349.        
  350.         private static XmlNode GetAndRemoveNonNegativeAttributeInternal(XmlNode node, string attrib, bool fRequired, ref int val)
  351.         {
  352.             XmlNode a = GetAndRemoveIntegerAttributeInternal(node, attrib, fRequired, ref val);
  353.            
  354.             if (a != null && val < 0) {
  355.                 throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_nonnegative_integer_attribute, attrib), a);
  356.             }
  357.            
  358.             return a;
  359.         }
  360.        
  361.         static internal XmlNode GetAndRemoveNonNegativeIntegerAttribute(XmlNode node, string attrib, ref int val)
  362.         {
  363.                 /*fRequired*/            return GetAndRemoveNonNegativeAttributeInternal(node, attrib, false, ref val);
  364.         }
  365.        
  366.         static internal void CheckForUnrecognizedAttributes(XmlNode node)
  367.         {
  368.             if (node.Attributes.Count != 0) {
  369.                 throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_unrecognized_attribute, node.Attributes[0].Name), node.Attributes[0]);
  370.             }
  371.         }
  372.        
  373.         //
  374.         // XML Element Helpers
  375.         //
  376.        
  377.         static internal void CheckForNonElement(XmlNode node)
  378.         {
  379.             if (node.NodeType != XmlNodeType.Element) {
  380.                 throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_elements_only), node);
  381.             }
  382.         }
  383.        
  384.        
  385.         static internal bool IsIgnorableAlsoCheckForNonElement(XmlNode node)
  386.         {
  387.             if (node.NodeType == XmlNodeType.Comment || node.NodeType == XmlNodeType.Whitespace) {
  388.                 return true;
  389.             }
  390.            
  391.             CheckForNonElement(node);
  392.            
  393.             return false;
  394.         }
  395.        
  396.         static internal void CheckForChildNodes(XmlNode node)
  397.         {
  398.             if (node.HasChildNodes) {
  399.                 throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_no_child_nodes), node.FirstChild);
  400.             }
  401.         }
  402.        
  403.         static internal void ThrowUnrecognizedElement(XmlNode node)
  404.         {
  405.             throw new ConfigurationErrorsException(SR.GetString(SR.Config_base_unrecognized_element), node);
  406.         }
  407.        
  408.     }
  409. }

Developer Fusion