| 
									
										
										
										
											2021-03-06 00:12:42 +01:00
										 |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  | using System.Linq; | 
					
						
							|  |  |  | using Microsoft.CodeAnalysis; | 
					
						
							|  |  |  | using Microsoft.CodeAnalysis.CSharp; | 
					
						
							|  |  |  | using Microsoft.CodeAnalysis.CSharp.Syntax; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Godot.SourceGenerators | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static class ExtensionMethods | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         public static bool TryGetGlobalAnalyzerProperty( | 
					
						
							|  |  |  |             this GeneratorExecutionContext context, string property, out string? value | 
					
						
							|  |  |  |         ) => context.AnalyzerConfigOptions.GlobalOptions | 
					
						
							|  |  |  |             .TryGetValue("build_property." + property, out value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool InheritsFrom(this INamedTypeSymbol? symbol, string baseName) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (symbol == null) | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             while (true) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (symbol.ToString() == baseName) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (symbol.BaseType != null) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     symbol = symbol.BaseType; | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool IsGodotScriptClass( | 
					
						
							|  |  |  |             this ClassDeclarationSyntax cds, Compilation compilation, | 
					
						
							|  |  |  |             out INamedTypeSymbol? symbol | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             var sm = compilation.GetSemanticModel(cds.SyntaxTree); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var classTypeSymbol = sm.GetDeclaredSymbol(cds); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (classTypeSymbol?.BaseType == null | 
					
						
							|  |  |  |                 || !classTypeSymbol.BaseType.InheritsFrom(GodotClasses.Object)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 symbol = null; | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             symbol = classTypeSymbol; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public static IEnumerable<(ClassDeclarationSyntax cds, INamedTypeSymbol symbol)> SelectGodotScriptClasses( | 
					
						
							|  |  |  |             this IEnumerable<ClassDeclarationSyntax> source, | 
					
						
							|  |  |  |             Compilation compilation | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             foreach (var cds in source) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (cds.IsGodotScriptClass(compilation, out var symbol)) | 
					
						
							|  |  |  |                     yield return (cds, symbol!); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public static bool IsPartial(this ClassDeclarationSyntax cds) | 
					
						
							|  |  |  |             => cds.Modifiers.Any(SyntaxKind.PartialKeyword); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public static bool HasDisableGeneratorsAttribute(this INamedTypeSymbol symbol) | 
					
						
							|  |  |  |             => symbol.GetAttributes().Any(attr => | 
					
						
							|  |  |  |                 attr.AttributeClass?.ToString() == GodotClasses.DisableGodotGeneratorsAttr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } = | 
					
						
							|  |  |  |             SymbolDisplayFormat.FullyQualifiedFormat | 
					
						
							|  |  |  |                 .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public static string FullQualifiedName(this INamedTypeSymbol symbol) | 
					
						
							|  |  |  |             => symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal); | 
					
						
							| 
									
										
										
										
											2021-03-13 01:04:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         public static string FullQualifiedName(this INamespaceSymbol namespaceSymbol) | 
					
						
							|  |  |  |             => namespaceSymbol.ToDisplayString(FullyQualifiedFormatOmitGlobal); | 
					
						
							| 
									
										
										
										
											2021-03-06 00:12:42 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } |