Browse Source

Fix #2330: Add conditional sub directory support

pull/2567/head
Siegfried Pammer 3 years ago
parent
commit
a48f0d311c
  1. 2
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForLoopTests.xml
  2. 2
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/HelloWorld.xml
  3. 2
      ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.xml
  4. 8
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
  5. 5
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  6. 21
      ICSharpCode.Decompiler/DecompilerSettings.cs
  7. 12
      ILSpy/Options/MiscSettingsPanel.xaml
  8. 4
      ILSpy/Options/MiscSettingsPanel.xaml.cs
  9. 26
      ILSpy/Properties/Resources.Designer.cs
  10. 14
      ILSpy/Properties/Resources.resx

2
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForLoopTests.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<symbols> <symbols>
<files> <files>
<file id="1" name="ICSharpCode\Decompiler\Tests\TestCases\PdbGen\ForLoopTests.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System; <file id="1" name="ICSharpCode.Decompiler.Tests.TestCases.PdbGen\ForLoopTests.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen; namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;

2
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/HelloWorld.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<symbols> <symbols>
<files> <files>
<file id="1" name="ICSharpCode\Decompiler\Tests\TestCases\PdbGen\HelloWorld.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System; <file id="1" name="ICSharpCode.Decompiler.Tests.TestCases.PdbGen\HelloWorld.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen; namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;

2
ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<symbols> <symbols>
<files> <files>
<file id="1" name="ICSharpCode\Decompiler\Tests\TestCases\PdbGen\LambdaCapturing.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System; <file id="1" name="ICSharpCode.Decompiler.Tests.TestCases.PdbGen\LambdaCapturing.cs" language="C#" checksumAlgorithm="SHA256"><![CDATA[using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen; namespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;

8
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs

