Skip to content

Commit 1a3c6d7

Browse files
committed
[ASTGen] Handle new parser validation in ASTGen.
Replace the use of the "consistency check" vended by swift-syntax with an ASTGen-implemented operation that emits diagnostics from the new parser via the normal diagnostic engine. This eliminates our last dependency on SwiftCompilerSupport, so stop linking it.
1 parent e51176b commit 1a3c6d7

File tree

6 files changed

+77
-65
lines changed

6 files changed

+77
-65
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,12 +1964,6 @@ ERROR(attr_requires_concurrency, none,
19641964
ERROR(associatedtype_cannot_be_variadic,none,
19651965
"associated types cannot be variadic", ())
19661966

1967-
//------------------------------------------------------------------------------
1968-
// MARK: Consistency diagnostics
1969-
//------------------------------------------------------------------------------
1970-
ERROR(new_parser_failure, none,
1971-
"new parser has failed consistency checking; please see errors above", ())
1972-
19731967
//------------------------------------------------------------------------------
19741968
// MARK: syntax parsing diagnostics
19751969
//------------------------------------------------------------------------------
@@ -2021,6 +2015,9 @@ ERROR(macro_expansion_decl_expected_macro_identifier,none,
20212015

20222016
ERROR(parser_round_trip_error,none,
20232017
"source file did not round-trip through the Swift Swift parser", ())
2018+
ERROR(parser_new_parser_errors,none,
2019+
"Swift Swift parser generated errors for code that C++ parser accepted",
2020+
())
20242021

20252022
#define UNDEFINE_DIAGNOSTIC_MACROS
20262023
#include "DefineDiagnosticMacros.h"

lib/ASTGen/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ if (SWIFT_SWIFT_PARSER)
7676
SwiftOperators
7777
SwiftSyntaxBuilder
7878
_SwiftSyntaxMacros
79-
SwiftCompilerSupport
8079
)
8180

8281
# Compute the list of SwiftSyntax targets

lib/ASTGen/Sources/ASTGen/SourceFile.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import SwiftParser
22
import SwiftSyntax
3+
import SwiftParserDiagnostics
34

45
/// Describes a source file that has been "exported" to the C++ part of the
56
/// compiler, with enough information to interface with the C++ layer.
@@ -59,3 +60,49 @@ public func roundTripCheck(
5960
return sf.syntax.syntaxTextBytes.elementsEqual(sf.buffer) ? 0 : 1
6061
}
6162
}
63+
64+
extension Syntax {
65+
/// Whether this syntax node is or is enclosed within a #if.
66+
fileprivate var isInIfConfig: Bool {
67+
if self.is(IfConfigDeclSyntax.self) {
68+
return true
69+
}
70+
71+
return parent?.isInIfConfig ?? false
72+
}
73+
}
74+
75+
/// Emit diagnostics within the given source file.
76+
@_cdecl("swift_ASTGen_emitParserDiagnostics")
77+
public func emitParserDiagnostics(
78+
diagEnginePtr: UnsafeMutablePointer<UInt8>,
79+
sourceFilePtr: UnsafeMutablePointer<UInt8>
80+
) -> CInt {
81+
return sourceFilePtr.withMemoryRebound(
82+
to: ExportedSourceFile.self, capacity: 1
83+
) { sourceFile in
84+
var anyDiags = false
85+
86+
let diags = ParseDiagnosticsGenerator.diagnostics(
87+
for: sourceFile.pointee.syntax
88+
)
89+
for diag in diags {
90+
// Skip over diagnostics within #if, because we don't know whether
91+
// we are in an active region or not.
92+
// FIXME: This heuristic could be improved.
93+
if diag.node.isInIfConfig {
94+
continue
95+
}
96+
97+
emitDiagnostic(
98+
diagEnginePtr: diagEnginePtr,
99+
sourceFileBuffer: UnsafeMutableBufferPointer(
100+
mutating: sourceFile.pointee.buffer),
101+
diagnostic: diag
102+
)
103+
anyDiags = true
104+
}
105+
106+
return anyDiags ? 1 : 0
107+
}
108+
}

