@@ -82,6 +82,7 @@ INamedTypeSymbol symbol
82
82
bool hasNamespace = classNs . Length != 0 ;
83
83
84
84
bool isInnerClass = symbol . ContainingType != null ;
85
+ bool isNode = symbol . InheritsFrom ( "GodotSharp" , GodotClasses . Node ) ;
85
86
86
87
string uniqueHint = symbol . FullQualifiedNameOmitGlobal ( ) . SanitizeQualifiedNameForUniqueHint ( )
87
88
+ "_ScriptMethods.generated" ;
@@ -134,6 +135,27 @@ void AppendPartialContainingTypeDeclarations(INamedTypeSymbol? containingType)
134
135
. Distinct ( new MethodOverloadEqualityComparer ( ) )
135
136
. ToArray ( ) ;
136
137
138
+ List < ISymbol > getNode = new List < ISymbol > ( ) ;
139
+ getNode . AddRange ( members . Where ( s => s . Kind == SymbolKind . Property )
140
+ . Cast < IPropertySymbol > ( )
141
+ . Where ( s => s . GetAttributes ( )
142
+ . Any ( a => a . AttributeClass ? . IsGodotGetNodeAttribute ( ) ?? false ) ) ) ;
143
+
144
+ getNode . AddRange ( members . Where ( s => s . Kind == SymbolKind . Field && ! s . IsImplicitlyDeclared )
145
+ . Cast < IFieldSymbol > ( )
146
+ . Where ( s => s . GetAttributes ( )
147
+ . Any ( a => a . AttributeClass ? . IsGodotGetNodeAttribute ( ) ?? false ) ) ) ;
148
+
149
+
150
+ if ( ! isNode && getNode . Count > 0 )
151
+ {
152
+ context . ReportDiagnostic ( Diagnostic . Create (
153
+ Common . OnlyNodesShouldHaveGetNodeRule ,
154
+ symbol . Locations . FirstLocationWithSourceTreeOrDefault ( )
155
+ ) ) ;
156
+ getNode . Clear ( ) ;
157
+ }
158
+
137
159
source . Append ( "#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n " ) ;
138
160
139
161
source . Append ( " /// <summary>\n " )
@@ -148,7 +170,10 @@ void AppendPartialContainingTypeDeclarations(INamedTypeSymbol? containingType)
148
170
var distinctMethodNames = godotClassMethods
149
171
. Select ( m => m . Method . Name )
150
172
. Distinct ( )
151
- . ToArray ( ) ;
173
+ . ToList ( ) ;
174
+
175
+ if ( getNode . Count > 0 )
176
+ distinctMethodNames . Add ( "_InitGodotGetNodeMembers" ) ;
152
177
153
178
foreach ( string methodName in distinctMethodNames )
154
179
{
@@ -205,13 +230,34 @@ void AppendPartialContainingTypeDeclarations(INamedTypeSymbol? containingType)
205
230
206
231
// Generate InvokeGodotClassMethod
207
232
208
- if ( godotClassMethods . Length > 0 )
233
+ if ( getNode . Count > 0 )
234
+ {
235
+ source . Append ( " [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]\n " ) ;
236
+ source . Append ( " protected override void _InitGodotGetNodeMembers() {\n " ) ;
237
+ source . Append ( " base._InitGodotGetNodeMembers();\n " ) ;
238
+ foreach ( var member in getNode )
239
+ {
240
+ AppendGetNodeSetter ( context , source , member ) ;
241
+ }
242
+ source . Append ( " }\n " ) ;
243
+ }
244
+
245
+ if ( godotClassMethods . Length > 0 || getNode . Count > 0 )
209
246
{
210
247
source . Append ( " /// <inheritdoc/>\n " ) ;
211
248
source . Append ( " [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]\n " ) ;
212
249
source . Append ( " protected override bool InvokeGodotClassMethod(in godot_string_name method, " ) ;
213
250
source . Append ( "NativeVariantPtrArgs args, out godot_variant ret)\n {\n " ) ;
214
251
252
+ if ( getNode . Count > 0 )
253
+ {
254
+ source . Append ( " if(method == global::Godot.Node.MethodName._Ready && args.Count == 0) {\n " ) ;
255
+ source . Append ( " _InitGodotGetNodeMembers();\n " ) ;
256
+ source . Append ( " ret = default;\n " ) ;
257
+ source . Append ( " return true;\n " ) ;
258
+ source . Append ( " }\n " ) ;
259
+ }
260
+
215
261
foreach ( var method in godotClassMethods )
216
262
{
217
263
GenerateMethodInvoker ( method , source ) ;
@@ -247,7 +293,7 @@ void AppendPartialContainingTypeDeclarations(INamedTypeSymbol? containingType)
247
293
248
294
// Generate HasGodotClassMethod
249
295
250
- if ( distinctMethodNames . Length > 0 )
296
+ if ( distinctMethodNames . Count > 0 )
251
297
{
252
298
source . Append ( " /// <inheritdoc/>\n " ) ;
253
299
source . Append ( " [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]\n " ) ;
@@ -285,6 +331,130 @@ void AppendPartialContainingTypeDeclarations(INamedTypeSymbol? containingType)
285
331
context . AddSource ( uniqueHint , SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
286
332
}
287
333
334
+ private static void AppendGetNodeSetter ( GeneratorExecutionContext context , StringBuilder source , ISymbol symbol )
335
+ {
336
+ var attr = symbol . GetAttributes ( )
337
+ . Where ( a => a . AttributeClass ? . IsGodotGetNodeAttribute ( ) ?? false )
338
+ . First ( ) ;
339
+
340
+ string path = attr . ConstructorArguments . Length >= 0 ? attr . ConstructorArguments [ 0 ] . Value as string ?? string . Empty : string . Empty ;
341
+ if ( string . IsNullOrEmpty ( path ) )
342
+ {
343
+ context . ReportDiagnostic ( Diagnostic . Create (
344
+ Common . GetNodeAttributePathIsEmpty ,
345
+ symbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
346
+ symbol . ToDisplayString ( )
347
+ ) ) ;
348
+ return ;
349
+ }
350
+
351
+ ITypeSymbol type ;
352
+ if ( symbol is IPropertySymbol )
353
+ {
354
+ var propertySymbol = ( IPropertySymbol ) symbol ;
355
+ type = propertySymbol . Type ;
356
+
357
+ if ( propertySymbol . IsStatic )
358
+ {
359
+ context . ReportDiagnostic ( Diagnostic . Create (
360
+ Common . GetNodeMemberIsStaticRule ,
361
+ symbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
362
+ symbol . ToDisplayString ( )
363
+ ) ) ;
364
+ return ;
365
+ }
366
+
367
+ if ( propertySymbol . SetMethod == null || propertySymbol . SetMethod . IsInitOnly )
368
+ {
369
+ context . ReportDiagnostic ( Diagnostic . Create (
370
+ Common . GetNodeMemberIsReadOnlyRule ,
371
+ symbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
372
+ symbol . ToDisplayString ( )
373
+ ) ) ;
374
+ return ;
375
+ }
376
+
377
+ if ( propertySymbol . IsIndexer )
378
+ {
379
+ context . ReportDiagnostic ( Diagnostic . Create (
380
+ Common . GetNodeMemberIsIndexerRule ,
381
+ propertySymbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
382
+ propertySymbol . ToDisplayString ( )
383
+ ) ) ;
384
+ return ;
385
+ }
386
+
387
+ if ( propertySymbol . ExplicitInterfaceImplementations . Length > 0 )
388
+ {
389
+ context . ReportDiagnostic ( Diagnostic . Create (
390
+ Common . GetNodeMemberIsExplicitInterfaceImplementationRule ,
391
+ propertySymbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
392
+ propertySymbol . ToDisplayString ( )
393
+ ) ) ;
394
+ return ;
395
+ }
396
+ }
397
+ else if ( symbol is IFieldSymbol )
398
+ {
399
+ var fieldSymbol = ( IFieldSymbol ) symbol ;
400
+ type = fieldSymbol . Type ;
401
+
402
+ if ( fieldSymbol . IsStatic )
403
+ {
404
+ context . ReportDiagnostic ( Diagnostic . Create (
405
+ Common . GetNodeMemberIsStaticRule ,
406
+ symbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
407
+ symbol . ToDisplayString ( )
408
+ ) ) ;
409
+ return ;
410
+ }
411
+
412
+ if ( fieldSymbol . IsReadOnly )
413
+ {
414
+ context . ReportDiagnostic ( Diagnostic . Create (
415
+ Common . GetNodeMemberIsReadOnlyRule ,
416
+ symbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
417
+ symbol . ToDisplayString ( )
418
+ ) ) ;
419
+ return ;
420
+ }
421
+
422
+ }
423
+ else
424
+ {
425
+ //Should not happen.
426
+ return ;
427
+ }
428
+
429
+
430
+ if ( ! type . InheritsFrom ( "GodotSharp" , GodotClasses . Node ) )
431
+ {
432
+ context . ReportDiagnostic ( Diagnostic . Create (
433
+ Common . GetNodeMemberShouldBeNodes ,
434
+ symbol . Locations . FirstLocationWithSourceTreeOrDefault ( ) ,
435
+ symbol . ToDisplayString ( )
436
+ ) ) ;
437
+ return ;
438
+ }
439
+
440
+ source . Append ( " try\n " ) ;
441
+ source . Append ( " {\n " ) ;
442
+ source . Append ( " " )
443
+ . Append ( symbol . Name )
444
+ . Append ( " = GetNode<" )
445
+ . Append ( type . Name )
446
+ . Append ( ">(\" " )
447
+ . Append ( attr . ConstructorArguments [ 0 ] . Value )
448
+ . Append ( "\" );\n " ) ;
449
+ source . Append ( " }\n " ) ;
450
+ source . Append ( " catch (global::System.Exception e)\n " ) ;
451
+ source . Append ( " {\n " ) ;
452
+ source . Append ( " global::Godot.GD.PushError($\" Error GetNode for '{this.Name}." )
453
+ . Append ( symbol . Name )
454
+ . Append ( "': {e.Message}\" );\n " ) ;
455
+ source . Append ( " }\n " ) ;
456
+ }
457
+
288
458
private static void AppendMethodInfo ( StringBuilder source , MethodInfo methodInfo )
289
459
{
290
460
source . Append ( " methods.Add(new(name: MethodName." )
0 commit comments