├── .gitattributes ├── .gitignore ├── CSharpMinifier.GUI ├── App.config ├── CSharpMinifier.GUI.csproj ├── Error.png ├── Ok.png ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── frmMain.Designer.cs ├── frmMain.cs └── frmMain.resx ├── CSharpMinifier.Tests ├── CSharpMinifier.Tests.csproj ├── IdGeneratorTests.cs ├── MinifierTests.cs ├── Properties │ └── AssemblyInfo.cs ├── Samples │ ├── EnumToIntConversion.cs │ ├── Minecraft19.cs │ ├── Minecraft20.cs │ ├── MiscCompression.cs │ ├── RLE.cs │ ├── Test1.cs │ └── Test2.cs └── packages.config ├── CSharpMinifier.sln ├── CSharpMinifier ├── CSharpMinifier.csproj ├── CompileUtils.cs ├── MinIdGenerator.cs ├── Minifier.cs ├── MinifierOptions.cs ├── MinifyEnumsAstVisitor.cs ├── MinifyLocalsAstVisitor.cs ├── MinifyMembersAstVisitor.cs ├── MinifyTypesAstVisitor.cs ├── NRefactoryUtils.cs ├── NameNode.cs ├── NamesGenerator.cs ├── Properties │ └── AssemblyInfo.cs ├── RandomIdGenerator.cs ├── ResolveResultType.cs ├── Substitutor.cs └── packages.config ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | .vs/ 45 | 46 | # Build results 47 | 48 | [Dd]ebug/ 49 | [Rr]elease/ 50 | x64/ 51 | build/ 52 | [Bb]in/ 53 | [Oo]bj/ 54 | 55 | # MSTest test Results 56 | [Tt]est[Rr]esult*/ 57 | [Bb]uild[Ll]og.* 58 | 59 | *_i.c 60 | *_p.c 61 | *.ilk 62 | *.meta 63 | *.obj 64 | *.pch 65 | *.pdb 66 | *.pgc 67 | *.pgd 68 | *.rsp 69 | *.sbr 70 | *.tlb 71 | *.tli 72 | *.tlh 73 | *.tmp 74 | *.tmp_proj 75 | *.log 76 | *.vspscc 77 | *.vssscc 78 | .builds 79 | *.pidb 80 | *.log 81 | *.scc 82 | 83 | # Visual C++ cache files 84 | ipch/ 85 | *.aps 86 | *.ncb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | 91 | # Visual Studio profiler 92 | *.psess 93 | *.vsp 94 | *.vspx 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | 103 | # TeamCity is a build add-in 104 | _TeamCity* 105 | 106 | # DotCover is a Code Coverage Tool 107 | *.dotCover 108 | 109 | # NCrunch 110 | *.ncrunch* 111 | .*crunch*.local.xml 112 | 113 | # Installshield output folder 114 | [Ee]xpress/ 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish/ 128 | 129 | # Publish Web Output 130 | *.Publish.xml 131 | *.pubxml 132 | 133 | # NuGet Packages Directory 134 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 135 | packages/ 136 | 137 | # Windows Azure Build Output 138 | csx 139 | *.build.csdef 140 | 141 | # Windows Store app package directory 142 | AppPackages/ 143 | 144 | # Others 145 | sql/ 146 | *.Cache 147 | ClientBin/ 148 | [Ss]tyle[Cc]op.* 149 | ~$* 150 | *~ 151 | *.dbmdl 152 | *.[Pp]ublish.xml 153 | *.pfx 154 | *.publishsettings 155 | 156 | # RIA/Silverlight projects 157 | Generated_Code/ 158 | 159 | # Backup & report files from converting an old project file to a newer 160 | # Visual Studio version. Backup files are not needed, because we have git ;-) 161 | _UpgradeReport_Files/ 162 | Backup*/ 163 | UpgradeLog*.XML 164 | UpgradeLog*.htm 165 | 166 | # SQL Server files 167 | App_Data/*.mdf 168 | App_Data/*.ldf 169 | 170 | ############# 171 | ## Windows detritus 172 | ############# 173 | 174 | # Windows image file caches 175 | Thumbs.db 176 | ehthumbs.db 177 | 178 | # Folder config file 179 | Desktop.ini 180 | 181 | # Recycle Bin used on file shares 182 | $RECYCLE.BIN/ 183 | 184 | # Mac crap 185 | .DS_Store 186 | 187 | 188 | ############# 189 | ## Python 190 | ############# 191 | 192 | *.py[co] 193 | 194 | # Packages 195 | *.egg 196 | *.egg-info 197 | dist/ 198 | build/ 199 | eggs/ 200 | parts/ 201 | var/ 202 | sdist/ 203 | develop-eggs/ 204 | .installed.cfg 205 | 206 | # Installer logs 207 | pip-log.txt 208 | 209 | # Unit test / coverage reports 210 | .coverage 211 | .tox 212 | 213 | #Translations 214 | *.mo 215 | 216 | #Mr Developer 217 | .mr.developer.cfg 218 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | True 15 | 16 | 17 | True 18 | 19 | 20 | 80 21 | 22 | 23 | False 24 | 25 | 26 | True 27 | 28 | 29 | True 30 | 31 | 32 | 0, 0 33 | 34 | 35 | 0, 0 36 | 37 | 38 | Normal 39 | 40 | 41 | 0 42 | 43 | 44 | True 45 | 46 | 47 | True 48 | 49 | 50 | False 51 | 52 | 53 | False 54 | 55 | 56 | True 57 | 58 | 59 | True 60 | 61 | 62 | True 63 | 64 | 65 | 66 | 67 | 68 | True 69 | 70 | 71 | True 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/CSharpMinifier.GUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1E6C7AB5-3E2F-4F5E-B5BD-B24E2258D0E2} 8 | WinExe 9 | Properties 10 | CSharpMinifier.GUI 11 | CSharpMinifier.GUI 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | false 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Form 47 | 48 | 49 | frmMain.cs 50 | 51 | 52 | 53 | 54 | frmMain.cs 55 | 56 | 57 | ResXFileCodeGenerator 58 | Resources.Designer.cs 59 | Designer 60 | 61 | 62 | True 63 | Resources.resx 64 | True 65 | 66 | 67 | SettingsSingleFileGenerator 68 | Settings.Designer.cs 69 | 70 | 71 | True 72 | Settings.settings 73 | True 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | {a26c936c-846b-4165-9574-42c74075d4cd} 82 | CSharpMinifier 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 99 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KvanTTT/CSharp-Minifier/887784c070e613f208e5e8b2952409077cb43110/CSharpMinifier.GUI/Error.png -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KvanTTT/CSharp-Minifier/887784c070e613f208e5e8b2952409077cb43110/CSharpMinifier.GUI/Ok.png -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace CSharpMinifier.GUI 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new frmMain()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CSharpMinifier.GUI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CSharpMinifier.GUI")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b98fd791-968a-4437-be08-881e2ecd212e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CSharpMinifier.GUI.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CSharpMinifier.GUI.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap Error { 67 | get { 68 | object obj = ResourceManager.GetObject("Error", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap Ok { 77 | get { 78 | object obj = ResourceManager.GetObject("Ok", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Error.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Ok.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CSharpMinifier.GUI.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 29 | public bool RemoveComments { 30 | get { 31 | return ((bool)(this["RemoveComments"])); 32 | } 33 | set { 34 | this["RemoveComments"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 41 | public bool RemoveSpaces { 42 | get { 43 | return ((bool)(this["RemoveSpaces"])); 44 | } 45 | set { 46 | this["RemoveSpaces"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("80")] 53 | public int LineLength { 54 | get { 55 | return ((int)(this["LineLength"])); 56 | } 57 | set { 58 | this["LineLength"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 65 | public bool MinifyFiles { 66 | get { 67 | return ((bool)(this["MinifyFiles"])); 68 | } 69 | set { 70 | this["MinifyFiles"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | public global::System.Collections.Specialized.StringCollection FileList { 77 | get { 78 | return ((global::System.Collections.Specialized.StringCollection)(this["FileList"])); 79 | } 80 | set { 81 | this["FileList"] = value; 82 | } 83 | } 84 | 85 | [global::System.Configuration.UserScopedSettingAttribute()] 86 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 87 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 88 | public bool RemoveRegions { 89 | get { 90 | return ((bool)(this["RemoveRegions"])); 91 | } 92 | set { 93 | this["RemoveRegions"] = value; 94 | } 95 | } 96 | 97 | [global::System.Configuration.UserScopedSettingAttribute()] 98 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 99 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 100 | public bool MiscCompressing { 101 | get { 102 | return ((bool)(this["MiscCompressing"])); 103 | } 104 | set { 105 | this["MiscCompressing"] = value; 106 | } 107 | } 108 | 109 | [global::System.Configuration.UserScopedSettingAttribute()] 110 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 111 | [global::System.Configuration.DefaultSettingValueAttribute("0, 0")] 112 | public global::System.Drawing.Point WindowLocation { 113 | get { 114 | return ((global::System.Drawing.Point)(this["WindowLocation"])); 115 | } 116 | set { 117 | this["WindowLocation"] = value; 118 | } 119 | } 120 | 121 | [global::System.Configuration.UserScopedSettingAttribute()] 122 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 123 | [global::System.Configuration.DefaultSettingValueAttribute("0, 0")] 124 | public global::System.Drawing.Size WindowSize { 125 | get { 126 | return ((global::System.Drawing.Size)(this["WindowSize"])); 127 | } 128 | set { 129 | this["WindowSize"] = value; 130 | } 131 | } 132 | 133 | [global::System.Configuration.UserScopedSettingAttribute()] 134 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 135 | [global::System.Configuration.DefaultSettingValueAttribute("Normal")] 136 | public string WindowState { 137 | get { 138 | return ((string)(this["WindowState"])); 139 | } 140 | set { 141 | this["WindowState"] = value; 142 | } 143 | } 144 | 145 | [global::System.Configuration.UserScopedSettingAttribute()] 146 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 147 | [global::System.Configuration.DefaultSettingValueAttribute("0")] 148 | public int InputPanelHeight { 149 | get { 150 | return ((int)(this["InputPanelHeight"])); 151 | } 152 | set { 153 | this["InputPanelHeight"] = value; 154 | } 155 | } 156 | 157 | [global::System.Configuration.UserScopedSettingAttribute()] 158 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 159 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 160 | public bool ConsoleApp { 161 | get { 162 | return ((bool)(this["ConsoleApp"])); 163 | } 164 | set { 165 | this["ConsoleApp"] = value; 166 | } 167 | } 168 | 169 | [global::System.Configuration.UserScopedSettingAttribute()] 170 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 171 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 172 | public bool RemoveNamespaces { 173 | get { 174 | return ((bool)(this["RemoveNamespaces"])); 175 | } 176 | set { 177 | this["RemoveNamespaces"] = value; 178 | } 179 | } 180 | 181 | [global::System.Configuration.UserScopedSettingAttribute()] 182 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 183 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 184 | public bool RemoveToStringMethods { 185 | get { 186 | return ((bool)(this["RemoveToStringMethods"])); 187 | } 188 | set { 189 | this["RemoveToStringMethods"] = value; 190 | } 191 | } 192 | 193 | [global::System.Configuration.UserScopedSettingAttribute()] 194 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 195 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 196 | public bool CompressPublic { 197 | get { 198 | return ((bool)(this["CompressPublic"])); 199 | } 200 | set { 201 | this["CompressPublic"] = value; 202 | } 203 | } 204 | 205 | [global::System.Configuration.UserScopedSettingAttribute()] 206 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 207 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 208 | public bool LocalVarsCompressing { 209 | get { 210 | return ((bool)(this["LocalVarsCompressing"])); 211 | } 212 | set { 213 | this["LocalVarsCompressing"] = value; 214 | } 215 | } 216 | 217 | [global::System.Configuration.UserScopedSettingAttribute()] 218 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 219 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 220 | public bool MembersCompressing { 221 | get { 222 | return ((bool)(this["MembersCompressing"])); 223 | } 224 | set { 225 | this["MembersCompressing"] = value; 226 | } 227 | } 228 | 229 | [global::System.Configuration.UserScopedSettingAttribute()] 230 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 231 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 232 | public bool TypesCompressing { 233 | get { 234 | return ((bool)(this["TypesCompressing"])); 235 | } 236 | set { 237 | this["TypesCompressing"] = value; 238 | } 239 | } 240 | 241 | [global::System.Configuration.UserScopedSettingAttribute()] 242 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 243 | [global::System.Configuration.DefaultSettingValueAttribute("")] 244 | public string Code { 245 | get { 246 | return ((string)(this["Code"])); 247 | } 248 | set { 249 | this["Code"] = value; 250 | } 251 | } 252 | 253 | [global::System.Configuration.UserScopedSettingAttribute()] 254 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 255 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 256 | public bool UselessMembersCompressing { 257 | get { 258 | return ((bool)(this["UselessMembersCompressing"])); 259 | } 260 | set { 261 | this["UselessMembersCompressing"] = value; 262 | } 263 | } 264 | 265 | [global::System.Configuration.UserScopedSettingAttribute()] 266 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 267 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 268 | public bool Unsafe { 269 | get { 270 | return ((bool)(this["Unsafe"])); 271 | } 272 | set { 273 | this["Unsafe"] = value; 274 | } 275 | } 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | True 7 | 8 | 9 | True 10 | 11 | 12 | 80 13 | 14 | 15 | False 16 | 17 | 18 | 19 | 20 | 21 | True 22 | 23 | 24 | True 25 | 26 | 27 | 0, 0 28 | 29 | 30 | 0, 0 31 | 32 | 33 | Normal 34 | 35 | 36 | 0 37 | 38 | 39 | True 40 | 41 | 42 | True 43 | 44 | 45 | False 46 | 47 | 48 | False 49 | 50 | 51 | True 52 | 53 | 54 | True 55 | 56 | 57 | True 58 | 59 | 60 | 61 | 62 | 63 | True 64 | 65 | 66 | True 67 | 68 | 69 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/frmMain.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CSharpMinifier.GUI 2 | { 3 | partial class frmMain 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmMain)); 32 | this.btnMinify = new System.Windows.Forms.Button(); 33 | this.splitContainer = new System.Windows.Forms.SplitContainer(); 34 | this.tbInput = new System.Windows.Forms.TextBox(); 35 | this.btnOpenFiles = new System.Windows.Forms.Button(); 36 | this.label4 = new System.Windows.Forms.Label(); 37 | this.lbInputFiles = new System.Windows.Forms.ListBox(); 38 | this.label1 = new System.Windows.Forms.Label(); 39 | this.tbOutput = new System.Windows.Forms.TextBox(); 40 | this.label2 = new System.Windows.Forms.Label(); 41 | this.cbRemoveSpaces = new System.Windows.Forms.CheckBox(); 42 | this.cbCompressLocalVars = new System.Windows.Forms.CheckBox(); 43 | this.cbRemoveComments = new System.Windows.Forms.CheckBox(); 44 | this.btnCopyToClipboard = new System.Windows.Forms.Button(); 45 | this.tbLineLength = new System.Windows.Forms.TextBox(); 46 | this.label3 = new System.Windows.Forms.Label(); 47 | this.ofdInputCodeFiles = new System.Windows.Forms.OpenFileDialog(); 48 | this.cbMinifyFiles = new System.Windows.Forms.CheckBox(); 49 | this.lblOutputCompilied = new System.Windows.Forms.Label(); 50 | this.lblInputCompilied = new System.Windows.Forms.Label(); 51 | this.cbRemoveRegions = new System.Windows.Forms.CheckBox(); 52 | this.cbCompressMisc = new System.Windows.Forms.CheckBox(); 53 | this.label5 = new System.Windows.Forms.Label(); 54 | this.label6 = new System.Windows.Forms.Label(); 55 | this.tbInputLength = new System.Windows.Forms.TextBox(); 56 | this.tbOutputLength = new System.Windows.Forms.TextBox(); 57 | this.tbOutputInputRatio = new System.Windows.Forms.TextBox(); 58 | this.label7 = new System.Windows.Forms.Label(); 59 | this.pbOutputCompilied = new System.Windows.Forms.PictureBox(); 60 | this.cbRemoveNamespaces = new System.Windows.Forms.CheckBox(); 61 | this.cbConsoleApp = new System.Windows.Forms.CheckBox(); 62 | this.cbRemoveToStringMethods = new System.Windows.Forms.CheckBox(); 63 | this.cbCompressPublic = new System.Windows.Forms.CheckBox(); 64 | this.cbCompressMemebers = new System.Windows.Forms.CheckBox(); 65 | this.cbCompressTypes = new System.Windows.Forms.CheckBox(); 66 | this.dgvErrors = new System.Windows.Forms.DataGridView(); 67 | this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); 68 | this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); 69 | this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); 70 | this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); 71 | this.label8 = new System.Windows.Forms.Label(); 72 | this.cbUselessMembersCompressing = new System.Windows.Forms.CheckBox(); 73 | this.cbEnumToIntConversion = new System.Windows.Forms.CheckBox(); 74 | this.cbUnsafe = new System.Windows.Forms.CheckBox(); 75 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit(); 76 | this.splitContainer.Panel1.SuspendLayout(); 77 | this.splitContainer.Panel2.SuspendLayout(); 78 | this.splitContainer.SuspendLayout(); 79 | ((System.ComponentModel.ISupportInitialize)(this.pbOutputCompilied)).BeginInit(); 80 | ((System.ComponentModel.ISupportInitialize)(this.dgvErrors)).BeginInit(); 81 | this.SuspendLayout(); 82 | // 83 | // btnMinify 84 | // 85 | this.btnMinify.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 86 | this.btnMinify.Location = new System.Drawing.Point(664, 392); 87 | this.btnMinify.Name = "btnMinify"; 88 | this.btnMinify.Size = new System.Drawing.Size(191, 26); 89 | this.btnMinify.TabIndex = 1; 90 | this.btnMinify.Text = "Minify"; 91 | this.btnMinify.UseVisualStyleBackColor = true; 92 | this.btnMinify.Click += new System.EventHandler(this.btnMinify_Click); 93 | // 94 | // splitContainer 95 | // 96 | this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 97 | | System.Windows.Forms.AnchorStyles.Left) 98 | | System.Windows.Forms.AnchorStyles.Right))); 99 | this.splitContainer.Location = new System.Drawing.Point(12, 12); 100 | this.splitContainer.Name = "splitContainer"; 101 | this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal; 102 | // 103 | // splitContainer.Panel1 104 | // 105 | this.splitContainer.Panel1.Controls.Add(this.tbInput); 106 | this.splitContainer.Panel1.Controls.Add(this.btnOpenFiles); 107 | this.splitContainer.Panel1.Controls.Add(this.label4); 108 | this.splitContainer.Panel1.Controls.Add(this.lbInputFiles); 109 | this.splitContainer.Panel1.Controls.Add(this.label1); 110 | // 111 | // splitContainer.Panel2 112 | // 113 | this.splitContainer.Panel2.Controls.Add(this.tbOutput); 114 | this.splitContainer.Panel2.Controls.Add(this.label2); 115 | this.splitContainer.Size = new System.Drawing.Size(645, 747); 116 | this.splitContainer.SplitterDistance = 364; 117 | this.splitContainer.TabIndex = 2; 118 | // 119 | // tbInput 120 | // 121 | this.tbInput.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 122 | | System.Windows.Forms.AnchorStyles.Left) 123 | | System.Windows.Forms.AnchorStyles.Right))); 124 | this.tbInput.Location = new System.Drawing.Point(8, 33); 125 | this.tbInput.Multiline = true; 126 | this.tbInput.Name = "tbInput"; 127 | this.tbInput.ScrollBars = System.Windows.Forms.ScrollBars.Both; 128 | this.tbInput.Size = new System.Drawing.Size(506, 325); 129 | this.tbInput.TabIndex = 11; 130 | this.tbInput.Text = resources.GetString("tbInput.Text"); 131 | this.tbInput.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbInput_KeyDown); 132 | // 133 | // btnOpenFiles 134 | // 135 | this.btnOpenFiles.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 136 | this.btnOpenFiles.Location = new System.Drawing.Point(551, 5); 137 | this.btnOpenFiles.Name = "btnOpenFiles"; 138 | this.btnOpenFiles.Size = new System.Drawing.Size(89, 23); 139 | this.btnOpenFiles.TabIndex = 9; 140 | this.btnOpenFiles.Text = "Open"; 141 | this.btnOpenFiles.UseVisualStyleBackColor = true; 142 | this.btnOpenFiles.Click += new System.EventHandler(this.btnOpenFiles_Click); 143 | // 144 | // label4 145 | // 146 | this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 147 | this.label4.AutoSize = true; 148 | this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 149 | this.label4.Location = new System.Drawing.Point(517, 10); 150 | this.label4.Name = "label4"; 151 | this.label4.Size = new System.Drawing.Size(37, 16); 152 | this.label4.TabIndex = 9; 153 | this.label4.Text = "Files"; 154 | // 155 | // lbInputFiles 156 | // 157 | this.lbInputFiles.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 158 | | System.Windows.Forms.AnchorStyles.Right))); 159 | this.lbInputFiles.FormattingEnabled = true; 160 | this.lbInputFiles.Location = new System.Drawing.Point(520, 33); 161 | this.lbInputFiles.Name = "lbInputFiles"; 162 | this.lbInputFiles.Size = new System.Drawing.Size(120, 316); 163 | this.lbInputFiles.TabIndex = 9; 164 | this.lbInputFiles.SelectedIndexChanged += new System.EventHandler(this.lbInputFiles_SelectedIndexChanged); 165 | // 166 | // label1 167 | // 168 | this.label1.AutoSize = true; 169 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 170 | this.label1.Location = new System.Drawing.Point(5, 10); 171 | this.label1.Name = "label1"; 172 | this.label1.Size = new System.Drawing.Size(36, 16); 173 | this.label1.TabIndex = 2; 174 | this.label1.Text = "Input"; 175 | // 176 | // tbOutput 177 | // 178 | this.tbOutput.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 179 | | System.Windows.Forms.AnchorStyles.Left) 180 | | System.Windows.Forms.AnchorStyles.Right))); 181 | this.tbOutput.Location = new System.Drawing.Point(8, 25); 182 | this.tbOutput.Multiline = true; 183 | this.tbOutput.Name = "tbOutput"; 184 | this.tbOutput.ReadOnly = true; 185 | this.tbOutput.ScrollBars = System.Windows.Forms.ScrollBars.Both; 186 | this.tbOutput.Size = new System.Drawing.Size(632, 351); 187 | this.tbOutput.TabIndex = 12; 188 | this.tbOutput.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbInput_KeyDown); 189 | // 190 | // label2 191 | // 192 | this.label2.AutoSize = true; 193 | this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 194 | this.label2.Location = new System.Drawing.Point(5, 6); 195 | this.label2.Name = "label2"; 196 | this.label2.Size = new System.Drawing.Size(46, 16); 197 | this.label2.TabIndex = 3; 198 | this.label2.Text = "Output"; 199 | // 200 | // cbRemoveSpaces 201 | // 202 | this.cbRemoveSpaces.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 203 | this.cbRemoveSpaces.AutoSize = true; 204 | this.cbRemoveSpaces.Checked = true; 205 | this.cbRemoveSpaces.CheckState = System.Windows.Forms.CheckState.Checked; 206 | this.cbRemoveSpaces.Location = new System.Drawing.Point(663, 86); 207 | this.cbRemoveSpaces.Name = "cbRemoveSpaces"; 208 | this.cbRemoveSpaces.Size = new System.Drawing.Size(166, 17); 209 | this.cbRemoveSpaces.TabIndex = 3; 210 | this.cbRemoveSpaces.Text = "Remove spaces && line breaks"; 211 | this.cbRemoveSpaces.UseVisualStyleBackColor = true; 212 | // 213 | // cbCompressLocalVars 214 | // 215 | this.cbCompressLocalVars.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 216 | this.cbCompressLocalVars.AutoSize = true; 217 | this.cbCompressLocalVars.Checked = true; 218 | this.cbCompressLocalVars.CheckState = System.Windows.Forms.CheckState.Checked; 219 | this.cbCompressLocalVars.Location = new System.Drawing.Point(663, 17); 220 | this.cbCompressLocalVars.Name = "cbCompressLocalVars"; 221 | this.cbCompressLocalVars.Size = new System.Drawing.Size(120, 17); 222 | this.cbCompressLocalVars.TabIndex = 4; 223 | this.cbCompressLocalVars.Text = "Compress local vars"; 224 | this.cbCompressLocalVars.UseVisualStyleBackColor = true; 225 | // 226 | // cbRemoveComments 227 | // 228 | this.cbRemoveComments.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 229 | this.cbRemoveComments.AutoSize = true; 230 | this.cbRemoveComments.Checked = true; 231 | this.cbRemoveComments.CheckState = System.Windows.Forms.CheckState.Checked; 232 | this.cbRemoveComments.Location = new System.Drawing.Point(663, 109); 233 | this.cbRemoveComments.Name = "cbRemoveComments"; 234 | this.cbRemoveComments.Size = new System.Drawing.Size(117, 17); 235 | this.cbRemoveComments.TabIndex = 5; 236 | this.cbRemoveComments.Text = "Remove comments"; 237 | this.cbRemoveComments.UseVisualStyleBackColor = true; 238 | // 239 | // btnCopyToClipboard 240 | // 241 | this.btnCopyToClipboard.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 242 | this.btnCopyToClipboard.Location = new System.Drawing.Point(665, 732); 243 | this.btnCopyToClipboard.Name = "btnCopyToClipboard"; 244 | this.btnCopyToClipboard.Size = new System.Drawing.Size(189, 26); 245 | this.btnCopyToClipboard.TabIndex = 6; 246 | this.btnCopyToClipboard.Text = "Copy to clipboard"; 247 | this.btnCopyToClipboard.UseVisualStyleBackColor = true; 248 | this.btnCopyToClipboard.Click += new System.EventHandler(this.btnCopyToClipboard_Click); 249 | // 250 | // tbLineLength 251 | // 252 | this.tbLineLength.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 253 | this.tbLineLength.Location = new System.Drawing.Point(744, 341); 254 | this.tbLineLength.Name = "tbLineLength"; 255 | this.tbLineLength.Size = new System.Drawing.Size(84, 20); 256 | this.tbLineLength.TabIndex = 7; 257 | this.tbLineLength.Text = "80"; 258 | this.tbLineLength.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 259 | // 260 | // label3 261 | // 262 | this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 263 | this.label3.AutoSize = true; 264 | this.label3.Location = new System.Drawing.Point(664, 344); 265 | this.label3.Name = "label3"; 266 | this.label3.Size = new System.Drawing.Size(63, 13); 267 | this.label3.TabIndex = 8; 268 | this.label3.Text = "Line Length"; 269 | // 270 | // ofdInputCodeFiles 271 | // 272 | this.ofdInputCodeFiles.Filter = "C# files|*.cs"; 273 | this.ofdInputCodeFiles.Multiselect = true; 274 | // 275 | // cbMinifyFiles 276 | // 277 | this.cbMinifyFiles.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 278 | this.cbMinifyFiles.AutoSize = true; 279 | this.cbMinifyFiles.Location = new System.Drawing.Point(667, 369); 280 | this.cbMinifyFiles.Name = "cbMinifyFiles"; 281 | this.cbMinifyFiles.Size = new System.Drawing.Size(47, 17); 282 | this.cbMinifyFiles.TabIndex = 9; 283 | this.cbMinifyFiles.Text = "Files"; 284 | this.cbMinifyFiles.UseVisualStyleBackColor = true; 285 | // 286 | // lblOutputCompilied 287 | // 288 | this.lblOutputCompilied.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 289 | this.lblOutputCompilied.AutoSize = true; 290 | this.lblOutputCompilied.Location = new System.Drawing.Point(706, 703); 291 | this.lblOutputCompilied.Name = "lblOutputCompilied"; 292 | this.lblOutputCompilied.Size = new System.Drawing.Size(0, 13); 293 | this.lblOutputCompilied.TabIndex = 11; 294 | // 295 | // lblInputCompilied 296 | // 297 | this.lblInputCompilied.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 298 | this.lblInputCompilied.AutoSize = true; 299 | this.lblInputCompilied.Location = new System.Drawing.Point(706, 703); 300 | this.lblInputCompilied.Name = "lblInputCompilied"; 301 | this.lblInputCompilied.Size = new System.Drawing.Size(0, 13); 302 | this.lblInputCompilied.TabIndex = 13; 303 | this.lblInputCompilied.Visible = false; 304 | // 305 | // cbRemoveRegions 306 | // 307 | this.cbRemoveRegions.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 308 | this.cbRemoveRegions.AutoSize = true; 309 | this.cbRemoveRegions.Checked = true; 310 | this.cbRemoveRegions.CheckState = System.Windows.Forms.CheckState.Checked; 311 | this.cbRemoveRegions.Location = new System.Drawing.Point(663, 132); 312 | this.cbRemoveRegions.Name = "cbRemoveRegions"; 313 | this.cbRemoveRegions.Size = new System.Drawing.Size(103, 17); 314 | this.cbRemoveRegions.TabIndex = 14; 315 | this.cbRemoveRegions.Text = "Remove regions"; 316 | this.cbRemoveRegions.UseVisualStyleBackColor = true; 317 | // 318 | // cbCompressMisc 319 | // 320 | this.cbCompressMisc.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 321 | this.cbCompressMisc.AutoSize = true; 322 | this.cbCompressMisc.Checked = true; 323 | this.cbCompressMisc.CheckState = System.Windows.Forms.CheckState.Checked; 324 | this.cbCompressMisc.Location = new System.Drawing.Point(663, 155); 325 | this.cbCompressMisc.Name = "cbCompressMisc"; 326 | this.cbCompressMisc.Size = new System.Drawing.Size(97, 17); 327 | this.cbCompressMisc.TabIndex = 15; 328 | this.cbCompressMisc.Text = "Compress Misc"; 329 | this.cbCompressMisc.UseVisualStyleBackColor = true; 330 | // 331 | // label5 332 | // 333 | this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 334 | this.label5.AutoSize = true; 335 | this.label5.Location = new System.Drawing.Point(664, 614); 336 | this.label5.Name = "label5"; 337 | this.label5.Size = new System.Drawing.Size(67, 13); 338 | this.label5.TabIndex = 16; 339 | this.label5.Text = "Input Length"; 340 | // 341 | // label6 342 | // 343 | this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 344 | this.label6.AutoSize = true; 345 | this.label6.Location = new System.Drawing.Point(664, 641); 346 | this.label6.Name = "label6"; 347 | this.label6.Size = new System.Drawing.Size(75, 13); 348 | this.label6.TabIndex = 17; 349 | this.label6.Text = "Output Length"; 350 | // 351 | // tbInputLength 352 | // 353 | this.tbInputLength.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 354 | this.tbInputLength.Location = new System.Drawing.Point(756, 611); 355 | this.tbInputLength.Name = "tbInputLength"; 356 | this.tbInputLength.ReadOnly = true; 357 | this.tbInputLength.Size = new System.Drawing.Size(72, 20); 358 | this.tbInputLength.TabIndex = 18; 359 | // 360 | // tbOutputLength 361 | // 362 | this.tbOutputLength.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 363 | this.tbOutputLength.Location = new System.Drawing.Point(756, 640); 364 | this.tbOutputLength.Name = "tbOutputLength"; 365 | this.tbOutputLength.ReadOnly = true; 366 | this.tbOutputLength.Size = new System.Drawing.Size(72, 20); 367 | this.tbOutputLength.TabIndex = 19; 368 | // 369 | // tbOutputInputRatio 370 | // 371 | this.tbOutputInputRatio.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 372 | this.tbOutputInputRatio.Location = new System.Drawing.Point(756, 666); 373 | this.tbOutputInputRatio.Name = "tbOutputInputRatio"; 374 | this.tbOutputInputRatio.ReadOnly = true; 375 | this.tbOutputInputRatio.Size = new System.Drawing.Size(72, 20); 376 | this.tbOutputInputRatio.TabIndex = 21; 377 | // 378 | // label7 379 | // 380 | this.label7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 381 | this.label7.AutoSize = true; 382 | this.label7.Location = new System.Drawing.Point(664, 669); 383 | this.label7.Name = "label7"; 384 | this.label7.Size = new System.Drawing.Size(32, 13); 385 | this.label7.TabIndex = 20; 386 | this.label7.Text = "Ratio"; 387 | // 388 | // pbOutputCompilied 389 | // 390 | this.pbOutputCompilied.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 391 | this.pbOutputCompilied.Location = new System.Drawing.Point(668, 693); 392 | this.pbOutputCompilied.Name = "pbOutputCompilied"; 393 | this.pbOutputCompilied.Size = new System.Drawing.Size(35, 33); 394 | this.pbOutputCompilied.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 395 | this.pbOutputCompilied.TabIndex = 10; 396 | this.pbOutputCompilied.TabStop = false; 397 | // 398 | // cbRemoveNamespaces 399 | // 400 | this.cbRemoveNamespaces.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 401 | this.cbRemoveNamespaces.AutoSize = true; 402 | this.cbRemoveNamespaces.Checked = true; 403 | this.cbRemoveNamespaces.CheckState = System.Windows.Forms.CheckState.Checked; 404 | this.cbRemoveNamespaces.Location = new System.Drawing.Point(663, 201); 405 | this.cbRemoveNamespaces.Name = "cbRemoveNamespaces"; 406 | this.cbRemoveNamespaces.Size = new System.Drawing.Size(131, 17); 407 | this.cbRemoveNamespaces.TabIndex = 22; 408 | this.cbRemoveNamespaces.Text = "Remove Namespaces"; 409 | this.cbRemoveNamespaces.UseVisualStyleBackColor = true; 410 | // 411 | // cbConsoleApp 412 | // 413 | this.cbConsoleApp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 414 | this.cbConsoleApp.AutoSize = true; 415 | this.cbConsoleApp.Checked = true; 416 | this.cbConsoleApp.CheckState = System.Windows.Forms.CheckState.Checked; 417 | this.cbConsoleApp.Location = new System.Drawing.Point(663, 178); 418 | this.cbConsoleApp.Name = "cbConsoleApp"; 419 | this.cbConsoleApp.Size = new System.Drawing.Size(86, 17); 420 | this.cbConsoleApp.TabIndex = 23; 421 | this.cbConsoleApp.Text = "Console App"; 422 | this.cbConsoleApp.UseVisualStyleBackColor = true; 423 | // 424 | // cbRemoveToStringMethods 425 | // 426 | this.cbRemoveToStringMethods.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 427 | this.cbRemoveToStringMethods.AutoSize = true; 428 | this.cbRemoveToStringMethods.Checked = true; 429 | this.cbRemoveToStringMethods.CheckState = System.Windows.Forms.CheckState.Checked; 430 | this.cbRemoveToStringMethods.Location = new System.Drawing.Point(663, 247); 431 | this.cbRemoveToStringMethods.Name = "cbRemoveToStringMethods"; 432 | this.cbRemoveToStringMethods.Size = new System.Drawing.Size(115, 17); 433 | this.cbRemoveToStringMethods.TabIndex = 24; 434 | this.cbRemoveToStringMethods.Text = "Remove ToString()"; 435 | this.cbRemoveToStringMethods.UseVisualStyleBackColor = true; 436 | // 437 | // cbCompressPublic 438 | // 439 | this.cbCompressPublic.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 440 | this.cbCompressPublic.AutoSize = true; 441 | this.cbCompressPublic.Checked = true; 442 | this.cbCompressPublic.CheckState = System.Windows.Forms.CheckState.Checked; 443 | this.cbCompressPublic.Location = new System.Drawing.Point(663, 224); 444 | this.cbCompressPublic.Name = "cbCompressPublic"; 445 | this.cbCompressPublic.Size = new System.Drawing.Size(104, 17); 446 | this.cbCompressPublic.TabIndex = 25; 447 | this.cbCompressPublic.Text = "Compress Public"; 448 | this.cbCompressPublic.UseVisualStyleBackColor = true; 449 | // 450 | // cbCompressMemebers 451 | // 452 | this.cbCompressMemebers.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 453 | this.cbCompressMemebers.AutoSize = true; 454 | this.cbCompressMemebers.Checked = true; 455 | this.cbCompressMemebers.CheckState = System.Windows.Forms.CheckState.Checked; 456 | this.cbCompressMemebers.Location = new System.Drawing.Point(663, 40); 457 | this.cbCompressMemebers.Name = "cbCompressMemebers"; 458 | this.cbCompressMemebers.Size = new System.Drawing.Size(123, 17); 459 | this.cbCompressMemebers.TabIndex = 26; 460 | this.cbCompressMemebers.Text = "Compress memebers"; 461 | this.cbCompressMemebers.UseVisualStyleBackColor = true; 462 | // 463 | // cbCompressTypes 464 | // 465 | this.cbCompressTypes.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 466 | this.cbCompressTypes.AutoSize = true; 467 | this.cbCompressTypes.Checked = true; 468 | this.cbCompressTypes.CheckState = System.Windows.Forms.CheckState.Checked; 469 | this.cbCompressTypes.Location = new System.Drawing.Point(663, 63); 470 | this.cbCompressTypes.Name = "cbCompressTypes"; 471 | this.cbCompressTypes.Size = new System.Drawing.Size(100, 17); 472 | this.cbCompressTypes.TabIndex = 27; 473 | this.cbCompressTypes.Text = "Compress types"; 474 | this.cbCompressTypes.UseVisualStyleBackColor = true; 475 | // 476 | // dgvErrors 477 | // 478 | this.dgvErrors.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 479 | this.dgvErrors.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 480 | this.dgvErrors.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 481 | this.Column1, 482 | this.Column2, 483 | this.Column3, 484 | this.Column4}); 485 | this.dgvErrors.Location = new System.Drawing.Point(665, 480); 486 | this.dgvErrors.Name = "dgvErrors"; 487 | this.dgvErrors.ReadOnly = true; 488 | this.dgvErrors.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 489 | this.dgvErrors.Size = new System.Drawing.Size(189, 111); 490 | this.dgvErrors.TabIndex = 28; 491 | this.dgvErrors.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvErrors_CellMouseDoubleClick); 492 | // 493 | // Column1 494 | // 495 | this.Column1.HeaderText = "Line"; 496 | this.Column1.Name = "Column1"; 497 | this.Column1.ReadOnly = true; 498 | this.Column1.Width = 52; 499 | // 500 | // Column2 501 | // 502 | this.Column2.HeaderText = "Row"; 503 | this.Column2.Name = "Column2"; 504 | this.Column2.ReadOnly = true; 505 | this.Column2.Width = 54; 506 | // 507 | // Column3 508 | // 509 | this.Column3.HeaderText = "Description"; 510 | this.Column3.Name = "Column3"; 511 | this.Column3.ReadOnly = true; 512 | this.Column3.Width = 85; 513 | // 514 | // Column4 515 | // 516 | this.Column4.HeaderText = "Field"; 517 | this.Column4.Name = "Column4"; 518 | this.Column4.ReadOnly = true; 519 | this.Column4.Width = 54; 520 | // 521 | // label8 522 | // 523 | this.label8.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 524 | this.label8.AutoSize = true; 525 | this.label8.Location = new System.Drawing.Point(663, 437); 526 | this.label8.Name = "label8"; 527 | this.label8.Size = new System.Drawing.Size(34, 13); 528 | this.label8.TabIndex = 29; 529 | this.label8.Text = "Errors"; 530 | // 531 | // cbUselessMembersCompressing 532 | // 533 | this.cbUselessMembersCompressing.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 534 | this.cbUselessMembersCompressing.AutoSize = true; 535 | this.cbUselessMembersCompressing.Checked = true; 536 | this.cbUselessMembersCompressing.CheckState = System.Windows.Forms.CheckState.Checked; 537 | this.cbUselessMembersCompressing.Location = new System.Drawing.Point(663, 270); 538 | this.cbUselessMembersCompressing.Name = "cbUselessMembersCompressing"; 539 | this.cbUselessMembersCompressing.Size = new System.Drawing.Size(172, 17); 540 | this.cbUselessMembersCompressing.TabIndex = 30; 541 | this.cbUselessMembersCompressing.Text = "Useless Members Compressing"; 542 | this.cbUselessMembersCompressing.UseVisualStyleBackColor = true; 543 | // 544 | // cbEnumToIntConversion 545 | // 546 | this.cbEnumToIntConversion.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 547 | this.cbEnumToIntConversion.AutoSize = true; 548 | this.cbEnumToIntConversion.Checked = true; 549 | this.cbEnumToIntConversion.CheckState = System.Windows.Forms.CheckState.Checked; 550 | this.cbEnumToIntConversion.Location = new System.Drawing.Point(663, 293); 551 | this.cbEnumToIntConversion.Name = "cbEnumToIntConversion"; 552 | this.cbEnumToIntConversion.Size = new System.Drawing.Size(140, 17); 553 | this.cbEnumToIntConversion.TabIndex = 31; 554 | this.cbEnumToIntConversion.Text = "Enum To Int Conversion"; 555 | this.cbEnumToIntConversion.UseVisualStyleBackColor = true; 556 | // 557 | // cbUnsafe 558 | // 559 | this.cbUnsafe.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 560 | this.cbUnsafe.AutoSize = true; 561 | this.cbUnsafe.Checked = true; 562 | this.cbUnsafe.CheckState = System.Windows.Forms.CheckState.Checked; 563 | this.cbUnsafe.Location = new System.Drawing.Point(663, 316); 564 | this.cbUnsafe.Name = "cbUnsafe"; 565 | this.cbUnsafe.Size = new System.Drawing.Size(60, 17); 566 | this.cbUnsafe.TabIndex = 32; 567 | this.cbUnsafe.Text = "Unsafe"; 568 | this.cbUnsafe.UseVisualStyleBackColor = true; 569 | // 570 | // frmMain 571 | // 572 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 573 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 574 | this.ClientSize = new System.Drawing.Size(866, 771); 575 | this.Controls.Add(this.cbUnsafe); 576 | this.Controls.Add(this.cbEnumToIntConversion); 577 | this.Controls.Add(this.cbUselessMembersCompressing); 578 | this.Controls.Add(this.label8); 579 | this.Controls.Add(this.dgvErrors); 580 | this.Controls.Add(this.cbCompressTypes); 581 | this.Controls.Add(this.cbCompressMemebers); 582 | this.Controls.Add(this.cbCompressPublic); 583 | this.Controls.Add(this.cbRemoveToStringMethods); 584 | this.Controls.Add(this.cbConsoleApp); 585 | this.Controls.Add(this.cbRemoveNamespaces); 586 | this.Controls.Add(this.tbOutputInputRatio); 587 | this.Controls.Add(this.label7); 588 | this.Controls.Add(this.tbOutputLength); 589 | this.Controls.Add(this.tbInputLength); 590 | this.Controls.Add(this.label6); 591 | this.Controls.Add(this.label5); 592 | this.Controls.Add(this.cbCompressMisc); 593 | this.Controls.Add(this.cbRemoveRegions); 594 | this.Controls.Add(this.lblInputCompilied); 595 | this.Controls.Add(this.lblOutputCompilied); 596 | this.Controls.Add(this.pbOutputCompilied); 597 | this.Controls.Add(this.cbMinifyFiles); 598 | this.Controls.Add(this.label3); 599 | this.Controls.Add(this.tbLineLength); 600 | this.Controls.Add(this.btnCopyToClipboard); 601 | this.Controls.Add(this.cbRemoveComments); 602 | this.Controls.Add(this.cbCompressLocalVars); 603 | this.Controls.Add(this.cbRemoveSpaces); 604 | this.Controls.Add(this.splitContainer); 605 | this.Controls.Add(this.btnMinify); 606 | this.Name = "frmMain"; 607 | this.Text = "C# Minifier"; 608 | this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.frmMain_FormClosed); 609 | this.splitContainer.Panel1.ResumeLayout(false); 610 | this.splitContainer.Panel1.PerformLayout(); 611 | this.splitContainer.Panel2.ResumeLayout(false); 612 | this.splitContainer.Panel2.PerformLayout(); 613 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit(); 614 | this.splitContainer.ResumeLayout(false); 615 | ((System.ComponentModel.ISupportInitialize)(this.pbOutputCompilied)).EndInit(); 616 | ((System.ComponentModel.ISupportInitialize)(this.dgvErrors)).EndInit(); 617 | this.ResumeLayout(false); 618 | this.PerformLayout(); 619 | 620 | } 621 | 622 | #endregion 623 | 624 | private System.Windows.Forms.Button btnMinify; 625 | private System.Windows.Forms.SplitContainer splitContainer; 626 | private System.Windows.Forms.Label label1; 627 | private System.Windows.Forms.Label label2; 628 | private System.Windows.Forms.CheckBox cbRemoveSpaces; 629 | private System.Windows.Forms.CheckBox cbCompressLocalVars; 630 | private System.Windows.Forms.CheckBox cbRemoveComments; 631 | private System.Windows.Forms.Button btnCopyToClipboard; 632 | private System.Windows.Forms.TextBox tbLineLength; 633 | private System.Windows.Forms.Label label3; 634 | private System.Windows.Forms.Button btnOpenFiles; 635 | private System.Windows.Forms.Label label4; 636 | private System.Windows.Forms.ListBox lbInputFiles; 637 | private System.Windows.Forms.OpenFileDialog ofdInputCodeFiles; 638 | private System.Windows.Forms.CheckBox cbMinifyFiles; 639 | private System.Windows.Forms.PictureBox pbOutputCompilied; 640 | private System.Windows.Forms.Label lblOutputCompilied; 641 | private System.Windows.Forms.Label lblInputCompilied; 642 | private System.Windows.Forms.CheckBox cbRemoveRegions; 643 | private System.Windows.Forms.CheckBox cbCompressMisc; 644 | private System.Windows.Forms.Label label5; 645 | private System.Windows.Forms.Label label6; 646 | private System.Windows.Forms.TextBox tbInputLength; 647 | private System.Windows.Forms.TextBox tbOutputLength; 648 | private System.Windows.Forms.TextBox tbOutputInputRatio; 649 | private System.Windows.Forms.Label label7; 650 | private System.Windows.Forms.CheckBox cbRemoveNamespaces; 651 | private System.Windows.Forms.CheckBox cbConsoleApp; 652 | private System.Windows.Forms.CheckBox cbRemoveToStringMethods; 653 | private System.Windows.Forms.CheckBox cbCompressPublic; 654 | private System.Windows.Forms.CheckBox cbCompressMemebers; 655 | private System.Windows.Forms.CheckBox cbCompressTypes; 656 | private System.Windows.Forms.DataGridView dgvErrors; 657 | private System.Windows.Forms.Label label8; 658 | private System.Windows.Forms.DataGridViewTextBoxColumn Column1; 659 | private System.Windows.Forms.DataGridViewTextBoxColumn Column2; 660 | private System.Windows.Forms.DataGridViewTextBoxColumn Column3; 661 | private System.Windows.Forms.DataGridViewTextBoxColumn Column4; 662 | private System.Windows.Forms.CheckBox cbUselessMembersCompressing; 663 | private System.Windows.Forms.TextBox tbInput; 664 | private System.Windows.Forms.TextBox tbOutput; 665 | private System.Windows.Forms.CheckBox cbEnumToIntConversion; 666 | private System.Windows.Forms.CheckBox cbUnsafe; 667 | } 668 | } 669 | 670 | -------------------------------------------------------------------------------- /CSharpMinifier.GUI/frmMain.cs: -------------------------------------------------------------------------------- 1 | using CSharpMinifier.GUI.Properties; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Collections.Specialized; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Windows.Forms; 8 | 9 | namespace CSharpMinifier.GUI 10 | { 11 | public partial class frmMain : Form 12 | { 13 | class ListBoxItem 14 | { 15 | public string Key { get; set; } 16 | public string Value { get; set; } 17 | 18 | public ListBoxItem(string key, string value) 19 | { 20 | Key = key; 21 | Value = value; 22 | } 23 | 24 | public override string ToString() 25 | { 26 | return Value; 27 | } 28 | } 29 | 30 | void FillList(string[] fileNames) 31 | { 32 | Sources = new Dictionary(); 33 | foreach (var fileName in fileNames) 34 | { 35 | var lbItem = new ListBoxItem(fileName, Path.GetFileName(fileName)); 36 | try 37 | { 38 | Sources[lbItem.Key] = File.ReadAllText(lbItem.Key); 39 | lbInputFiles.Items.Add(lbItem); 40 | } 41 | catch 42 | { 43 | } 44 | } 45 | } 46 | 47 | Dictionary Sources = new Dictionary(); 48 | 49 | public frmMain() 50 | { 51 | InitializeComponent(); 52 | 53 | if (!Settings.Default.WindowLocation.IsEmpty) 54 | Location = Settings.Default.WindowLocation; 55 | if (!Settings.Default.WindowSize.IsEmpty) 56 | Size = Settings.Default.WindowSize; 57 | WindowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), Settings.Default.WindowState); 58 | if (Settings.Default.InputPanelHeight != 0) 59 | splitContainer.SplitterDistance = Settings.Default.InputPanelHeight; 60 | cbRemoveComments.Checked = Settings.Default.RemoveComments; 61 | cbRemoveRegions.Checked = Settings.Default.RemoveRegions; 62 | cbCompressLocalVars.Checked = Settings.Default.LocalVarsCompressing; 63 | cbCompressMemebers.Checked = Settings.Default.MembersCompressing; 64 | cbCompressTypes.Checked = Settings.Default.TypesCompressing; 65 | cbRemoveSpaces.Checked = Settings.Default.RemoveSpaces; 66 | cbCompressMisc.Checked = Settings.Default.MiscCompressing; 67 | cbRemoveNamespaces.Checked = Settings.Default.RemoveNamespaces; 68 | cbConsoleApp.Checked = Settings.Default.ConsoleApp; 69 | tbLineLength.Text = Settings.Default.LineLength.ToString(); 70 | cbMinifyFiles.Checked = Settings.Default.MinifyFiles; 71 | if (Settings.Default.FileList != null) 72 | FillList(Settings.Default.FileList.Cast().ToArray()); 73 | tbInput.Text = Settings.Default.Code; 74 | cbCompressPublic.Checked = Settings.Default.CompressPublic; 75 | cbRemoveToStringMethods.Checked = Settings.Default.RemoveToStringMethods; 76 | cbUselessMembersCompressing.Checked = Settings.Default.UselessMembersCompressing; 77 | cbUnsafe.Checked = Settings.Default.Unsafe; 78 | } 79 | 80 | private void frmMain_FormClosed(object sender, FormClosedEventArgs e) 81 | { 82 | Settings.Default.WindowLocation = Location; 83 | Settings.Default.WindowSize = Size; 84 | Settings.Default.WindowState = WindowState.ToString(); 85 | Settings.Default.InputPanelHeight = splitContainer.Panel1.Height; 86 | Settings.Default.RemoveComments = cbRemoveComments.Checked; 87 | Settings.Default.RemoveRegions = cbRemoveRegions.Checked; 88 | Settings.Default.LocalVarsCompressing = cbCompressLocalVars.Checked; 89 | Settings.Default.MembersCompressing = cbCompressMemebers.Checked; 90 | Settings.Default.TypesCompressing = cbCompressTypes.Checked; 91 | Settings.Default.RemoveSpaces = cbRemoveSpaces.Checked; 92 | Settings.Default.MiscCompressing = cbCompressMisc.Checked; 93 | Settings.Default.ConsoleApp = cbConsoleApp.Checked; 94 | Settings.Default.RemoveNamespaces = cbRemoveNamespaces.Checked; 95 | Settings.Default.LineLength = int.Parse(tbLineLength.Text); 96 | Settings.Default.MinifyFiles = cbMinifyFiles.Checked; 97 | var stringCollection = new StringCollection(); 98 | foreach (var fileName in Sources) 99 | stringCollection.Add(fileName.Key); 100 | Settings.Default.FileList = stringCollection; 101 | Settings.Default.Code = tbInput.Text; 102 | Settings.Default.CompressPublic = cbCompressPublic.Checked; 103 | Settings.Default.RemoveToStringMethods = cbRemoveToStringMethods.Checked; 104 | Settings.Default.UselessMembersCompressing = cbUselessMembersCompressing.Checked; 105 | Settings.Default.Unsafe = cbUnsafe.Checked; 106 | Settings.Default.Save(); 107 | } 108 | 109 | private void btnMinify_Click(object sender, EventArgs e) 110 | { 111 | var minifierOptions = new MinifierOptions 112 | { 113 | LocalVarsCompressing = cbCompressLocalVars.Checked, 114 | MembersCompressing = cbCompressMemebers.Checked, 115 | TypesCompressing = cbCompressTypes.Checked, 116 | SpacesRemoving = cbRemoveSpaces.Checked, 117 | RegionsRemoving = cbRemoveRegions.Checked, 118 | CommentsRemoving = cbRemoveComments.Checked, 119 | MiscCompressing = cbCompressMisc.Checked, 120 | ConsoleApp = cbConsoleApp.Checked, 121 | NamespacesRemoving = cbRemoveNamespaces.Checked, 122 | LineLength = int.Parse(tbLineLength.Text), 123 | ToStringMethodsRemoving = cbRemoveToStringMethods.Checked, 124 | PublicCompressing = cbCompressPublic.Checked, 125 | EnumToIntConversion = cbEnumToIntConversion.Checked, 126 | Unsafe = cbUnsafe.Checked 127 | }; 128 | Minifier minifier = new Minifier(minifierOptions); 129 | tbOutput.Text = !cbMinifyFiles.Checked ? minifier.MinifyFromString(tbInput.Text) : minifier.MinifyFiles(Sources.Select(source => source.Value).ToArray()); 130 | 131 | tbInputLength.Text = tbInput.Text.Length.ToString(); 132 | tbOutputLength.Text = tbOutput.Text.Length.ToString(); 133 | tbOutputInputRatio.Text = ((double)tbOutput.Text.Length / tbInput.Text.Length).ToString("0.000000"); 134 | var compileResult = CompileUtils.Compile(tbOutput.Text); 135 | dgvErrors.Rows.Clear(); 136 | if (!compileResult.Errors.HasErrors) 137 | { 138 | pbOutputCompilied.Image = Resources.Ok; 139 | lblOutputCompilied.Text = "Compilied"; 140 | } 141 | else 142 | { 143 | pbOutputCompilied.Image = Resources.Error; 144 | lblOutputCompilied.Text = "Not compilied"; 145 | for (int i = 0; i < compileResult.Errors.Count; i++) 146 | { 147 | var error = compileResult.Errors[i]; 148 | dgvErrors.Rows.Add(error.Line.ToString(), error.Column.ToString(), 149 | error.ErrorText, "output"); 150 | } 151 | } 152 | } 153 | 154 | private void btnCopyToClipboard_Click(object sender, EventArgs e) 155 | { 156 | if (!string.IsNullOrEmpty(tbOutput.Text)) 157 | Clipboard.SetText(tbOutput.Text); 158 | } 159 | 160 | private void btnOpenFiles_Click(object sender, EventArgs e) 161 | { 162 | if (ofdInputCodeFiles.ShowDialog() == DialogResult.OK) 163 | { 164 | FillList(ofdInputCodeFiles.FileNames); 165 | } 166 | } 167 | 168 | private void lbInputFiles_SelectedIndexChanged(object sender, EventArgs e) 169 | { 170 | try 171 | { 172 | if (lbInputFiles.SelectedIndex != -1) 173 | { 174 | tbInput.Text = Sources[((ListBoxItem)lbInputFiles.SelectedItem).Key]; 175 | } 176 | } 177 | catch 178 | { 179 | } 180 | } 181 | 182 | private void tbInput_Load(object sender, EventArgs e) 183 | { 184 | } 185 | 186 | private void dgvErrors_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) 187 | { 188 | if (dgvErrors.SelectedRows.Count > 0) 189 | { 190 | var cells = dgvErrors.SelectedRows[0].Cells; 191 | bool input = cells[3].Value.ToString() == "input"; 192 | var textBox = input ? tbInput : tbOutput; 193 | int line = Convert.ToInt32(cells[0].Value); 194 | int column = Convert.ToInt32(cells[1].Value); 195 | var pos = GetPosFromLineColumn(textBox.Text, line, column); 196 | textBox.Select(pos, 0); 197 | textBox.ScrollToCaret(); 198 | textBox.Focus(); 199 | } 200 | } 201 | 202 | private int GetPosFromLineColumn(string text, int line, int column) 203 | { 204 | var strs = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); 205 | return strs.Take(line - 1).Aggregate(0, (count, str) => count += str.Length + Environment.NewLine.Length) + column - 1; 206 | } 207 | 208 | private void tbInput_KeyDown(object sender, KeyEventArgs e) 209 | { 210 | if (e.Control && e.KeyCode == Keys.A) 211 | { 212 | if (sender != null) 213 | ((TextBox)sender).SelectAll(); 214 | e.Handled = true; 215 | } 216 | } 217 | } 218 | } -------------------------------------------------------------------------------- /CSharpMinifier.GUI/frmMain.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | // Comment at the begin 122 | using System; 123 | namespace A 124 | { 125 | #region Test region 126 | 127 | internal class A 128 | { 129 | public int C = 22; 130 | 131 | public void B() 132 | { 133 | int A = 10; 134 | var b = new B(); 135 | b.A = 5; 136 | 137 | int C = 4; 138 | C = 7; 139 | this.C = 28; 140 | bool q = true; 141 | 142 | Console.WriteLine(A); 143 | if (q) 144 | Console.WriteLine(0); 145 | if (q == false) 146 | Console.WriteLine(1); 147 | if (C == 4) 148 | { 149 | Console.WriteLine(C); 150 | } 151 | if (C == 7) 152 | { 153 | Console.WriteLine(A); 154 | Console.WriteLine(b); 155 | } 156 | { 157 | } 158 | Console.WriteLine(this.C); 159 | } 160 | 161 | private void MethodWithOneStatement() 162 | { 163 | Console.WriteLine(true); 164 | } 165 | } 166 | 167 | #endregion 168 | 169 | internal class B 170 | { 171 | /* 172 | * Multiline comment 173 | */ 174 | public int A; 175 | } 176 | 177 | // Single line comment 178 | 179 | internal class C 180 | { 181 | const int a = 0/*comment*/; 182 | const int b = 0xFF; 183 | private const string s = "asdf"; 184 | 185 | public C() 186 | : base() 187 | { 188 | } 189 | } 190 | } 191 | // Comment at the end 192 | 193 | 194 | 17, 17 195 | 196 | 197 | True 198 | 199 | 200 | True 201 | 202 | 203 | True 204 | 205 | 206 | True 207 | 208 | 209 | 36 210 | 211 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/CSharpMinifier.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {24A6BB34-4BE9-4504-926D-16D52FE5AC41} 8 | Library 9 | Properties 10 | CSharpMinifier.Tests 11 | CSharpMinifier.Tests 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {a26c936c-846b-4165-9574-42c74075d4cd} 61 | CSharpMinifier 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/IdGeneratorTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System.Collections.Generic; 3 | 4 | namespace CSharpMinifier.Tests 5 | { 6 | [TestFixture] 7 | public class IdGeneratorTests 8 | { 9 | [Test] 10 | public void MinIdGeneratorTest() 11 | { 12 | var minIdGenerator = new MinIdGenerator(); 13 | for (int i = 0; i < MinIdGenerator.Chars0.Length; i++) 14 | Assert.AreEqual(MinIdGenerator.Chars0[i].ToString(), minIdGenerator.Next()); 15 | for (int i = 0; i < MinIdGenerator.CharsN.Length; i++) 16 | Assert.AreEqual(MinIdGenerator.Chars0[0].ToString() + MinIdGenerator.CharsN[i], minIdGenerator.Next()); 17 | } 18 | 19 | [Test] 20 | public void RandomIdGeneratorTest() 21 | { 22 | var randomIdGenerator = new RandomIdGenerator(1, 1); 23 | 24 | var generatedIds = new HashSet(); 25 | for (int i = 0; i < MinIdGenerator.Chars0.Length; i++) 26 | generatedIds.Add(randomIdGenerator.Next()); 27 | 28 | Assert.AreEqual(MinIdGenerator.Chars0.Length, generatedIds.Count); 29 | Assert.AreEqual(MinIdGenerator.Chars0.Length - 1, randomIdGenerator.CurrentCombinationNumber); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/MinifierTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace CSharpMinifier.Tests 7 | { 8 | [TestFixture] 9 | public class MinifierTests 10 | { 11 | Dictionary Samples; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | Samples = new Dictionary(); 17 | var sampleFiles = Directory.GetFiles(@"..\..\Samples"); 18 | foreach (var file in sampleFiles) 19 | { 20 | var code = File.ReadAllText(file); 21 | Samples.Add(Path.GetFileNameWithoutExtension(file), code); 22 | if (!CompileUtils.CanCompile(code)) 23 | Assert.Inconclusive("All input code should be compilied"); 24 | } 25 | } 26 | 27 | [Test] 28 | public void RemoveSpaces() 29 | { 30 | var minifierOptions = new MinifierOptions(false) 31 | { 32 | SpacesRemoving = true 33 | }; 34 | var minifier = new Minifier(minifierOptions); 35 | foreach (var sample in Samples) 36 | { 37 | var minified = minifier.MinifyFromString(sample.Value); 38 | Assert.IsTrue(CompileUtils.CanCompile(minified)); 39 | if (sample.Key == "Test1") 40 | Assert.IsFalse(minified.Contains(" /*")); 41 | } 42 | } 43 | 44 | [Test] 45 | public void LineLengthConstraint() 46 | { 47 | var minifierOptions = new MinifierOptions 48 | { 49 | SpacesRemoving = true, 50 | CommentsRemoving = true, 51 | LineLength = 80, 52 | RegionsRemoving = true 53 | }; 54 | var minifier = new Minifier(minifierOptions); 55 | foreach (var sample in Samples) 56 | { 57 | var minified = minifier.MinifyFromString(sample.Value); 58 | Assert.IsTrue(CompileUtils.CanCompile(minified)); 59 | } 60 | } 61 | 62 | [Test] 63 | public void RemoveComments() 64 | { 65 | var minifierOptions = new MinifierOptions(false) 66 | { 67 | SpacesRemoving = true, 68 | CommentsRemoving = true 69 | }; 70 | var minifier = new Minifier(minifierOptions); 71 | 72 | var test = Samples["Test1"]; 73 | if (!test.Contains("//") || !test.Contains("/*") || !test.Contains("*/")) 74 | Assert.Inconclusive("Invalid test sample for RemoveComments test"); 75 | var minified = minifier.MinifyFromString(test); 76 | Assert.IsTrue(CompileUtils.CanCompile(minified)); 77 | Assert.IsFalse(minified.Contains("//")); 78 | Assert.IsFalse(minified.Contains("/*")); 79 | Assert.IsFalse(minified.Contains("*/")); 80 | } 81 | 82 | [Test] 83 | public void RemoveRegions() 84 | { 85 | var minifierOptions = new MinifierOptions 86 | { 87 | SpacesRemoving = true, 88 | RegionsRemoving = true 89 | }; 90 | var minifier = new Minifier(minifierOptions); 91 | 92 | var test = Samples["Test1"]; 93 | if (!test.Contains("#region") || !test.Contains("#endregion")) 94 | Assert.Inconclusive("Invalid test sample for RemoveRegions test"); 95 | var minified = minifier.MinifyFromString(test); 96 | Assert.IsTrue(CompileUtils.CanCompile(minified)); 97 | Assert.IsFalse(minified.Contains("#region")); 98 | Assert.IsFalse(minified.Contains("#endregion")); 99 | } 100 | 101 | [Test] 102 | public void CompressIdentifiers() 103 | { 104 | var minifierOptions = new MinifierOptions(false) 105 | { 106 | LocalVarsCompressing = true, 107 | MembersCompressing = true, 108 | TypesCompressing = true 109 | }; 110 | var minifier = new Minifier(minifierOptions); 111 | foreach (var sample in Samples) 112 | { 113 | var minified = minifier.MinifyFromString(sample.Value); 114 | Assert.IsTrue(CompileUtils.CanCompile(minified)); 115 | } 116 | } 117 | 118 | [Test] 119 | public void CompressMisc() 120 | { 121 | var minifierOptions = new MinifierOptions(false) 122 | { 123 | MiscCompressing = true 124 | }; 125 | var minifier = new Minifier(minifierOptions); 126 | var minified = minifier.MinifyFromString(Samples["MiscCompression"]); 127 | Assert.IsTrue(minified.Contains("255")); 128 | Assert.IsTrue(minified.Contains("0x7048860F9180")); 129 | Assert.IsFalse(minified.Contains("private")); 130 | Assert.AreEqual(2, minified.Count(c => c == '{')); 131 | Assert.AreEqual(2, minified.Count(c => c == '}')); 132 | } 133 | 134 | [Test] 135 | public void IgnoredIdAndComments() 136 | { 137 | var minifier = new Minifier(null, new string[] { "unminifiedId" }, new string[] { "unremovableComment", "/*unremovableComment1*/" }); 138 | var test = Samples["Test1"]; 139 | if (!test.Contains("unminifiedId") || !test.Contains("unremovableComment") || !test.Contains("/*unremovableComment1*/")) 140 | Assert.Inconclusive("Invalid test sample for IgnoredIdAndComments test"); 141 | var minified = minifier.MinifyFromString(test); 142 | Assert.IsTrue(minified.Contains("unminifiedId")); 143 | Assert.IsTrue(minified.Contains("unremovableComment")); 144 | Assert.IsTrue(minified.Contains("/*unremovableComment1*/")); 145 | } 146 | 147 | [Test] 148 | public void IncrementPlus() 149 | { 150 | var minifier = new Minifier(new MinifierOptions { LocalVarsCompressing = false }); 151 | var testCode = 152 | @"public class Test 153 | { 154 | public void Main() 155 | { 156 | int x = 1; 157 | int y = 2; 158 | int z1 = y + ++x; 159 | int z2 = y + --x; 160 | int z3 = y - ++x; 161 | int z4 = y - --x; 162 | } 163 | }"; 164 | var minified = minifier.MinifyFromString(testCode); 165 | Assert.IsTrue(minified.Contains("int z1=y+ ++x")); 166 | Assert.IsTrue(minified.Contains("int z2=y+--x")); 167 | Assert.IsTrue(minified.Contains("int z3=y-++x")); 168 | Assert.IsTrue(minified.Contains("int z4=y- --x")); 169 | } 170 | 171 | [Test] 172 | public void NestedClassesWithSameInnterName() 173 | { 174 | var minifier = new Minifier(); 175 | var testCode = 176 | @"public static class A 177 | { 178 | public static class One 179 | { 180 | public void foo() {} 181 | } 182 | } 183 | 184 | public static class B 185 | { 186 | public static class One 187 | { 188 | public void foo() {} 189 | } 190 | }"; 191 | 192 | var minified = minifier.MinifyFromString(testCode); 193 | Assert.AreEqual("public static class b{public static class c{public void a(){}}}public static class d{public static class c{public void a(){}}}", minified); 194 | } 195 | 196 | [Test] 197 | public void ShouldProperlyConvertEnumWithoutInitializersToInt() 198 | { 199 | var minifier = new Minifier(); 200 | var minified = minifier.MinifyFromString(Samples["EnumToIntConversion"]); 201 | 202 | Assert.IsTrue(CompileUtils.CanCompile(minified)); 203 | Assert.AreEqual( 204 | "using System.Collections.Generic;class c{static int a=5;static Dictionary>b=new Dictionary>{{5,new Dictionary{{' ',8}}},{6,new Dictionary{{' ',24}}}};}", 205 | minified); 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CSharpMinifier.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CSharpMinifier.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8f63cfda-b2cf-4ab1-81e2-0c6c7e9ce794")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Samples/EnumToIntConversion.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | class TextUtils 3 | { 4 | public enum FONT { DEFAULT = 5, MONOSPACE }; 5 | private static FONT selectedFont = FONT.DEFAULT; 6 | 7 | private static Dictionary> LetterWidths = new Dictionary>{ 8 | { 9 | FONT.DEFAULT, 10 | new Dictionary { 11 | {' ', 8 } 12 | } 13 | }, 14 | { 15 | FONT.MONOSPACE, 16 | new Dictionary { 17 | {' ', 24 } 18 | } 19 | } 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Samples/Minecraft19.cs: -------------------------------------------------------------------------------- 1 | // https://code.google.com/p/minecraft-19lines/source/browse/trunk/Program.cs 2 | class Minecraft19 3 | { 4 | static void Main(string[] args) 5 | { 6 | begin: 7 | // Вывод логотипа и карты с одновременной подстановкой персонажа 8 | System.Console.SetCursorPosition(0, 0); 9 | System.Console.WriteLine(new string(map).Remove((offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))), 1).Insert((offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))), "8")); 10 | // Расчет новой позиции персонажа на основе нажатых клавиш 11 | var key = System.Console.ReadKey(true); 12 | position = (((!(map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '+' || map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '~') && !(map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '@' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '#' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '+')) ? (((position >> shift) & mask)) : ((key.Modifiers != System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.A && (map[offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) - 1))] == ' ' || map[offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) - 1))] == '~' || map[offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) - 1))] == '+') && ((map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '+' || map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '~') || (map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '@' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '#' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '+'))) ? (((position >> shift) & mask) - 1) : ((key.Modifiers != System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.D && (map[offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) + 1))] == ' ' || map[offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) + 1))] == '~' || map[offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) + 1))] == '+') && ((map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '+' || map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '~') || (map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '@' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '#' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '+'))) ? (((position >> shift) & mask) + 1) : (((position >> shift) & mask))))) << 8) | ((!(map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '+' || map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '~') && !(map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '@' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '#' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '+')) ? ((position & mask) + 1) : ((key.Modifiers != System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.W && (((map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == ' ' || map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == '~' || map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == '+') && (map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '#' || map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '+')) || ((map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == ' ' || map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == '~' || map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == '+') && (map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '+' || map[offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))] == '~') && (map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == '+' || map[offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))] == '~')))) ? ((position & mask) - 1) : ((key.Modifiers != System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.S && (map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == ' ' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '~' || map[offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))] == '+')) ? ((position & mask) + 1) : ((position & mask))))); 13 | // 1 и 2 проход - обработка воды, 3 проход - установка и разрушение блоков 14 | for (int index = 0; index < ((map.Length - offset) * 3); index++) 15 | map[offset + (index % (map.Length - offset))] = ((((index / (map.Length - offset)) == 0) && map[offset + (index % (map.Length - offset))] == ' ' && (map[offset + (index % (map.Length - offset)) - (width + 1)] == '~' || map[offset + (index % (map.Length - offset)) - 1] == '~' || map[offset + (index % (map.Length - offset)) + 1] == '~')) ? ('.') : (((index / (map.Length - offset)) == 1) && (map[offset + (index % (map.Length - offset))] == '.') ? ('~') : ((((index / (map.Length - offset)) == 2) && key.Key == System.ConsoleKey.D1 && (offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))) == (offset + (index % (map.Length - offset))) && (map[offset + (index % (map.Length - offset))] == '+' || map[offset + (index % (map.Length - offset))] == '~')) ? (' ') : ((((index / (map.Length - offset)) == 2) && key.Key == System.ConsoleKey.D2 && (offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))) == (offset + (index % (map.Length - offset))) && (map[offset + (index % (map.Length - offset))] == ' ' || map[offset + (index % (map.Length - offset))] == '~')) ? ('#') : ((((index / (map.Length - offset)) == 2) && key.Key == System.ConsoleKey.D3 && (offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))) == (offset + (index % (map.Length - offset))) && (map[offset + (index % (map.Length - offset))] == ' ' || map[offset + (index % (map.Length - offset))] == '~')) ? ('+') : ((((index / (map.Length - offset)) == 2) && key.Key == System.ConsoleKey.D4 && (offset + ((position & mask) * (width + 1) + ((position >> shift) & mask))) == (offset + (index % (map.Length - offset))) && map[offset + (index % (map.Length - offset))] == ' ') ? ('~') : ((((index / (map.Length - offset)) == 2) && key.Modifiers == System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.A && (offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) - 1))) == (offset + (index % (map.Length - offset))) && (map[offset + (index % (map.Length - offset))] == '#' || map[offset + (index % (map.Length - offset))] == '+')) ? (' ') : ((((index / (map.Length - offset)) == 2) && key.Modifiers == System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.D && (offset + ((position & mask) * (width + 1) + (((position >> shift) & mask) + 1))) == (offset + (index % (map.Length - offset))) && (map[offset + (index % (map.Length - offset))] == '#' || map[offset + (index % (map.Length - offset))] == '+')) ? (' ') : ((((index / (map.Length - offset)) == 2) && key.Modifiers == System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.W && (offset + (((position & mask) - 1) * (width + 1) + ((position >> shift) & mask))) == (offset + (index % (map.Length - offset))) && (map[offset + (index % (map.Length - offset))] == '#' || map[offset + (index % (map.Length - offset))] == '+')) ? (' ') : ((((index / (map.Length - offset)) == 2) && key.Modifiers == System.ConsoleModifiers.Shift && key.Key == System.ConsoleKey.S && (offset + (((position & mask) + 1) * (width + 1) + ((position >> shift) & mask))) == (offset + (index % (map.Length - offset))) && (map[offset + (index % (map.Length - offset))] == '#' || map[offset + (index % (map.Length - offset))] == '+')) ? (' ') : (map[offset + (index % (map.Length - offset))]))))))))))); 16 | goto begin; 17 | } 18 | private static int mask = 255, shift = 8, width = 79, offset = 800, position = (25 << 8) | 4; 19 | private static char[] map = " ###` ##``##``##` ##``###### ###### ######``######``######`####### \n ###`` ###``##``###``##``##```` ##```` ##``##``#````#``##````````##`` \n ###```###``##``###``##``##```` ##```` ##``#```#````#``##````````##` \n `########```##``##`####``###### ##```` #####```##```#``#######```### \n ###`##`##``##``###`####``##```` ## ##``##``######``###````````## \n `##``#``##``##``##```###``##```` ## ##``##``###`##```##``` ```##` \n ##``````##``##``##```##```#####` ###### ##``##``###``##``##`` ```### \n ##`````###``##``##```##````##### ###### `#``###``##``##``##` ````## \n ````` ```````````` ``````````` `````` `` ``````````````` ````` \n ```` ``````````` `````````` `````` `` `` ``````````` ```` \n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@ @\n@ ###+ +#########+ @\n@ ####+ +###############+ @\n@ +++++ +##### ####+ @\n@# +###+ +##### #+ ++ +#### #########++##@\n@##~~~~~~~~~~~+###+######### ##+ +#+ +##### ####### +##@\n@###~~~~~~~~~~####+######### ###+ +##+ +########## ##### +###@\n@###~~~~~~~~~~####+######### ####+ +################ +####@\n@###### ##########+######### ######+################## +##~~~~~~~###########@\n@###### ##########+## +#### #####+############## +#####~~~~############@\n@# #### ##+## +### + ########### +######################@\n@####+ + + +#####+ +#######################@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@".ToCharArray(); 20 | } -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Samples/Minecraft20.cs: -------------------------------------------------------------------------------- 1 | // https://code.google.com/p/minecraft-19lines/source/browse/trunk/Minecraft20/Program.cs 2 | class Minecraft20 3 | { 4 | static void Main(string[] args) 5 | { 6 | ops.Add(delegate(int _pos) { System.Console.SetCursorPosition(int.Parse(data.Substring(int.Parse(data.Substring(_pos + arg1, numLen)), numLen)) % width, int.Parse(data.Substring(int.Parse(data.Substring(_pos + arg1, numLen)), numLen)) / width); }); 7 | ops.Add(delegate(int _pos) { System.Console.Write(data.Substring(int.Parse(data.Substring(_pos + arg1, numLen)), int.Parse(data.Substring(_pos + arg2, numLen)))); }); 8 | ops.Add(delegate(int _pos) { data = data.Remove(int.Parse(data.Substring(_pos + arg1, numLen)), 1).Insert(int.Parse(data.Substring(_pos + arg1, numLen)), new string(new char[] { System.Console.ReadKey(true).KeyChar })); }); 9 | ops.Add(delegate(int _pos) { data = data.Remove(int.Parse(data.Substring(_pos + arg1, numLen)) + int.Parse(data.Substring(int.Parse(data.Substring(_pos + arg2, numLen)), numLen)), (data[_pos + arg3 + numLen] - 'a')).Insert(int.Parse(data.Substring(_pos + arg1, numLen)) + int.Parse(data.Substring(int.Parse(data.Substring(_pos + arg2, numLen)), numLen)), data.Substring(int.Parse(data.Substring(_pos + arg3, numLen)), (data[_pos + arg3 + numLen] - 'a'))); }); 10 | ops.Add(delegate(int _pos) { data = data.Remove(int.Parse(data.Substring(_pos + arg1, numLen)), numLen).Insert(int.Parse(data.Substring(_pos + arg1, numLen)), (int.Parse(data.Substring(int.Parse(data.Substring(_pos + arg1, numLen)), numLen)) + int.Parse(data.Substring(int.Parse(data.Substring(_pos + arg2, numLen)), numLen))).ToString("0000;-000")); }); 11 | ops.Add(delegate(int _pos) { pos = (data.Substring(int.Parse(data.Substring(_pos + arg1, numLen)) + int.Parse(data.Substring(int.Parse(data.Substring(_pos + arg2, numLen)), numLen)), (data[_pos + arg5] - 'a')) == data.Substring(int.Parse(data.Substring(_pos + arg3, numLen)), (data[_pos + arg5] - 'a')) == (data[_pos + arg5 + lenLen] != 'a')) ? int.Parse(data.Substring(_pos + arg4, numLen)) : pos; }); 12 | begin: 13 | string op = data.Substring(pos, nameLen + lenLen); 14 | pos += (op[nameLen] - 'a'); 15 | ops[op[0] - 'a'](pos - (op[nameLen] - 'a')); 16 | goto begin; 17 | } 18 | private static int pos = 0, nameLen = 1, lenLen = 1, numLen = 4, width = 80, arg1 = nameLen + lenLen, arg2 = arg1 + numLen, arg3 = arg2 + numLen, arg4 = arg3 + numLen, arg5 = arg4 + numLen; 19 | private static System.Collections.Generic.List> ops = new System.Collections.Generic.List>(); 20 | private static string data = "fv0021002100212023eb 00000001-001\n000000010800008010381920-0010001-08000808adwsADWS12345 @#+~Ww. 01850000 ###` ##``##``##` ##``###### ###### ######``######``######`####### \n ###`` ###``##``###``##``##```` ##```` ##``##``#````#``##````````##`` \n ###```###``##``###``##``##```` ##```` ##``#```#````#``##````````##` \n `########```##``##`####``###### ##```` #####```##```#``#######```### \n ###`##`##``##``###`####``##```` ## ##``##``######``###````````## \n `##``#``##``##``##```###``##```` ## ##``##``###`##```##``` ```##` \n ##``````##``##``##```##```#####` ###### ##``##``###``##``##`` ```### \n ##`````###``##``##```##````##### ###### `#``###``##``##``##` ````## \n ````` ```````````` ``````````` `````` `` ``````````````` ````` \n ```` ``````````` `````````` `````` `` `` ``````````` ```` @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@ @\n@ ###+ +#########+ @\n@ ####+ +###############+ @\n@ +++++ +##### ####+ @\n@# +###+ +##### #+ ++ +#### #########++##@\n@##~~~~~~~~~~~+###+######### ##+ +#+ +##### ####### +##@\n@###~~~~~~~~~~####+######### ###+ +##+ +########## ##### +###@\n@###~~~~~~~~~~####+######### ####+ +################ +####@\n@######+++########+######### ######+################## +##~~~~~~~###########@\n@######+++########+## +#### #####+############## +#####~~~~############@\n@#++++++++## ##+## +### + ########### +######################@\n@###+++W+++++ +++ + +#####+ +#######################@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@bk01050799ag0042bk09041119fv0021002100212074eb 0000dp207000210042eek20700097ag2070bk00740001ag0054cg0096fv0021002100212152eb 0000fv0021002100212181eb 00000000dp010100210034efv0904009700882295bb fv0904009700942295bb fv0904009700932295bb dp217300210034efv0021002100212310eb dp217300210038efv2173002100342506eb dp217700210097eek21770070fv0904217700892455bb fv0904217700902455bb fv0904217700912455bb dp217300210034efv0021002100212470eb dp217300210038efv2173002100382506eb dp010100210038efv0101002100342558eb ek00970070fv0021002100214248eb fv0021002100212587eb 00000000dp214800210034efv0096002100752840ba dp258300210097eek25830058fv0904258300882789bb fv0904258300912789bb fv0904258300922789bb fv0904258300942789bb fv0904258300932789bb dp257900210034efv0021002100212804eb dp257900210038efv2579002100342840eb dp214800210038efv2148002100342892eb ek00970058fv0021002100214248eb fv0021002100212921eb 00000000dp214800210034efv0096002100763174ba dp291700210097eek29170062fv0904291700883123bb fv0904291700913123bb fv0904291700923123bb fv0904291700943123bb fv0904291700933123bb dp291300210034efv0021002100213138eb dp291300210038efv2913002100343174eb dp214800210038efv2148002100343226eb ek00970062fv0021002100214248eb fv0021002100213255eb 00000000dp214800210034efv0096002100773883ba dp325100210097eek32510066fv0904325100883457bb fv0904325100913457bb fv0904325100923457bb fv0904325100943457bb fv0904325100933457bb dp324700210034efv0021002100213472eb dp324700210038efv3247002100343883eb fv0021002100213522eb 00000000dp324700210034efv0904325100883636bb fv0904325100943636bb fv0904325100933636bb dp351400210034efv0021002100213651eb dp351400210038efv3514002100343847eb dp351800213251eek35180070fv0904351800893796bb fv0904351800903796bb fv0904351800913796bb dp351400210034efv0021002100213811eb dp351400210038efv3514002100383847eb dp324700210038efv3247002100383883eb dp214800210038efv2148002100343935eb ek00970066fv0021002100214248eb fv0021002100213964eb 00000000dp214800210034efv0096002100784217ba dp396000210097eek39600070fv0904396000884166bb fv0904396000914166bb fv0904396000924166bb fv0904396000944166bb fv0904396000934166bb dp395600210034efv0021002100214181eb dp395600210038efv3956002100344217eb dp214800210038efv2148002100344248eb ek00970070fv0101002100385241eb fv0021002100214298eb 00000000fv0096002100794473ba dp429400210097eek42940058fv0904429400904401bb dp429000210034efv0021002100214416eb dp429000210038efv4290002100344473eb dp090442940088bfv0021002100214977eb fv0096002100804648ba dp429400210097eek42940062fv0904429400904576bb dp429000210034efv0021002100214591eb dp429000210038efv4290002100344648eb dp090442940088bfv0021002100214977eb fv0096002100814823ba dp429400210097eek42940066fv0904429400904751bb dp429000210034efv0021002100214766eb dp429000210038efv4290002100344823eb dp090442940088bfv0021002100214977eb fv0096002100824977ba dp429400210097eek42940070fv0904429400904926bb dp429000210034efv0021002100214941eb dp429000210038efv4290002100344977eb dp090442940088bfv0096002100835034ba dp090400970088bfv0021002100215241eb fv0096002100845091ba dp090400970090bfv0021002100215241eb fv0096002100855148ba dp090400970091bfv0021002100215241eb fv0096002100865205ba dp090400970092bfv0021002100215241eb fv0096002100875241ba dp090400970093bfv0021002100215266eb 0000dp526200210046efv0021002100215306eb 0000fv0904526200885510ba dp530200215262eek53020058fv0904530200925388ba dp090452620095bdp530200215262eek53020062fv0904530200925449ba dp090452620095bdp530200215262eek53020066fv0904530200925510ba dp090452620095bfv0021002100215535eb 0000fv0904526200945739ba dp553100215262eek55310058fv0904553100925617ba dp090452620095bdp553100215262eek55310062fv0904553100925678ba dp090452620095bdp553100215262eek55310066fv0904553100925739ba dp090452620095bfv0021002100215764eb 0000fv0904526200935968ba dp576000215262eek57600058fv0904576000925846ba dp090452620095bdp576000215262eek57600062fv0904576000925907ba dp090452620095bdp576000215262eek57600066fv0904576000925968ba dp090452620095bek52620025fv5262002100506020eb fv0021002100215281eb dp526200210046efv0904526200956071ba dp090452620092bek52620025fv5262002100506123eb fv0021002100216035eb dp526200210046efv0021002100216163eb 0000fv0904526200916367ba dp615900215262eek61590058fv0904615900946245ba dp090452620095bdp615900215262eek61590062fv0904615900946306ba dp090452620095bdp615900215262eek61590070fv0904615900946367ba dp090452620095bfv0021002100216392eb 0000fv0904526200916596ba dp638800215262eek63880058fv0904638800936474ba dp090452620095bdp638800215262eek63880062fv0904638800936535ba dp090452620095bdp638800215262eek63880070fv0904638800936596ba dp090452620095bek52620025fv5262002100506648eb fv0021002100216138eb dp526200210046efv0904526200956699ba dp090452620094bek52620025fv5262002100506751eb fv0021002100216663eb dp526200210046efv0904526200936802ba dp090452620095bfv0904526200946838ba dp090452620093bek52620025fv5262002100506890eb fv0021002100216766eb dp526200210046efv0904526200956941ba dp090452620094bek52620025fv5262002100506993eb fv0021002100216905eb ag0042bk09041119fv0021002100217034eb 0000dp703000210042eek70300097ag7030bk00740001ag0054fv0021002100212121eb "; 21 | } -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Samples/MiscCompression.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | class MiscCompression 3 | { 4 | private void func() 5 | { 6 | long a = 10; 7 | if (a == 0xFF || a == 123456789123456) 8 | { 9 | Console.Write(a); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Samples/RLE.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Asciimation 4 | { 5 | public class RLE 6 | { 7 | public static byte[] Encode(byte[] bytes) 8 | { 9 | List result = new List(); 10 | 11 | int i = 0; 12 | while (i < bytes.Length) 13 | { 14 | int j = i; 15 | do 16 | { 17 | j++; 18 | } 19 | while (j != bytes.Length && bytes[j] == bytes[i]); 20 | 21 | int repeatCount = j - i; 22 | if (repeatCount >= 2) 23 | { 24 | int segmentCount = repeatCount / 129; 25 | int rest = repeatCount % 129; 26 | 27 | for (int k = 0; k < segmentCount; k++) 28 | { 29 | result.Add(127); 30 | result.Add(bytes[i]); 31 | } 32 | result.Add((byte)(rest - 2)); 33 | result.Add(bytes[i]); 34 | i = j; 35 | } 36 | else 37 | { 38 | while (j != bytes.Length && bytes[j] != bytes[j - 1]) 39 | j++; 40 | 41 | int nonrepeatCount = j - i; 42 | if (j != bytes.Length) 43 | nonrepeatCount--; 44 | int segmentCount = nonrepeatCount / 128; 45 | int rest = nonrepeatCount % 128; 46 | 47 | for (int k = 0; k < segmentCount; k++) 48 | { 49 | result.Add(0xFF); 50 | for (int l = 0; l < 128; l++) 51 | result.Add(bytes[i + k * 128 + l]); 52 | } 53 | result.Add((byte)(0x80 | (rest - 1))); 54 | for (int l = 0; l < rest; l++) 55 | result.Add(bytes[i + segmentCount * 128 + l]); 56 | i = j; 57 | if (j != bytes.Length) 58 | i--; 59 | } 60 | } 61 | 62 | return result.ToArray(); 63 | } 64 | 65 | public static byte[] Decode(byte[] bytes) 66 | { 67 | List result = new List(); 68 | 69 | int i = 0; 70 | while (i < bytes.Length) 71 | { 72 | if ((bytes[i] & 0x80) == 0) 73 | { 74 | int repeatCount = bytes[i] + 2; 75 | for (int j = 0; j < repeatCount; j++) 76 | result.Add(bytes[i + 1]); 77 | i = i + 2; 78 | } 79 | else 80 | { 81 | int repeatCount = (0x7F & bytes[i]) + 1; 82 | for (int j = 0; j < repeatCount; j++) 83 | result.Add(bytes[i + 1 + j]); 84 | i = i + 1 + repeatCount; 85 | } 86 | } 87 | 88 | return result.ToArray(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Samples/Test1.cs: -------------------------------------------------------------------------------- 1 | // Comment at the begin 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace A 6 | { 7 | #region Test region 8 | 9 | internal class A 10 | { 11 | protected const char qwer = 'd', fdsa = 's'; 12 | protected int C = 22; 13 | protected int zzz; 14 | protected Dictionary dict = new Dictionary() 15 | { 16 | { "a", 23 } 17 | }; 18 | 19 | class a 20 | { 21 | } 22 | 23 | protected string Prop 24 | { 25 | get; 26 | set; 27 | } 28 | 29 | public void B() 30 | { 31 | const uint M = 34; 32 | 33 | List asdf = new List(); 34 | List qwer; 35 | 36 | int A = 10; 37 | var b = new B(); 38 | B b1 = new B(); 39 | b.A = 5; 40 | 41 | int C = 4; 42 | C = 7; 43 | this.C = 28; 44 | bool q = true; 45 | /*unremovableComment*/ 46 | int unminifiedId = 0; 47 | 48 | Console.WriteLine(A); 49 | if (q) 50 | Console.WriteLine(0); 51 | if (q == false) 52 | Console.WriteLine(1); 53 | if (C == 4) 54 | { 55 | Console.WriteLine(C); 56 | } 57 | if (C == 7) 58 | { 59 | Console.WriteLine(A); 60 | Console.WriteLine(b); 61 | } 62 | Console.WriteLine(this.C); 63 | Console.WriteLine(unminifiedId); 64 | } 65 | 66 | public static A operator+(A a, A b) 67 | { 68 | return null; 69 | } 70 | 71 | static A() 72 | { 73 | } 74 | 75 | public A() 76 | { 77 | EventHandler(null, null); 78 | } 79 | 80 | ~A() 81 | { 82 | } 83 | 84 | public event EventHandler EventHandler; 85 | 86 | private void MethodWithOneStatement() 87 | { 88 | Console.WriteLine(true); 89 | } 90 | } 91 | 92 | #endregion 93 | 94 | internal class B 95 | { 96 | /* 97 | * Multiline comment 98 | */ 99 | public int A; 100 | } 101 | 102 | // Single line comment 103 | 104 | internal class C 105 | { 106 | const int a = 0/*comment*/; 107 | const int b = 0xFF; 108 | private const string s = "asdf"; 109 | 110 | /*unremovableComment1*/ 111 | public C() 112 | : base() 113 | { 114 | } 115 | 116 | public void TryCatch() 117 | { 118 | string s; 119 | try 120 | { 121 | s = "success"; 122 | } 123 | catch (Exception e) 124 | { 125 | s = "fail"; 126 | } 127 | } 128 | 129 | public void EmptyStatements() 130 | { 131 | int a = 1, b = 2; 132 | if (a == b) { } 133 | int c = 1, d = 2; 134 | if (c == d) ; 135 | { } 136 | ; 137 | } 138 | 139 | public override string ToString() 140 | { 141 | return "C string"; 142 | } 143 | } 144 | 145 | internal class D : A 146 | { 147 | } 148 | 149 | interface Inter 150 | { 151 | } 152 | 153 | struct str 154 | { 155 | } 156 | } 157 | // Comment at the end -------------------------------------------------------------------------------- /CSharpMinifier.Tests/Samples/Test2.cs: -------------------------------------------------------------------------------- 1 | public class ByteCount 2 | { 3 | public byte Byte; 4 | public int Count; 5 | } 6 | 7 | public class HuffmanTreeNode 8 | { 9 | public HuffmanTreeNode Left, Right, Parent; 10 | public ByteCount ByteCount; 11 | 12 | public HuffmanTreeNode() 13 | { 14 | } 15 | 16 | public HuffmanTreeNode(HuffmanTreeNode left, HuffmanTreeNode right) 17 | { 18 | Left = left; 19 | Right = right; 20 | Left.Parent = Right.Parent = this; 21 | if (ByteCount == null) 22 | ByteCount = new ByteCount(); 23 | this.ByteCount.Count = Left.ByteCount.Count + Right.ByteCount.Count; 24 | } 25 | } -------------------------------------------------------------------------------- /CSharpMinifier.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /CSharpMinifier.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpMinifier", "CSharpMinifier\CSharpMinifier.csproj", "{A26C936C-846B-4165-9574-42C74075D4CD}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpMinifier.GUI", "CSharpMinifier.GUI\CSharpMinifier.GUI.csproj", "{1E6C7AB5-3E2F-4F5E-B5BD-B24E2258D0E2}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpMinifier.Tests", "CSharpMinifier.Tests\CSharpMinifier.Tests.csproj", "{24A6BB34-4BE9-4504-926D-16D52FE5AC41}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {A26C936C-846B-4165-9574-42C74075D4CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {A26C936C-846B-4165-9574-42C74075D4CD}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {A26C936C-846B-4165-9574-42C74075D4CD}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {A26C936C-846B-4165-9574-42C74075D4CD}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {1E6C7AB5-3E2F-4F5E-B5BD-B24E2258D0E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {1E6C7AB5-3E2F-4F5E-B5BD-B24E2258D0E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {1E6C7AB5-3E2F-4F5E-B5BD-B24E2258D0E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {1E6C7AB5-3E2F-4F5E-B5BD-B24E2258D0E2}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {24A6BB34-4BE9-4504-926D-16D52FE5AC41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {24A6BB34-4BE9-4504-926D-16D52FE5AC41}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {24A6BB34-4BE9-4504-926D-16D52FE5AC41}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {24A6BB34-4BE9-4504-926D-16D52FE5AC41}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /CSharpMinifier/CSharpMinifier.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A26C936C-846B-4165-9574-42C74075D4CD} 8 | Library 9 | Properties 10 | CSharpMinifier 11 | CSharpMinifier 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | False 39 | ..\packages\ICSharpCode.NRefactory.5.5.1\lib\Net40\ICSharpCode.NRefactory.dll 40 | 41 | 42 | False 43 | ..\packages\ICSharpCode.NRefactory.5.5.1\lib\Net40\ICSharpCode.NRefactory.Cecil.dll 44 | 45 | 46 | False 47 | ..\packages\ICSharpCode.NRefactory.5.5.1\lib\Net40\ICSharpCode.NRefactory.CSharp.dll 48 | 49 | 50 | False 51 | ..\packages\ICSharpCode.NRefactory.5.5.1\lib\Net40\ICSharpCode.NRefactory.Xml.dll 52 | 53 | 54 | False 55 | ..\packages\Mono.Cecil.0.9.5.4\lib\net40\Mono.Cecil.dll 56 | 57 | 58 | False 59 | ..\packages\Mono.Cecil.0.9.5.4\lib\net40\Mono.Cecil.Mdb.dll 60 | 61 | 62 | False 63 | ..\packages\Mono.Cecil.0.9.5.4\lib\net40\Mono.Cecil.Pdb.dll 64 | 65 | 66 | False 67 | ..\packages\Mono.Cecil.0.9.5.4\lib\net40\Mono.Cecil.Rocks.dll 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Designer 92 | 93 | 94 | 95 | 102 | -------------------------------------------------------------------------------- /CSharpMinifier/CompileUtils.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CSharp; 2 | using System.CodeDom.Compiler; 3 | 4 | namespace CSharpMinifier 5 | { 6 | public class CompileUtils 7 | { 8 | public static bool CanCompile(string program) 9 | { 10 | return !Compile(program).Errors.HasErrors; 11 | } 12 | 13 | public static CompilerResults Compile(string program) 14 | { 15 | CompilerResults compilerResults = null; 16 | using (CSharpCodeProvider provider = new CSharpCodeProvider()) 17 | { 18 | compilerResults = provider.CompileAssemblyFromSource(new CompilerParameters(new string[] 19 | { 20 | "System.dll" 21 | }), 22 | new string[] { program }); 23 | } 24 | return compilerResults; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CSharpMinifier/MinIdGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace CSharpMinifier 5 | { 6 | public class MinIdGenerator : NamesGenerator 7 | { 8 | public static string Chars0 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; 9 | public static string CharsN = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; 10 | 11 | List _indexes; 12 | 13 | public MinIdGenerator() 14 | : base() 15 | { 16 | } 17 | 18 | public override void Reset() 19 | { 20 | base.Reset(); 21 | _indexes = new List(); 22 | } 23 | 24 | public override string Next() 25 | { 26 | int i = _indexes.Count - 1; 27 | bool inc; 28 | do 29 | { 30 | if (i == -1) 31 | { 32 | _indexes.Add(0); 33 | break; 34 | } 35 | _indexes[i] = _indexes[i] + 1; 36 | inc = false; 37 | if ((i == 0 && _indexes[i] >= Chars0.Length) || _indexes[i] >= CharsN.Length) 38 | { 39 | _indexes[i--] = 0; 40 | inc = true; 41 | } 42 | } 43 | while (inc); 44 | 45 | StringBuilder result = new StringBuilder(_indexes.Count); 46 | for (int j = 0; j < _indexes.Count; j++) 47 | result.Append(j == 0 ? Chars0[_indexes[j]] : CharsN[_indexes[j]]); 48 | 49 | CurrentCombination = result.ToString(); 50 | CurrentCombinationNumber++; 51 | 52 | return Prefix + CurrentCombination + Postfix; 53 | } 54 | 55 | public override int CurrentCombinationNumber 56 | { 57 | get 58 | { 59 | return base.CurrentCombinationNumber; 60 | } 61 | set 62 | { 63 | base.CurrentCombinationNumber = value; 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /CSharpMinifier/Minifier.cs: -------------------------------------------------------------------------------- 1 | using ICSharpCode.NRefactory; 2 | using ICSharpCode.NRefactory.CSharp; 3 | using ICSharpCode.NRefactory.CSharp.Resolver; 4 | using ICSharpCode.NRefactory.CSharp.TypeSystem; 5 | using ICSharpCode.NRefactory.Semantics; 6 | using ICSharpCode.NRefactory.TypeSystem; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Reflection; 11 | using System.Text; 12 | using System.Threading; 13 | using System.Threading.Tasks; 14 | 15 | namespace CSharpMinifier 16 | { 17 | public class Minifier 18 | { 19 | private static string[] NameKeys = new string[] { "Name", "LiteralValue", "Keyword" }; 20 | private const string VarId = "var"; 21 | public static string ParserTempFileName = "temp.cs"; 22 | 23 | private CSharpUnresolvedFile _unresolvedFile; 24 | private IProjectContent _projectContent; 25 | private ICompilation _compilation; 26 | private CSharpAstResolver _resolver; 27 | private AstNode _prevNode; 28 | 29 | public SyntaxTree SyntaxTree 30 | { 31 | get; 32 | private set; 33 | } 34 | 35 | public MinifierOptions Options 36 | { 37 | get; 38 | private set; 39 | } 40 | 41 | public List IgnoredIdentifiers 42 | { 43 | get; 44 | private set; 45 | } 46 | 47 | public List IgnoredComments 48 | { 49 | get; 50 | private set; 51 | } 52 | 53 | #region Public 54 | 55 | public Minifier(MinifierOptions options = null, string[] ignoredIdentifiers = null, string[] ignoredComments = null) 56 | { 57 | Options = options ?? new MinifierOptions(); 58 | 59 | _projectContent = new CSharpProjectContent(); 60 | var assemblies = new List 61 | { 62 | typeof(object).Assembly, // mscorlib 63 | typeof(Uri).Assembly, // System.dll 64 | typeof(Enumerable).Assembly, // System.Core.dll 65 | }; 66 | 67 | var unresolvedAssemblies = new IUnresolvedAssembly[assemblies.Count]; 68 | Parallel.For( 69 | 0, assemblies.Count, 70 | delegate (int i) 71 | { 72 | var loader = new CecilLoader(); 73 | var path = assemblies[i].Location; 74 | unresolvedAssemblies[i] = loader.LoadAssemblyFile(assemblies[i].Location); 75 | }); 76 | _projectContent = _projectContent.AddAssemblyReferences((IEnumerable)unresolvedAssemblies); 77 | 78 | 79 | IgnoredIdentifiers = ignoredIdentifiers == null ? new List() : ignoredIdentifiers.ToList(); 80 | IgnoredComments = new List(); 81 | if (ignoredComments != null) 82 | { 83 | foreach (string comment in ignoredComments) 84 | { 85 | var str = comment; 86 | if (str.StartsWith("//")) 87 | str = str.Substring("//".Length); 88 | else if (str.StartsWith("/*") && str.EndsWith("*/")) 89 | str = str.Substring("/*".Length, str.Length - "/*".Length - "*/".Length); 90 | if (!IgnoredComments.Contains(str)) 91 | IgnoredComments.Add(str); 92 | } 93 | } 94 | } 95 | 96 | public string MinifyFiles(string[] csFiles) 97 | { 98 | CSharpParser parser = new CSharpParser(); 99 | SyntaxTree[] trees = csFiles.Select(file => parser.Parse(file, file + "_" + ParserTempFileName)).ToArray(); 100 | 101 | SyntaxTree globalTree = new SyntaxTree(); 102 | globalTree.FileName = ParserTempFileName; 103 | 104 | var usings = new List(); 105 | var types = new List(); 106 | foreach (var tree in trees) 107 | { 108 | List treeUsings = new List(); 109 | GetUsingsAndRemoveUsingsAndNamespaces(tree, treeUsings, types); 110 | usings.AddRange(treeUsings.Where(u1 => !usings.Exists(u2 => u2.Namespace == u1.Namespace))); 111 | } 112 | 113 | foreach (var u in usings) 114 | globalTree.AddChild(u.Clone(), new Role("UsingDeclaration")); 115 | foreach (var t in types) 116 | globalTree.AddChild(t.Clone(), new Role("TypeDeclaration")); 117 | 118 | SyntaxTree = globalTree; 119 | 120 | return Minify(); 121 | } 122 | 123 | public string MinifyFromString(string csharpCode) 124 | { 125 | SyntaxTree = new CSharpParser().Parse(csharpCode, ParserTempFileName); 126 | 127 | return Minify(); 128 | } 129 | 130 | public string Minify() 131 | { 132 | if (Options.CommentsRemoving || Options.RegionsRemoving) 133 | RemoveCommentsAndRegions(); 134 | 135 | if (Options.LocalVarsCompressing || Options.UselessMembersCompressing) 136 | CompressLocals(); 137 | if (Options.MembersCompressing || Options.UselessMembersCompressing) 138 | CompressMembers(); 139 | if (Options.TypesCompressing) 140 | CompressTypes(); 141 | if (Options.EnumToIntConversion) 142 | ConvertEnumToInts(); 143 | if (Options.MiscCompressing || Options.NamespacesRemoving) 144 | CompressMixed(); 145 | 146 | string result; 147 | if (Options.SpacesRemoving) 148 | result = GetStringWithoutSpaces(); 149 | else 150 | result = SyntaxTree.ToString(); 151 | 152 | return result; 153 | } 154 | 155 | private void GetUsingsAndRemoveUsingsAndNamespaces(SyntaxTree tree, List usings, List types) 156 | { 157 | foreach (var child in tree.Children) 158 | GetUsingsAndRemoveUsingsAndNamespaces(child, usings, types); 159 | } 160 | 161 | private void GetUsingsAndRemoveUsingsAndNamespaces(AstNode node, List usings, List types) 162 | { 163 | if (node.Role.ToString() == "Member" && node.GetType().Name == "UsingDeclaration") 164 | { 165 | usings.Add((UsingDeclaration)node); 166 | } 167 | else if (node.Role.ToString() == "Member" && node.GetType().Name == "NamespaceDeclaration") 168 | { 169 | AstNode parent = node.Parent; 170 | foreach (AstNode child in node.Children) 171 | { 172 | if (child.NodeType == NodeType.TypeDeclaration) 173 | { 174 | types.Add((TypeDeclaration)child); 175 | } 176 | else if (child.ToString() == "Member" && child.GetType().Name == "NamespaceDeclaration") 177 | { 178 | GetUsingsAndRemoveUsingsAndNamespaces(child, usings, types); 179 | } 180 | } 181 | } 182 | else 183 | { 184 | if (node.Children.Count() >= 1) 185 | { 186 | foreach (var child in node.Children) 187 | GetUsingsAndRemoveUsingsAndNamespaces(child, usings, types); 188 | } 189 | } 190 | } 191 | 192 | #endregion 193 | 194 | #region Misc Compression 195 | 196 | private void CompressMixed() 197 | { 198 | UpdateSyntaxTree(); 199 | CompileAndResolve(); 200 | TraverseNodes(SyntaxTree); 201 | } 202 | 203 | private void TraverseNodes(AstNode node) 204 | { 205 | foreach (var child in node.Children) 206 | { 207 | if (Options.MiscCompressing && child is PrimitiveExpression) 208 | { 209 | var primitiveExpression = (PrimitiveExpression)child; 210 | if (IsIntegerNumber(primitiveExpression.Value)) 211 | { 212 | string str = primitiveExpression.Value.ToString(); 213 | long number; 214 | if (long.TryParse(str, out number)) 215 | { 216 | string hex = "0x" + number.ToString("X"); 217 | primitiveExpression.SetValue(primitiveExpression.Value, str.Length < hex.Length ? str : hex); 218 | } 219 | } 220 | } 221 | else if (Options.MiscCompressing && child is CSharpModifierToken) 222 | { 223 | // private int a => int a 224 | var modifier = ((CSharpModifierToken)child).Modifier; 225 | if (modifier.HasFlag(Modifiers.Private) && (modifier & ~Modifiers.Private) == 0) 226 | child.Remove(); 227 | else 228 | modifier &= ~Modifiers.Private; 229 | } 230 | else if (Options.NamespacesRemoving && child is NamespaceDeclaration) 231 | { 232 | var childrenToRemove = child.Children.TakeWhile(c => !(c is CSharpTokenNode && c.Role.ToString() == "{")); 233 | foreach (AstNode childToRemove in childrenToRemove) 234 | childToRemove.Remove(); 235 | if (child.Children.Count() > 0) 236 | child.Children.First().Remove(); 237 | if (child.Children.Count() > 0) 238 | child.Children.Last().Remove(); 239 | var namespaceChildrens = child.Children; 240 | 241 | var parent = child.Parent; 242 | foreach (var c in parent.Children) 243 | { 244 | if (c == child) 245 | { 246 | foreach (var nsChildren in namespaceChildrens) 247 | parent.InsertChildAfter(c, nsChildren.Clone(), new Role(nsChildren.Role.ToString())); 248 | c.Remove(); 249 | break; 250 | } 251 | } 252 | foreach (AstNode c in parent.Children) 253 | TraverseNodes(c); 254 | } 255 | else if (Options.MiscCompressing && child is VariableDeclarationStatement) 256 | { 257 | // List a = new List() => var a = new List() 258 | // var a = new b() => b a = new b() 259 | var varDecExpr = (VariableDeclarationStatement)child; 260 | if (!varDecExpr.Modifiers.HasFlag(Modifiers.Const)) 261 | { 262 | var type = varDecExpr.Type.ToString().Replace(" ", ""); 263 | if (type == VarId) 264 | { 265 | // Resolving expression type. 266 | CompileAndResolve(); 267 | var expectedType = _resolver.GetExpectedType(varDecExpr.Variables.Single().Initializer); 268 | if (expectedType.Namespace != "System.Collections.Generic") 269 | { 270 | string typeStr = expectedType.Name; 271 | bool replace = NamesGenerator.CSharpTypeSynonyms.TryGetValue(typeStr, out typeStr); 272 | if (!replace) 273 | typeStr = expectedType.Name; 274 | if (typeStr.Length <= VarId.Length) 275 | replace = true; 276 | else 277 | replace = false; 278 | if (replace) 279 | { 280 | if (expectedType.Namespace == "System") 281 | varDecExpr.Type = new PrimitiveType(typeStr); 282 | else 283 | varDecExpr.Type = new SimpleType(typeStr); 284 | } 285 | } 286 | } 287 | else 288 | { 289 | if (varDecExpr.Variables.Count == 1) 290 | { 291 | string typeStr; 292 | var typeStrWithoutNamespaces = varDecExpr.Type.ToString(); 293 | typeStrWithoutNamespaces = typeStrWithoutNamespaces.Substring(typeStrWithoutNamespaces.LastIndexOf('.') + 1); 294 | NamesGenerator.CSharpTypeSynonyms.TryGetValue(typeStrWithoutNamespaces, out typeStr); 295 | if (typeStr == null) 296 | typeStr = varDecExpr.Type.ToString(); 297 | var initializer = varDecExpr.Variables.Single().Initializer; 298 | if (((typeStr == "string" || typeStr == "char" || typeStr == "bool") && initializer != NullReferenceExpression.Null) 299 | || initializer is ObjectCreateExpression) 300 | { 301 | if (VarId.Length < type.Length) 302 | varDecExpr.Type = new SimpleType(VarId); 303 | } 304 | } 305 | } 306 | } 307 | foreach (var variable in varDecExpr.Variables) 308 | TraverseNodes(child); 309 | } 310 | else if (child is EmptyStatement) 311 | { 312 | // { ; ; } => {} 313 | if (!(child.Parent is BlockStatement)) 314 | { 315 | if (Options.Unsafe) 316 | { 317 | node.Remove(); 318 | } 319 | } 320 | else 321 | { 322 | child.Remove(); 323 | } 324 | } 325 | else 326 | { 327 | string role = child.Role.ToString(); 328 | if (Options.MiscCompressing && child is BlockStatement && role != "Body" && role != "TryBlock") 329 | { 330 | // if (a) { b; } => if (a) b; 331 | var childrenCount = child.Children.Count(c => !(c is NewLineNode)); 332 | if (childrenCount == 3) 333 | child.ReplaceWith(child.Children.Skip(1).FirstOrDefault(c => !(c is NewLineNode))); 334 | else if (childrenCount < 3) 335 | { 336 | if (!(child.Parent is BlockStatement)) 337 | { 338 | if (Options.Unsafe) 339 | { 340 | node.Remove(); 341 | } 342 | else 343 | { 344 | child.ReplaceWith(new EmptyStatement()); 345 | } 346 | } 347 | else 348 | { 349 | child.Remove(); 350 | } 351 | } 352 | } 353 | else if (Options.Unsafe && child is BinaryOperatorExpression) 354 | { 355 | // if (a == true) => if (a) 356 | // if (a == false) => if (!a) 357 | var binaryExpression = (BinaryOperatorExpression)child; 358 | var primitiveExpression = binaryExpression.Left as PrimitiveExpression; 359 | var expression = binaryExpression.Right; 360 | if (primitiveExpression == null) 361 | { 362 | primitiveExpression = binaryExpression.Right as PrimitiveExpression; 363 | expression = binaryExpression.Left; 364 | } 365 | if (primitiveExpression != null && primitiveExpression.Value is bool) 366 | { 367 | var boolean = (bool)primitiveExpression.Value; 368 | expression.Remove(); 369 | if (boolean) 370 | child.ReplaceWith(expression); 371 | else 372 | child.ReplaceWith(new UnaryOperatorExpression(UnaryOperatorType.Not, expression)); 373 | } 374 | } 375 | TraverseNodes(child); 376 | } 377 | } 378 | } 379 | 380 | public static bool IsIntegerNumber(object value) 381 | { 382 | return value is sbyte || value is byte || 383 | value is short || value is ushort || value is int || 384 | value is uint || value is long || value is ulong; 385 | } 386 | 387 | #endregion 388 | 389 | #region Comments & Regions Removing 390 | 391 | private void RemoveCommentsAndRegions() 392 | { 393 | RemoveCommentsAndRegions(SyntaxTree); 394 | } 395 | 396 | private void RemoveCommentsAndRegions(AstNode node) 397 | { 398 | foreach (AstNode children in node.Children) 399 | { 400 | if (Options.CommentsRemoving && children is Comment) 401 | { 402 | var properties = children.GetProperties(); 403 | var commentType = properties.GetPropertyValueEnum(children, "CommentType"); 404 | var content = properties.GetPropertyValue(children, "Content"); 405 | if (!IgnoredComments.Contains(content) && commentType != CommentType.InactiveCode) 406 | children.Remove(); 407 | } 408 | else if (Options.RegionsRemoving && children is PreProcessorDirective) 409 | { 410 | var type = children.GetPropertyValueEnum("Type"); 411 | switch (type) 412 | { 413 | case PreProcessorDirectiveType.Region: 414 | case PreProcessorDirectiveType.Endregion: 415 | case PreProcessorDirectiveType.Warning: 416 | children.Remove(); 417 | break; 418 | } 419 | } 420 | else 421 | RemoveCommentsAndRegions(children); 422 | } 423 | } 424 | 425 | #endregion 426 | 427 | #region Identifiers Compressing 428 | 429 | private void CompressLocals() 430 | { 431 | var localsVisitor = new MinifyLocalsAstVisitor(IgnoredIdentifiers); 432 | CompileAndAcceptVisitor(localsVisitor); 433 | var substitutor = new Substitutor(new MinIdGenerator()); 434 | var ignoredNames = new List(IgnoredIdentifiers); 435 | ignoredNames.AddRange(localsVisitor.NotLocalsIdNames); 436 | var substituton = substitutor.Generate(localsVisitor.MethodVars, ignoredNames.ToArray()); 437 | 438 | var astSubstitution = new Dictionary>>>(); 439 | foreach (var method in localsVisitor.MethodVars) 440 | { 441 | var localVarsAstNodes = new List>>(); 442 | astSubstitution[method.Key] = localVarsAstNodes; 443 | var localsSubst = substituton[method.Key]; 444 | foreach (NameNode localVar in method.Value) 445 | localVarsAstNodes.Add(new Tuple>(localsSubst[localVar.Name], GetResolvedNodes(ResolveResultType.Local, localVar.Node))); 446 | } 447 | 448 | RenameOrRemoveNodes(astSubstitution, true, Options.LocalVarsCompressing); 449 | } 450 | 451 | private void CompressMembers() 452 | { 453 | var membersVisitor = new MinifyMembersAstVisitor(IgnoredIdentifiers, Options.ConsoleApp, Options.PublicCompressing, Options.ToStringMethodsRemoving); 454 | CompileAndAcceptVisitor(membersVisitor); 455 | var substitutor = new Substitutor(new MinIdGenerator()); 456 | var ignoredNames = new List(IgnoredIdentifiers); 457 | ignoredNames.AddRange(membersVisitor.NotMembersIdNames); 458 | var substituton = substitutor.Generate(membersVisitor.TypesMembers, ignoredNames.ToArray()); 459 | 460 | var astSubstitution = new Dictionary>>>(); 461 | foreach (var typeMembers in membersVisitor.TypesMembers) 462 | { 463 | var typeMembersAstNodes = new List>>(); 464 | astSubstitution[typeMembers.Key] = typeMembersAstNodes; 465 | var membersSubst = substituton[typeMembers.Key]; 466 | foreach (NameNode member in typeMembers.Value) 467 | typeMembersAstNodes.Add(new Tuple>(membersSubst[member.Name], GetResolvedNodes(ResolveResultType.Member, member.Node))); 468 | } 469 | 470 | RenameOrRemoveNodes(astSubstitution, true, Options.MembersCompressing); 471 | } 472 | 473 | private void CompressTypes() 474 | { 475 | var typesVisitor = new MinifyTypesAstVisitor(IgnoredIdentifiers, Options.PublicCompressing); 476 | CompileAndAcceptVisitor(typesVisitor); 477 | var substitutor = new Substitutor(new MinIdGenerator()); 478 | var ignoredNames = new List(IgnoredIdentifiers); 479 | ignoredNames.AddRange(typesVisitor.NotTypesIdNames); 480 | var substitution = substitutor.Generate(typesVisitor.Types, ignoredNames.ToArray()); 481 | 482 | var astSubstitution = new List>>(); 483 | foreach (var type in typesVisitor.Types) 484 | astSubstitution.Add(new Tuple>(substitution[type.Name], GetResolvedNodes(ResolveResultType.Type, type.Node))); 485 | 486 | RenameOrRemoveNodes(astSubstitution, false, Options.TypesCompressing); 487 | } 488 | 489 | private void ConvertEnumToInts() 490 | { 491 | UpdateSyntaxTree(); 492 | var enumVisitor = new MinifyEnumsAstVisitor(); 493 | CompileAndAcceptVisitor(enumVisitor); 494 | 495 | var members = enumVisitor.EnumMembers; 496 | foreach (var member in members) 497 | { 498 | var enumTypeRefs = GetResolvedNodes(ResolveResultType.Type, member.Key); 499 | int currentEnumValue = 0; 500 | foreach (var enumMember in member.Value) 501 | { 502 | Expression initExpr = ((EnumMemberDeclaration)enumMember.Node).Initializer; 503 | if (initExpr is PrimitiveExpression) 504 | { 505 | int.TryParse(((PrimitiveExpression)initExpr).Value.ToString(), out currentEnumValue); 506 | } 507 | var enumMemberRefs = GetResolvedNodes(ResolveResultType.Member, enumMember.Node); 508 | foreach (var node in enumMemberRefs) 509 | { 510 | if (!(node is EntityDeclaration)) 511 | { 512 | node.ReplaceWith(new PrimitiveExpression(currentEnumValue)); 513 | } 514 | } 515 | currentEnumValue++; 516 | } 517 | foreach (var typeRef in enumTypeRefs) 518 | if (typeRef is SimpleType) 519 | typeRef.ReplaceWith(new PrimitiveType("int")); 520 | member.Key.Remove(); 521 | } 522 | } 523 | 524 | private void CompileAndAcceptVisitor(DepthFirstAstVisitor visitor) 525 | { 526 | CompileAndResolve(); 527 | SyntaxTree.AcceptVisitor(visitor); 528 | } 529 | 530 | private void CompileAndResolve() 531 | { 532 | _unresolvedFile = SyntaxTree.ToTypeSystem(); 533 | _projectContent = _projectContent.AddOrUpdateFiles(_unresolvedFile); 534 | _compilation = _projectContent.CreateCompilation(); 535 | _resolver = new CSharpAstResolver(_compilation, SyntaxTree, _unresolvedFile); 536 | } 537 | 538 | private List GetResolvedNodes(ResolveResultType type, AstNode node) 539 | { 540 | var resolvedNodes = new List(); 541 | ResolveResult resolveResult = _resolver.Resolve(node); 542 | if (resolveResult != null) 543 | { 544 | var findReferences = new FindReferences(); 545 | FoundReferenceCallback callback = delegate (AstNode matchNode, ResolveResult result) 546 | { 547 | resolvedNodes.Add(matchNode); 548 | }; 549 | 550 | if (type == ResolveResultType.Local) 551 | { 552 | var localResolveResult = resolveResult as LocalResolveResult; 553 | if (localResolveResult != null) 554 | findReferences.FindLocalReferences(localResolveResult.Variable, _unresolvedFile, SyntaxTree, _compilation, callback, CancellationToken.None); 555 | } 556 | else if (type == ResolveResultType.Member) 557 | { 558 | var memberResolveResult = resolveResult as MemberResolveResult; 559 | if (memberResolveResult != null) 560 | { 561 | var searchScopes = findReferences.GetSearchScopes(memberResolveResult.Member); 562 | findReferences.FindReferencesInFile(searchScopes, _unresolvedFile, SyntaxTree, _compilation, callback, CancellationToken.None); 563 | } 564 | } 565 | else if (type == ResolveResultType.Type) 566 | { 567 | var typeResolveResult = resolveResult as TypeResolveResult; 568 | if (typeResolveResult != null) 569 | { 570 | var searchScopes = findReferences.GetSearchScopes(typeResolveResult.Type.GetDefinition()); 571 | findReferences.FindReferencesInFile(searchScopes, _unresolvedFile, SyntaxTree, _compilation, callback, CancellationToken.None); 572 | } 573 | } 574 | } 575 | else 576 | { 577 | } 578 | return resolvedNodes; 579 | } 580 | 581 | private void RenameOrRemoveNodes(Dictionary>>> substitution, bool removeOneRefNodes, bool rename) 582 | { 583 | foreach (var resolveNode in substitution) 584 | RenameOrRemoveNodes(resolveNode.Value, removeOneRefNodes, rename); 585 | } 586 | 587 | private void RenameOrRemoveNodes(List>> substitution, bool removeOneRefNodes, bool rename) 588 | { 589 | foreach (var node in substitution) 590 | { 591 | if (rename) 592 | { 593 | foreach (var astNode in node.Item2) 594 | RenameNode(astNode, node.Item1); 595 | } 596 | 597 | var first = node.Item2.FirstOrDefault() as VariableInitializer; 598 | if (removeOneRefNodes && Options.UselessMembersCompressing && first != null) 599 | { 600 | bool constNode = false; 601 | var fieldDeclaration = first.Parent as FieldDeclaration; 602 | if (fieldDeclaration != null) 603 | constNode = fieldDeclaration.Modifiers.HasFlag(Modifiers.Const); 604 | else 605 | { 606 | var varDeclaration = first.Parent as VariableDeclarationStatement; 607 | if (varDeclaration != null) 608 | constNode = varDeclaration.Modifiers.HasFlag(Modifiers.Const); 609 | } 610 | 611 | if (!constNode || first.Initializer == NullReferenceExpression.Null) 612 | { 613 | //if (node.Item2.Count == 1) 614 | // first.Parent.Remove(); 615 | } 616 | else 617 | { 618 | var initializerStr = GetStringWithoutSpaces(first.Parent); 619 | var exprStr = GetStringWithoutSpaces(first.Initializer); 620 | if (initializerStr.Length + (node.Item2.Count - 1) * node.Item1.Length > (node.Item2.Count - 1) * exprStr.Length) 621 | { 622 | foreach (var child in node.Item2.Skip(1)) 623 | { 624 | child.ReplaceWith(first.Initializer.Clone()); 625 | } 626 | first.Parent.Remove(); 627 | } 628 | } 629 | } 630 | } 631 | } 632 | 633 | private void RenameNode(AstNode node, string newName) 634 | { 635 | if (node is ParameterDeclaration) 636 | ((ParameterDeclaration)node).Name = newName; 637 | else if (node is VariableInitializer) 638 | ((VariableInitializer)node).Name = newName; 639 | 640 | else if (node is VariableInitializer) 641 | ((VariableInitializer)node).Name = newName; 642 | else if (node is MethodDeclaration) 643 | ((MethodDeclaration)node).Name = newName; 644 | else if (node is PropertyDeclaration) 645 | ((PropertyDeclaration)node).Name = newName; 646 | else if (node is IndexerDeclaration) 647 | ((IndexerDeclaration)node).Name = newName; 648 | else if (node is OperatorDeclaration) 649 | ((OperatorDeclaration)node).Name = newName; 650 | else if (node is MemberReferenceExpression) 651 | ((MemberReferenceExpression)node).MemberName = newName; 652 | else if (node is IdentifierExpression) 653 | ((IdentifierExpression)node).Identifier = newName; 654 | else if (node is InvocationExpression) 655 | { 656 | var invExpression = (InvocationExpression)node; 657 | if (invExpression.Target is IdentifierExpression) 658 | ((IdentifierExpression)invExpression.Target).Identifier = newName; 659 | else if (invExpression.Target is MemberReferenceExpression) 660 | ((MemberReferenceExpression)invExpression.Target).MemberName = newName; 661 | else 662 | { 663 | } 664 | } 665 | else if (node is NamedExpression) 666 | ((NamedExpression)node).Name = newName; 667 | else if (node is TypeDeclaration) 668 | ((TypeDeclaration)node).Name = newName; 669 | else if (node is SimpleType) 670 | ((SimpleType)node).Identifier = newName; 671 | else if (node is EnumMemberDeclaration) 672 | ((EnumMemberDeclaration)node).Name = newName; 673 | else 674 | { 675 | } 676 | } 677 | 678 | private void UpdateSyntaxTree() 679 | { 680 | // TODO: Fix it. 681 | SyntaxTree = new CSharpParser().Parse(SyntaxTree.ToString(), ParserTempFileName); 682 | } 683 | 684 | #endregion 685 | 686 | #region Removing of spaces and line breaks 687 | 688 | private string GetStringWithoutSpaces() 689 | { 690 | UpdateSyntaxTree(); 691 | return GetStringWithoutSpaces(SyntaxTree.Children); 692 | } 693 | 694 | private string GetStringWithoutSpaces(AstNode node) 695 | { 696 | return GetStringWithoutSpaces(new List() { node }); 697 | } 698 | 699 | private string GetStringWithoutSpaces(IEnumerable nodes) 700 | { 701 | StringBuilder line; 702 | StringBuilder result; 703 | 704 | result = new StringBuilder(); 705 | line = new StringBuilder(Options.LineLength); 706 | 707 | _prevNode = null; 708 | foreach (var node in nodes) 709 | { 710 | RemoveSpacesAndAppend(node, line, result); 711 | if (node.Children.Count() <= 1 && !(node is NewLineNode)) 712 | _prevNode = node; 713 | } 714 | result.Append(line); 715 | 716 | return result.ToString(); 717 | } 718 | 719 | private void RemoveSpacesAndAppend(AstNode node, StringBuilder line, StringBuilder result) 720 | { 721 | if (node.Children.Count() == 0) 722 | { 723 | string indent = GetIndent(node, line); 724 | 725 | string newString = indent + GetLeafNodeString(node); 726 | if (Options.LineLength == 0) 727 | result.Append(newString); 728 | else 729 | { 730 | if (line.Length + newString.Length > Options.LineLength) 731 | { 732 | result.AppendLine(line.ToString()); 733 | line.Clear(); 734 | line.Append(newString.TrimStart()); 735 | } 736 | else 737 | { 738 | line.Append(newString); 739 | } 740 | } 741 | } 742 | else 743 | { 744 | List children; 745 | if (node is ArraySpecifier) 746 | { 747 | children = new List(); 748 | children.Add(node.Children.FirstOrDefault(c => c.Role.ToString() == "[")); 749 | children.AddRange(node.Children.Where(c => c.Role.ToString() != "[" && c.Role.ToString() != "]")); 750 | children.AddRange(node.Children.Where(c => c.Role.ToString() == "]")); 751 | } 752 | else if (node is ArrayInitializerExpression) 753 | { 754 | var arrayInitExpr = (ArrayInitializerExpression)node; 755 | children = node.Children.ToList(); 756 | int exprNodeInd1 = -1, exprNodeInd2 = -1, commaInd1 = -1; 757 | for (int i = 0; i < children.Count; i++) 758 | { 759 | var c = children[i]; 760 | if (!(c is NewLineNode || c is CSharpTokenNode || c is Comment)) 761 | { 762 | if (exprNodeInd1 == -1) 763 | exprNodeInd1 = i; 764 | else 765 | { 766 | exprNodeInd2 = i; 767 | break; 768 | } 769 | } 770 | else if (exprNodeInd1 > -1 && exprNodeInd2 == -1 && c.ToString() == ",") 771 | commaInd1 = i; 772 | } 773 | if (exprNodeInd1 != -1 && commaInd1 == -1 && exprNodeInd2 != -1) 774 | children.Insert(exprNodeInd1 + 1, 775 | new CSharpTokenNode(TextLocation.Empty, Roles.Comma) { Role = Roles.Comma }); 776 | } 777 | else 778 | children = node.Children.ToList(); 779 | foreach (AstNode child in children) 780 | { 781 | RemoveSpacesAndAppend(child, line, result); 782 | if (child.Children.Count() <= 1 && !(child is NewLineNode)) 783 | _prevNode = child; 784 | } 785 | } 786 | } 787 | 788 | private string GetIndent(AstNode node, StringBuilder line) 789 | { 790 | string indent = " "; 791 | char last = (char)0; 792 | if (line.Length != 0) 793 | { 794 | last = line[line.Length - 1]; 795 | } 796 | 797 | if (last == ' ' || last == '\r' || last == '\n' || last == ';' || _prevNode == null || node == null) 798 | { 799 | indent = ""; 800 | } 801 | else 802 | { 803 | var prevComment = _prevNode as Comment; 804 | if (prevComment != null) 805 | { 806 | if (prevComment.CommentType == CommentType.SingleLine || prevComment.CommentType == CommentType.Documentation) 807 | indent = Environment.NewLine; 808 | else 809 | indent = ""; 810 | } 811 | else if (node is PreProcessorDirective || _prevNode is PreProcessorDirective) 812 | { 813 | indent = Environment.NewLine; 814 | } 815 | else 816 | { 817 | string prevNodeString = _prevNode.Role.ToString(); 818 | string nodeString = node.Role.ToString(); 819 | if (_prevNode is CSharpTokenNode && prevNodeString.All(c => !char.IsLetterOrDigit(c))) 820 | { 821 | if ((prevNodeString == "+" && nodeString != "++") || 822 | (prevNodeString == "-" && nodeString != "--") || 823 | (prevNodeString != "+" && prevNodeString != "-")) 824 | { 825 | indent = ""; 826 | } 827 | } 828 | else if (_prevNode is NewLineNode || 829 | _prevNode is EmptyStatement || 830 | (node is CSharpTokenNode && nodeString.All(c => !char.IsLetterOrDigit(c))) || 831 | node is NewLineNode || 832 | node is Comment) 833 | { 834 | indent = ""; 835 | } 836 | } 837 | } 838 | 839 | return indent; 840 | } 841 | 842 | public static string GetLeafNodeString(AstNode node) 843 | { 844 | string nodeRole = node.Role.ToString(); 845 | var properties = node.GetProperties(); 846 | if (nodeRole == "Comment") 847 | { 848 | CommentType commentType = properties.GetPropertyValueEnum(node, "CommentType"); 849 | string content = properties.GetPropertyValue(node, "Content"); 850 | switch (commentType) 851 | { 852 | default: 853 | case CommentType.SingleLine: 854 | return "//" + content; 855 | case CommentType.Documentation: 856 | return "///" + content; 857 | case CommentType.MultiLine: 858 | return "/*" + content + "*/"; 859 | case CommentType.InactiveCode: 860 | return content; 861 | case CommentType.MultiLineDocumentation: 862 | return "/**" + content + "*/"; 863 | } 864 | } 865 | else if (nodeRole == "Modifier") 866 | { 867 | return properties.GetPropertyValue(node, "Modifier").ToLower(); 868 | } 869 | else if (nodeRole == "Target" || nodeRole == "Right") 870 | { 871 | string typeName = node.GetType().Name; 872 | if (typeName == nameof(ThisReferenceExpression)) 873 | return "this"; 874 | else if (typeName == nameof(BaseReferenceExpression)) 875 | return "base"; 876 | else if (typeName == nameof(NullReferenceExpression)) 877 | return "null"; 878 | } 879 | else if (nodeRole == "PreProcessorDirective") 880 | { 881 | var type = properties.GetPropertyValue(node, "Type").ToLower(); 882 | var argument = properties.GetPropertyValue(node, "Argument"); 883 | var result = "#" + type; 884 | if (argument != string.Empty) 885 | result += " " + argument; 886 | return result; 887 | } 888 | 889 | if (node is ThisReferenceExpression) 890 | return "this"; 891 | else if (node is BaseReferenceExpression) 892 | return "base"; 893 | else if (node is NullReferenceExpression) 894 | return "null"; 895 | else if (node is CSharpTokenNode || node is CSharpModifierToken) 896 | return nodeRole; 897 | else if (node is NewLineNode) 898 | return ""; 899 | else if (node is EmptyStatement) 900 | return ";"; 901 | 902 | return properties 903 | .FirstOrDefault(p => NameKeys.Contains(p.Name)) 904 | .GetValue(node, null) 905 | .ToString(); 906 | } 907 | 908 | #endregion 909 | } 910 | } 911 | -------------------------------------------------------------------------------- /CSharpMinifier/MinifierOptions.cs: -------------------------------------------------------------------------------- 1 | namespace CSharpMinifier 2 | { 3 | public class MinifierOptions 4 | { 5 | public bool LocalVarsCompressing 6 | { 7 | get; 8 | set; 9 | } 10 | 11 | public bool MembersCompressing 12 | { 13 | get; 14 | set; 15 | } 16 | 17 | public bool TypesCompressing 18 | { 19 | get; 20 | set; 21 | } 22 | 23 | public bool SpacesRemoving 24 | { 25 | get; 26 | set; 27 | } 28 | 29 | public bool CommentsRemoving 30 | { 31 | get; 32 | set; 33 | } 34 | 35 | public int LineLength 36 | { 37 | get; 38 | set; 39 | } 40 | 41 | public bool RegionsRemoving 42 | { 43 | get; 44 | set; 45 | } 46 | 47 | public bool MiscCompressing 48 | { 49 | get; 50 | set; 51 | } 52 | 53 | public bool ConsoleApp 54 | { 55 | get; 56 | set; 57 | } 58 | 59 | public bool NamespacesRemoving 60 | { 61 | get; 62 | set; 63 | } 64 | 65 | public bool PublicCompressing 66 | { 67 | get; 68 | set; 69 | } 70 | 71 | public bool ToStringMethodsRemoving 72 | { 73 | get; 74 | set; 75 | } 76 | 77 | public bool UselessMembersCompressing 78 | { 79 | get; 80 | set; 81 | } 82 | 83 | public bool EnumToIntConversion 84 | { 85 | get; 86 | set; 87 | } 88 | 89 | public bool Unsafe 90 | { 91 | get; 92 | set; 93 | } 94 | 95 | public MinifierOptions(bool maxCompression = true) 96 | { 97 | if (maxCompression) 98 | { 99 | LocalVarsCompressing = true; 100 | MembersCompressing = true; 101 | TypesCompressing = true; 102 | SpacesRemoving = true; 103 | CommentsRemoving = true; 104 | RegionsRemoving = true; 105 | MiscCompressing = true; 106 | NamespacesRemoving = true; 107 | PublicCompressing = true; 108 | ToStringMethodsRemoving = true; 109 | UselessMembersCompressing = true; 110 | EnumToIntConversion = true; 111 | Unsafe = true; 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /CSharpMinifier/MinifyEnumsAstVisitor.cs: -------------------------------------------------------------------------------- 1 | using ICSharpCode.NRefactory.CSharp; 2 | using System.Collections.Generic; 3 | 4 | namespace CSharpMinifier 5 | { 6 | public class MinifyEnumsAstVisitor : DepthFirstAstVisitor 7 | { 8 | private string _currentNamespace; 9 | private List _currentEnumMembers; 10 | 11 | public Dictionary> EnumMembers 12 | { 13 | get; 14 | private set; 15 | } 16 | 17 | public MinifyEnumsAstVisitor() 18 | { 19 | EnumMembers = new Dictionary>(); 20 | } 21 | 22 | public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) 23 | { 24 | _currentNamespace = namespaceDeclaration.Name; 25 | base.VisitNamespaceDeclaration(namespaceDeclaration); 26 | } 27 | 28 | public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) 29 | { 30 | if (typeDeclaration.TypeKeyword.ToString() == "enum") 31 | { 32 | _currentEnumMembers = new List(); 33 | EnumMembers.Add(typeDeclaration, _currentEnumMembers); 34 | } 35 | base.VisitTypeDeclaration(typeDeclaration); 36 | } 37 | 38 | public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration) 39 | { 40 | _currentEnumMembers.Add(new NameNode(enumMemberDeclaration.Name, enumMemberDeclaration)); 41 | base.VisitEnumMemberDeclaration(enumMemberDeclaration); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /CSharpMinifier/MinifyLocalsAstVisitor.cs: -------------------------------------------------------------------------------- 1 | using ICSharpCode.NRefactory.CSharp; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace CSharpMinifier 7 | { 8 | public class MinifyLocalsAstVisitor : DepthFirstAstVisitor 9 | { 10 | private string _currentNamespace; 11 | private List _currentTypes; 12 | private List _currentMethodVars; 13 | private IEnumerable _ignoredLocals; 14 | 15 | public HashSet NotLocalsIdNames 16 | { 17 | get; 18 | private set; 19 | } 20 | 21 | public Dictionary> MethodVars 22 | { 23 | get; 24 | private set; 25 | } 26 | 27 | public MinifyLocalsAstVisitor(IEnumerable ignoredLocals = null) 28 | { 29 | NotLocalsIdNames = new HashSet(); 30 | MethodVars = new Dictionary>(); 31 | _ignoredLocals = ignoredLocals ?? new List(); 32 | _currentTypes = new List(); 33 | } 34 | 35 | public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) 36 | { 37 | _currentNamespace = namespaceDeclaration.Name; 38 | base.VisitNamespaceDeclaration(namespaceDeclaration); 39 | } 40 | 41 | public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) 42 | { 43 | _currentTypes.Add(typeDeclaration.Name); 44 | base.VisitTypeDeclaration(typeDeclaration); 45 | _currentTypes.RemoveAt(_currentTypes.Count - 1); 46 | } 47 | 48 | #region Visit members with body declarations 49 | 50 | public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) 51 | { 52 | VisitMember(methodDeclaration.Name, methodDeclaration.Parameters.Select(p => p.Type.ToString())); 53 | base.VisitMethodDeclaration(methodDeclaration); 54 | } 55 | 56 | public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) 57 | { 58 | VisitMember(propertyDeclaration.Name); 59 | base.VisitPropertyDeclaration(propertyDeclaration); 60 | } 61 | 62 | public override void VisitEventDeclaration(EventDeclaration eventDeclaration) 63 | { 64 | foreach (var v in eventDeclaration.Variables) 65 | VisitMember(v.Name); 66 | base.VisitEventDeclaration(eventDeclaration); 67 | } 68 | 69 | public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) 70 | { 71 | VisitMember(indexerDeclaration.Name, indexerDeclaration.Parameters.Select(p => p.Type.ToString())); 72 | base.VisitIndexerDeclaration(indexerDeclaration); 73 | } 74 | 75 | public override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) 76 | { 77 | VisitMember(operatorDeclaration.Name, operatorDeclaration.Parameters.Select(p => p.Type.ToString())); 78 | base.VisitOperatorDeclaration(operatorDeclaration); 79 | } 80 | 81 | public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) 82 | { 83 | string prefix = ""; 84 | if ((constructorDeclaration.Modifiers & Modifiers.Static) == Modifiers.Static) 85 | prefix = "static."; 86 | VisitMember(prefix + constructorDeclaration.Name, constructorDeclaration.Parameters.Select(p => p.Type.ToString())); 87 | base.VisitConstructorDeclaration(constructorDeclaration); 88 | } 89 | 90 | public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) 91 | { 92 | VisitMember(destructorDeclaration.Name); 93 | base.VisitDestructorDeclaration(destructorDeclaration); 94 | } 95 | 96 | private void VisitMember(string memberName, IEnumerable parameters = null) 97 | { 98 | StringBuilder memberKey = new StringBuilder(); 99 | string prefix = string.IsNullOrEmpty(_currentNamespace) ? "" : "." + _currentNamespace; 100 | memberKey.AppendFormat("{0}{1}.{2}", prefix, string.Join(".", _currentTypes), memberName); 101 | if (parameters != null) 102 | { 103 | memberKey.Append('('); 104 | foreach (var param in parameters) 105 | { 106 | memberKey.Append(param); 107 | memberKey.Append(','); 108 | } 109 | if (parameters.Count() != 0) 110 | memberKey.Remove(memberKey.Length - 1, 1); 111 | memberKey.Append(')'); 112 | } 113 | _currentMethodVars = new List(); 114 | MethodVars.Add(memberKey.ToString(), _currentMethodVars); 115 | } 116 | 117 | #endregion 118 | 119 | #region Visit local declarations 120 | 121 | public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration) 122 | { 123 | if (!_ignoredLocals.Contains(parameterDeclaration.Name)) 124 | _currentMethodVars.Add(new NameNode(parameterDeclaration.Name, parameterDeclaration)); 125 | base.VisitParameterDeclaration(parameterDeclaration); 126 | } 127 | 128 | public override void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement) 129 | { 130 | foreach (var varInitializer in variableDeclarationStatement.Variables) 131 | { 132 | if (!_ignoredLocals.Contains(varInitializer.Name)) 133 | _currentMethodVars.Add(new NameNode(varInitializer.Name, varInitializer)); 134 | } 135 | base.VisitVariableDeclarationStatement(variableDeclarationStatement); 136 | } 137 | 138 | #endregion 139 | 140 | public override void VisitIdentifier(Identifier identifier) 141 | { 142 | if (_currentMethodVars == null || _currentMethodVars.FirstOrDefault(v => v.Name == identifier.Name) == null) 143 | NotLocalsIdNames.Add(identifier.Name); 144 | base.VisitIdentifier(identifier); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /CSharpMinifier/MinifyMembersAstVisitor.cs: -------------------------------------------------------------------------------- 1 | using ICSharpCode.NRefactory.CSharp; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace CSharpMinifier 8 | { 9 | public class MinifyMembersAstVisitor : DepthFirstAstVisitor 10 | { 11 | private Stack> _currentNamespaces = new Stack>(); 12 | private Stack, CSharpTokenNode>> _currentMembers = new Stack, CSharpTokenNode>>(); 13 | private IEnumerable _ignoredMembers; 14 | 15 | public bool ConsoleApp 16 | { 17 | get; 18 | private set; 19 | } 20 | 21 | public bool CompressPublic 22 | { 23 | get; 24 | private set; 25 | } 26 | 27 | public bool RemoveToString 28 | { 29 | get; 30 | private set; 31 | } 32 | 33 | public HashSet NotMembersIdNames 34 | { 35 | get; 36 | private set; 37 | } 38 | 39 | public Dictionary> TypesMembers 40 | { 41 | get; 42 | private set; 43 | } 44 | 45 | public MinifyMembersAstVisitor(IEnumerable ignoredMembers, bool consoleApp, bool compressPublic, bool removeToString) 46 | { 47 | TypesMembers = new Dictionary>(); 48 | NotMembersIdNames = new HashSet(); 49 | _ignoredMembers = ignoredMembers ?? new List(); 50 | ConsoleApp = consoleApp; 51 | CompressPublic = compressPublic; 52 | RemoveToString = removeToString; 53 | } 54 | 55 | public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) 56 | { 57 | _currentNamespaces.Push(new Tuple(namespaceDeclaration.Name, namespaceDeclaration.Children.LastOrDefault() as CSharpTokenNode)); 58 | base.VisitNamespaceDeclaration(namespaceDeclaration); 59 | } 60 | 61 | public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) 62 | { 63 | string key = string.Join(".", _currentNamespaces.ToArray().Reverse().Select(ns => ns.Item1)); 64 | if (key != "") 65 | key += "."; 66 | key += string.Join(".", _currentMembers.ToArray().Reverse().Select(m => m.Item1)); 67 | if (key != "" && key[key.Length - 1] != '.') 68 | key += "."; 69 | key += typeDeclaration.Name; 70 | 71 | List nameNodes; 72 | if (!TypesMembers.ContainsKey(key)) 73 | { 74 | nameNodes = new List(); 75 | TypesMembers.Add(key, nameNodes); 76 | } 77 | else 78 | nameNodes = TypesMembers[key]; 79 | 80 | _currentMembers.Push(new Tuple, CSharpTokenNode>(typeDeclaration.Name, nameNodes, 81 | (CSharpTokenNode)typeDeclaration.Children.Last())); 82 | 83 | base.VisitTypeDeclaration(typeDeclaration); 84 | } 85 | 86 | #region Visit type members 87 | 88 | public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration) 89 | { 90 | if (CheckModifiers(fieldDeclaration)) 91 | foreach (var v in fieldDeclaration.Variables) 92 | if (!_ignoredMembers.Contains(v.Name)) 93 | _currentMembers.Peek().Item2.Add(new NameNode(v.Name, v)); 94 | base.VisitFieldDeclaration(fieldDeclaration); 95 | } 96 | 97 | public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) 98 | { 99 | if (CheckModifiers(methodDeclaration) && !_ignoredMembers.Contains(methodDeclaration.Name) && 100 | (ConsoleApp ? methodDeclaration.Name != "Main" : true) && 101 | (methodDeclaration.Modifiers & Modifiers.Override) != Modifiers.Override) 102 | _currentMembers.Peek().Item2.Add(new NameNode(methodDeclaration.Name, methodDeclaration)); 103 | if (RemoveToString && methodDeclaration.Name == "ToString" && (methodDeclaration.Modifiers & Modifiers.Override) == Modifiers.Override) 104 | methodDeclaration.Remove(); 105 | base.VisitMethodDeclaration(methodDeclaration); 106 | } 107 | 108 | public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) 109 | { 110 | if (CheckModifiers(propertyDeclaration) && !_ignoredMembers.Contains(propertyDeclaration.Name) && 111 | (propertyDeclaration.Modifiers & Modifiers.Override) != Modifiers.Override) 112 | _currentMembers.Peek().Item2.Add(new NameNode(propertyDeclaration.Name, propertyDeclaration)); 113 | base.VisitPropertyDeclaration(propertyDeclaration); 114 | } 115 | 116 | public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration) 117 | { 118 | if (!_ignoredMembers.Contains(enumMemberDeclaration.Name)) 119 | _currentMembers.Peek().Item2.Add(new NameNode(enumMemberDeclaration.Name, enumMemberDeclaration)); 120 | base.VisitEnumMemberDeclaration(enumMemberDeclaration); 121 | } 122 | 123 | public override void VisitEventDeclaration(EventDeclaration eventDeclaration) 124 | { 125 | if (CheckModifiers(eventDeclaration) && !_ignoredMembers.Contains(eventDeclaration.Name)) 126 | foreach (var v in eventDeclaration.Variables) 127 | _currentMembers.Peek().Item2.Add(new NameNode(v.Name, v)); 128 | base.VisitEventDeclaration(eventDeclaration); 129 | } 130 | 131 | public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) 132 | { 133 | base.VisitIndexerDeclaration(indexerDeclaration); 134 | } 135 | 136 | public override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) 137 | { 138 | base.VisitOperatorDeclaration(operatorDeclaration); 139 | } 140 | 141 | public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) 142 | { 143 | base.VisitConstructorDeclaration(constructorDeclaration); 144 | } 145 | 146 | public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) 147 | { 148 | base.VisitDestructorDeclaration(destructorDeclaration); 149 | } 150 | 151 | #endregion 152 | 153 | public override void VisitCSharpTokenNode(CSharpTokenNode token) 154 | { 155 | if (_currentNamespaces.Count != 0 && token == _currentNamespaces.Peek().Item2) 156 | { 157 | _currentNamespaces.Pop(); 158 | } 159 | else if (_currentMembers.Count != 0 && token == _currentMembers.Peek().Item3) 160 | { 161 | _currentMembers.Pop(); 162 | } 163 | base.VisitCSharpTokenNode(token); 164 | } 165 | 166 | public override void VisitIdentifier(Identifier identifier) 167 | { 168 | if (_currentMembers.Count == 0 || _currentMembers.Peek().Item2.FirstOrDefault(v => v.Name == identifier.Name) == null) 169 | NotMembersIdNames.Add(identifier.Name); 170 | base.VisitIdentifier(identifier); 171 | } 172 | 173 | private bool CheckModifiers(EntityDeclaration declaration) 174 | { 175 | return CompressPublic || (declaration.Modifiers & Modifiers.Public) == Modifiers.None; 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /CSharpMinifier/MinifyTypesAstVisitor.cs: -------------------------------------------------------------------------------- 1 | using ICSharpCode.NRefactory.CSharp; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace CSharpMinifier 6 | { 7 | public class MinifyTypesAstVisitor : DepthFirstAstVisitor 8 | { 9 | private string _currentNamespace; 10 | private List _currentMembers; 11 | private IEnumerable _ignoredTypes; 12 | 13 | public bool CompressPublic 14 | { 15 | get; 16 | private set; 17 | } 18 | 19 | public HashSet NotTypesIdNames 20 | { 21 | get; 22 | private set; 23 | } 24 | 25 | public List Types 26 | { 27 | get; 28 | private set; 29 | } 30 | 31 | public MinifyTypesAstVisitor(IEnumerable ignoredTypes, bool compressPublic) 32 | { 33 | _ignoredTypes = ignoredTypes; 34 | CompressPublic = compressPublic; 35 | Types = new List(); 36 | NotTypesIdNames = new HashSet(); 37 | } 38 | 39 | public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) 40 | { 41 | _currentNamespace = namespaceDeclaration.Name; 42 | base.VisitNamespaceDeclaration(namespaceDeclaration); 43 | } 44 | 45 | public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) 46 | { 47 | _currentMembers = new List(); 48 | if (CheckModifiers(typeDeclaration) && !_ignoredTypes.Contains(typeDeclaration.Name)) 49 | Types.Add(new NameNode(typeDeclaration.Name, typeDeclaration)); 50 | base.VisitTypeDeclaration(typeDeclaration); 51 | } 52 | 53 | public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration) 54 | { 55 | foreach (var v in fieldDeclaration.Variables) 56 | NotTypesIdNames.Add(v.Name); 57 | base.VisitFieldDeclaration(fieldDeclaration); 58 | } 59 | 60 | public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) 61 | { 62 | NotTypesIdNames.Add(methodDeclaration.Name); 63 | base.VisitMethodDeclaration(methodDeclaration); 64 | } 65 | 66 | public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) 67 | { 68 | NotTypesIdNames.Add(propertyDeclaration.Name); 69 | base.VisitPropertyDeclaration(propertyDeclaration); 70 | } 71 | 72 | public override void VisitEventDeclaration(EventDeclaration eventDeclaration) 73 | { 74 | foreach (var v in eventDeclaration.Variables) 75 | NotTypesIdNames.Add(v.Name); 76 | base.VisitEventDeclaration(eventDeclaration); 77 | } 78 | 79 | public override void VisitIdentifier(Identifier identifier) 80 | { 81 | if (Types.FirstOrDefault(t => t.Name == identifier.Name) == null) 82 | NotTypesIdNames.Add(identifier.Name); 83 | base.VisitIdentifier(identifier); 84 | } 85 | 86 | private bool CheckModifiers(EntityDeclaration declaration) 87 | { 88 | return CompressPublic || (declaration.Modifiers & Modifiers.Public) == Modifiers.None; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /CSharpMinifier/NRefactoryUtils.cs: -------------------------------------------------------------------------------- 1 | using ICSharpCode.NRefactory.CSharp; 2 | using System; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace CSharpMinifier 7 | { 8 | public static class NRefactoryUtils 9 | { 10 | public static PropertyInfo[] GetProperties(this AstNode node) 11 | { 12 | return node.GetType().GetProperties(); 13 | } 14 | 15 | public static string GetPropertyValue(this AstNode node, string propertyName) 16 | { 17 | return node.GetType() 18 | .GetProperties() 19 | .GetPropertyValue(node, propertyName); 20 | } 21 | 22 | public static T GetPropertyValueEnum(this AstNode node, string propertyName) 23 | { 24 | return (T)node.GetType() 25 | .GetProperties() 26 | .GetPropertyValueEnum(node, propertyName); 27 | } 28 | 29 | public static string GetPropertyValue(this PropertyInfo[] properties, AstNode node, string propertyName) 30 | { 31 | return properties 32 | .Where(p => p.Name == propertyName) 33 | .FirstOrDefault() 34 | .GetValue(node, null) 35 | .ToString(); 36 | } 37 | 38 | public static T GetPropertyValueEnum(this PropertyInfo[] properties, AstNode node, string propertyName) 39 | { 40 | return (T)Enum.Parse(typeof(T), properties 41 | .Where(p => p.Name == propertyName) 42 | .FirstOrDefault() 43 | .GetValue(node, null) 44 | .ToString()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CSharpMinifier/NameNode.cs: -------------------------------------------------------------------------------- 1 | using ICSharpCode.NRefactory.CSharp; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace CSharpMinifier 8 | { 9 | public class NameNode 10 | { 11 | public string Name; 12 | public AstNode Node; 13 | 14 | public NameNode(string name, AstNode node) 15 | { 16 | Name = name; 17 | Node = node; 18 | } 19 | 20 | public override string ToString() 21 | { 22 | return Name + "; " + Node.ToString(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CSharpMinifier/NamesGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CSharpMinifier 4 | { 5 | public abstract class NamesGenerator 6 | { 7 | public static string[] CSharpKeywords = new string[] 8 | { 9 | "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", 10 | "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", 11 | "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", 12 | "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", 13 | "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", 14 | "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", 15 | "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", 16 | "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", 17 | "ushort", "using", "virtual", "void", "volatile", "while" 18 | }; 19 | 20 | public static Dictionary CSharpTypeSynonyms = new Dictionary() 21 | { 22 | { "Boolean", "bool" }, 23 | { "Char", "char" }, 24 | { "Byte", "byte" }, 25 | { "Double", "double" }, 26 | { "False", "false" }, 27 | { "Single", "float" }, 28 | { "Int32", "int" }, 29 | { "Int64", "long" }, 30 | { "Object", "object" }, 31 | { "SByte", "sbyte" }, 32 | { "Int16", "short" }, 33 | { "String", "string" }, 34 | { "True", "true" }, 35 | { "UInt32", "uint" }, 36 | { "UInt64", "ulong" }, 37 | { "UInt16", "ushort" } 38 | }; 39 | 40 | public abstract string Next(); 41 | 42 | public NamesGenerator() 43 | { 44 | Reset(); 45 | } 46 | 47 | public virtual void Reset() 48 | { 49 | CurrentCombinationNumber = -1; 50 | CurrentCombination = string.Empty; 51 | Prefix = ""; 52 | Postfix = ""; 53 | } 54 | 55 | public virtual int CurrentCombinationNumber 56 | { 57 | get; 58 | set; 59 | } 60 | 61 | public string CurrentCombination 62 | { 63 | get; 64 | protected set; 65 | } 66 | 67 | public string Prefix 68 | { 69 | get; 70 | protected set; 71 | } 72 | 73 | public string Postfix 74 | { 75 | get; 76 | protected set; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /CSharpMinifier/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CSharpMinifier")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CSharpMinifier")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c10cd76d-98b2-43b5-9813-035afa0051b6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CSharpMinifier/RandomIdGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace CSharpMinifier 7 | { 8 | public class RandomIdGenerator : NamesGenerator 9 | { 10 | private List _generatedIds; 11 | private Random _random; 12 | 13 | public int MinLength 14 | { 15 | get; 16 | set; 17 | } 18 | 19 | public int MaxLength 20 | { 21 | get; 22 | set; 23 | } 24 | 25 | public RandomIdGenerator(int minLength, int maxLength) 26 | : base() 27 | { 28 | MinLength = minLength; 29 | MaxLength = MaxLength; 30 | } 31 | 32 | public override void Reset() 33 | { 34 | _generatedIds = new List(); 35 | _random = new Random(); 36 | base.Reset(); 37 | } 38 | 39 | public override string Next() 40 | { 41 | int length = _random.Next(MinLength, MaxLength + 1); 42 | 43 | if (CurrentCombinationNumber < _generatedIds.Count) 44 | { 45 | StringBuilder result = new StringBuilder(length); 46 | do 47 | { 48 | result.Clear(); 49 | result.Append(MinIdGenerator.Chars0[_random.Next(MinIdGenerator.Chars0.Length)]); 50 | for (int i = 1; i < length; i++) 51 | result.Append(MinIdGenerator.CharsN[_random.Next(MinIdGenerator.CharsN.Length)]); 52 | CurrentCombination = result.ToString(); 53 | } 54 | while (_generatedIds.Contains(CurrentCombination)); 55 | _generatedIds.Add(CurrentCombination); 56 | } 57 | else 58 | CurrentCombination = _generatedIds[CurrentCombinationNumber]; 59 | 60 | CurrentCombinationNumber++; 61 | return Prefix + CurrentCombination + Postfix; 62 | } 63 | 64 | public override int CurrentCombinationNumber 65 | { 66 | get 67 | { 68 | return base.CurrentCombinationNumber; 69 | } 70 | set 71 | { 72 | CurrentCombination = CurrentCombinationNumber >= 0 && CurrentCombinationNumber < _generatedIds.Count ? _generatedIds[CurrentCombinationNumber] : ""; 73 | base.CurrentCombinationNumber = value; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /CSharpMinifier/ResolveResultType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace CSharpMinifier 7 | { 8 | public enum ResolveResultType 9 | { 10 | Local, 11 | Member, 12 | Type 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /CSharpMinifier/Substitutor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace CSharpMinifier 5 | { 6 | public class Substitutor 7 | { 8 | public NamesGenerator Generator 9 | { 10 | get; 11 | set; 12 | } 13 | 14 | public Substitutor(NamesGenerator generator) 15 | { 16 | Generator = generator; 17 | } 18 | 19 | public Dictionary> Generate(Dictionary> idNameNodes, IEnumerable excludedNames) 20 | { 21 | var result = new Dictionary>(); 22 | 23 | foreach (var vars in idNameNodes) 24 | result.Add(vars.Key, Generate(vars.Value, excludedNames)); 25 | 26 | return result; 27 | } 28 | 29 | public Dictionary Generate(List idNameNodes, IEnumerable excludedNames) 30 | { 31 | Generator.Reset(); 32 | 33 | int varCount = idNameNodes.Count; 34 | string[] newNames = new string[varCount]; 35 | var newSubstitution = new Dictionary(); 36 | 37 | for (int i = 0; i < varCount; i++) 38 | { 39 | string newName; 40 | do 41 | { 42 | newName = Generator.Next(); 43 | } 44 | while (excludedNames.Contains(newName) || NamesGenerator.CSharpKeywords.Contains(newName)); 45 | newNames[i] = newName; 46 | } 47 | 48 | int ind = 0; 49 | foreach (NameNode v in idNameNodes) 50 | if (!newSubstitution.ContainsKey(v.Name)) 51 | newSubstitution.Add(v.Name, newNames[ind++]); 52 | 53 | return newSubstitution; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /CSharpMinifier/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CSharp-Minifier 2 | =============== 3 | 4 | Library for C# code minification based on NRefactory. That is lib for spaces, line breaks, comments removing, reduction of identifiers name length and so on in C# code. 5 | 6 | This lib primarily developed for code minification in quines (for my [Freaky-Sources](https://github.com/KvanTTT/Freaky-Sources) project). 7 | 8 | Implemented features: 9 | 10 | * Identifiers compression (ignored names are supported too): 11 | * Local vars 12 | * Type members 13 | * Types 14 | * Misc minifications: 15 | * private words removing 16 | * namespaces words removing 17 | * vars initialization expression compressing: 18 | * List a = new List() => var a = new List() 19 | * var a = new b() => b a = new b() 20 | * Curly spaces with one expression inside removing ```if (a) { b; } => if (a) b;``` 21 | * boolean expressions optimization: ```if (a == true) => if (a); if (a == false) => if (!a)``` 22 | * Comments and regions removing 23 | * Whitespaces chars removing with maximum string length limit. 24 | 25 | Tests and GUI application are included. 26 | 27 | --------------------------------------------------------------------------------