Skip to content

Commit fba2523

Browse files
committed
Introduce NINVK005 and NINVK006 diagnostics
* NINVK005: Interface has no valid methods to generate * NINVK006: Missing library name in [NativeImport] attribute
1 parent 13365b5 commit fba2523

3 files changed

Lines changed: 57 additions & 7 deletions

File tree

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; Shipped analyzer releases
1+
; Shipped analyzer releases
22
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
33

44
## 1.0.0
@@ -7,7 +7,17 @@
77

88
Rule ID | Category | Severity | Notes
99
--------|----------|----------|-------
10-
NINVK001 | NativeInvoke | Error | Diagnostics
11-
NINVK002 | NativeInvoke | Error | Diagnostics
12-
NINVK003 | NativeInvoke | Error | Diagnostics
13-
NINVK004 | NativeInvoke | Error | Diagnostics
10+
NINVK001 | NativeInvoke | Error | Type must be partial to use [NativeImport]
11+
NINVK002 | NativeInvoke | Error | Property must be static partial to use [NativeImport]
12+
NINVK003 | NativeInvoke | Error | Property type must be interface to use [NativeImport]
13+
NINVK004 | NativeInvoke | Error | Method has non-blittable signature
14+
15+
16+
## 1.3.5
17+
18+
### New Rules
19+
20+
Rule ID | Category | Severity | Notes
21+
--------|----------|----------|-------
22+
NINVK005 | NativeInvoke | Warning | Interface has no valid methods to generate
23+
NINVK006 | NativeInvoke | Error | Missing library name in [NativeImport] attribute

NativeInvoke/Generator/Diagnostics.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,20 @@ internal static partial class Diagnostics
3333
category: "NativeInvoke",
3434
defaultSeverity: DiagnosticSeverity.Error,
3535
isEnabledByDefault: true);
36+
37+
public static readonly DiagnosticDescriptor EmptyInterface = new(
38+
id: "NINVK005",
39+
title: "Interface has no valid methods",
40+
messageFormat: "Interface '{0}' has no valid methods to generate (ensure the interface contains at least one method)",
41+
category: "NativeInvoke",
42+
defaultSeverity: DiagnosticSeverity.Warning,
43+
isEnabledByDefault: true);
44+
45+
public static readonly DiagnosticDescriptor MissingLibraryName = new(
46+
id: "NINVK006",
47+
title: "Missing library name",
48+
messageFormat: "[NativeImport] attribute requires a library name (provide a valid library name via the constructor parameter)",
49+
category: "NativeInvoke",
50+
defaultSeverity: DiagnosticSeverity.Error,
51+
isEnabledByDefault: true);
3652
}

NativeInvoke/Generator/NativeImportGenerator.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,27 @@ private static void GenerateForProperty(
102102
Debugger.Launch();
103103
#endif
104104

105+
// Validate library name is provided
106+
if (pAttr.ConstructorArguments.Length == 0)
107+
{
108+
spc.ReportDiagnostic(Diagnostic.Create(
109+
Diagnostics.MissingLibraryName,
110+
prop.Locations[0]));
111+
return;
112+
}
113+
var libraryName = pAttr.ConstructorArguments[0].Value as string;
114+
if (string.IsNullOrEmpty(libraryName))
115+
{
116+
spc.ReportDiagnostic(Diagnostic.Create(
117+
Diagnostics.MissingLibraryName,
118+
prop.Locations[0]));
119+
return;
120+
}
121+
105122
// Attribute data
106123
NativeImportAttribute nativeImportAttr;
107124
{
108125
var temp = new NativeImportAttribute(string.Empty); // Temporary instance to get the default values
109-
var libraryName = (string?)pAttr.ConstructorArguments[0].Value ?? "__Internal"; // TODO/FIXME: Report a diagnostic
110126
var enforceBlittable = (bool)(pAttr.NamedArguments
111127
.FirstOrDefault(static kv => kv.Key == nameof(NativeImportAttribute.EnforceBlittable))
112128
.Value.Value ?? temp.EnforceBlittable);
@@ -131,7 +147,7 @@ private static void GenerateForProperty(
131147
var symbolSuffix = (pAttr.NamedArguments
132148
.FirstOrDefault(static kv => kv.Key == nameof(NativeImportAttribute.SymbolSuffix))
133149
.Value.Value ?? temp.SymbolSuffix) as string;
134-
nativeImportAttr = new NativeImportAttribute(libraryName)
150+
nativeImportAttr = new NativeImportAttribute(libraryName!)
135151
{
136152
EnforceBlittable = enforceBlittable,
137153
ExplicitOnly = explicitOnly,
@@ -254,6 +270,14 @@ private static void GenerateForProperty(
254270
// Generate a file per container type
255271
spc.AddSource($"{containingType.Name}.{prop.Name}-{Guid.NewGuid():N}.g.cs", source); // Append Guid to avoid collisions, just in case
256272
}
273+
else
274+
{
275+
// Report warning for empty interfaces
276+
spc.ReportDiagnostic(Diagnostic.Create(
277+
Diagnostics.EmptyInterface,
278+
prop.Locations[0],
279+
iface.Name));
280+
}
257281
}
258282

259283
private static string ResolveMethodEntryPoint(string? entryPoint, string methodName, string? symbolPrefix, string? symbolSuffix)

0 commit comments

Comments
 (0)