Skip to content

Commit

Permalink
Add Info warning for int return values (#89601)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jtschuster and jkoritzinsky authored Aug 1, 2023
1 parent 99503f1 commit 531ad95
Show file tree
Hide file tree
Showing 20 changed files with 282 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/project/list-of-diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
| __`SYSLIB1089`__ | _`SYSLIB1070`-`SYSLIB1089` reserved for System.Runtime.InteropServices.JavaScript.JSImportGenerator._ |
| __`SYSLIB1090`__ | Invalid 'GeneratedComInterfaceAttribute' usage |
| __`SYSLIB1091`__ | Method is declared in different partial declaration than the 'GeneratedComInterface' attribute. |
| __`SYSLIB1092`__ | Specified interface derives from two or more 'GeneratedComInterfaceAttribute'-attributed interfaces. |
| __`SYSLIB1092`__ | 'GenerateComInterfaceAttribute' usage not recommended. See aka.ms/GeneratedComInterfaceUsage for recommended usage. |
| __`SYSLIB1093`__ | Analysis for COM interface generation has failed |
| __`SYSLIB1094`__ | The base COM interface failed to generate source. Code will not be generated for this interface. |
| __`SYSLIB1095`__ | Invalid 'GeneratedComClassAttribute' usage |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,12 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M
}
else
{
if ((returnSwappedSignatureElements[i].ManagedType is SpecialTypeInfo { SpecialType: SpecialType.System_Int32 or SpecialType.System_Enum } or EnumTypeInfo
&& returnSwappedSignatureElements[i].MarshallingAttributeInfo.Equals(NoMarshallingInfo.Instance))
|| (returnSwappedSignatureElements[i].ManagedType.FullTypeName.Split('.', ':').LastOrDefault()?.ToLowerInvariant() is "hr" or "hresult"))
{
generatorDiagnostics.ReportDiagnostic(DiagnosticInfo.Create(GeneratorDiagnostics.ComMethodManagedReturnWillBeOutVariable, symbol.Locations[0]));
}
// Convert the current element into an out parameter on the native signature
// while keeping it at the return position in the managed signature.
var managedSignatureAsNativeOut = returnSwappedSignatureElements[i] with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class Ids
public const string UnnecessaryMarshallingInfo = Prefix + "1063";
public const string InvalidGeneratedComInterfaceAttributeUsage = Prefix + "1090";
public const string MemberWillNotBeSourceGenerated = Prefix + "1091";
public const string MultipleComInterfaceBaseTypes = Prefix + "1092";
public const string NotRecommendedGeneratedComInterfaceUsage = Prefix + "1092";
public const string AnalysisFailed = Prefix + "1093";
public const string BaseInterfaceFailedGeneration = Prefix + "1094";
public const string InvalidGeneratedComClassAttributeUsage = Prefix + "1095";
Expand Down Expand Up @@ -340,7 +340,7 @@ public class Ids
/// <inheritdoc cref="SR.MultipleComInterfaceBaseTypesMessage"/>
public static readonly DiagnosticDescriptor MultipleComInterfaceBaseTypes =
new DiagnosticDescriptor(
Ids.MultipleComInterfaceBaseTypes,
Ids.InvalidGeneratedComInterfaceAttributeUsage,
GetResourceString(nameof(SR.MultipleComInterfaceBaseTypesTitle)),
GetResourceString(nameof(SR.MultipleComInterfaceBaseTypesMessage)),
Category,
Expand Down Expand Up @@ -444,6 +444,16 @@ public class Ids
WellKnownDiagnosticTags.Unnecessary
});

/// <inheritdoc cref="SR.ComMethodReturningIntWillBeOutParameterMessage"/>
public static readonly DiagnosticDescriptor ComMethodManagedReturnWillBeOutVariable =
new DiagnosticDescriptor(
Ids.NotRecommendedGeneratedComInterfaceUsage,
GetResourceString(nameof(SR.ComMethodReturningIntWillBeOutParameterTitle)),
GetResourceString(nameof(SR.ComMethodReturningIntWillBeOutParameterMessage)),
Category,
DiagnosticSeverity.Info,
isEnabledByDefault: true);

/// <summary>
/// Report diagnostic for invalid configuration for string marshalling.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -880,4 +880,10 @@
<data name="OutAttributeNotSupportedOnByValueParameters" xml:space="preserve">
<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>
</data>
</root>
<data name="ComMethodReturningIntWillBeOutParameterMessage" xml:space="preserve">
<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>
</data>
<data name="ComMethodReturningIntWillBeOutParameterTitle" xml:space="preserve">
<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>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">Hostování .NET COM s EnableComHosting nepodporuje rozhraní s generatedComInterfaceAttribute</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">Model COM vygenerovaný zdrojem bude ignorovat všechny nepodporované konfigurace.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">Das .NET COM-Hosting mit "EnableComHosting" unterstützt keine Schnittstellen mit "GeneratedComInterfaceAttribute".</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">Quellgeneriertes COM ignoriert alle Konfigurationen, die nicht unterstützt werden.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">El hospedaje COM de .NET con “EnableComHosting” no admite interfaces con “GeneratedComInterfaceAttribute”</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">COM generado por el origen omitirá cualquier configuración que no se admita.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">L'hébergement .NET COM avec 'EnableComHosting' ne prend pas en charge les interfaces avec 'GeneratedComInterfaceAttribute'</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">COM généré par la source ignore toute configuration qui n’est pas prise en charge.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">L'hosting COM .NET con 'EnableComHosting' non supporta le interfacce con 'GeneratedComInterfaceAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">I COM generati dall'origine ignoreranno qualsiasi configurazione non supportata.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">'EnableComHosting' を使用した .NET COM ホスティングでは、'GeneratedComInterfaceAttribute' のインターフェイスはサポートされていません</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">ソース生成済みの COM は、サポートされていない構成を無視します。</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">'EnableComHosting'을 사용한 .NET COM 호스팅은 'GeneratedComInterfaceAttribute'를 사용한 인터페이스를 지원하지 않습니다.</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">소스 생성 COM은 지원되지 않는 구성을 무시합니다.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
<target state="translated">Hosting modelu COM platformy .NET z elementem „EnableComHosting” nie obsługuje interfejsów z atrybutem „GeneratedComInterfaceAttribute”</target>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterMessage">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ComMethodReturningIntWillBeOutParameterTitle">
<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>
<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>
<note />
</trans-unit>
<trans-unit id="ConfigurationNotSupportedDescriptionCom">
<source>Source-generated COM will ignore any configuration that is not supported.</source>
<target state="translated">COM wygenerowany przez źródło zignoruje każdą konfigurację, która nie jest obsługiwana.</target>
Expand Down
Loading

0 comments on commit 531ad95

Please sign in to comment.