lib/Parse/CMakeLists.txt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ if (SWIFT_SWIFT_PARSER)
3333
#
3434
# target_link_libraries(swiftParse
3535
# PRIVATE
36-
# SwiftSyntax::SwiftCompilerSupport
36+
# SwiftSyntax::SwiftParser
3737
# ...
3838
# )
3939
target_link_libraries(swiftParse
@@ -46,7 +46,6 @@ if (SWIFT_SWIFT_PARSER)
4646
SwiftSyntax::SwiftOperators
4747
SwiftSyntax::SwiftSyntaxBuilder
4848
SwiftSyntax::_SwiftSyntaxMacros
49-
SwiftSyntax::SwiftCompilerSupport
5049
$<TARGET_OBJECTS:swiftASTGen>
5150
)
5251

@@ -59,15 +58,9 @@ if (SWIFT_SWIFT_PARSER)
5958
SwiftSyntax::SwiftOperators
6059
SwiftSyntax::SwiftSyntaxBuilder
6160
SwiftSyntax::_SwiftSyntaxMacros
62-
SwiftSyntax::SwiftCompilerSupport
6361
swiftASTGen
6462
)
6563

66-
target_include_directories(swiftParse
67-
PRIVATE
68-
${CMAKE_CURRENT_SOURCE_DIR}/../../../swift-syntax/Sources/SwiftCompilerSupport
69-
)
70-
7164
target_compile_definitions(swiftParse
7265
PRIVATE
7366
SWIFT_SWIFT_PARSER

lib/Parse/ParseDecl.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ extern "C" void swift_ASTGen_destroySourceFile(void *sourceFile);
182182
/// round-trip succeeded, non-zero otherwise.
183183
extern "C" int swift_ASTGen_roundTripCheck(void *sourceFile);
184184

185+
/// Emit parser diagnostics for given source file.. Returns non-zero if any
186+
/// diagnostics were emitted.
187+
extern "C" int swift_ASTGen_emitParserDiagnostics(
188+
void *diagEngine, void *sourceFile
189+
);
185190

186191
// Build AST nodes for the top-level entities in the syntax.
187192
extern "C" void swift_ASTGen_buildTopLevelASTNodes(void *sourceFile,
@@ -203,6 +208,7 @@ void Parser::parseTopLevelItems(SmallVectorImpl<ASTNode> &items) {
203208
if ((Context.LangOpts.hasFeature(Feature::Macros) ||
204209
Context.LangOpts.hasFeature(Feature::BuiltinMacros) ||
205210
Context.LangOpts.hasFeature(Feature::ParserRoundTrip) ||
211+
Context.LangOpts.hasFeature(Feature::ParserValidation) ||
206212
Context.LangOpts.hasFeature(Feature::ParserASTGen)) &&
207213
!SourceMgr.hasIDEInspectionTargetBuffer() &&
208214
SF.Kind != SourceFileKind::SIL) {
@@ -281,16 +287,28 @@ void Parser::parseTopLevelItems(SmallVectorImpl<ASTNode> &items) {
281287
}
282288

283289
#if SWIFT_SWIFT_PARSER
284-
// Perform round-trip checking.
285-
if (Context.LangOpts.hasFeature(Feature::ParserRoundTrip) &&
290+
// Perform round-trip and/or validation checking.
291+
if ((Context.LangOpts.hasFeature(Feature::ParserRoundTrip) ||
292+
Context.LangOpts.hasFeature(Feature::ParserValidation)) &&
286293
SF.exportedSourceFile &&
287-
!L->lexingCutOffOffset() &&
288-
swift_ASTGen_roundTripCheck(SF.exportedSourceFile)) {
289-
SourceLoc loc;
290-
if (auto bufferID = SF.getBufferID()) {
291-
loc = Context.SourceMgr.getLocForBufferStart(*bufferID);
294+
!L->lexingCutOffOffset()) {
295+
if (Context.LangOpts.hasFeature(Feature::ParserRoundTrip) &&
296+
swift_ASTGen_roundTripCheck(SF.exportedSourceFile)) {
297+
SourceLoc loc;
298+
if (auto bufferID = SF.getBufferID()) {
299+
loc = Context.SourceMgr.getLocForBufferStart(*bufferID);
300+
}
301+
diagnose(loc, diag::parser_round_trip_error);
302+
} else if (Context.LangOpts.hasFeature(Feature::ParserValidation) &&
303+
!Context.Diags.hadAnyError() &&
304+
swift_ASTGen_emitParserDiagnostics(
305+
&Context.Diags, SF.exportedSourceFile)) {
306+
SourceLoc loc;
307+
if (auto bufferID = SF.getBufferID()) {
308+
loc = Context.SourceMgr.getLocForBufferStart(*bufferID);
309+
}
310+
diagnose(loc, diag::parser_new_parser_errors);
292311
}
293-
diagnose(loc, diag::parser_round_trip_error);
294312
}
295313
#endif
296314
}

lib/Parse/ParseRequests.cpp

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
#include "swift/Parse/Parser.h"
2424
#include "swift/Subsystems.h"
2525

26-
#if SWIFT_SWIFT_PARSER
27-
#include "SwiftCompilerSupport.h"
28-
#endif
29-
3026
using namespace swift;
3127

3228
namespace swift {
@@ -175,44 +171,6 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator,
175171
if (auto tokens = parser.takeTokenReceiver()->finalize())
176172
tokensRef = ctx.AllocateCopy(*tokens);
177173

178-
#if SWIFT_SWIFT_PARSER
179-
if (ctx.LangOpts.hasFeature(Feature::ParserValidation) &&
180-
ctx.SourceMgr.getIDEInspectionTargetBufferID() != bufferID &&
181-
SF->Kind != SourceFileKind::SIL) {
182-
auto bufferRange = ctx.SourceMgr.getRangeForBuffer(*bufferID);
183-
unsigned int flags = 0;
184-
185-
if (!ctx.Diags.hadAnyError() &&
186-
ctx.LangOpts.hasFeature(Feature::ParserValidation))
187-
flags |= SCC_ParseDiagnostics;
188-
189-
if (ctx.LangOpts.hasFeature(Feature::ParserSequenceFolding) &&
190-
!parser.L->lexingCutOffOffset())
191-
flags |= SCC_FoldSequences;
192-
193-
if (flags) {
194-
SourceLoc startLoc =
195-
parser.SourceMgr.getLocForBufferStart(parser.L->getBufferID());
196-
struct ParserContext {
197-
SourceLoc startLoc;
198-
DiagnosticEngine *engine;
199-
} context{startLoc, &parser.Diags};
200-
int roundTripResult = swift_parser_consistencyCheck(
201-
bufferRange.str().data(), bufferRange.getByteLength(),
202-
SF->getFilename().str().c_str(), flags, static_cast<void *>(&context),
203-
[](ptrdiff_t off, const char *text, void *ctx) {
204-
auto *context = static_cast<ParserContext *>(ctx);
205-
SourceLoc loc = context->startLoc.getAdvancedLoc(off);
206-
context->engine->diagnose(loc, diag::foreign_diagnostic,
207-
StringRef(text));
208-
});
209-
210-
if (roundTripResult)
211-
ctx.Diags.diagnose(SourceLoc(), diag::new_parser_failure);
212-
}
213-
}
214-
#endif
215-
216174
return SourceFileParsingResult{ctx.AllocateCopy(items), tokensRef,
217175
parser.CurrentTokenHash};
218176
}

0 commit comments

Comments
 (0)