Skip to content

Commit 873b008

Browse files
authored
Warn in CustomMarshallerAnalyzer if the MarshaMode is not valid (#87198)
I ran into an issue when making some tests where I tried to use MarshalMode as a flags enum, which lead to the generated code not being correct, but no warning was showing up. This PR creates a warning if you try to do an operation on the MarshalMode argument or if a casted int value is not defined in the MarshalMode enum. Fixes #87139
1 parent 0caa3e7 commit 873b008

File tree

16 files changed

+219
-32
lines changed

16 files changed

+219
-32
lines changed

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Collections.Immutable;
7-
using System.Diagnostics;
87
using System.Diagnostics.CodeAnalysis;
98
using System.Linq;
10-
using System.Runtime.InteropServices;
11-
using System.Text;
129
using Microsoft.CodeAnalysis;
13-
using Microsoft.CodeAnalysis.CSharp;
1410
using Microsoft.CodeAnalysis.CSharp.Syntax;
1511
using Microsoft.CodeAnalysis.Diagnostics;
1612
using Microsoft.CodeAnalysis.DotnetRuntime.Extensions;
@@ -395,6 +391,17 @@ public static ImmutableDictionary<string, string> CreateDiagnosticPropertiesForM
395391
isEnabledByDefault: true,
396392
description: GetResourceString(nameof(SR.ManagedTypeMustBeNonNullDescription)));
397393

394+
/// <inheritdoc cref="SR.MarshalModeMustBeValidEnumValue" />
395+
public static readonly DiagnosticDescriptor MarshalModeMustBeValidValue =
396+
new DiagnosticDescriptor(
397+
Ids.InvalidCustomMarshallerAttributeUsage,
398+
GetResourceString(nameof(SR.InvalidMarshalModeTitle)),
399+
GetResourceString(nameof(SR.MarshalModeMustBeValidEnumValue)),
400+
Category,
401+
DiagnosticSeverity.Error,
402+
isEnabledByDefault: true,
403+
description: GetResourceString(nameof(SR.MarshalModeMustBeValidEnumValue)));
404+
398405
// We are intentionally using the same diagnostic IDs as the parent type.
399406
// These diagnostics are the same diagnostics, but with a different severity,
400407
// as the Default marshaller shape can have support for the managed-to-unmanaged shape
@@ -676,11 +683,19 @@ public void AnalyzeAttribute(OperationAnalysisContext context)
676683
{
677684
return;
678685
}
686+
var marshalModeArgument = attrCreation.GetArgumentByOrdinal(1);
687+
if (marshalModeArgument.Value is not IFieldReferenceOperation { ConstantValue.Value: var marshalMode }
688+
|| !Enum.IsDefined(typeof(MarshalMode), (MarshalMode)marshalMode))
689+
{
690+
DiagnosticReporter marshalModeReporter = DiagnosticReporter.CreateForLocation(marshalModeArgument.Syntax.GetLocation(), context.ReportDiagnostic);
691+
marshalModeReporter.CreateAndReportDiagnostic(MarshalModeMustBeValidValue);
692+
return;
693+
}
679694

