Skip to content

Commit

Permalink
Update LangVersion to C# 9.
Browse files Browse the repository at this point in the history
mono was the bottleneck restricting our ability to use a newer C# version. mono 6.12 is currently available. Although poorly documented on their website, this supports C# 9. https://www.mono-project.com/docs/about-mono/versioning/#mono-source-versioning indicates mono 6.12 uses Roslyn 3.9.0. https://github.com/dotnet/roslyn/blob/main/docs/wiki/NuGet-packages.md#versioning indicates Roslyn 3.9.0 supports C# 9.

This unlocks C# 8 and C# 9 features previously unavailable to us.
- https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history#c-version-80
- https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history#c-version-9

A newer version of StyleCop is required to avoid rules tripping up on the new syntax. Currently only prerelease versions are available but their use is encouraged DotNetAnalyzers/StyleCopAnalyzers#3420 (comment)

Fix style rule violations on existing rules where the newer language version makes some existing casts redundant or allows use of the null coalescing assignment operator.
  • Loading branch information
RoosterDragon committed Mar 26, 2023
1 parent 8a4303c commit 74475ec
Show file tree
Hide file tree
Showing 18 changed files with 40 additions and 36 deletions.
25 changes: 15 additions & 10 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ dotnet_diagnostic.IDE0044.severity = warning

# IDE0062 Make local function static
#csharp_prefer_static_local_function = true
dotnet_diagnostic.IDE0062.severity = silent # Requires C# 8
dotnet_diagnostic.IDE0062.severity = silent # Requires C# 8 - TODO Consider enabling

# IDE0064 Make struct fields writable
# No options
Expand Down Expand Up @@ -137,15 +137,15 @@ dotnet_diagnostic.IDE0050.severity = silent
# IDE0054/IDE0074 Use compound assignment/Use coalesce compound assignment
#dotnet_style_prefer_compound_assignment = true
dotnet_diagnostic.IDE0054.severity = warning
dotnet_diagnostic.IDE0074.severity = silent # Requires C# 8
dotnet_diagnostic.IDE0074.severity = silent # Requires C# 8 - TODO Consider enabling

# IDE0056 Use index operator
#csharp_style_prefer_index_operator = true
dotnet_diagnostic.IDE0056.severity = silent # Requires C# 8
dotnet_diagnostic.IDE0056.severity = silent # Requires C# 8 - TODO Consider enabling

# IDE0057 Use range operator
#csharp_style_prefer_range_operator = true
dotnet_diagnostic.IDE0057.severity = silent # Requires C# 8
dotnet_diagnostic.IDE0057.severity = silent # Requires C# 8 - TODO Consider enabling

# IDE0070 Use 'System.HashCode.Combine'
# No options
Expand All @@ -169,7 +169,7 @@ dotnet_diagnostic.IDE0082.severity = warning

# IDE0090 Simplify 'new' expression
#csharp_style_implicit_object_creation_when_type_is_apparent = true
dotnet_diagnostic.IDE0090.severity = silent # Requires C# 9
dotnet_diagnostic.IDE0090.severity = silent # Requires C# 9 - TODO Consider enabling

# IDE0180 Use tuple to swap values
#csharp_style_prefer_tuple_swap = true
Expand Down Expand Up @@ -204,7 +204,7 @@ dotnet_diagnostic.IDE0041.severity = warning

# IDE0150 Prefer 'null' check over type check
#csharp_style_prefer_null_check_over_type_check = true
dotnet_diagnostic.IDE0150.severity = silent # Requires C# 9
dotnet_diagnostic.IDE0150.severity = silent # Requires C# 9 - TODO Consider enabling

# IDE1005 Use conditional delegate call
csharp_style_conditional_delegate_call = true # true is the default, but the rule is not triggered if this is not specified.
Expand Down Expand Up @@ -272,11 +272,11 @@ dotnet_diagnostic.IDE0066.severity = silent

# IDE0078 Use pattern matching
#csharp_style_prefer_pattern_matching = true
dotnet_diagnostic.IDE0078.severity = silent # Requires C# 9
dotnet_diagnostic.IDE0078.severity = silent # Requires C# 9 - TODO Consider enabling