@ -214,7 +214,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
} }
else else
{ {
string dir = CleanUpDirectoryName(ns); string dir = Settings.UseNestedDirectoriesForNamespaces ? CleanUpPath(ns) : CleanUpDirectoryName(ns);
if (directories.Add(dir)) if (directories.Add(dir))
Directory.CreateDirectory(Path.Combine(TargetDirectory, dir)); Directory.CreateDirectory(Path.Combine(TargetDirectory, dir));
return Path.Combine(dir, file); return Path.Combine(dir, file);
@ -368,6 +368,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
// That is, a full name of the form "Namespace1.Namespace2{...}.NamespaceN.ResourceName" is split such that // That is, a full name of the form "Namespace1.Namespace2{...}.NamespaceN.ResourceName" is split such that
// the directory part Namespace1\Namespace2\... reuses as many existing directories as // the directory part Namespace1\Namespace2\... reuses as many existing directories as
// possible, and only the remaining name parts are used as prefix for the filename. // possible, and only the remaining name parts are used as prefix for the filename.
// This is not affected by the UseNestedDirectoriesForNamespaces setting.
string[] splitName = fullName.Split(Path.DirectorySeparatorChar); string[] splitName = fullName.Split(Path.DirectorySeparatorChar);
string fileName = string.Join(".", splitName); string fileName = string.Join(".", splitName);
string separator = Path.DirectorySeparatorChar.ToString(); string separator = Path.DirectorySeparatorChar.ToString();
@ -682,6 +683,11 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
/// Cleans up a node name for use as a directory name. /// Cleans up a node name for use as a directory name.
/// </summary> /// </summary>
public static string CleanUpDirectoryName(string text) public static string CleanUpDirectoryName(string text)
{
return CleanUpName(text, separateAtDots: false, treatAsFileName: false);
}
public static string CleanUpPath(string text)
{ {
return CleanUpName(text, separateAtDots: true, treatAsFileName: false) return CleanUpName(text, separateAtDots: true, treatAsFileName: false)
.Replace('.', Path.DirectorySeparatorChar); .Replace('.', Path.DirectorySeparatorChar);

5
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -66,7 +66,10 @@ namespace ICSharpCode.Decompiler.DebugInfo
string BuildFileNameFromTypeName(TypeDefinitionHandle handle) string BuildFileNameFromTypeName(TypeDefinitionHandle handle)
{ {
var typeName = handle.GetFullTypeName(reader).TopLevelTypeName; var typeName = handle.GetFullTypeName(reader).TopLevelTypeName;
return Path.Combine(WholeProjectDecompiler.CleanUpDirectoryName(typeName.Namespace), WholeProjectDecompiler.CleanUpFileName(typeName.Name) + ".cs"); string ns = settings.UseNestedDirectoriesForNamespaces
? WholeProjectDecompiler.CleanUpPath(typeName.Namespace)
: WholeProjectDecompiler.CleanUpDirectoryName(typeName.Namespace);
return Path.Combine(ns, WholeProjectDecompiler.CleanUpFileName(typeName.Name) + ".cs");
} }
foreach (var sourceFile in reader.GetTopLevelTypeDefinitions().GroupBy(BuildFileNameFromTypeName)) foreach (var sourceFile in reader.GetTopLevelTypeDefinitions().GroupBy(BuildFileNameFromTypeName))

21
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -1777,7 +1777,7 @@ namespace ICSharpCode.Decompiler
/// Gets or sets a value indicating whether the new SDK style format /// Gets or sets a value indicating whether the new SDK style format
/// shall be used for the generated project files. /// shall be used for the generated project files.
/// </summary> /// </summary>
[Category("DecompilerSettings.Other")] [Category("DecompilerSettings.ProjectExport")]
[Description("DecompilerSettings.UseSdkStyleProjectFormat")] [Description("DecompilerSettings.UseSdkStyleProjectFormat")]
public bool UseSdkStyleProjectFormat { public bool UseSdkStyleProjectFormat {
get { return useSdkStyleProjectFormat; } get { return useSdkStyleProjectFormat; }
@ -1790,6 +1790,25 @@ namespace ICSharpCode.Decompiler
} }
} }
bool useNestedDirectoriesForNamespaces;
/// <summary>
/// Gets/sets whether namespaces and namespace-like identifiers should be split at '.'
/// and each part should produce a new level of nesting in the output directory structure.
/// </summary>
[Category("DecompilerSettings.ProjectExport")]
[Description("DecompilerSettings.UseNestedDirectoriesForNamespaces")]
public bool UseNestedDirectoriesForNamespaces {
get { return useNestedDirectoriesForNamespaces; }
set {
if (useNestedDirectoriesForNamespaces != value)
{
useNestedDirectoriesForNamespaces = value;
OnPropertyChanged();
}
}
}
bool aggressiveScalarReplacementOfAggregates = false; bool aggressiveScalarReplacementOfAggregates = false;
[Category("DecompilerSettings.Other")] [Category("DecompilerSettings.Other")]

12
ILSpy/Options/MiscSettingsPanel.xaml

@ -6,9 +6,13 @@
xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties" xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"> d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Margin="10"> <StackPanel Orientation="Vertical">
<CheckBox IsChecked="{Binding AllowMultipleInstances}" Content="{x:Static properties:Resources.AllowMultipleInstances}" /> <GroupBox Header="{x:Static properties:Resources.Misc}">
<CheckBox IsChecked="{Binding LoadPreviousAssemblies}" Content="{x:Static properties:Resources.LoadAssembliesThatWereLoadedInTheLastInstance}"/> <StackPanel Margin="10">
<Button Command="{Binding AddRemoveShellIntegrationCommand}" Content="{Binding AddRemoveShellIntegrationText}" Margin="3" /> <CheckBox IsChecked="{Binding AllowMultipleInstances}" Content="{x:Static properties:Resources.AllowMultipleInstances}" />
<CheckBox IsChecked="{Binding LoadPreviousAssemblies}" Content="{x:Static properties:Resources.LoadAssembliesThatWereLoadedInTheLastInstance}"/>
<Button Command="{Binding AddRemoveShellIntegrationCommand}" Content="{Binding AddRemoveShellIntegrationText}" Margin="3" />
</StackPanel>
</GroupBox>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

4
ILSpy/Options/MiscSettingsPanel.xaml.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.Options
{ {
XElement e = settings["MiscSettings"]; XElement e = settings["MiscSettings"];
var s = new MiscSettings(); var s = new MiscSettings();
s.AllowMultipleInstances = (bool?)e.Attribute("AllowMultipleInstances") ?? false; s.AllowMultipleInstances = (bool?)e.Attribute(nameof(s.AllowMultipleInstances)) ?? false;
s.LoadPreviousAssemblies = (bool?)e.Attribute(nameof(s.LoadPreviousAssemblies)) ?? true; s.LoadPreviousAssemblies = (bool?)e.Attribute(nameof(s.LoadPreviousAssemblies)) ?? true;
return s; return s;
@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy.Options
var s = (MiscSettings)this.DataContext; var s = (MiscSettings)this.DataContext;
var section = new XElement("MiscSettings"); var section = new XElement("MiscSettings");
section.SetAttributeValue("AllowMultipleInstances", s.AllowMultipleInstances); section.SetAttributeValue(nameof(s.AllowMultipleInstances), s.AllowMultipleInstances);
section.SetAttributeValue(nameof(s.LoadPreviousAssemblies), s.LoadPreviousAssemblies); section.SetAttributeValue(nameof(s.LoadPreviousAssemblies), s.LoadPreviousAssemblies);
XElement existingElement = root.Element("MiscSettings"); XElement existingElement = root.Element("MiscSettings");

26
ILSpy/Properties/Resources.Designer.cs generated

@ -1127,6 +1127,15 @@ namespace ICSharpCode.ILSpy.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Project export.
/// </summary>
public static string DecompilerSettings_ProjectExport {
get {
return ResourceManager.GetString("DecompilerSettings.ProjectExport", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Ranges. /// Looks up a localized string similar to Ranges.
/// </summary> /// </summary>
@ -1316,6 +1325,15 @@ namespace ICSharpCode.ILSpy.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Use nested directories for namespaces.
/// </summary>
public static string DecompilerSettings_UseNestedDirectoriesForNamespaces {
get {
return ResourceManager.GetString("DecompilerSettings.UseNestedDirectoriesForNamespaces", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Use non-trailing named arguments. /// Looks up a localized string similar to Use non-trailing named arguments.
/// </summary> /// </summary>
@ -2002,7 +2020,7 @@ namespace ICSharpCode.ILSpy.Properties {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to You can change this by toggling the setting at Options &gt; Decompiler &gt; Other &gt; Use new SDK style format for generated project files (*.csproj).. /// Looks up a localized string similar to You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use new SDK style format for generated project files (*.csproj)..
/// </summary> /// </summary>
public static string ProjectExportFormatChangeSettingHint { public static string ProjectExportFormatChangeSettingHint {
get { get {
@ -2029,9 +2047,11 @@ namespace ICSharpCode.ILSpy.Properties {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to Failed to decompile the assemblies {0} because the namespace directory structure is nested too deep. /// Looks up a localized string similar to Failed to decompile the assemblies {0} because the namespace names are too long or the directory structure is nested too deep.
///
///If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable &quot;Long path support&quot; by creating a REG_DWORD registry key named &quot;LongPathsEnabled&quot; with value 0x1 at &quot;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem&quot; (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).
/// ///
///If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable &quot;Long path support&quot; by creating a REG_DWORD registry key named &quot;LongPathsEnabled&quot; with value 0x1 at &quot;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem&quot; (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).. ///If this does not [rest of string was truncated]&quot;;.
/// </summary> /// </summary>
public static string ProjectExportPathTooLong { public static string ProjectExportPathTooLong {
get { get {

14
ILSpy/Properties/Resources.resx

@ -399,6 +399,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.PatternMatching" xml:space="preserve"> <data name="DecompilerSettings.PatternMatching" xml:space="preserve">
<value>Use pattern matching expressions</value> <value>Use pattern matching expressions</value>
</data> </data>
<data name="DecompilerSettings.ProjectExport" xml:space="preserve">
<value>Project export</value>
</data>
<data name="DecompilerSettings.Ranges" xml:space="preserve"> <data name="DecompilerSettings.Ranges" xml:space="preserve">
<value>Ranges</value> <value>Ranges</value>
</data> </data>
@ -462,6 +465,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.UseNamedArguments" xml:space="preserve"> <data name="DecompilerSettings.UseNamedArguments" xml:space="preserve">
<value>Use named arguments</value> <value>Use named arguments</value>
</data> </data>
<data name="DecompilerSettings.UseNestedDirectoriesForNamespaces" xml:space="preserve">
<value>Use nested directories for namespaces</value>
</data>
<data name="DecompilerSettings.UseNonTrailingNamedArguments" xml:space="preserve"> <data name="DecompilerSettings.UseNonTrailingNamedArguments" xml:space="preserve">
<value>Use non-trailing named arguments</value> <value>Use non-trailing named arguments</value>
</data> </data>
@ -689,7 +695,7 @@ Please disable all filters that might hide the item (i.e. activate "View &gt; Sh
<value>Portable PDB|*.pdb|All files|*.*</value> <value>Portable PDB|*.pdb|All files|*.*</value>
</data> </data>
<data name="ProjectExportFormatChangeSettingHint" xml:space="preserve"> <data name="ProjectExportFormatChangeSettingHint" xml:space="preserve">
<value>You can change this by toggling the setting at Options &gt; Decompiler &gt; Other &gt; Use new SDK style format for generated project files (*.csproj).</value> <value>You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use new SDK style format for generated project files (*.csproj).</value>
</data> </data>
<data name="ProjectExportFormatNonSDKHint" xml:space="preserve"> <data name="ProjectExportFormatNonSDKHint" xml:space="preserve">
<value>A Non-SDK project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value> <value>A Non-SDK project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value>
@ -698,9 +704,11 @@ Please disable all filters that might hide the item (i.e. activate "View &gt; Sh
<value>A SDK-style project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value> <value>A SDK-style project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value>
</data> </data>
<data name="ProjectExportPathTooLong" xml:space="preserve"> <data name="ProjectExportPathTooLong" xml:space="preserve">
<value>Failed to decompile the assemblies {0} because the namespace directory structure is nested too deep. <value>Failed to decompile the assemblies {0} because the namespace names are too long or the directory structure is nested too deep.
If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable "Long path support" by creating a REG_DWORD registry key named "LongPathsEnabled" with value 0x1 at "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem" (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).
If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable "Long path support" by creating a REG_DWORD registry key named "LongPathsEnabled" with value 0x1 at "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem" (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).</value> If this does not solve the problem and your system supports long paths, you can try to use a nested path structure. You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use nested directories for namespaces. This helps because even on "long-path-aware" platforms, the length of a directory name is limited, on Windows/NTFS this is 255 characters.</value>
</data> </data>
<data name="PropertyManuallyMissingReferencesListLoadedAssemblies" xml:space="preserve"> <data name="PropertyManuallyMissingReferencesListLoadedAssemblies" xml:space="preserve">
<value>for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.</value> <value>for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.</value>

Loading…
Cancel
Save