Skip to content

Commit

Permalink
Add unsupported language detection to the STJ source generator (#87950)
Browse files Browse the repository at this point in the history
* Make the STJ source generator detect unsupported C# language versions and emit error diagnostics.

* Fix whitespace

* Do not hardcode minimal lang version on diagnostic string.
  • Loading branch information
eiriktsarpalis authored Jun 23, 2023
1 parent 5316458 commit 478130b
Show file tree
Hide file tree
Showing 21 changed files with 368 additions and 268 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ namespace System.Text.Json.SourceGeneration
{
internal static class RoslynExtensions
{
public static LanguageVersion? GetLanguageVersion(this Compilation compilation)
=> compilation is CSharpCompilation csc ? csc.LanguageVersion : null;

public static INamedTypeSymbol? GetBestTypeByMetadataName(this Compilation compilation, Type type)
{
Debug.Assert(!type.IsArray, "Resolution logic only capable of handling named types.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ internal static class DiagnosticDescriptors
category: JsonConstants.SystemTextJsonSourceGenerationName,
defaultSeverity: DiagnosticSeverity.Warning,
isEnabledByDefault: true);

public static DiagnosticDescriptor JsonUnsupportedLanguageVersion { get; } = new DiagnosticDescriptor(
id: "SYSLIB1042",
title: new LocalizableResourceString(nameof(SR.JsonUnsupportedLanguageVersionTitle), SR.ResourceManager, typeof(FxResources.System.Text.Json.SourceGeneration.SR)),
messageFormat: new LocalizableResourceString(nameof(SR.JsonUnsupportedLanguageVersionMessageFormat), SR.ResourceManager, typeof(FxResources.System.Text.Json.SourceGeneration.SR)),
category: JsonConstants.SystemTextJsonSourceGenerationName,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);
}
}
}
12 changes: 11 additions & 1 deletion src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text.Json.Serialization;
using System.Threading;
using Microsoft.CodeAnalysis;
Expand All @@ -17,6 +16,9 @@ namespace System.Text.Json.SourceGeneration
{
public sealed partial class JsonSourceGenerator
{
// The source generator requires NRT and init-only property support.
private const LanguageVersion MinimumSupportedLanguageVersion = LanguageVersion.CSharp9;

private sealed class Parser
{
private const string SystemTextJsonNamespace = "System.Text.Json";
Expand Down Expand Up @@ -104,6 +106,14 @@ public Parser(KnownTypeSymbols knownSymbols)
return null;
}

LanguageVersion? langVersion = _knownSymbols.Compilation.GetLanguageVersion();
if (langVersion is null or < MinimumSupportedLanguageVersion)
{
// Unsupported lang version should be the first (and only) diagnostic emitted by the generator.
ReportDiagnostic(DiagnosticDescriptors.JsonUnsupportedLanguageVersion, contextTypeSymbol.GetDiagnosticLocation(), langVersion?.ToDisplayString(), MinimumSupportedLanguageVersion.ToDisplayString());
return null;
}

Location contextLocation = contextClassDeclaration.GetLocation();
if (!TryGetNestedTypeDeclarations(contextClassDeclaration, semanticModel, cancellationToken, out List<string>? classDeclarationList))
{
Expand Down
6 changes: 6 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,10 @@
<data name="JsonConverterAttributeInvalidTypeMessageFormat" xml:space="preserve">
<value>The 'JsonConverterAttribute' type '{0}' specified on member '{1}' is not a converter type or does not contain an accessible parameterless constructor.</value>
</data>
<data name="JsonUnsupportedLanguageVersionTitle" xml:space="preserve">
<value>C# language version not supported by the source generator.</value>
</data>
<data name="JsonUnsupportedLanguageVersionMessageFormat" xml:space="preserve">
<value>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</value>
</data>
</root>
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">Neobecný objekt JsonStringEnumConverter vyžaduje dynamický kód.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">Typ {0} má více konstruktorů anotovaných s JsonConstructorAttribute. </target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">Der nicht generische "JsonStringEnumConverter" erfordert dynamischen Code.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">Typ "{0}" weist mehrere Konstruktoren mit dem Kommentar "JsonConstructorAttribute" auf.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">El elemento 'JsonStringEnumConverter' no genérico requiere código dinámico.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">El tipo '{0}' tiene varios constructores anotados con 'JsonConstructorAttribute'.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">Le 'JsonStringEnumConverter' non générique requiert du code dynamique.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">Le type' {0} 'a plusieurs constructeurs annotés avec’JsonConstructorAttribute'.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">L'elemento 'JsonStringEnumConverter' non generico richiede un codice dinamico.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">Il tipo '{0}' contiene più costruttori che presentano l'annotazione 'JsonConstructorAttribute'.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">非ジェネリック 'JsonStringEnumConverter' には動的コードが必要です。</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">型 '{0}' には、'JsonConstructorAttribute' で注釈が付けられた複数のコンストラクターがあります。</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">제네릭이 아닌 'JsonStringEnumConverter'에는 동적 코드가 필요합니다.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">'{0}' 형식에 'JsonConstructorAttribute'로 주석이 추가된 여러 생성자가 있습니다.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">Nieogólny element „JsonStringEnumConverter” wymaga dynamicznego kodu.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">Typ "{0}" ma wiele konstruktorów z adnotacją "JsonConstructorAttribute".</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">O "JsonStringEnumConverter" não genérico requer código dinâmico.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">O tipo '{0}' tem vários construtores anotados com 'JsonConstructorAttribute'.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">Для неуниверсального параметра JsonStringEnumConverter требуется динамический код.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">Тип "{0}" имеет несколько конструкторов, аннотированных с использованием JsonConstructorAttribute.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">Genel olmayan 'JsonStringEnumConverter' parametresi dinamik kod gerektirir.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">'{0}' türünün 'JsonConstructorAttribute' ile açıklanan birden çok oluşturucusu var.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">非泛型 "JsonStringEnumConverter" 需要动态代码。</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">类型“{0}”具有用 “JsonConstructorAttribute” 批注的多个构造函数。</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
<target state="translated">非一般 'JsonStringEnumConverter' 需要動態程式碼。</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionMessageFormat">
<source>The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</source>
<target state="new">The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater.</target>
<note />
</trans-unit>
<trans-unit id="JsonUnsupportedLanguageVersionTitle">
<source>C# language version not supported by the source generator.</source>
<target state="new">C# language version not supported by the source generator.</target>
<note />
</trans-unit>
<trans-unit id="MultipleJsonConstructorAttributeFormat">
<source>Type '{0}' has multiple constructors annotated with 'JsonConstructorAttribute'.</source>
<target state="translated">類型 '{0}' 包含多個以 'JsonConstructorAttribute' 註解的建構函式。</target>
Expand Down
Loading

0 comments on commit 478130b

Please sign in to comment.