ExtensionMethods.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using Microsoft.CodeAnalysis;
  4. using Microsoft.CodeAnalysis.CSharp;
  5. using Microsoft.CodeAnalysis.CSharp.Syntax;
  6. namespace Godot.SourceGenerators
  7. {
  8. static class ExtensionMethods
  9. {
  10. public static bool TryGetGlobalAnalyzerProperty(
  11. this GeneratorExecutionContext context, string property, out string? value
  12. ) => context.AnalyzerConfigOptions.GlobalOptions
  13. .TryGetValue("build_property." + property, out value);
  14. private static bool InheritsFrom(this INamedTypeSymbol? symbol, string baseName)
  15. {
  16. if (symbol == null)
  17. return false;
  18. while (true)
  19. {
  20. if (symbol.ToString() == baseName)
  21. {
  22. return true;
  23. }
  24. if (symbol.BaseType != null)
  25. {
  26. symbol = symbol.BaseType;
  27. continue;
  28. }
  29. break;
  30. }
  31. return false;
  32. }
  33. private static bool IsGodotScriptClass(
  34. this ClassDeclarationSyntax cds, Compilation compilation,
  35. out INamedTypeSymbol? symbol
  36. )
  37. {
  38. var sm = compilation.GetSemanticModel(cds.SyntaxTree);
  39. var classTypeSymbol = sm.GetDeclaredSymbol(cds);
  40. if (classTypeSymbol?.BaseType == null
  41. || !classTypeSymbol.BaseType.InheritsFrom(GodotClasses.Object))
  42. {
  43. symbol = null;
  44. return false;
  45. }
  46. symbol = classTypeSymbol;
  47. return true;
  48. }
  49. public static IEnumerable<(ClassDeclarationSyntax cds, INamedTypeSymbol symbol)> SelectGodotScriptClasses(
  50. this IEnumerable<ClassDeclarationSyntax> source,
  51. Compilation compilation
  52. )
  53. {
  54. foreach (var cds in source)
  55. {
  56. if (cds.IsGodotScriptClass(compilation, out var symbol))
  57. yield return (cds, symbol!);
  58. }
  59. }
  60. public static bool IsPartial(this ClassDeclarationSyntax cds)
  61. => cds.Modifiers.Any(SyntaxKind.PartialKeyword);
  62. public static bool HasDisableGeneratorsAttribute(this INamedTypeSymbol symbol)
  63. => symbol.GetAttributes().Any(attr =>
  64. attr.AttributeClass?.ToString() == GodotClasses.DisableGodotGeneratorsAttr);
  65. private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } =
  66. SymbolDisplayFormat.FullyQualifiedFormat
  67. .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted);
  68. public static string FullQualifiedName(this INamedTypeSymbol symbol)
  69. => symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal);
  70. }
  71. }