13
13
#include < array>
14
14
#include < vector>
15
15
16
+ #include " swift/AST/DiagnosticGroups.h"
16
17
#include " swift/Basic/Feature.h"
17
18
#include " swift/Frontend/Frontend.h"
18
19
@@ -22,11 +23,58 @@ using namespace swift;
22
23
23
24
namespace swift {
24
25
namespace features {
26
+
27
+ // / The subset of diagnostic groups (called categories by the diagnostic machinery) whose diagnostics should be
28
+ // / considered to be part of the migration for this feature.
29
+ // /
30
+ // / When making a feature migratable, ensure that all of the warnings that are used to drive the migration are
31
+ // / part of a diagnostic group, and put that diagnostic group into the list for that feature here.
32
+ static std::vector<DiagGroupID> migratableCategories (Feature feature) {
33
+ switch (feature) {
34
+ case Feature::InnerKind::ExistentialAny:
35
+ return { DiagGroupID::ExistentialAny };
36
+ case Feature::InnerKind::InferIsolatedConformances:
37
+ return { DiagGroupID::IsolatedConformances };
38
+ case Feature::InnerKind::NonisolatedNonsendingByDefault:
39
+ return { DiagGroupID::NonisolatedNonsendingByDefault };
40
+ case Feature::InnerKind::StrictMemorySafety:
41
+ return { DiagGroupID::StrictMemorySafety };
42
+
43
+ // Provide unreachable cases for all of the non-migratable features.
44
+ #define LANGUAGE_FEATURE (FeatureName, SENumber, Description ) case Feature::FeatureName:
45
+ #define MIGRATABLE_UPCOMING_FEATURE (FeatureName, SENumber, Version )
46
+ #define MIGRATABLE_EXPERIMENTAL_FEATURE (FeatureName, AvailableInProd )
47
+ #define MIGRATABLE_OPTIONAL_LANGUAGE_FEATURE (FeatureName, SENumber, Name )
48
+ #include " swift/Basic/Features.def"
49
+ llvm_unreachable (" Not a migratable feature" );
50
+ }
51
+ }
52
+
53
+ // / For optional language features, return the flag name used by the compiler to enable the feature. For all others,
54
+ // / returns an empty optional.
55
+ static std::optional<std::string_view> optionalFlagName (Feature feature) {
56
+ switch (feature) {
57
+ case Feature::StrictMemorySafety:
58
+ return " -strict-memory-safety" ;
59
+
60
+ #define LANGUAGE_FEATURE (FeatureName, SENumber, Description ) case Feature::FeatureName:
61
+ #define OPTIONAL_LANGUAGE_FEATURE (FeatureName, SENumber, Description )
62
+ #include " swift/Basic/Features.def"
63
+ return std::nullopt ;
64
+ }
65
+ }
66
+
25
67
// / Print information about what features upcoming/experimental are
26
68
// / supported by the compiler.
27
69
// / The information includes whether a feature is adoptable and for
28
70
// / upcoming features - what is the first mode it's introduced.
29
71
void printSupportedFeatures (llvm::raw_ostream &out) {
72
+ std::array optional{
73
+ #define LANGUAGE_FEATURE (FeatureName, SENumber, Description )
74
+ #define OPTIONAL_LANGUAGE_FEATURE (FeatureName, SENumber, Description ) Feature::FeatureName,
75
+ #include " swift/Basic/Features.def"
76
+ };
77
+
30
78
std::array upcoming{
31
79
#define LANGUAGE_FEATURE (FeatureName, SENumber, Description )
32
80
#define UPCOMING_FEATURE (FeatureName, SENumber, Version ) Feature::FeatureName,
@@ -50,14 +98,32 @@ void printSupportedFeatures(llvm::raw_ostream &out) {
50
98
out << " { \" name\" : \" " << feature.getName () << " \" " ;
51
99
if (feature.isMigratable ()) {
52
100
out << " , \" migratable\" : true" ;
101
+
102
+ auto categories = migratableCategories (feature);
103
+ out << " , \" categories\" : [" ;
104
+ llvm::interleave (categories, [&out](DiagGroupID diagGroupID) {
105
+ out << " \" " << getDiagGroupInfoByID (diagGroupID).name << " \" " ;
106
+ }, [&out] {
107
+ out << " , " ;
108
+ });
109
+ out << " ]" ;
53
110
}
54
111
if (auto version = feature.getLanguageVersion ()) {
55
112
out << " , \" enabled_in\" : \" " << *version << " \" " ;
56
113
}
114
+
115
+ if (auto flagName = optionalFlagName (feature)) {
116
+ out << " , \" flag_name\" : \" " << *flagName << " \" " ;
117
+ }
118
+
57
119
out << " }" ;
58
120
};
59
121
60
122
out << " \" features\" : {\n " ;
123
+ out << " \" optional\" : [\n " ;
124
+ llvm::interleave (optional, printFeature, [&out] { out << " ,\n " ; });
125
+ out << " \n ],\n " ;
126
+
61
127
out << " \" upcoming\" : [\n " ;
62
128
llvm::interleave (upcoming, printFeature, [&out] { out << " ,\n " ; });
63
129
out << " \n ],\n " ;
0 commit comments