# IDE0083 Use pattern matching ('not' operator)
#csharp_style_prefer_not_pattern = true
dotnet_diagnostic.IDE0083.severity = silent # Requires C# 9
dotnet_diagnostic.IDE0083.severity = silent # Requires C# 9 - TODO Consider enabling

# IDE0170 Simplify property pattern
#csharp_style_prefer_extended_property_pattern = true
Expand All @@ -291,7 +291,7 @@ dotnet_diagnostic.IDE0011.severity = none

# IDE0063 Use simple 'using' statement
#csharp_prefer_simple_using_statement = true
dotnet_diagnostic.IDE0063.severity = silent # Requires C# 8
dotnet_diagnostic.IDE0063.severity = silent # Requires C# 8 - TODO Consider enabling

## 'using' directive preferences

Expand Down Expand Up @@ -375,7 +375,7 @@ dotnet_diagnostic.IDE0100.severity = warning

# IDE0110 Remove unnecessary discard
# No options
dotnet_diagnostic.IDE0110.severity = silent # Requires C# 9
dotnet_diagnostic.IDE0110.severity = silent # Requires C# 9 - TODO Consider enabling

### Miscellaneous Rules
### https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/miscellaneous-rules
Expand Down Expand Up @@ -598,6 +598,11 @@ dotnet_diagnostic.SA1633.severity = none # FileMustHaveHeader
dotnet_diagnostic.SA1642.severity = none # ConstructorSummaryDocumentationShouldBeginWithStandardText
dotnet_diagnostic.SA1649.severity = none # FileNameMustMatchTypeName

# Requires C# 8/9 - TODO Consider enabling
dotnet_diagnostic.SA1141.severity = none # UseTupleSyntax
dotnet_diagnostic.SA1316.severity = none # TupleElementNamesShouldUseCorrectCasing
dotnet_diagnostic.SA1414.severity = none # TupleTypesInSignaturesShouldHaveElementNames

#### Code Quality Rules
#### https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/

Expand Down
5 changes: 2 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<LangVersion>7.3</LangVersion>
<LangVersion>9</LangVersion>
<DebugSymbols>true</DebugSymbols>
<EngineRootPath Condition="'$(EngineRootPath)' == ''">..</EngineRootPath>
<OutputPath>$(EngineRootPath)/bin</OutputPath>
Expand Down Expand Up @@ -51,7 +51,6 @@

<!-- StyleCop -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Run the game with `launch-game.cmd`. It can be handed arguments that specify the
Linux
=====

