mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
Document the two roles of the language version in the settings API
The language version appears in two places that share a name but not a concept, which repeatedly reads as one confused API: on DecompilerSettings it is a construction shortcut (SetLanguageVersion initializes the feature flags once and the version is not stored, so the flags are the only state and the call is deliberately one-way), while on WholeProjectDecompiler it is an export parameter (the LangVersion stamped into the project file, defaulting to GetMinimumRequiredVersion() and rejected below it as a safety net against exporting uncompilable projects). Spell both roles out in the XML docs so the distinction no longer has to be reverse-engineered. Assisted-by: Claude:claude-fable-5:Claude Code
This commit is contained in:
@@ -332,12 +332,12 @@ namespace ICSharpCode.Decompiler
|
||||
context.AddSource(hintName, SourceText.From(builder.ToString().Replace("\r\n", "\n"), Encoding.UTF8));
|
||||
}
|
||||
|
||||
// Emitted as partial implementing declarations: the containing class supplies the defining
|
||||
// stubs, which is where the XML documentation lives (the docs on a partial method's defining
|
||||
// declaration apply as long as the implementation carries none).
|
||||
static void WriteSetLanguageVersion(StringBuilder builder, IGrouping<int, SettingInfo>[] versionBuckets)
|
||||
{
|
||||
builder.AppendLine("\t\t/// <summary>");
|
||||
builder.AppendLine("\t\t/// Deactivates all language features from versions newer than <paramref name=\"languageVersion\"/>.");
|
||||
builder.AppendLine("\t\t/// </summary>");
|
||||
builder.AppendLine("\t\tpublic void SetLanguageVersion(global::ICSharpCode.Decompiler.CSharp.LanguageVersion languageVersion)");
|
||||
builder.AppendLine("\t\tpublic partial void SetLanguageVersion(global::ICSharpCode.Decompiler.CSharp.LanguageVersion languageVersion)");
|
||||
builder.AppendLine("\t\t{");
|
||||
builder.AppendLine("\t\t\t// By default, all decompiler features are enabled.");
|
||||
builder.AppendLine("\t\t\t// Disable some of them based on language version:");
|
||||
@@ -356,10 +356,7 @@ namespace ICSharpCode.Decompiler
|
||||
|
||||
static void WriteGetMinimumRequiredVersion(StringBuilder builder, IGrouping<int, SettingInfo>[] versionBuckets)
|
||||
{
|
||||
builder.AppendLine("\t\t/// <summary>");
|
||||
builder.AppendLine("\t\t/// Gets the lowest language version that includes all currently enabled language features.");
|
||||
builder.AppendLine("\t\t/// </summary>");
|
||||
builder.AppendLine("\t\tpublic global::ICSharpCode.Decompiler.CSharp.LanguageVersion GetMinimumRequiredVersion()");
|
||||
builder.AppendLine("\t\tpublic partial global::ICSharpCode.Decompiler.CSharp.LanguageVersion GetMinimumRequiredVersion()");
|
||||
builder.AppendLine("\t\t{");
|
||||
foreach (var bucket in versionBuckets.Reverse())
|
||||
{
|
||||
|
||||
@@ -60,6 +60,13 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
|
||||
|
||||
LanguageVersion? languageVersion;
|
||||
|
||||
/// <summary>
|
||||
/// The C# language version written into the exported project file as LangVersion.
|
||||
/// This is an export parameter, not decompiler state: when not set explicitly, it defaults
|
||||
/// to <see cref="DecompilerSettings.GetMinimumRequiredVersion"/> of the current settings,
|
||||
/// and an explicit value below that minimum is rejected (here and again when the export
|
||||
/// starts) because the emitted code could not compile under it.
|
||||
/// </summary>
|
||||
public LanguageVersion LanguageVersion {
|
||||
get { return languageVersion ?? Settings.GetMinimumRequiredVersion(); }
|
||||
set {
|
||||
|
||||
@@ -44,12 +44,31 @@ namespace ICSharpCode.Decompiler
|
||||
/// This does not imply that the resulting code strictly uses only language features from
|
||||
/// that version. Language constructs like generics or ref locals cannot be removed from
|
||||
/// the compiled code.
|
||||
/// The language version is a construction shortcut, not state: it initializes the feature
|
||||
/// flags once (see <see cref="SetLanguageVersion"/>) and is not stored afterwards.
|
||||
/// </remarks>
|
||||
public DecompilerSettings(CSharp.LanguageVersion languageVersion)
|
||||
{
|
||||
SetLanguageVersion(languageVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One-shot profile initializer: deactivates all language features from versions newer than
|
||||
/// <paramref name="languageVersion"/>. The version itself is not stored - the feature flags
|
||||
/// are the only state - so the call is not reversible and a later call with a higher version
|
||||
/// does not re-enable features. Use <see cref="GetMinimumRequiredVersion"/> to derive a
|
||||
/// version back from the flags.
|
||||
/// </summary>
|
||||
public partial void SetLanguageVersion(CSharp.LanguageVersion languageVersion);
|
||||
|
||||
/// <summary>
|
||||
/// Derives the lowest language version that includes all currently enabled language
|
||||
/// features. The settings do not store a language version, so this derivation is how a
|
||||
/// version is recovered from the flags; project export uses it as the default (and lower
|
||||
/// bound) for the LangVersion written into the project file.
|
||||
/// </summary>
|
||||
public partial CSharp.LanguageVersion GetMinimumRequiredVersion();
|
||||
|
||||
/// <summary>
|
||||
/// Use C# 9 <c>nint</c>/<c>nuint</c> types.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user