Skip to content

Commit 375ead3

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 aa05d4a commit 375ead3

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
@@ -863,6 +863,23 @@ if(XCODE)
863863
set(SWIFT_SDKS "OSX")
864864
endif()
865865

866+
# When we have the early SwiftSyntax build, we can include its parser.
867+
if(SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR)
868+
# An option that specifies how the SwiftSyntax-based Swift parser is
869+
# integrated.
870+
option(SWIFT_SWIFT_PARSER_MODE [=[
871+
How to use the SwiftSyntax-based Swift parser. Possible values are
872+
OFF: do not use this parser at all
873+
ROUNDTRIP: ensure that the SwiftSyntax-based Swift parser round-trips
874+
]=] OFF)
875+
876+
if(SWIFT_SWIFT_PARSER_MODE)
877+
set(SWIFT_SWIFT_PARSER TRUE)
878+
include(${SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR}/cmake/SwiftSyntaxTargets.cmake)
879+
endif()
880+
endif()
881+
882+
866883
# FIXME: the parameters we specify in SWIFT_SDKS are lacking architecture specifics,
867884
# so we need to hard-code it. For example, the SDK for Android is just 'ANDROID',
868885
# 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
@@ -609,6 +609,11 @@ function(add_swift_host_library name)
609609
610610
translate_flags(ASHL "${options}")
611611
612+
# Once the new Swift parser is linked, everything has Swift modules.
613+
if (SWIFT_SWIFT_PARSER AND ASHL_SHARED)
614+
set(ASHL_HAS_SWIFT_MODULES ON)
615+
endif()
616+
612617
if(NOT ASHL_SHARED AND NOT ASHL_STATIC AND NOT ASHL_OBJECT)
613618
message(FATAL_ERROR "One of SHARED/STATIC/OBJECT must be specified")
614619
endif()
@@ -835,6 +840,11 @@ function(add_swift_host_tool executable)
835840
JOB_POOL_LINK swift_link_job_pool)
836841
endif()
837842
843+
# Once the new Swift parser is linked in, every host tool has Swift modules.
844+
if (SWIFT_SWIFT_PARSER)
845+
set(ASHT_HAS_SWIFT_MODULES ON)
846+
endif()
847+
838848
if (ASHT_HAS_SWIFT_MODULES)
839849
_add_swift_runtime_link_flags(${executable} "../lib" "${ASHT_BOOTSTRAPPING}")
840850
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)