diff options
Diffstat (limited to 'modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs')
-rw-r--r-- | modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs | 494 |
1 files changed, 113 insertions, 381 deletions
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs index 1113629fef..6cd5ddb42f 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs @@ -1,7 +1,5 @@ -using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; namespace Godot.SourceGenerators { @@ -67,430 +65,164 @@ namespace Godot.SourceGenerators outerTypeDeclSyntax.SyntaxTree.FilePath)); } - public static void ReportExportedMemberIsStatic( - GeneratorExecutionContext context, - ISymbol exportedMemberSymbol - ) - { - var locations = exportedMemberSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - bool isField = exportedMemberSymbol is IFieldSymbol; - - string message = $"Attempted to export static {(isField ? "field" : "property")}: " + - $"'{exportedMemberSymbol.ToDisplayString()}'"; - - string description = $"{message}. Only instance fields and properties can be exported." + - " Remove the 'static' modifier or the '[Export]' attribute."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0101", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0101")), - location, - location?.SourceTree?.FilePath)); - } - - public static void ReportExportedMemberTypeNotSupported( - GeneratorExecutionContext context, - ISymbol exportedMemberSymbol - ) - { - var locations = exportedMemberSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - bool isField = exportedMemberSymbol is IFieldSymbol; - - string message = $"The type of the exported {(isField ? "field" : "property")} " + - $"is not supported: '{exportedMemberSymbol.ToDisplayString()}'"; - - string description = $"{message}. Use a supported type or remove the '[Export]' attribute."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0102", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0102")), - location, - location?.SourceTree?.FilePath)); - } - - public static void ReportExportedMemberIsReadOnly( - GeneratorExecutionContext context, - ISymbol exportedMemberSymbol - ) - { - var locations = exportedMemberSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - bool isField = exportedMemberSymbol is IFieldSymbol; - - string message = $"The exported {(isField ? "field" : "property")} " + - $"is read-only: '{exportedMemberSymbol.ToDisplayString()}'"; - - string description = isField ? - $"{message}. Exported fields cannot be read-only." : - $"{message}. Exported properties must be writable."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0103", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0103")), - location, - location?.SourceTree?.FilePath)); - } - - public static void ReportExportedMemberIsWriteOnly( - GeneratorExecutionContext context, - ISymbol exportedMemberSymbol - ) - { - var locations = exportedMemberSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - - string message = $"The exported property is write-only: '{exportedMemberSymbol.ToDisplayString()}'"; - - string description = $"{message}. Exported properties must be readable."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0104", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0104")), - location, - location?.SourceTree?.FilePath)); - } - - public static void ReportExportedMemberIsIndexer( - GeneratorExecutionContext context, - ISymbol exportedMemberSymbol - ) - { - var locations = exportedMemberSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - - string message = $"Attempted to export indexer property: " + - $"'{exportedMemberSymbol.ToDisplayString()}'"; - - string description = $"{message}. Indexer properties can't be exported." + - " Remove the '[Export]' attribute."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0105", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0105")), - location, - location?.SourceTree?.FilePath)); - } - - public static void ReportExportedMemberIsExplicitInterfaceImplementation( - GeneratorExecutionContext context, - ISymbol exportedMemberSymbol - ) - { - var locations = exportedMemberSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - - string message = $"Attempted to export explicit interface property implementation: " + - $"'{exportedMemberSymbol.ToDisplayString()}'"; - - string description = $"{message}. Explicit interface implementations can't be exported." + - " Remove the '[Export]' attribute."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0106", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0106")), - location, - location?.SourceTree?.FilePath)); - } - - public static void ReportOnlyNodesShouldExportNodes( - GeneratorExecutionContext context, - ISymbol exportedMemberSymbol - ) - { - var locations = exportedMemberSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - bool isField = exportedMemberSymbol is IFieldSymbol; - - string message = $"Types not derived from Node should not export Node {(isField ? "fields" : "properties")}"; - - string description = $"{message}. Node export is only supported in Node-derived classes."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0107", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description), - location, - location?.SourceTree?.FilePath)); - } - - public static void ReportSignalDelegateMissingSuffix( - GeneratorExecutionContext context, - INamedTypeSymbol delegateSymbol) - { - var locations = delegateSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); - - string message = "The name of the delegate must end with 'EventHandler': " + - delegateSymbol.ToDisplayString() + - $". Did you mean '{delegateSymbol.Name}EventHandler'?"; + public static readonly DiagnosticDescriptor MultipleClassesInGodotScriptRule = + new DiagnosticDescriptor(id: "GD0003", + title: "Found multiple classes with the same name in the same script file", + messageFormat: "Found multiple classes with the name '{0}' in the same script file", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "Found multiple classes with the same name in the same script file. A script file must only contain one class with a name that matches the file name.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0003")); - string description = $"{message}. Rename the delegate accordingly or remove the '[Signal]' attribute."; + public static readonly DiagnosticDescriptor ExportedMemberIsStaticRule = + new DiagnosticDescriptor(id: "GD0101", + title: "The exported member is static", + messageFormat: "The exported member '{0}' is static", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The exported member is static. Only instance fields and properties can be exported. Remove the 'static' modifier, or the '[Export]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0101")); - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0201", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0201")), - location, - location?.SourceTree?.FilePath)); - } + public static readonly DiagnosticDescriptor ExportedMemberTypeIsNotSupportedRule = + new DiagnosticDescriptor(id: "GD0102", + title: "The type of the exported member is not supported", + messageFormat: "The type of the exported member '{0}' is not supported", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The type of the exported member is not supported. Use a supported type, or remove the '[Export]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0102")); - public static void ReportSignalParameterTypeNotSupported( - GeneratorExecutionContext context, - IParameterSymbol parameterSymbol) - { - var locations = parameterSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); + public static readonly DiagnosticDescriptor ExportedMemberIsReadOnlyRule = + new DiagnosticDescriptor(id: "GD0103", + title: "The exported member is read-only", + messageFormat: "The exported member '{0}' is read-only", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The exported member is read-only. Exported member must be writable.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0103")); - string message = "The parameter of the delegate signature of the signal " + - $"is not supported: '{parameterSymbol.ToDisplayString()}'"; + public static readonly DiagnosticDescriptor ExportedPropertyIsWriteOnlyRule = + new DiagnosticDescriptor(id: "GD0104", + title: "The exported property is write-only", + messageFormat: "The exported property '{0}' is write-only", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The exported property is write-only. Exported properties must be readable.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0104")); - string description = $"{message}. Use supported types only or remove the '[Signal]' attribute."; + public static readonly DiagnosticDescriptor ExportedMemberIsIndexerRule = + new DiagnosticDescriptor(id: "GD0105", + title: "The exported property is an indexer", + messageFormat: "The exported property '{0}' is an indexer", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The exported property is an indexer. Remove the '[Export]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0105")); - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0202", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0202")), - location, - location?.SourceTree?.FilePath)); - } + public static readonly DiagnosticDescriptor ExportedMemberIsExplicitInterfaceImplementationRule = + new DiagnosticDescriptor(id: "GD0106", + title: "The exported property is an explicit interface implementation", + messageFormat: "The exported property '{0}' is an explicit interface implementation", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The exported property is an explicit interface implementation. Remove the '[Export]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0106")); - public static void ReportSignalDelegateSignatureMustReturnVoid( - GeneratorExecutionContext context, - INamedTypeSymbol delegateSymbol) - { - var locations = delegateSymbol.Locations; - var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault(); + public static readonly DiagnosticDescriptor OnlyNodesShouldExportNodesRule = + new DiagnosticDescriptor(id: "GD0107", + title: "Types not derived from Node should not export Node members", + messageFormat: "Types not derived from Node should not export Node members", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "Types not derived from Node should not export Node members. Node export is only supported in Node-derived classes.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0107")); - string message = "The delegate signature of the signal " + - $"must return void: '{delegateSymbol.ToDisplayString()}'"; + public static readonly DiagnosticDescriptor SignalDelegateMissingSuffixRule = + new DiagnosticDescriptor(id: "GD0201", + title: "The name of the delegate must end with 'EventHandler'", + messageFormat: "The name of the delegate '{0}' must end with 'EventHandler'", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The name of the delegate must end with 'EventHandler'. Rename the delegate accordingly, or remove the '[Signal]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0201")); - string description = $"{message}. Return void or remove the '[Signal]' attribute."; + public static readonly DiagnosticDescriptor SignalParameterTypeNotSupportedRule = + new DiagnosticDescriptor(id: "GD0202", + title: "The parameter of the delegate signature of the signal is not supported", + messageFormat: "The parameter of the delegate signature of the signal '{0}' is not supported", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The parameter of the delegate signature of the signal is not supported. Use supported types only, or remove the '[Signal]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0202")); - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0203", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0203")), - location, - location?.SourceTree?.FilePath)); - } + public static readonly DiagnosticDescriptor SignalDelegateSignatureMustReturnVoidRule = + new DiagnosticDescriptor(id: "GD0203", + title: "The delegate signature of the signal must return void", + messageFormat: "The delegate signature of the signal '{0}' must return void", + category: "Usage", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + "The delegate signature of the signal must return void. Return void, or remove the '[Signal]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0203")); public static readonly DiagnosticDescriptor GenericTypeArgumentMustBeVariantRule = new DiagnosticDescriptor(id: "GD0301", title: "The generic type argument must be a Variant compatible type", - messageFormat: "The generic type argument must be a Variant compatible type: {0}", + messageFormat: "The generic type argument '{0}' must be a Variant compatible type", category: "Usage", DiagnosticSeverity.Error, isEnabledByDefault: true, "The generic type argument must be a Variant compatible type. Use a Variant compatible type as the generic type argument.", helpLinkUri: string.Format(_helpLinkFormat, "GD0301")); - public static void ReportGenericTypeArgumentMustBeVariant( - SyntaxNodeAnalysisContext context, - SyntaxNode typeArgumentSyntax, - ISymbol typeArgumentSymbol) - { - string message = "The generic type argument " + - $"must be a Variant compatible type: '{typeArgumentSymbol.ToDisplayString()}'"; - - string description = $"{message}. Use a Variant compatible type as the generic type argument."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0301", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0301")), - typeArgumentSyntax.GetLocation(), - typeArgumentSyntax.SyntaxTree.FilePath)); - } - public static readonly DiagnosticDescriptor GenericTypeParameterMustBeVariantAnnotatedRule = new DiagnosticDescriptor(id: "GD0302", - title: "The generic type parameter must be annotated with the MustBeVariant attribute", - messageFormat: "The generic type argument must be a Variant type: {0}", + title: "The generic type parameter must be annotated with the '[MustBeVariant]' attribute", + messageFormat: "The generic type parameter '{0}' must be annotated with the '[MustBeVariant]' attribute", category: "Usage", DiagnosticSeverity.Error, isEnabledByDefault: true, - "The generic type argument must be a Variant type. Use a Variant type as the generic type argument.", + "The generic type parameter must be annotated with the '[MustBeVariant]' attribute. Add the '[MustBeVariant]' attribute to the generic type parameter.", helpLinkUri: string.Format(_helpLinkFormat, "GD0302")); - public static void ReportGenericTypeParameterMustBeVariantAnnotated( - SyntaxNodeAnalysisContext context, - SyntaxNode typeArgumentSyntax, - ISymbol typeArgumentSymbol) - { - string message = "The generic type parameter must be annotated with the MustBeVariant attribute"; - - string description = $"{message}. Add the MustBeVariant attribute to the generic type parameter."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0302", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0302")), - typeArgumentSyntax.GetLocation(), - typeArgumentSyntax.SyntaxTree.FilePath)); - } - public static readonly DiagnosticDescriptor TypeArgumentParentSymbolUnhandledRule = new DiagnosticDescriptor(id: "GD0303", - title: "The generic type parameter must be annotated with the MustBeVariant attribute", - messageFormat: "The generic type argument must be a Variant type: {0}", + title: "The parent symbol of a type argument that must be Variant compatible was not handled", + messageFormat: "The parent symbol '{0}' of a type argument that must be Variant compatible was not handled", category: "Usage", DiagnosticSeverity.Error, isEnabledByDefault: true, - "The generic type argument must be a Variant type. Use a Variant type as the generic type argument.", + "The parent symbol of a type argument that must be Variant compatible was not handled. This is an issue in the engine, and should be reported.", helpLinkUri: string.Format(_helpLinkFormat, "GD0303")); - public static void ReportTypeArgumentParentSymbolUnhandled( - SyntaxNodeAnalysisContext context, - SyntaxNode typeArgumentSyntax, - ISymbol parentSymbol) - { - string message = $"Symbol '{parentSymbol.ToDisplayString()}' parent of a type argument " + - "that must be Variant compatible was not handled."; - - string description = $"{message}. Handle type arguments that are children of the unhandled symbol type."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0303", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0303")), - typeArgumentSyntax.GetLocation(), - typeArgumentSyntax.SyntaxTree.FilePath)); - } - public static readonly DiagnosticDescriptor GlobalClassMustDeriveFromGodotObjectRule = new DiagnosticDescriptor(id: "GD0401", - title: "The class must derive from GodotObject or a derived class", - messageFormat: "The class '{0}' must derive from GodotObject or a derived class", + title: $"The class must derive from {GodotClasses.GodotObject} or a derived class", + messageFormat: $"The class '{{0}}' must derive from {GodotClasses.GodotObject} or a derived class", category: "Usage", DiagnosticSeverity.Error, isEnabledByDefault: true, - "The class must derive from GodotObject or a derived class. Change the base class or remove the '[GlobalClass]' attribute.", + $"The class must derive from {GodotClasses.GodotObject} or a derived class. Change the base type, or remove the '[GlobalClass]' attribute.", helpLinkUri: string.Format(_helpLinkFormat, "GD0401")); - public static void ReportGlobalClassMustDeriveFromGodotObject( - SyntaxNodeAnalysisContext context, - SyntaxNode classSyntax, - ISymbol typeSymbol) - { - string message = $"The class '{typeSymbol.ToDisplayString()}' must derive from GodotObject or a derived class"; - - string description = $"{message}. Change the base class or remove the '[GlobalClass]' attribute."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0401", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0401")), - classSyntax.GetLocation(), - classSyntax.SyntaxTree.FilePath)); - } - public static readonly DiagnosticDescriptor GlobalClassMustNotBeGenericRule = new DiagnosticDescriptor(id: "GD0402", - title: "The class must not contain generic arguments", - messageFormat: "The class '{0}' must not contain generic arguments", + title: "The class must not be generic", + messageFormat: "The class '{0}' must not be generic", category: "Usage", DiagnosticSeverity.Error, isEnabledByDefault: true, - "The class must be a non-generic type. Remove the generic arguments or the '[GlobalClass]' attribute.", - helpLinkUri: string.Format(_helpLinkFormat, "GD0401")); - - public static void ReportGlobalClassMustNotBeGeneric( - SyntaxNodeAnalysisContext context, - SyntaxNode classSyntax, - ISymbol typeSymbol) - { - string message = $"The class '{typeSymbol.ToDisplayString()}' must not contain generic arguments"; - - string description = $"{message}. Remove the generic arguments or the '[GlobalClass]' attribute."; - - context.ReportDiagnostic(Diagnostic.Create( - new DiagnosticDescriptor(id: "GD0402", - title: message, - messageFormat: message, - category: "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description, - helpLinkUri: string.Format(_helpLinkFormat, "GD0402")), - classSyntax.GetLocation(), - classSyntax.SyntaxTree.FilePath)); - } + "The class must not be generic. Make the class non-generic, or remove the '[GlobalClass]' attribute.", + helpLinkUri: string.Format(_helpLinkFormat, "GD0402")); } } |