.NET 6 or Mono (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 6 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project.
.NET 6 or Mono (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project.

The [.NET 6 download page](https://dotnet.microsoft.com/download/dotnet/6.0) provides repositories for various package managers and binary releases for several architectures. If you prefer to use Mono, we suggest adding the [upstream repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version and the `msbuild` toolchain.

Expand Down Expand Up @@ -78,6 +78,6 @@ Type `sudo make install` for system-wide installation. Run `sudo make install-li
macOS
=====

[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 6 unless you are running a very old version of macOS (10.9 through 10.14).
[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 unless you are running a very old version of macOS (10.9 through 10.14).

To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). Run with `./launch-game.sh`.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# to compile, run:
# make
#
# to compile using Mono (version 6.4 or greater) instead of .NET 6, run:
# to compile using Mono (version 6.12 or greater) instead of .NET 6, run:
# make RUNTIME=mono
#
# to compile using system libraries for native dependencies, run:
Expand Down Expand Up @@ -92,7 +92,7 @@ endif
all:
@echo "Compiling in ${CONFIGURATION} mode..."
ifeq ($(RUNTIME), mono)
@command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.4."; exit 1)
@command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.12."; exit 1)
@$(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM)
else
@$(DOTNET) build -c ${CONFIGURATION} -nologo -p:TargetPlatform=$(TARGETPLATFORM)
Expand Down Expand Up @@ -173,7 +173,7 @@ help:
@echo 'to compile, run:'
@echo ' make'
@echo
@echo 'to compile using Mono (version 6.4 or greater) instead of .NET 6, run:'
@echo 'to compile using Mono (version 6.12 or greater) instead of .NET 6, run:'
@echo ' make RUNTIME=mono'
@echo
@echo 'to compile using system libraries for native dependencies, run:'
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Game/Exts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public static T RandomOrDefault<T>(this IEnumerable<T> ts, MersenneTwister r)
static T Random<T>(IEnumerable<T> ts, MersenneTwister r, bool throws)
{
var xs = ts as ICollection<T>;
xs = xs ?? ts.ToList();
xs ??= ts.ToList();
if (xs.Count == 0)
{
if (throws)
Expand Down Expand Up @@ -396,8 +396,8 @@ public static Dictionary<TKey, TElement> ToDictionaryWithConflictLog<TSource, TK
string debugName, Func<TKey, string> logKey = null, Func<TElement, string> logValue = null)
{
// Fall back on ToString() if null functions are provided:
logKey = logKey ?? (s => s.ToString());
logValue = logValue ?? (s => s.ToString());
logKey ??= s => s.ToString();
logValue ??= s => s.ToString();

// Try to build a dictionary and log all duplicates found (if any):
var dupKeys = new Dictionary<TKey, List<string>>();
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Activities/Move/Move.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ protected override void OnFirstRun(Actor self)
if (evaluateNearestMovableCell && destination.HasValue)
{
var movableDestination = mobile.NearestMoveableCell(destination.Value);
destination = mobile.CanEnterCell(movableDestination, check: BlockedByActor.Immovable) ? movableDestination : (CPos?)null;
destination = mobile.CanEnterCell(movableDestination, check: BlockedByActor.Immovable) ? movableDestination : null;
}

// TODO: Change this to BlockedByActor.Stationary after improving the local avoidance behaviour
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ public virtual void ResolveSprites(SpriteCache cache)
});
}).ToArray();

length = length ?? allSprites.Length - start;
length ??= allSprites.Length - start;

if (alpha != null)
{
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Pathfinder/PathSearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static PathSearch ToTargetCell(
else
graph = new MapPathGraph(LayerPoolForWorld(world), locomotor, self, world, check, customCost, ignoreActor, laneBias, inReverse);

heuristic = heuristic ?? DefaultCostEstimator(locomotor, target);
heuristic ??= DefaultCostEstimator(locomotor, target);
var search = new PathSearch(graph, heuristic, heuristicWeightPercentage, loc => loc == target, recorder);

AddInitialCells(world, locomotor, froms, customCost, search);
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public Actor[] Reinforce(Player owner, string[] actorTypes, CPos[] entryPath, in
for (var i = 0; i < actorTypes.Length; i++)
{
var af = actionFunc != null ? (LuaFunction)actionFunc.CopyReference() : null;
var actor = CreateActor(owner, actorTypes[i], false, entryPath[0], entryPath.Length > 1 ? entryPath[1] : (CPos?)null);
var actor = CreateActor(owner, actorTypes[i], false, entryPath[0], entryPath.Length > 1 ? entryPath[1] : null);
actors.Add(actor);

var actionDelay = i * interval;
Expand Down Expand Up @@ -118,7 +118,7 @@ public Actor[] Reinforce(Player owner, string[] actorTypes, CPos[] entryPath, in
public LuaTable ReinforceWithTransport(Player owner, string actorType, string[] cargoTypes, CPos[] entryPath, CPos[] exitPath = null,
LuaFunction actionFunc = null, LuaFunction exitFunc = null, int dropRange = 3)
{
var transport = CreateActor(owner, actorType, true, entryPath[0], entryPath.Length > 1 ? entryPath[1] : (CPos?)null);
var transport = CreateActor(owner, actorType, true, entryPath[0], entryPath.Length > 1 ? entryPath[1] : null);
var cargo = transport.TraitOrDefault<Cargo>();

var passengers = new List<Actor>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public RepairableBuildingProperties(ScriptContext context, Actor self)
[Desc("Start repairs on this building. `repairer` can be an allied player.")]
public void StartBuildingRepairs(Player repairer = null)
{
repairer = repairer ?? Self.Owner;
repairer ??= Self.Owner;

if (!rb.Repairers.Contains(repairer))
rb.RepairBuilding(Self, repairer);
Expand All @@ -38,7 +38,7 @@ public void StartBuildingRepairs(Player repairer = null)
[Desc("Stop repairs on this building. `repairer` can be an allied player.")]
public void StopBuildingRepairs(Player repairer = null)
{
repairer = repairer ?? Self.Owner;
repairer ??= Self.Owner;

if (rb.RepairActive && rb.Repairers.Contains(repairer))
rb.RepairBuilding(Self, repairer);
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Traits/Cargo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ public string VoicePhraseForOrder(Actor self, Order order)

public Actor Unload(Actor self, Actor passenger = null)
{
passenger = passenger ?? cargo.Last();
passenger ??= cargo.Last();
if (!cargo.Remove(passenger))
throw new ArgumentException("Attempted to unload an actor that is not a passenger.");

Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Traits/Turreted.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static Func<WAngle> WorldFacingFromInit(IActorInitializer init, TraitInfo
if (turretFacingInit != null)
{
var facing = turretFacingInit.Value;
return bodyFacing != null ? (Func<WAngle>)(() => bodyFacing() + facing) : () => facing;
return bodyFacing != null ? () => bodyFacing() + facing : () => facing;
}

var dynamicFacingInit = init.GetOrDefault<DynamicTurretFacingInit>(info);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public override IEnumerable<string> UpdateSequenceNode(ModData modData, MiniYaml
continue;

resolvedSequenceNode.Value.Nodes = MiniYaml.Merge(new[] { resolvedDefaultsNode.Value.Nodes, resolvedSequenceNode.Value.Nodes });
resolvedSequenceNode.Value.Value = resolvedSequenceNode.Value.Value ?? resolvedDefaultsNode.Value.Value;
resolvedSequenceNode.Value.Value ??= resolvedDefaultsNode.Value.Value;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void OpenMenuPanel(MenuButtonWidget button, WidgetArgs widgetArgs = null)
if (button.DisableWorldSounds)
Game.Sound.DisableWorldSounds = true;

widgetArgs = widgetArgs ?? new WidgetArgs();
widgetArgs ??= new WidgetArgs();
widgetArgs.Add("onExit", () =>
{
if (button.HideIngameUI)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ internal LobbyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer,
{
{ "initialMap", modData.MapCache.PickLastModifiedMap(MapVisibility.Lobby) ?? map.Uid },
{ "initialTab", MapClassification.System },
{ "onExit", Game.IsHost ? (Action)UpdateSelectedMap : modData.MapCache.UpdateMaps },
{ "onExit", Game.IsHost ? UpdateSelectedMap : modData.MapCache.UpdateMaps },
{ "onSelect", Game.IsHost ? onSelect : null },
{ "filter", MapVisibility.Lobby },
});
Expand Down
2 changes: 1 addition & 1 deletion packaging/macos/checkmono.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <dlfcn.h>

#define SYSTEM_MONO_PATH "/Library/Frameworks/Mono.framework/Versions/Current/"
#define SYSTEM_MONO_MIN_VERSION "6.4"
#define SYSTEM_MONO_MIN_VERSION "6.12"

typedef char *(* mono_get_runtime_build_info)(void);

Expand Down
2 changes: 1 addition & 1 deletion packaging/macos/launcher.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <mach/machine.h>

#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/"
#define SYSTEM_MONO_MIN_VERSION @"6.4"
#define SYSTEM_MONO_MIN_VERSION @"6.12"
#define DOTNET_MIN_MACOS_VERSION 10.15

@interface OpenRALauncher : NSObject <NSApplicationDelegate>
Expand Down
2 changes: 1 addition & 1 deletion packaging/macos/utility.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <mach/machine.h>

#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/"
#define SYSTEM_MONO_MIN_VERSION @"6.4"
#define SYSTEM_MONO_MIN_VERSION @"6.12"
#define DOTNET_MIN_MACOS_VERSION 10.15

typedef void* hostfxr_handle;
Expand Down

0 comments on commit 74475ec

Please sign in to comment.