Skip to content

Commit 531ad95

Browse files
Add Info warning for int return values (#89601)
Adds an 'info' level diagnostic if a GeneratedComInterface method returns int, enum, or a type name "HR" or "HResult" to tell the user that the generated code will put the managed return value as an 'out' parameter on the COM definition. Co-authored-by: Jeremy Koritzinsky <jkoritzinsky@gmail.com>
1 parent 99503f1 commit 531ad95

File tree

20 files changed

+282
-9
lines changed

20 files changed

+282
-9
lines changed

docs/project/list-of-diagnostics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
208208
| __`SYSLIB1089`__ | _`SYSLIB1070`-`SYSLIB1089` reserved for System.Runtime.InteropServices.JavaScript.JSImportGenerator._ |
209209
| __`SYSLIB1090`__ | Invalid 'GeneratedComInterfaceAttribute' usage |
210210
| __`SYSLIB1091`__ | Method is declared in different partial declaration than the 'GeneratedComInterface' attribute. |
211-
| __`SYSLIB1092`__ | Specified interface derives from two or more 'GeneratedComInterfaceAttribute'-attributed interfaces. |
211+
| __`SYSLIB1092`__ | 'GenerateComInterfaceAttribute' usage not recommended. See aka.ms/GeneratedComInterfaceUsage for recommended usage. |
212212
| __`SYSLIB1093`__ | Analysis for COM interface generation has failed |
213213
| __`SYSLIB1094`__ | The base COM interface failed to generate source. Code will not be generated for this interface. |
214214
| __`SYSLIB1095`__ | Invalid 'GeneratedComClassAttribute' usage |

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M
278278
}
279279
else
280280
{
281+
if ((returnSwappedSignatureElements[i].ManagedType is SpecialTypeInfo { SpecialType: SpecialType.System_Int32 or SpecialType.System_Enum } or EnumTypeInfo
282+
&& returnSwappedSignatureElements[i].MarshallingAttributeInfo.Equals(NoMarshallingInfo.Instance))
283+
|| (returnSwappedSignatureElements[i].ManagedType.FullTypeName.Split('.', ':').LastOrDefault()?.ToLowerInvariant() is "hr" or "hresult"))
284+
{
285+
generatorDiagnostics.ReportDiagnostic(DiagnosticInfo.Create(GeneratorDiagnostics.ComMethodManagedReturnWillBeOutVariable, symbol.Locations[0]));
286+
}
281287
// Convert the current element into an out parameter on the native signature
282288
// while keeping it at the return position in the managed signature.
283289
var managedSignatureAsNativeOut = returnSwappedSignatureElements[i] with

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class Ids
2222
public const string UnnecessaryMarshallingInfo = Prefix + "1063";
2323
public const string InvalidGeneratedComInterfaceAttributeUsage = Prefix + "1090";
2424
public const string MemberWillNotBeSourceGenerated = Prefix + "1091";
25-
public const string MultipleComInterfaceBaseTypes = Prefix + "1092";
25+
public const string NotRecommendedGeneratedComInterfaceUsage = Prefix + "1092";
2626
public const string AnalysisFailed = Prefix + "1093";
2727
public const string BaseInterfaceFailedGeneration = Prefix + "1094";
2828
public const string InvalidGeneratedComClassAttributeUsage = Prefix + "1095";
@@ -340,7 +340,7 @@ public class Ids
340340
/// <inheritdoc cref="SR.MultipleComInterfaceBaseTypesMessage"/>
341341
public static readonly DiagnosticDescriptor MultipleComInterfaceBaseTypes =
342342
new DiagnosticDescriptor(
343-
Ids.MultipleComInterfaceBaseTypes,
343+
Ids.InvalidGeneratedComInterfaceAttributeUsage,
344344
GetResourceString(nameof(SR.MultipleComInterfaceBaseTypesTitle)),
345345
GetResourceString(nameof(SR.MultipleComInterfaceBaseTypesMessage)),
346346
Category,
@@ -444,6 +444,16 @@ public class Ids
444444
WellKnownDiagnosticTags.Unnecessary
445445
});
446446