680695
AnalyzeMarshallerType(
681696
marshallerTypeReporter,
682697
managedType,
683-
(MarshalMode)attrCreation.GetArgumentByOrdinal(1).Value.ConstantValue.Value,
698+
(MarshalMode)marshalMode,
684699
(INamedTypeSymbol)marshallerType,
685700
ManualTypeMarshallingHelper.IsLinearCollectionEntryPoint(entryType));
686701
}

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/Strings.resx

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<root>
3-
<!--
4-
Microsoft ResX Schema
5-
3+
<!--
4+
Microsoft ResX Schema
5+
66
Version 2.0
7-
8-
The primary goals of this format is to allow a simple XML format
9-
that is mostly human readable. The generation and parsing of the
10-
various data types are done through the TypeConverter classes
7+
8+
The primary goals of this format is to allow a simple XML format
9+
that is mostly human readable. The generation and parsing of the
10+
various data types are done through the TypeConverter classes
1111
associated with the data types.
12-
12+
1313
Example:
14-
14+
1515
... ado.net/XML headers & schema ...
1616
<resheader name="resmimetype">text/microsoft-resx</resheader>
1717
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
2626
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
2727
<comment>This is a comment</comment>
2828
</data>
29-
30-
There are any number of "resheader" rows that contain simple
29+
30+
There are any number of "resheader" rows that contain simple
3131
name/value pairs.
32-
33-
Each data row contains a name, and value. The row also contains a
34-
type or mimetype. Type corresponds to a .NET class that support
35-
text/value conversion through the TypeConverter architecture.
36-
Classes that don't support this are serialized and stored with the
32+
33+
Each data row contains a name, and value. The row also contains a
34+
type or mimetype. Type corresponds to a .NET class that support
35+
text/value conversion through the TypeConverter architecture.
36+
Classes that don't support this are serialized and stored with the
3737
mimetype set.
38-
39-
The mimetype is used for serialized objects, and tells the
40-
ResXResourceReader how to depersist the object. This is currently not
38+
39+
The mimetype is used for serialized objects, and tells the
40+
ResXResourceReader how to depersist the object. This is currently not
4141
extensible. For a given mimetype the value must be set accordingly:
42-
43-
Note - application/x-microsoft.net.object.binary.base64 is the format
44-
that the ResXResourceWriter will generate, however the reader can
42+
43+
Note - application/x-microsoft.net.object.binary.base64 is the format
44+
that the ResXResourceWriter will generate, however the reader can
4545
read any of the formats listed below.
46-
46+
4747
mimetype: application/x-microsoft.net.object.binary.base64
48-
value : The object must be serialized with
48+
value : The object must be serialized with
4949
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
5050
: and then encoded with base64 encoding.
51-
51+
5252
mimetype: application/x-microsoft.net.object.soap.base64
53-
value : The object must be serialized with
53+
value : The object must be serialized with
5454
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
5555
: and then encoded with base64 encoding.
5656
5757
mimetype: application/x-microsoft.net.object.bytearray.base64
58-
value : The object must be serialized into a byte array
58+
value : The object must be serialized into a byte array
5959
: using a System.ComponentModel.TypeConverter
6060
: and then encoded with base64 encoding.
6161
-->
@@ -497,4 +497,10 @@
497497
<data name="ConvertToLibraryImportWithSuffixAddUnsafe" xml:space="preserve">
498498
<value>Convert to 'LibraryImport' with '{0}' suffix and enable unsafe code</value>
499499
</data>
500+
<data name="InvalidMarshalModeTitle" xml:space="preserve">
501+
<value>Invalid 'MarshalMode' value.</value>
502+
</data>
503+
<data name="MarshalModeMustBeValidEnumValue" xml:space="preserve">
504+
<value>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</value>
505+
</data>
500506
</root>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.cs.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">Zadaný spravovaný typ je neplatný</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">Zadaný zařazovací typ je neplatný</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">Spravovaný typ pro zařazovací typ vstupního bodu {0} nesmí nabývat hodnoty null.</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">Zařazovací typ musí být uzavřený obecný typ nebo mít stejný počet obecných parametrů jako spravovaný typ, aby mohl vygenerovaný kód použít konkrétní vytvoření instance.</target>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.de.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">Der angegebene verwaltete Typ ist ungültig.</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">Der angegebene Marshallertyp ist ungültig.</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">Der verwaltete Typ für den Einstiegspunkt-Marshallertyp "{0}" darf nicht "NULL" sein</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">Der Marshaller-Typ muss ein geschlossener generischer Typ sein oder dieselbe Anzahl generischer Parameter wie der verwaltete Typ aufweisen, damit der ausgegebene Code eine bestimmte Instanziierung verwenden kann.</target>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.es.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">El tipo administrado especificado no es válido</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">El tipo de serializador especificado no es válido</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">El tipo administrado para el tipo de serializador de punto de entrada "{0}" no debe ser "null"</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">El tipo serializador debe ser un genérico cerrado o tener el mismo número de parámetros genéricos que el tipo administrado para que el código emitido pueda usar una creación de instancia específica.</target>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.fr.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">Le type managé spécifié n’est pas valide</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">Le type de marshaleur spécifié n’est pas valide</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">Le type managé du type marshaleur de point d’entrée « {0} » ne doit pas avoir la valeur 'null'</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">Le type marshaler doit être un générique fermé ou avoir le même nombre de paramètres génériques que le type managé pour que le code émis puisse utiliser une instanciation spécifique.</target>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.it.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">Il tipo gestito specificato non è valido</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">Il tipo di marshaller specificato non è valido</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">Il tipo gestito per il tipo di marshaller del punto di ingresso '{0}' non deve essere 'null'</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">Il tipo di marshaller deve essere un generico chiuso o avere lo stesso numero di parametri generici del tipo gestito, in modo che il codice generato possa usare una creazione di istanza specifica.</target>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ja.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">指定されたマネージド型が無効です</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">指定されたマーシャラー型が無効です</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">エントリ ポイント マーシャラー型 '{0}' のマネージド型を 'null' にすることはできません</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">マーシャラー型は、クローズ ジェネリックであるか、マネージド型と同じ数のジェネリック パラメーターを持つ必要があります。これにより、生成されたコードが特定のインスタンス化を使用できるようになります。</target>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ko.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">지정된 관리 유형이 잘못되었습니다.</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">지정된 마샬러 유형이 잘못되었습니다.</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">진입점 마샬러 유형 '{0}'의 관리 유형은 'null'이 아니어야 합니다.</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">마샬러 형식은 닫힌 제네릭이거나 관리되는 형식과 동일한 수의 제네릭 매개 변수가 있어야 내보낸 코드에서 특정 인스턴스화를 사용할 수 있습니다.</target>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pl.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@
217217
<target state="translated">Określony typ zarządzany jest nieprawidłowy</target>
218218
<note />
219219
</trans-unit>
220+
<trans-unit id="InvalidMarshalModeTitle">
221+
<source>Invalid 'MarshalMode' value.</source>
222+
<target state="new">Invalid 'MarshalMode' value.</target>
223+
<note />
224+
</trans-unit>
220225
<trans-unit id="InvalidMarshallerTypeTitle">
221226
<source>Specified marshaller type is invalid</source>
222227
<target state="translated">Określony typ marshallera jest nieprawidłowy</target>
@@ -312,6 +317,11 @@
312317
<target state="translated">Typ zarządzany dla typu marshaller punktu wejścia „{0}” nie może mieć wartości „null”</target>
313318
<note />
314319
</trans-unit>
320+
<trans-unit id="MarshalModeMustBeValidEnumValue">
321+
<source>The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</source>
322+
<target state="new">The 'marshalMode' argument of 'CustomMarshallerAttribute' must be a valid enum value of 'MarshalMode'.</target>
323+
<note />
324+
</trans-unit>
315325
<trans-unit id="MarshallerTypeMustBeClosedOrMatchArityDescription">
316326
<source>The marshaller type must be a closed generic or have the same number of generic parameters as the managed type so the emitted code can use a specific instantiation.</source>
317327
<target state="translated">Typ marshallera musi być zamkniętym typem ogólnym lub mieć taką samą liczbę parametrów ogólnych jak typ zarządzany, aby emitowany kod mógł używać określonego wystąpienia.</target>

0 commit comments

Comments
 (0)