Skip to content

Commit 5ea5f3b

Browse files
committed
Optional support for round-trip testing the new Swift parser.
When enabled, compile in support for round-trip testing the new SwiftSyntax-provided Swift parser alongside the existing parser. Right now, this means parsing every source file with the new parser and ensuring that the resulting syntax tree can reproduce the input source precisely. Over time, this is expected to grow. Opt in to this behavior by passing the following to build-script: build-script --early-swiftsyntax --extra-cmake-options=-DSWIFT_SWIFT_PARSER_MODE:STRING=ROUNDTRIP
1 parent c89e270 commit 5ea5f3b

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,23 @@ if(XCODE)
868868
set(SWIFT_SDKS "OSX")
869869
endif()
870870

871+
# When we have the early SwiftSyntax build, we can include its parser.
872+
if(SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR)
873+
# An option that specifies how the SwiftSyntax-based Swift parser is
874+
# integrated.
875+
option(SWIFT_SWIFT_PARSER_MODE [=[
876+
How to use the SwiftSyntax-based Swift parser. Possible values are
877+
OFF: do not use this parser at all
878+
ROUNDTRIP: ensure that the SwiftSyntax-based Swift parser round-trips
879+
]=] OFF)
880+
881+
if(SWIFT_SWIFT_PARSER_MODE)
882+
set(SWIFT_SWIFT_PARSER TRUE)
883+
include(${SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR}/cmake/SwiftSyntaxTargets.cmake)
884+
endif()
885+
endif()
886+
887+
871888
# FIXME: the parameters we specify in SWIFT_SDKS are lacking architecture specifics,
872889
# so we need to hard-code it. For example, the SDK for Android is just 'ANDROID',
873890
# and we have to specify SWIFT_SDK_ANDROID_ARCHITECTURES separately.

cmake/modules/AddSwift.cmake

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,11 @@ function(add_swift_host_library name)
608608
609609
translate_flags(ASHL "${options}")
610610
611+
# Once the new Swift parser is linked, everything has Swift modules.
612+
if (SWIFT_SWIFT_PARSER AND ASHL_SHARED)
613+
set(ASHL_HAS_SWIFT_MODULES ON)
614+
endif()
615+
611616
if(NOT ASHL_SHARED AND NOT ASHL_STATIC AND NOT ASHL_OBJECT)
612617
message(FATAL_ERROR "One of SHARED/STATIC/OBJECT must be specified")
613618
endif()
@@ -834,6 +839,11 @@ function(add_swift_host_tool executable)
834839
JOB_POOL_LINK swift_link_job_pool)
835840
endif()
836841
842+
# Once the new Swift parser is linked in, every host tool has Swift modules.
843+
if (SWIFT_SWIFT_PARSER)
844+
set(ASHT_HAS_SWIFT_MODULES ON)
845+
endif()
846+
837847
if (ASHT_HAS_SWIFT_MODULES)
838848
_add_swift_runtime_link_flags(${executable} "../lib" "${ASHT_BOOTSTRAPPING}")
839849
endif()

lib/Parse/CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,34 @@ target_link_libraries(swiftParse PRIVATE
3535
swiftSyntaxParse
3636
)
3737

38+
if (SWIFT_SWIFT_PARSER)
39+
# Link against the SwiftSyntax parser and libraries it depends on. The actual
40+
# formulation of this is a hack to work around a CMake bug in Ninja file
41+
# generation that results in multiple Ninja targets producing the same file in
42+
# a downstream SourceKit target. This should be expressed as:
43+
#
44+
# target_link_libraries(swiftParse
45+
# PRIVATE
46+
# SwiftSyntax::SwiftParser
47+
# )
48+
target_link_libraries(swiftParse
49+
PRIVATE
50+
$<TARGET_OBJECTS:SwiftSyntax::SwiftParser>
51+
$<TARGET_OBJECTS:SwiftSyntax::SwiftDiagnostics>
52+
$<TARGET_OBJECTS:SwiftSyntax::SwiftSyntax>
53+
)
54+
55+
target_include_directories(swiftParse
56+
PRIVATE
57+
${CMAKE_CURRENT_SOURCE_DIR}/../../../swift-syntax/Sources/SwiftParser
58+
)
59+
60+
target_compile_definitions(swiftParse
61+
PRIVATE
62+
SWIFT_SWIFT_PARSER_ROUNDTRIP
63+
)
64+
endif()
65+
3866
add_dependencies(swiftParse swift-parse-syntax-generated-headers)
3967

