-
Couldn't load subscription status.
- Fork 22
Add nullable annotations #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
770992b
70e9fd8
3bc96df
c2dd68a
ee868e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||
| using Microsoft.CodeAnalysis; | ||||||||
| using System.Diagnostics.CodeAnalysis; | ||||||||
| using Microsoft.CodeAnalysis; | ||||||||
| using Microsoft.CodeAnalysis.Diagnostics; | ||||||||
| using Scriban; | ||||||||
|
|
||||||||
|
|
@@ -7,9 +8,10 @@ namespace GodotSharp.SourceGenerators.CodeCommentsExtensions; | |||||||
| [Generator] | ||||||||
| internal class CodeCommentsSourceGenerator : SourceGeneratorForDeclaredTypeWithAttribute<Godot.CodeCommentsAttribute> | ||||||||
| { | ||||||||
| [field: MaybeNull] | ||||||||
| private static Template CodeCommentsTemplate => field ??= Template.Parse(Resources.CodeCommentsTemplate); | ||||||||
|
|
||||||||
| protected override (string GeneratedCode, DiagnosticDetail Error) GenerateCode(Compilation compilation, SyntaxNode node, INamedTypeSymbol symbol, AttributeData attribute, AnalyzerConfigOptions options) | ||||||||
| protected override (string? GeneratedCode, DiagnosticDetail? Error) GenerateCode(Compilation compilation, SyntaxNode node, INamedTypeSymbol symbol, AttributeData attribute, AnalyzerConfigOptions options) | ||||||||
| { | ||||||||
| var model = new CodeCommentsDataModel(symbol, node, ReconstructAttribute().Strip); | ||||||||
| Log.Debug($"--- MODEL ---\n{model}\n"); | ||||||||
|
|
@@ -20,6 +22,6 @@ protected override (string GeneratedCode, DiagnosticDetail Error) GenerateCode(C | |||||||
| return (output, null); | ||||||||
|
|
||||||||
| Godot.CodeCommentsAttribute ReconstructAttribute() | ||||||||
| => new((string)attribute.ConstructorArguments[0].Value); | ||||||||
| => new((string)attribute.ConstructorArguments[0].Value!); | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Potentially unsafe cast with null-forgiving operator. Using Consider safer casting: -=> new((string)attribute.ConstructorArguments[0].Value!);
+=> new(attribute.ConstructorArguments[0].Value as string ?? throw new InvalidOperationException("CodeComments attribute requires a string argument"));📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
| } | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||
| using Microsoft.CodeAnalysis; | ||||||||
| using System.Diagnostics.CodeAnalysis; | ||||||||
| using Microsoft.CodeAnalysis; | ||||||||
| using Microsoft.CodeAnalysis.Diagnostics; | ||||||||
| using Scriban; | ||||||||
|
|
||||||||
|
|
@@ -7,9 +8,10 @@ namespace GodotSharp.SourceGenerators.GodotOverrideExtensions; | |||||||
| [Generator] | ||||||||
| internal class GodotOverrideSourceGenerator : SourceGeneratorForDeclaredMethodWithAttribute<Godot.GodotOverrideAttribute> | ||||||||
| { | ||||||||
| [field: MaybeNull] | ||||||||
| private static Template GodotOverrideTemplate => field ??= Template.Parse(Resources.GodotOverrideTemplate); | ||||||||
|
|
||||||||
| protected override (string GeneratedCode, DiagnosticDetail Error) GenerateCode(Compilation compilation, SyntaxNode node, IMethodSymbol symbol, AttributeData attribute, AnalyzerConfigOptions options) | ||||||||
| protected override (string? GeneratedCode, DiagnosticDetail? Error) GenerateCode(Compilation compilation, SyntaxNode node, IMethodSymbol symbol, AttributeData attribute, AnalyzerConfigOptions options) | ||||||||
| { | ||||||||
| var model = new GodotOverrideDataModel(symbol, ReconstructAttribute().Replace); | ||||||||
| Log.Debug($"--- MODEL ---\n{model}\n"); | ||||||||
|
|
@@ -20,6 +22,6 @@ protected override (string GeneratedCode, DiagnosticDetail Error) GenerateCode(C | |||||||
| return (output, null); | ||||||||
|
|
||||||||
| Godot.GodotOverrideAttribute ReconstructAttribute() | ||||||||
| => new((bool)attribute.ConstructorArguments[0].Value); | ||||||||
| => new((bool)attribute.ConstructorArguments[0].Value!); | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Potentially unsafe cast with null-forgiving operator. Similar to the previous file, using Consider safer casting: -=> new((bool)attribute.ConstructorArguments[0].Value!);
+=> new(attribute.ConstructorArguments[0].Value as bool? ?? throw new InvalidOperationException("GodotOverride attribute requires a boolean argument"));📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
| } | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,7 +5,7 @@ namespace Godot; | |||||
| [AttributeUsage(AttributeTargets.Class)] | ||||||
| public sealed class InputMapAttribute : Attribute | ||||||
| { | ||||||
| public InputMapAttribute([CallerFilePath] string classPath = null) | ||||||
| public InputMapAttribute([CallerFilePath] string classPath = null!) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Reconsider using null-forgiving operator as default value. Using Consider reverting to the nullable approach: -public InputMapAttribute([CallerFilePath] string classPath = null!)
+public InputMapAttribute([CallerFilePath] string? classPath = null)Or if you want to enforce non-null, use a proper default: -public InputMapAttribute([CallerFilePath] string classPath = null!)
+public InputMapAttribute([CallerFilePath] string classPath = "")📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| => ClassPath = classPath; | ||||||
|
|
||||||
| public string ClassPath { get; } | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,7 +5,7 @@ namespace Godot; | |||||
| [AttributeUsage(AttributeTargets.Class)] | ||||||
| public sealed class LayerNamesAttribute : Attribute | ||||||
| { | ||||||
| public LayerNamesAttribute([CallerFilePath] string classPath = null) | ||||||
| public LayerNamesAttribute([CallerFilePath] string classPath = null!) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Same issue as InputMapAttribute - avoid null-forgiving operator as default. This has the same problematic pattern as Apply the same fix as suggested for -public LayerNamesAttribute([CallerFilePath] string classPath = null!)
+public LayerNamesAttribute([CallerFilePath] string? classPath = null)Or use a proper non-null default if you want to enforce non-nullability. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents💡 Verification agent 🧩 Analysis chainConsistent but semantically confusing pattern with This follows the same pattern as other attribute classes in the PR, but maintains the semantic inconsistency of declaring a non-nullable parameter while defaulting to Consider establishing a consistent approach across all attribute classes - either maintain nullable parameters or use non-null defaults like empty strings. Let me verify this pattern across other attribute classes: 🏁 Script executed: #!/bin/bash
# Description: Check the pattern usage across all attribute classes in the codebase
# Expected: Find similar patterns in other attribute constructors
rg -A 2 -B 2 "\[CallerFilePath\].*classPath.*null!" --type csLength of output: 1458 Standardize CallerFilePath Parameter Defaults Across Attribute Constructors All three attribute constructors in this PR use the pattern: public XAttribute([CallerFilePath] string classPath = null!)– declaring a non‐nullable parameter with a Consider one of these two consistent approaches for all attribute classes:
Affected files:
🤖 Prompt for AI Agents |
||||||
| => ClassPath = classPath; | ||||||
|
|
||||||
| public string ClassPath { get; } | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Potentially unsafe attribute value casting.
Multiple uses of null-forgiving operators when casting attribute constructor arguments assume these values are never null, which could cause runtime exceptions if attributes are malformed.
Consider safer attribute value extraction:
Also applies to: 38-42
🤖 Prompt for AI Agents