Skip to content

Commit a485c0d

Browse files
authored
Merge pull request #59150 from ahoppen/pr-5.7/enable-disable-bare-slash
[5.7][SwiftSyntax] Add an API to enable or disable bare slash regex literals from SwiftSyntax
2 parents 1c222a8 + 12e608b commit a485c0d

File tree

5 files changed

+83
-13
lines changed

5 files changed

+83
-13
lines changed

include/swift-c/SyntaxParser/SwiftSyntaxParser.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ swiftparse_parser_create(void);
9393
SWIFTPARSE_PUBLIC void
9494
swiftparse_parser_dispose(swiftparse_parser_t);
9595

96+
/// Set the language version that should be used to parse the Swift source file.
97+
SWIFTPARSE_PUBLIC void
98+
swiftparse_parser_set_language_version(swiftparse_parser_t c_parser,
99+
const char *version);
100+
101+
/// Set whether bare slash regex literals are enabled.
102+
SWIFTPARSE_PUBLIC void swiftparse_parser_set_enable_bare_slash_regex_literal(
103+
swiftparse_parser_t c_parser, bool enabled);
104+
96105
/// Invoked by the parser when a syntax node is parsed. The client should
97106
/// return a pointer to associate with that particular node.
98107
typedef swiftparse_client_node_t

test/Syntax/Parser/unterminated_regex.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %swift-syntax-parser-test -dump-diags %s | %FileCheck %s
1+
// RUN: %swift-syntax-parser-test -dump-diags --swift-version 5 --enable-bare-slash-regex %s | %FileCheck %s
22
// CHECK: 6:21 Error: unterminated regex literal
33
// CHECK: 1 error(s) 0 warnings(s) 0 note(s)
44

tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/Module.h"
2020
#include "swift/Basic/LangOptions.h"
2121
#include "swift/Basic/SourceManager.h"
22+
#include "swift/Basic/Version.h"
2223
#include "swift/Parse/Parser.h"
2324
#include "swift/Parse/SyntaxParseActions.h"
2425
#include "swift/Parse/SyntaxRegexFallbackLexing.h"
@@ -58,6 +59,13 @@ class SynParser {
5859
swiftparse_node_handler_t NodeHandler = nullptr;
5960
swiftparse_node_lookup_t NodeLookup = nullptr;
6061
swiftparse_diagnostic_handler_t DiagHandler = nullptr;
62+
/// The language version that should be used to parse the Swift source file.
63+
/// If \c None this is the default langauge version specified in LangOptions.h
64+
Optional<version::Version> EffectiveLanguageVersion;
65+
66+
/// Whether bare slash regex literals are enabled.
67+
/// If \c None this is the default specified in LangOptions.h
68+
Optional<bool> EnableBareSlashRegexLiteral;
6169

6270
public:
6371
swiftparse_node_handler_t getNodeHandler() const {
@@ -90,6 +98,17 @@ class SynParser {
9098
Block_release(prevBlk);
9199
}
92100

101+
void setLanguageVersion(const char *versionString) {
102+
if (auto version = version::Version::parseVersionString(
103+
versionString, SourceLoc(), /*Diags=*/nullptr)) {
104+
this->EffectiveLanguageVersion = version;
105+
}
106+
}
107+
108+
void setEnableBareSlashRegexLiteral(bool EnableBareSlashRegexLiteral) {
109+
this->EnableBareSlashRegexLiteral = EnableBareSlashRegexLiteral;
110+
}
111+
93112
~SynParser() {
94113
setNodeHandler(nullptr);
95114
setNodeLookup(nullptr);
@@ -493,7 +512,12 @@ swiftparse_client_node_t SynParser::parse(const char *source, size_t len) {
493512

494513
// Always enable bare /.../ regex literal in syntax parser.
495514
langOpts.EnableExperimentalStringProcessing = true;
496-
langOpts.EnableBareSlashRegexLiterals = true;
515+
if (EnableBareSlashRegexLiteral && *EnableBareSlashRegexLiteral) {
516+
langOpts.EnableBareSlashRegexLiterals = true;
517+
}
518+
if (EffectiveLanguageVersion) {
519+
langOpts.EffectiveLanguageVersion = *EffectiveLanguageVersion;
520+
}
497521

498522
auto parseActions =
499523
std::make_shared<CLibParseActions>(*this, SM, bufID);
@@ -517,6 +541,18 @@ swiftparse_parser_create(void) {
517541
return new SynParser();
518542
}
519543

544+
void swiftparse_parser_set_language_version(swiftparse_parser_t c_parser,
545+
const char *version) {
546+
SynParser *parser = static_cast<SynParser *>(c_parser);
547+
parser->setLanguageVersion(version);
548+
}
549+
550+
void swiftparse_parser_set_enable_bare_slash_regex_literal(
551+
swiftparse_parser_t c_parser, bool enabled) {
552+
SynParser *parser = static_cast<SynParser *>(c_parser);
553+
parser->setEnableBareSlashRegexLiteral(enabled);
554+
}
555+
520556
void
521557
swiftparse_parser_dispose(swiftparse_parser_t c_parser) {
522558
SynParser *parser = static_cast<SynParser*>(c_parser);

tools/libSwiftSyntaxParser/libSwiftSyntaxParser.exports

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
swiftparse_parse_string
22
swiftparse_parser_create
3+
swiftparse_parser_set_language_version
4+
swiftparse_parser_set_enable_bare_slash_regex_literal
35
swiftparse_parser_dispose
46
swiftparse_parser_set_node_handler
57
swiftparse_parser_set_node_lookup

tools/swift-syntax-parser-test/swift-syntax-parser-test.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ Filename(cl::Positional, cl::desc("source file"), cl::Required);
5454
static cl::opt<unsigned>
5555
NumParses("n", cl::desc("number of invocations"), cl::init(1));
5656

57+
static cl::opt<std::string>
58+
SwiftVersion("swift-version",
59+
cl::desc("Interpret input according to a specific Swift "
60+
"language version number"));
61+
62+
static cl::opt<bool>
63+
EnableBareSlashRegex("enable-bare-slash-regex",
64+
cl::desc("Enable or disable the use of forward slash "
65+
"regular-expression literal syntax"));
5766
}
5867

5968
namespace {
@@ -136,8 +145,14 @@ makeNode(const swiftparse_syntax_node_t *raw_node, StringRef source) {
136145

137146
static swiftparse_client_node_t
138147
parse(StringRef source, swiftparse_node_handler_t node_handler,
148+
StringRef swift_version, bool enable_bare_slash_regex,
139149
swiftparse_diagnostic_handler_t diag_handler = nullptr) {
140150
swiftparse_parser_t parser = swiftparse_parser_create();
151+
if (!swift_version.empty()) {
152+
swiftparse_parser_set_language_version(parser, swift_version.str().c_str());
153+
}
154+
swiftparse_parser_set_enable_bare_slash_regex_literal(
155+
parser, enable_bare_slash_regex);
141156
swiftparse_parser_set_node_handler(parser, node_handler);
142157
swiftparse_parser_set_diagnostic_handler(parser, diag_handler);
143158
swiftparse_client_node_t top =
@@ -146,13 +161,15 @@ parse(StringRef source, swiftparse_node_handler_t node_handler,
146161
return top;
147162
}
148163

149-
static int dumpTree(StringRef source) {
164+
static int dumpTree(StringRef source, StringRef swiftVersion,
165+
bool enableBareSlashRegex) {
150166
swiftparse_node_handler_t nodeHandler =
151167
^swiftparse_client_node_t(const swiftparse_syntax_node_t *raw_node) {
152168
return makeNode(raw_node, source);
153169
};
154170

155-
std::unique_ptr<SPNode> top = convertClientNode(parse(source, nodeHandler));
171+
std::unique_ptr<SPNode> top = convertClientNode(
172+
parse(source, nodeHandler, swiftVersion, enableBareSlashRegex));
156173
top->dump(outs());
157174

158175
return 0;
@@ -217,16 +234,18 @@ static void printDiagInfo(const swiftparser_diagnostic_t diag,
217234
}
218235

219236
static int dumpDiagnostics(StringRef source, llvm::SourceMgr &SM,
220-
unsigned BufferId) {
237+
unsigned BufferId, StringRef swiftVersion,
238+
bool enableBareSlashRegex) {
221239
swiftparse_node_handler_t nodeHandler =
222240
^swiftparse_client_node_t(const swiftparse_syntax_node_t *raw_node) {
223241
return makeNode(raw_node, source);
224242
};
225243
std::shared_ptr<PrintDiagData> pData = std::make_shared<PrintDiagData>();
226-
convertClientNode(parse(source, nodeHandler,
244+
convertClientNode(parse(
245+
source, nodeHandler, swiftVersion, enableBareSlashRegex,
227246
^(const swiftparser_diagnostic_t diag) {
228-
printDiagInfo(diag, SM, BufferId, const_cast<PrintDiagData&>(*pData));
229-
}));
247+
printDiagInfo(diag, SM, BufferId, const_cast<PrintDiagData &>(*pData));
248+
}));
230249
return 0;
231250
}
232251

@@ -255,7 +274,8 @@ static void printTimeRecord(unsigned numInvoks, const TimeRecord &total,
255274
OS << '\n';
256275
}
257276

258-
static int timeParsing(StringRef source, unsigned numInvoks) {
277+
static int timeParsing(StringRef source, unsigned numInvoks,
278+
StringRef swiftVersion, bool enableBareSlashRegex) {
259279
swiftparse_node_handler_t nodeHandler =
260280
^swiftparse_client_node_t(const swiftparse_syntax_node_t *raw_node) {
261281
return nullptr;
@@ -264,7 +284,7 @@ static int timeParsing(StringRef source, unsigned numInvoks) {
264284
Timer timer;
265285
timer.startTimer();
266286
for (unsigned i = 0; i != numInvoks; ++i) {
267-
parse(source, nodeHandler);
287+
parse(source, nodeHandler, swiftVersion, enableBareSlashRegex);
268288
}
269289
timer.stopTimer();
270290

@@ -288,10 +308,13 @@ int main(int argc, char *argv[]) {
288308
auto BufferId = SM.AddNewSourceBuffer(std::move(*fileBufOrErr), SMLoc());
289309
switch (options::Action) {
290310
case ActionType::DumpTree:
291-
return dumpTree(source);
311+
return dumpTree(source, options::SwiftVersion,
312+
options::EnableBareSlashRegex);
292313
case ActionType::Time:
293-
return timeParsing(source, options::NumParses);
314+
return timeParsing(source, options::NumParses, options::SwiftVersion,
315+
options::EnableBareSlashRegex);
294316
case ActionType::Diagnostics:
295-
return dumpDiagnostics(source, SM, BufferId);
317+
return dumpDiagnostics(source, SM, BufferId, options::SwiftVersion,
318+
options::EnableBareSlashRegex);
296319
}
297320
}

0 commit comments

Comments
 (0)