Skip to content

Commit

Permalink
fix: Increase RMG060 default severity from info to warning (#1173)
Browse files Browse the repository at this point in the history
  • Loading branch information
latonz committed Mar 15, 2024
1 parent cc7e72b commit 3cba05b
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 24 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/test.yml
Expand Up @@ -44,8 +44,9 @@ jobs:
- if: failure()
uses: actions/upload-artifact@v4
with:
name: verify-test-results
name: verify-test-results-package
path: '**/*.received.*'
retention-days: 3
validate-package:
needs: package
runs-on: ubuntu-latest
Expand Down Expand Up @@ -102,8 +103,9 @@ jobs:
- if: failure()
uses: actions/upload-artifact@v4
with:
name: verify-test-results
name: verify-test-results-net${{ matrix.dotnet }}
path: '**/*.received.*'
retention-days: 3
integration-test-net-framework:
needs: package
runs-on: windows-latest
Expand All @@ -129,8 +131,9 @@ jobs:
- if: failure()
uses: actions/upload-artifact@v4
with:
name: verify-test-results
name: verify-test-results-net-framework
path: '**/*.received.*'
retention-days: 3
sample:
runs-on: ubuntu-latest
needs: package
Expand Down
61 changes: 61 additions & 0 deletions docs/docs/configuration/analyzer-diagnostics/RMG060.mdx
@@ -0,0 +1,61 @@
---
sidebar_label: RMG060
description: 'Mapperly analyzer diagnostic RMG060 — Multiple user mappings discovered without specifying an explicit default'
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# RMG060 — Multiple user-mappings discovered without specifying an explicit default

Multiple user-mappings for the same type pair are discovered
without specifying an explicit default.
Mapperly needs to now which mapping it should use.

To specify a default apply `[UserMapping(Default = true)]`.

See also [user-implemented mappings](../user-implemented-methods.mdx#default-user-implemented-mapping-method).

## Example

Two mappings from `Car` to `CarDto` are defined.
When Mapperly needs to map from `Car` to `CarDto` in `CarsToCarDtos`
it needs to know whether to use `CarToCarDto` or `CarToCarDtoIgnoreId`.
Apply `[UserMapping(Default = true)]` to the mapping which Mapperly should use
in such cases.

<Tabs>
<TabItem value="bad" label="Invalid" default>
```csharp
[Mapper]
public partial class CarMapper
{
public paratial List<CarDto> CarsToCarDtos(List<Car> cars);

public partial CarDto CarToCarDto(Car car);

[MapperIgnoreSource(nameof(Car.Id))]
public partial CarDto CarToCarDtoIgnoreId(Car car);
}
```

</TabItem>
<TabItem value="fixed" label="Fixed">
```csharp
[Mapper]
public partial class CarMapper
{
public paratial List<CarDto> CarsToCarDtos(List<Car> cars);

// highlight-start
[UserMapping(Default = true)]
// highlight-end
public partial CarDto CarToCarDto(Car car);

[MapperIgnoreSource(nameof(Car.Id))]
public partial CarDto CarToCarDtoIgnoreId(Car car);
}
```

</TabItem>
</Tabs>
2 changes: 1 addition & 1 deletion docs/docs/configuration/user-implemented-methods.mdx
Expand Up @@ -89,7 +89,7 @@ the first user-implemented mapping which has an unspecified `Default` value is u
For each type-pair only one default mapping can exist.

If multiple mappings exist for the same type-pair without a default mapping, `RMG060` is reported.
By default `RMG060` has a severity of info,
By default `RMG060` has a severity of warning,
which can be changed using the [`.editorconfig`](./analyzer-diagnostics/index.mdx#editorconfig).

## Map properties using user-implemented mappings
Expand Down
4 changes: 2 additions & 2 deletions src/Riok.Mapperly/AnalyzerReleases.Shipped.md
Expand Up @@ -144,11 +144,11 @@ RMG018 | Mapper | Disabled | Partial static mapping method in an instance map
Rule ID | Category | Severity | Notes
--------|----------|----------|-------
RMG059 | Mapper | Error | Multiple default user mappings found, only one is allowed
RMG060 | Mapper | Info | Multiple user mappings discovered without specifying an explicit default
RMG060 | Mapper | Warning | Multiple user mappings discovered without specifying an explicit default
RMG061 | Mapper | Error | The referenced mapping was not found
RMG062 | Mapper | Error | The referenced mapping name is ambiguous
RMG063 | Mapper | Error | Cannot configure an enum mapping on a non-enum mapping
RMG064 | Mapper | Error | Cannot configure an object mapping on a non-object mapping
RMG065 | Mapper | Warning | Cannot configure an object mapping on a queryable projection mapping, apply the configurations to an object mapping method instead
RMG066 | Mapper | Warning | No members are mapped in an object mapping
RMG066 | Mapper | Warning | No members are mapped in an object mapping
RMG067 | Mapper | Error | Invalid usage of the MapPropertyAttribute
5 changes: 3 additions & 2 deletions src/Riok.Mapperly/Diagnostics/DiagnosticDescriptors.cs
Expand Up @@ -581,8 +581,9 @@ public static class DiagnosticDescriptors
"Multiple user mappings discovered without specifying an explicit default",
"Multiple user mappings discovered for the mapping from {0} to {1} without specifying an explicit default",
DiagnosticCategories.Mapper,
DiagnosticSeverity.Info,
true
DiagnosticSeverity.Warning,
true,
helpLinkUri: BuildHelpUri("RMG060")
);

public static readonly DiagnosticDescriptor ReferencedMappingNotFound =
Expand Down
Expand Up @@ -9,6 +9,7 @@ namespace Riok.Mapperly.IntegrationTests.Mapper
[Mapper(EnumMappingStrategy = EnumMappingStrategy.ByValue)]
public static partial class StaticTestMapper
{
[UserMapping(Default = true)]
public static partial int DirectInt(int value);

public static partial int? DirectIntNullable(int? value);
Expand All @@ -33,6 +34,7 @@ public static partial class StaticTestMapper
[MapperRequiredMapping(RequiredMappingStrategy.Target)]
public static partial TestObjectDto MapToDtoExt(this TestObject src);

[UserMapping(Default = true)]
public static TestObjectDto MapToDto(TestObject src)
{
var target = MapToDtoInternal(src);
Expand Down Expand Up @@ -120,6 +122,7 @@ public static void MapExistingList(List<string> src, List<int> dst)
[MapperIgnoreTargetValue(TestEnum.Value30)]
public static partial TestEnum MapToEnumByNameWithIgnored(TestEnumDtoAdditionalValue v);

[UserMapping(Default = true)]
[MapEnum(EnumMappingStrategy.ByValueCheckDefined)]
public static partial TestEnum MapToEnumByValueCheckDefined(TestEnumDtoByValue v);

Expand Down
2 changes: 2 additions & 0 deletions test/Riok.Mapperly.IntegrationTests/Mapper/TestMapper.cs
Expand Up @@ -32,6 +32,7 @@ public TestMapper()
_formatEnUs.NumberFormat.CurrencyPositivePattern = 2;
}

[UserMapping(Default = true)]
public partial int DirectInt(int value);

public partial long ImplicitCastInt(int value);
Expand All @@ -48,6 +49,7 @@ public TestMapper()

public partial IEnumerable<TestObjectDto> MapAllDtos(IEnumerable<TestObject> objects);

[UserMapping(Default = true)]
public TestObjectDto MapToDto(TestObject src)
{
var target = MapToDtoInternal(src);
Expand Down
Expand Up @@ -23,7 +23,7 @@
CtorValue: 5,
CtorValue2: 100,
RequiredValue: 4,
StringValue: ,
StringValue: +after-map,
RenamedStringValue2: ,
Unflattening: {},
NestedNullableTargetNotNullable: {},
Expand Down
Expand Up @@ -23,7 +23,7 @@
CtorValue: 5,
CtorValue2: 100,
RequiredValue: 4,
StringValue: ,
StringValue: +after-map,
RenamedStringValue2: ,
Unflattening: {},
NestedNullableTargetNotNullable: {},
Expand Down
Expand Up @@ -28,7 +28,7 @@
CtorValue: 5,
CtorValue2: 100,
RequiredValue: 4,
StringValue: ,
StringValue: +after-map,
RenamedStringValue2: ,
Unflattening: {},
NestedNullableTargetNotNullable: {},
Expand Down
Expand Up @@ -28,7 +28,7 @@
CtorValue: 5,
CtorValue2: 100,
RequiredValue: 4,
StringValue: ,
StringValue: +after-map,
RenamedStringValue2: ,
Unflattening: {},
NestedNullableTargetNotNullable: {},
Expand Down
@@ -1,4 +1,4 @@
// <auto-generated />
// <auto-generated />
#nullable enable
namespace Riok.Mapperly.IntegrationTests.Mapper
{
Expand Down Expand Up @@ -55,7 +55,7 @@ public static partial class StaticTestMapper
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::System.Collections.Generic.IEnumerable<global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDto> MapAllDtos(global::System.Collections.Generic.IEnumerable<global::Riok.Mapperly.IntegrationTests.Models.TestObject> objects)
{
return global::System.Linq.Enumerable.Select(objects, x => MapToDtoExt(x));
return global::System.Linq.Enumerable.Select(objects, x => MapToDto(x));
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
Expand Down Expand Up @@ -101,7 +101,7 @@ public static partial class StaticTestMapper
}
if (src.RecursiveObject != null)
{
target.RecursiveObject = MapToDtoExt(src.RecursiveObject);
target.RecursiveObject = MapToDto(src.RecursiveObject);
}
else
{
Expand Down Expand Up @@ -214,7 +214,7 @@ public static partial class StaticTestMapper
}
if (testObject.RecursiveObject != null)
{
target.RecursiveObject = MapToDtoExt(testObject.RecursiveObject);
target.RecursiveObject = MapToDto(testObject.RecursiveObject);
}
else
{
Expand Down Expand Up @@ -420,7 +420,7 @@ public static partial class StaticTestMapper
}
if (source.RecursiveObject != null)
{
target.RecursiveObject = MapToDtoExt(source.RecursiveObject);
target.RecursiveObject = MapToDto(source.RecursiveObject);
}
else
{
Expand Down
Expand Up @@ -55,7 +55,7 @@ public static partial class StaticTestMapper
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
public static partial global::System.Collections.Generic.IEnumerable<global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDto> MapAllDtos(global::System.Collections.Generic.IEnumerable<global::Riok.Mapperly.IntegrationTests.Models.TestObject> objects)
{
return global::System.Linq.Enumerable.Select(objects, x => MapToDtoExt(x));
return global::System.Linq.Enumerable.Select(objects, x => MapToDto(x));
}

[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
Expand Down Expand Up @@ -101,7 +101,7 @@ public static partial class StaticTestMapper
}
if (src.RecursiveObject != null)
{
target.RecursiveObject = MapToDtoExt(src.RecursiveObject);
target.RecursiveObject = MapToDto(src.RecursiveObject);
}
else
{
Expand Down Expand Up @@ -216,7 +216,7 @@ public static partial class StaticTestMapper
}
if (testObject.RecursiveObject != null)
{
target.RecursiveObject = MapToDtoExt(testObject.RecursiveObject);
target.RecursiveObject = MapToDto(testObject.RecursiveObject);
}
else
{
Expand Down Expand Up @@ -427,7 +427,7 @@ public static partial class StaticTestMapper
}
if (source.RecursiveObject != null)
{
target.RecursiveObject = MapToDtoExt(source.RecursiveObject);
target.RecursiveObject = MapToDto(source.RecursiveObject);
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions test/Riok.Mapperly.Tests/Mapping/UserMethodTest.cs
Expand Up @@ -654,7 +654,7 @@ public void UserImplementedWithDefaultFalseUserMappingsShouldUseFirstNonFalseDef
);

TestHelper
.GenerateMapper(source, TestHelperOptions.AllowInfoDiagnostics)
.GenerateMapper(source, TestHelperOptions.AllowDiagnostics)
.Should()
.HaveDiagnostic(
DiagnosticDescriptors.MultipleUserMappingsWithoutDefault,
Expand Down Expand Up @@ -694,7 +694,7 @@ public void DisabledAutoUserMappingDiscoveryShouldUseFirstNonFalseDefault()
);

TestHelper
.GenerateMapper(source, TestHelperOptions.AllowInfoDiagnostics)
.GenerateMapper(source, TestHelperOptions.AllowDiagnostics)
.Should()
.HaveDiagnostic(
DiagnosticDescriptors.MultipleUserMappingsWithoutDefault,
Expand Down
Expand Up @@ -23,9 +23,10 @@
{
Id: RMG060,
Title: Multiple user mappings discovered without specifying an explicit default,
Severity: Info,
Severity: Warning,
WarningLevel: 1,
Location: : (12,0)-(12,71),
HelpLink: https://localhost:3000/docs/configuration/analyzer-diagnostics/RMG060,
MessageFormat: Multiple user mappings discovered for the mapping from {0} to {1} without specifying an explicit default,
Message: Multiple user mappings discovered for the mapping from A to B without specifying an explicit default,
Category: Mapper
Expand Down

0 comments on commit 3cba05b

Please sign in to comment.