4068
set_swift_llvm_is_available(swiftParse)

lib/Parse/ParseRequests.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#include "swift/Syntax/SyntaxNodes.h"
2727
#include "swift/SyntaxParse/SyntaxTreeCreator.h"
2828

29+
#ifdef SWIFT_SWIFT_PARSER_ROUNDTRIP
30+
#include "SwiftParserCompilerSupport.h"
31+
#endif
32+
2933
using namespace swift;
3034

3135
namespace swift {
@@ -189,6 +193,22 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator,
189193
if (auto tokens = parser.takeTokenReceiver()->finalize())
190194
tokensRef = ctx.AllocateCopy(*tokens);
191195

196+
#ifdef SWIFT_SWIFT_PARSER_ROUNDTRIP
197+
if (ctx.SourceMgr.getCodeCompletionBufferID() != bufferID) {
198+
auto bufferRange = ctx.SourceMgr.getRangeForBuffer(*bufferID);
199+
unsigned int flags = SPCC_RoundTrip;
200+
201+
int roundTripResult =
202+
swift_parser_consistencyCheck(
203+
bufferRange.str().data(), bufferRange.getByteLength(),
204+
SF->getFilename().str().c_str(), flags);
205+
206+
// FIXME: Produce an error on round-trip failure.
207+
if (roundTripResult)
208+
abort();
209+
}
210+
#endif
211+
192212
return SourceFileParsingResult{ctx.AllocateCopy(decls), tokensRef,
193213
parser.CurrentTokenHash, syntaxRoot};
194214
}

utils/swift_build_support/swift_build_support/products/swift.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010
#
1111
# ----------------------------------------------------------------------------
1212

13+
import os
14+
1315
from . import cmark
1416
from . import earlyswiftdriver
17+
from . import earlyswiftsyntax
1518
from . import libcxx
1619
from . import llvm
1720
from . import product
1821
from ..cmake import CMakeOptions
1922

20-
2123
class Swift(product.Product):
2224

2325
def __init__(self, args, toolchain, source_dir, build_dir):
@@ -55,6 +57,9 @@ def __init__(self, args, toolchain, source_dir, build_dir):
5557
# Add experimental distributed flag.
5658
self.cmake_options.extend(self._enable_experimental_distributed)
5759

60+
# Add path for the early SwiftSyntax build.
61+
self.cmake_options.extend(self._early_swiftsyntax_flags)
62+
5863
# Add static vprintf flag
5964
self.cmake_options.extend(self._enable_stdlib_static_vprintf)
6065

@@ -167,6 +172,18 @@ def _enable_experimental_distributed(self):
167172
return [('SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED:BOOL',
168173
self.args.enable_experimental_distributed)]
169174

175+
@property
176+
def _early_swiftsyntax_flags(self):
177+
result=[]
178+
if self.args.build_early_swiftsyntax:
179+
build_root = os.path.dirname(self.build_dir)
180+
early_swiftsyntax_build_dir = os.path.join(
181+
'..', build_root, '%s-%s' % ('earlyswiftsyntax',
182+
self.args.host_target))
183+
result.append(('SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR:PATH',
184+
early_swiftsyntax_build_dir))
185+
return result
186+
170187
@property
171188
def _enable_stdlib_static_vprintf(self):
172189
return [('SWIFT_STDLIB_STATIC_PRINT',
@@ -194,7 +211,11 @@ def _swift_tools_ld64_lto_codegen_only_for_supporting_targets(self):
194211

195212
@classmethod
196213
def get_dependencies(cls):
197-
return [cmark.CMark,
214+
deps = [cmark.CMark,
198215
earlyswiftdriver.EarlySwiftDriver,
199216
llvm.LLVM,
200217
libcxx.LibCXX]
218+
if self.args.build_early_swiftsyntax:
219+
deps.append(earlyswiftsyntax.EarlySwiftSyntax)
220+
221+
return deps

0 commit comments

Comments
 (0)