447+
/// <inheritdoc cref="SR.ComMethodReturningIntWillBeOutParameterMessage"/>
448+
public static readonly DiagnosticDescriptor ComMethodManagedReturnWillBeOutVariable =
449+
new DiagnosticDescriptor(
450+
Ids.NotRecommendedGeneratedComInterfaceUsage,
451+
GetResourceString(nameof(SR.ComMethodReturningIntWillBeOutParameterTitle)),
452+
GetResourceString(nameof(SR.ComMethodReturningIntWillBeOutParameterMessage)),
453+
Category,
454+
DiagnosticSeverity.Info,
455+
isEnabledByDefault: true);
456+
447457
/// <summary>
448458
/// Report diagnostic for invalid configuration for string marshalling.
449459
/// </summary>

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,4 +880,10 @@
880880
<data name="OutAttributeNotSupportedOnByValueParameters" xml:space="preserve">
881881
<value>The `[Out]` attribute is only supported on array parameters and parameters marshalled by pinning. Consider using 'out' or 'ref' keywords to make the parameter mutable.</value>
882882
</data>
883-
</root>
883+
<data name="ComMethodReturningIntWillBeOutParameterMessage" xml:space="preserve">
884+
<value>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</value>
885+
</data>
886+
<data name="ComMethodReturningIntWillBeOutParameterTitle" xml:space="preserve">
887+
<value>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</value>
888+
</data>
889+
</root>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">Hostování .NET COM s EnableComHosting nepodporuje rozhraní s generatedComInterfaceAttribute</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">Model COM vygenerovaný zdrojem bude ignorovat všechny nepodporované konfigurace.</target>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">Das .NET COM-Hosting mit "EnableComHosting" unterstützt keine Schnittstellen mit "GeneratedComInterfaceAttribute".</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">Quellgeneriertes COM ignoriert alle Konfigurationen, die nicht unterstützt werden.</target>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">El hospedaje COM de .NET con “EnableComHosting” no admite interfaces con “GeneratedComInterfaceAttribute”</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">COM generado por el origen omitirá cualquier configuración que no se admita.</target>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">L'hébergement .NET COM avec 'EnableComHosting' ne prend pas en charge les interfaces avec 'GeneratedComInterfaceAttribute'</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">COM généré par la source ignore toute configuration qui n’est pas prise en charge.</target>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">L'hosting COM .NET con 'EnableComHosting' non supporta le interfacce con 'GeneratedComInterfaceAttribute'.</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">I COM generati dall'origine ignoreranno qualsiasi configurazione non supportata.</target>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">'EnableComHosting' を使用した .NET COM ホスティングでは、'GeneratedComInterfaceAttribute' のインターフェイスはサポートされていません</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">ソース生成済みの COM は、サポートされていない構成を無視します。</target>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">'EnableComHosting'을 사용한 .NET COM 호스팅은 'GeneratedComInterfaceAttribute'를 사용한 인터페이스를 지원하지 않습니다.</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">소스 생성 COM은 지원되지 않는 구성을 무시합니다.</target>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@
147147
<target state="translated">Hosting modelu COM platformy .NET z elementem „EnableComHosting” nie obsługuje interfejsów z atrybutem „GeneratedComInterfaceAttribute”</target>
148148
<note />
149149
</trans-unit>
150+
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
151+
<source>The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</source>
152+
<target state="new">The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method.</target>
153+
<note />
154+
</trans-unit>
155+
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
156+
<source>The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</source>
157+
<target state="new">The return value in the managed definition will be converted to an additional 'out' parameter at the end of the parameter list when calling the unmanaged COM method.</target>
158+
<note />
159+
</trans-unit>
150160
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
151161
<source>Source-generated COM will ignore any configuration that is not supported.</source>
152162
<target state="translated">COM wygenerowany przez źródło zignoruje każdą konfigurację, która nie jest obsługiwana.</target>

0 commit comments

Comments
 (0)