| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877 |
- //
- // System.Web.Compilation.AppResourceFilesCollection
- //
- // Authors:
- // Marek Habersack ([email protected])
- //
- // (C) 2006 Marek Habersack
- // (C) 2007-2009 Novell, Inc http://novell.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.Generic;
- using System.ComponentModel.Design;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Resources;
- using System.Text;
- using System.Web;
- using System.Web.Caching;
- using System.Web.Configuration;
- using System.Web.Util;
- namespace System.Web.Compilation
- {
- class AppResourcesCompiler
- {
- // This class fixes bug #466059
- class TypeResolutionService : ITypeResolutionService
- {
- List <Assembly> referencedAssemblies;
- Dictionary <string, Type> mappedTypes;
- public Assembly GetAssembly (AssemblyName name)
- {
- return GetAssembly (name, false);
- }
-
- public Assembly GetAssembly (AssemblyName name, bool throwOnError)
- {
- try {
- return Assembly.Load (name);
- } catch {
- if (throwOnError)
- throw;
- }
- return null;
- }
- public void ReferenceAssembly (AssemblyName name)
- {
- if (referencedAssemblies == null)
- referencedAssemblies = new List <Assembly> ();
- Assembly asm = GetAssembly (name, false);
- if (asm == null)
- return;
-
- if (referencedAssemblies.Contains (asm))
- return;
-
- referencedAssemblies.Add (asm);
- }
- public string GetPathOfAssembly (AssemblyName name)
- {
- if (name == null)
- return null;
- Assembly asm = GetAssembly (name, false);
- if (asm == null)
- return null;
-
- return asm.Location;
- }
- public Type GetType (string name)
- {
- return GetType (name, false, false);
- }
- public Type GetType (string name, bool throwOnError)
- {
- return GetType (name, throwOnError, false);
- }
- public Type GetType (string name, bool throwOnError, bool ignoreCase)
- {
- if (String.IsNullOrEmpty (name)) {
- if (throwOnError)
- throw new ArgumentNullException ("name");
- else
- return null;
- }
- int idx = name.IndexOf (',');
- Type type = null;
- if (idx == -1) {
- type = MapType (name, false);
- if (type != null)
- return type;
-
- type = FindInAssemblies (name, ignoreCase);
- if (type == null) {
- if (throwOnError)
- throw new InvalidOperationException ("Type '" + name + "' is not fully qualified and there are no referenced assemblies.");
- else
- return null;
- }
- return type;
- }
- type = MapType (name, true);
- if (type != null)
- return type;
-
- return Type.GetType (name, throwOnError, ignoreCase);
- }
- Type MapType (string name, bool full)
- {
- if (mappedTypes == null)
- mappedTypes = new Dictionary <string, Type> (StringComparer.Ordinal);
- Type ret;
- if (mappedTypes.TryGetValue (name, out ret))
- return ret;
- if (!full) {
- if (String.Compare (name, "ResXDataNode", StringComparison.Ordinal) == 0)
- return AddMappedType (name, typeof (ResXDataNode));
- if (String.Compare (name, "ResXFileRef", StringComparison.Ordinal) == 0)
- return AddMappedType (name, typeof (ResXFileRef));
- if (String.Compare (name, "ResXNullRef", StringComparison.Ordinal) == 0)
- return AddMappedType (name, typeof (ResXNullRef));
- if (String.Compare (name, "ResXResourceReader", StringComparison.Ordinal) == 0)
- return AddMappedType (name, typeof (ResXResourceReader));
- if (String.Compare (name, "ResXResourceWriter", StringComparison.Ordinal) == 0)
- return AddMappedType (name, typeof (ResXResourceWriter));
- return null;
- }
- if (name.IndexOf ("System.Windows.Forms") == -1)
- return null;
- if (name.IndexOf ("ResXDataNode", StringComparison.Ordinal) != -1)
- return AddMappedType (name, typeof (ResXDataNode));
- if (name.IndexOf ("ResXFileRef", StringComparison.Ordinal) != -1)
- return AddMappedType (name, typeof (ResXFileRef));
- if (name.IndexOf ("ResXNullRef", StringComparison.Ordinal) != -1)
- return AddMappedType (name, typeof (ResXNullRef));
- if (name.IndexOf ("ResXResourceReader", StringComparison.Ordinal) != -1)
- return AddMappedType (name, typeof (ResXResourceReader));
- if (name.IndexOf ("ResXResourceWriter", StringComparison.Ordinal) != -1)
- return AddMappedType (name, typeof (ResXResourceWriter));
- return null;
- }
- Type AddMappedType (string name, Type type)
- {
- mappedTypes.Add (name, type);
- return type;
- }
-
- Type FindInAssemblies (string name, bool ignoreCase)
- {
- Type ret = Type.GetType (name, false);
- if (ret != null)
- return ret;
- if (referencedAssemblies == null || referencedAssemblies.Count == 0)
- return null;
- foreach (Assembly asm in referencedAssemblies) {
- ret = asm.GetType (name, false, ignoreCase);
- if (ret != null)
- return ret;
- }
- return null;
- }
- }
-
- const string cachePrefix = "@@LocalResourcesAssemblies";
-
- bool isGlobal;
- AppResourceFilesCollection files;
- string tempDirectory;
- string virtualPath;
- Dictionary <string, List <string>> cultureFiles;
- List <string> defaultCultureFiles;
-
- string TempDirectory {
- get {
- if (tempDirectory != null)
- return tempDirectory;
- return (tempDirectory = AppDomain.CurrentDomain.SetupInformation.DynamicBase);
- }
- }
- public Dictionary <string, List <string>> CultureFiles {
- get { return cultureFiles; }
- }
- public List <string> DefaultCultureFiles {
- get { return defaultCultureFiles; }
- }
-
- static AppResourcesCompiler ()
- {
- if (!BuildManager.IsPrecompiled)
- return;
- string[] binDirAssemblies = HttpApplication.BinDirectoryAssemblies;
- if (binDirAssemblies == null || binDirAssemblies.Length == 0)
- return;
- string name;
- Assembly asm;
- foreach (string asmPath in binDirAssemblies) {
- if (String.IsNullOrEmpty (asmPath))
- continue;
-
- name = Path.GetFileName (asmPath);
- if (name.StartsWith ("App_LocalResources.", StringComparison.OrdinalIgnoreCase)) {
- string virtualPath = GetPrecompiledVirtualPath (asmPath);
- if (String.IsNullOrEmpty (virtualPath))
- continue;
- asm = LoadAssembly (asmPath);
- if (asm == null)
- continue;
-
- AddAssemblyToCache (virtualPath, asm);
- continue;
- }
- if (String.Compare (name, "App_GlobalResources.dll", StringComparison.OrdinalIgnoreCase) != 0)
- continue;
- asm = LoadAssembly (asmPath);
- if (asm == null)
- continue;
- HttpContext.AppGlobalResourcesAssembly = asm;
- }
- }
-
- public AppResourcesCompiler (HttpContext context)
- {
- this.isGlobal = true;
- this.files = new AppResourceFilesCollection (context);
- this.cultureFiles = new Dictionary <string, List <string>> (StringComparer.OrdinalIgnoreCase);
- }
- public AppResourcesCompiler (string virtualPath)
- {
- this.virtualPath = virtualPath;
- this.isGlobal = false;
- this.files = new AppResourceFilesCollection (HttpContext.Current.Request.MapPath (virtualPath));
- this.cultureFiles = new Dictionary <string, List <string>> (StringComparer.OrdinalIgnoreCase);
- }
- static Assembly LoadAssembly (string asmPath)
- {
- try {
- return Assembly.LoadFrom (asmPath);
- } catch (BadImageFormatException) {
- // ignore
- return null;
- }
- }
-
- static string GetPrecompiledVirtualPath (string asmPath)
- {
- string compiledFile = Path.ChangeExtension (asmPath, ".compiled");
-
- if (!File.Exists (compiledFile))
- return null;
- var pfile = new PreservationFile (compiledFile);
- string virtualPath = pfile.VirtualPath;
- if (String.IsNullOrEmpty (virtualPath))
- return "/";
- if (virtualPath.EndsWith ("/App_LocalResources/", StringComparison.OrdinalIgnoreCase))
- virtualPath = virtualPath.Substring (0, virtualPath.Length - 19);
-
- return virtualPath;
- }
-
- public Assembly Compile ()
- {
- files.Collect ();
- if (!files.HasFiles)
- return null;
- if (isGlobal)
- return CompileGlobal ();
- else
- return CompileLocal ();
- }
- Assembly CompileGlobal ()
- {
- string assemblyPath = FileUtils.CreateTemporaryFile (TempDirectory,
- "App_GlobalResources",
- "dll",
- OnCreateRandomFile) as string;
- if (assemblyPath == null)
- throw new ApplicationException ("Failed to create global resources assembly");
-
- List <string>[] fileGroups = GroupGlobalFiles ();
- if (fileGroups == null || fileGroups.Length == 0)
- return null;
-
- CodeCompileUnit unit = new CodeCompileUnit ();
- CodeNamespace ns = new CodeNamespace (null);
- ns.Imports.Add (new CodeNamespaceImport ("System"));
- ns.Imports.Add (new CodeNamespaceImport ("System.Globalization"));
- ns.Imports.Add (new CodeNamespaceImport ("System.Reflection"));
- ns.Imports.Add (new CodeNamespaceImport ("System.Resources"));
- unit.Namespaces.Add (ns);
- AppResourcesAssemblyBuilder builder = new AppResourcesAssemblyBuilder ("App_GlobalResources", assemblyPath,
- this);
- CodeDomProvider provider = builder.Provider;
-
- Dictionary <string,bool> assemblies = new Dictionary<string,bool> ();
- foreach (List<string> ls in fileGroups)
- DomFromResource (ls [0], unit, assemblies, provider);
-
- foreach (KeyValuePair<string,bool> de in assemblies)
- unit.ReferencedAssemblies.Add (de.Key);
-
- builder.Build (unit);
- HttpContext.AppGlobalResourcesAssembly = builder.MainAssembly;
-
- return builder.MainAssembly;
- }
- Assembly CompileLocal ()
- {
- if (String.IsNullOrEmpty (virtualPath))
- return null;
-
- Assembly cached = GetCachedLocalResourcesAssembly (virtualPath);
- if (cached != null)
- return cached;
-
- string prefix;
- if (virtualPath == "/")
- prefix = "App_LocalResources.root";
- else
- prefix = "App_LocalResources" + virtualPath.Replace ('/', '.');
-
- string assemblyPath = FileUtils.CreateTemporaryFile (TempDirectory,
- prefix,
- "dll",
- OnCreateRandomFile) as string;
- if (assemblyPath == null)
- throw new ApplicationException ("Failed to create local resources assembly");
- List<AppResourceFileInfo> files = this.files.Files;
- foreach (AppResourceFileInfo arfi in files)
- GetResourceFile (arfi, true);
- AppResourcesAssemblyBuilder builder = new AppResourcesAssemblyBuilder ("App_LocalResources", assemblyPath,
- this);
- builder.Build ();
- Assembly ret = builder.MainAssembly;
-
- if (ret != null)
- AddAssemblyToCache (virtualPath, ret);
- return ret;
- }
-
- internal static Assembly GetCachedLocalResourcesAssembly (string path)
- {
- Dictionary <string, Assembly> cache;
- cache = HttpRuntime.InternalCache[cachePrefix] as Dictionary <string, Assembly>;
- if (cache == null || !cache.ContainsKey (path))
- return null;
- return cache [path];
- }
-
- static void AddAssemblyToCache (string path, Assembly asm)
- {
- Cache runtimeCache = HttpRuntime.InternalCache;
- Dictionary <string, Assembly> cache;
-
- cache = runtimeCache[cachePrefix] as Dictionary <string, Assembly>;
- if (cache == null)
- cache = new Dictionary <string, Assembly> ();
- cache [path] = asm;
- runtimeCache.Insert (cachePrefix, cache);
- }
-
- uint CountChars (char c, string s)
- {
- uint ret = 0;
- foreach (char ch in s) {
- if (ch == c)
- ret++;
- }
- return ret;
- }
- string IsFileCultureValid (string fileName)
- {
- string tmp = Path.GetFileNameWithoutExtension (fileName);
- tmp = Path.GetExtension (tmp);
- if (tmp != null && tmp.Length > 0) {
- tmp = tmp.Substring (1);
- try {
- CultureInfo.GetCultureInfo (tmp);
- return tmp;
- } catch {
- return null;
- }
- }
- return null;
- }
-
- string GetResourceFile (AppResourceFileInfo arfi, bool local)
- {
- string resfile;
- if (arfi.Kind == AppResourceFileKind.ResX)
- resfile = CompileResource (arfi, local);
- else
- resfile = arfi.Info.FullName;
- if (!String.IsNullOrEmpty (resfile)) {
- string culture = IsFileCultureValid (resfile);
- List <string> cfiles;
- if (culture != null) {
- if (cultureFiles.ContainsKey (culture))
- cfiles = cultureFiles [culture];
- else {
- cfiles = new List <string> (1);
- cultureFiles [culture] = cfiles;
- }
- } else {
- if (defaultCultureFiles == null)
- defaultCultureFiles = new List <string> ();
- cfiles = defaultCultureFiles;
- }
-
- cfiles.Add (resfile);
- }
-
- return resfile;
- }
-
- List <string>[] GroupGlobalFiles ()
- {
- List<AppResourceFileInfo> files = this.files.Files;
- List<List<string>> groups = new List<List<string>> ();
- AppResourcesLengthComparer<List<string>> lcList = new AppResourcesLengthComparer<List<string>> ();
-
- string tmp, s, basename;
- uint basedots, filedots;
- AppResourceFileInfo defaultFile;
-
- foreach (AppResourceFileInfo arfi in files) {
- if (arfi.Kind != AppResourceFileKind.ResX && arfi.Kind != AppResourceFileKind.Resource)
- continue;
- s = arfi.Info.FullName;
- basename = Path.GetFileNameWithoutExtension (s);
- basedots = CountChars ('.', basename);
- defaultFile = null;
-
- // If there are any files that start with this baseName, we have a default file
- foreach (AppResourceFileInfo fi in files) {
- if (fi.Seen)
- continue;
-
- string s2 = fi.Info.FullName;
- if (s2 == null || s == s2)
- continue;
- tmp = Path.GetFileNameWithoutExtension (s2);
- filedots = CountChars ('.', tmp);
- if (filedots == basedots + 1 && tmp.StartsWith (basename)) {
- if (IsFileCultureValid (s2) != null) {
- // A valid translated file for this name
- defaultFile = arfi;
- break;
- } else {
- // This file shares the base name, but the culture is invalid - we must
- // ignore it since the name of the generated strongly typed class for this
- // resource will clash with the one generated from the default file with
- // the given basename.
- fi.Seen = true;
- }
- }
- }
- if (defaultFile != null) {
- List<string> al = new List<string> ();
- al.Add (GetResourceFile (arfi, false));
- arfi.Seen = true;
- groups.Add (al);
-
- }
- }
- groups.Sort (lcList);
- string tmp2;
- // Now find their translated counterparts
- foreach (List<string> al in groups) {
- s = al [0];
- tmp = Path.GetFileNameWithoutExtension (s);
- if (tmp.StartsWith ("Resources."))
- tmp = tmp.Substring (10);
- foreach (AppResourceFileInfo arfi in files) {
- if (arfi.Seen)
- continue;
- s = arfi.Info.FullName;
- if (s == null)
- continue;
- tmp2 = arfi.Info.Name;
- if (tmp2.StartsWith (tmp)) {
- al.Add (GetResourceFile (arfi, false));
- arfi.Seen = true;
- }
- }
- }
- // Anything that's left here might be orphans or lone default files.
- // For those files we check the part following the last dot
- // before the .resx/.resource extensions and test whether it's a registered
- // culture or not. If it is not a culture, then we have a
- // default file that doesn't have any translations. Otherwise,
- // the file is ignored (it's the same thing MS.NET does)
- foreach (AppResourceFileInfo arfi in files) {
- if (arfi.Seen)
- continue;
- if (IsFileCultureValid (arfi.Info.FullName) != null)
- continue; // Culture found, we reject the file
- // A single default file, create a group
- List<string> al = new List<string> ();
- al.Add (GetResourceFile (arfi, false));
- groups.Add (al);
- }
- groups.Sort (lcList);
- return groups.ToArray ();
- }
- // CodeDOM generation
- void DomFromResource (string resfile, CodeCompileUnit unit, Dictionary <string,bool> assemblies,
- CodeDomProvider provider)
- {
- if (String.IsNullOrEmpty (resfile))
- return;
- string fname, nsname, classname;
- fname = Path.GetFileNameWithoutExtension (resfile);
- nsname = Path.GetFileNameWithoutExtension (fname);
- classname = Path.GetExtension (fname);
- if (classname == null || classname.Length == 0) {
- classname = nsname;
- nsname = "Resources";
- } else {
- if (!nsname.StartsWith ("Resources", StringComparison.InvariantCulture))
- nsname = String.Concat ("Resources.", nsname);
- classname = classname.Substring(1);
- }
- if (!String.IsNullOrEmpty (classname))
- classname = classname.Replace ('.', '_');
- if (!String.IsNullOrEmpty (nsname))
- nsname = nsname.Replace ('.', '_');
-
- if (!provider.IsValidIdentifier (nsname) || !provider.IsValidIdentifier (classname))
- throw new ApplicationException ("Invalid resource file name.");
- ResourceReader res;
- try {
- res = new ResourceReader (resfile);
- } catch (ArgumentException) {
- // invalid stream, probably empty - ignore silently and abort
- return;
- }
-
- CodeNamespace ns = new CodeNamespace (nsname);
- CodeTypeDeclaration cls = new CodeTypeDeclaration (classname);
- cls.IsClass = true;
- cls.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
- CodeMemberField cmf = new CodeMemberField (typeof(CultureInfo), "_culture");
- cmf.InitExpression = new CodePrimitiveExpression (null);
- cmf.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static;
- cls.Members.Add (cmf);
- cmf = new CodeMemberField (typeof(ResourceManager), "_resourceManager");
- cmf.InitExpression = new CodePrimitiveExpression (null);
- cmf.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static;
- cls.Members.Add (cmf);
-
- // Property: ResourceManager
- CodeMemberProperty cmp = new CodeMemberProperty ();
- cmp.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static;
- cmp.Name = "ResourceManager";
- cmp.HasGet = true;
- cmp.Type = new CodeTypeReference (typeof(ResourceManager));
- CodePropertyResourceManagerGet (cmp.GetStatements, resfile, classname);
- cls.Members.Add (cmp);
- // Property: Culture
- cmp = new CodeMemberProperty ();
- cmp.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- cmp.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static;
- cmp.Name = "Culture";
- cmp.HasGet = true;
- cmp.HasSet = true;
- cmp.Type = new CodeTypeReference (typeof(CultureInfo));
- CodePropertyGenericGet (cmp.GetStatements, "_culture", classname);
- CodePropertyGenericSet (cmp.SetStatements, "_culture", classname);
- cls.Members.Add (cmp);
- // Add the resource properties
- Dictionary<string,bool> imports = new Dictionary<string,bool> ();
- try {
- foreach (DictionaryEntry de in res) {
- Type type = de.Value.GetType ();
- if (!imports.ContainsKey (type.Namespace))
- imports [type.Namespace] = true;
- string asname = new AssemblyName (type.Assembly.FullName).Name;
- if (!assemblies.ContainsKey (asname))
- assemblies [asname] = true;
-
- cmp = new CodeMemberProperty ();
- cmp.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static;
- cmp.Name = SanitizeResourceName (provider, (string)de.Key);
- cmp.HasGet = true;
- CodePropertyResourceGet (cmp.GetStatements, (string)de.Key, type, classname);
- cmp.Type = new CodeTypeReference (type);
- cls.Members.Add (cmp);
- }
- } catch (Exception ex) {
- throw new ApplicationException ("Failed to compile global resources.", ex);
- }
- foreach (KeyValuePair<string,bool> de in imports)
- ns.Imports.Add (new CodeNamespaceImport(de.Key));
-
- ns.Types.Add (cls);
- unit.Namespaces.Add (ns);
- }
- static bool is_identifier_start_character (int c)
- {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || Char.IsLetter ((char)c);
- }
- static bool is_identifier_part_character (char c)
- {
- if (c >= 'a' && c <= 'z')
- return true;
- if (c >= 'A' && c <= 'Z')
- return true;
- if (c == '_' || (c >= '0' && c <= '9'))
- return true;
- if (c < 0x80)
- return false;
- return Char.IsLetter (c) || Char.GetUnicodeCategory (c) == UnicodeCategory.ConnectorPunctuation;
- }
-
- string SanitizeResourceName (CodeDomProvider provider, string name)
- {
- if (provider.IsValidIdentifier (name))
- return provider.CreateEscapedIdentifier (name);
- var sb = new StringBuilder ();
- char ch = name [0];
- if (is_identifier_start_character (ch))
- sb.Append (ch);
- else {
- sb.Append ('_');
- if (ch >= '0' && ch <= '9')
- sb.Append (ch);
- }
-
- for (int i = 1; i < name.Length; i++) {
- ch = name [i];
- if (is_identifier_part_character (ch))
- sb.Append (ch);
- else
- sb.Append ('_');
- }
-
- return provider.CreateEscapedIdentifier (sb.ToString ());
- }
-
- CodeObjectCreateExpression NewResourceManager (string name, string typename)
- {
- CodeExpression resname = new CodePrimitiveExpression (name);
- CodePropertyReferenceExpression asm = new CodePropertyReferenceExpression (
- new CodeTypeOfExpression (new CodeTypeReference (typename)),
- "Assembly");
-
- return new CodeObjectCreateExpression ("System.Resources.ResourceManager",
- new CodeExpression [] {resname, asm});
- }
-
- void CodePropertyResourceManagerGet (CodeStatementCollection csc, string resfile, string typename)
- {
- string name = Path.GetFileNameWithoutExtension (resfile);
- CodeStatement st;
- CodeExpression exp;
- exp = new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typename), "_resourceManager");
- st = new CodeConditionStatement (
- new CodeBinaryOperatorExpression (
- exp,
- CodeBinaryOperatorType.IdentityInequality,
- new CodePrimitiveExpression (null)),
- new CodeStatement [] { new CodeMethodReturnStatement (exp) });
- csc.Add (st);
- st = new CodeAssignStatement (exp, NewResourceManager (name, typename));
- csc.Add (st);
- csc.Add (new CodeMethodReturnStatement (exp));
- }
- void CodePropertyResourceGet (CodeStatementCollection csc, string resname, Type restype, string typename)
- {
- CodeStatement st = new CodeVariableDeclarationStatement (
- typeof (ResourceManager),
- "rm",
- new CodePropertyReferenceExpression (
- new CodeTypeReferenceExpression (typename), "ResourceManager"));
- csc.Add (st);
- st = new CodeConditionStatement (
- new CodeBinaryOperatorExpression (
- new CodeVariableReferenceExpression ("rm"),
- CodeBinaryOperatorType.IdentityEquality,
- new CodePrimitiveExpression (null)),
- new CodeStatement [] { new CodeMethodReturnStatement (new CodePrimitiveExpression (null)) });
- csc.Add (st);
- bool gotstr = (restype == typeof (string));
- CodeExpression exp = new CodeMethodInvokeExpression (
- new CodeVariableReferenceExpression ("rm"),
- gotstr ? "GetString" : "GetObject",
- new CodeExpression [] { new CodePrimitiveExpression (resname),
- new CodeFieldReferenceExpression (
- new CodeTypeReferenceExpression (typename), "_culture") });
- st = new CodeVariableDeclarationStatement (
- restype,
- "obj",
- gotstr ? exp : new CodeCastExpression (restype, exp));
- csc.Add (st);
- csc.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("obj")));
- }
-
- void CodePropertyGenericGet (CodeStatementCollection csc, string field, string typename)
- {
- csc.Add(new CodeMethodReturnStatement (
- new CodeFieldReferenceExpression (
- new CodeTypeReferenceExpression (typename), field)));
- }
- void CodePropertyGenericSet (CodeStatementCollection csc, string field, string typename)
- {
- csc.Add(new CodeAssignStatement (
- new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typename), field),
- new CodeVariableReferenceExpression ("value")));
- }
-
- string CompileResource (AppResourceFileInfo arfi, bool local)
- {
- string path = arfi.Info.FullName;
- string rname = Path.GetFileNameWithoutExtension (path) + ".resources";
- if (!local)
- rname = "Resources." + rname;
-
- string resource = Path.Combine (TempDirectory, rname);
- FileStream source = null, destination = null;
- IResourceReader reader = null;
- ResourceWriter writer = null;
- try {
- source = new FileStream (path, FileMode.Open, FileAccess.Read);
- destination = new FileStream (resource, FileMode.Create, FileAccess.Write);
- reader = GetReaderForKind (arfi.Kind, source, path);
- writer = new ResourceWriter (destination);
- foreach (DictionaryEntry de in reader) {
- object val = de.Value;
- if (val is string)
- writer.AddResource ((string)de.Key, (string)val);
- else
- writer.AddResource ((string)de.Key, val);
- }
- } catch (Exception ex) {
- throw new HttpException ("Failed to compile resource file", ex);
- } finally {
- if (reader != null)
- reader.Dispose ();
- if (source != null)
- source.Dispose ();
- if (writer != null)
- writer.Dispose ();
- if (destination != null)
- destination.Dispose ();
- }
-
- return resource;
- }
- IResourceReader GetReaderForKind (AppResourceFileKind kind, Stream stream, string path)
- {
- switch (kind) {
- case AppResourceFileKind.ResX:
- var ret = new ResXResourceReader (stream, new TypeResolutionService ());
- if (!String.IsNullOrEmpty (path))
- ret.BasePath = Path.GetDirectoryName (path);
- return ret;
- case AppResourceFileKind.Resource:
- return new ResourceReader (stream);
- default:
- return null;
- }
- }
-
-
- object OnCreateRandomFile (string path)
- {
- FileStream f = new FileStream (path, FileMode.CreateNew);
- f.Close ();
- return path;
- }
- };
- };
|