Skip to content

Commit 844aeae

Browse files
authored
Re-apply "libSyntax: create a basic infrastructure for generating libSyntax entities by using Parser." (#12538)
1 parent c4dca65 commit 844aeae

17 files changed

+500
-41
lines changed

Diff for: include/swift/AST/Module.h

+21
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ namespace swift {
7979
class VarDecl;
8080
class VisibleDeclConsumer;
8181

82+
namespace syntax {
83+
class SourceFileSyntax;
84+
class SyntaxParsingContext;
85+
class SyntaxParsingContextRoot;
86+
struct RawTokenInfo;
87+
}
88+
8289
/// Discriminator for file-units.
8390
enum class FileUnitKind {
8491
/// For a .swift source file.
@@ -765,6 +772,7 @@ class SourceFile final : public FileUnit {
765772
public:
766773
class LookupCache;
767774
class Impl;
775+
struct SourceFileSyntaxInfo;
768776

769777
/// The implicit module import that the SourceFile should get.
770778
enum class ImplicitModuleImportKind {
@@ -1082,9 +1090,22 @@ class SourceFile final : public FileUnit {
10821090
return (bool)AllCorrectedTokens;
10831091
}
10841092

1093+
syntax::SourceFileSyntax getSyntaxRoot() const;
1094+
10851095
private:
1096+
friend class syntax::SyntaxParsingContext;
1097+
friend class syntax::SyntaxParsingContextRoot;
1098+
10861099
/// If not None, the underlying vector should contain tokens of this source file.
10871100
Optional<std::vector<Token>> AllCorrectedTokens;
1101+
1102+
/// All of the raw token syntax nodes in the underlying source.
1103+
std::vector<syntax::RawTokenInfo> AllRawTokenSyntax;
1104+
1105+
SourceFileSyntaxInfo &SyntaxInfo;
1106+
1107+
void setSyntaxRoot(syntax::SourceFileSyntax &&Root);
1108+
bool hasSyntaxRoot() const;
10881109
};
10891110

10901111

Diff for: include/swift/Basic/OwnedString.h

-4
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ class OwnedString {
4949
assert(Length >= 0 && "expected length to be non-negative");
5050

5151
if (Ownership == StringOwnership::Copied && Data) {
52-
assert(
53-
Length <= strlen(Data) &&
54-
"expected length to be a valid index, within the length of the string");
55-
5652
char *substring = static_cast<char *>(malloc(Length + 1));
5753
assert(substring && "expected successful malloc of copy");
5854

Diff for: include/swift/Parse/Lexer.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/Parse/Token.h"
2424
#include "swift/Syntax/References.h"
2525
#include "swift/Syntax/Trivia.h"
26+
#include "swift/Syntax/SyntaxParsingContext.h"
2627
#include "llvm/ADT/SmallVector.h"
2728
#include "llvm/Support/SaveAndRestore.h"
2829

@@ -245,7 +246,7 @@ class Lexer {
245246
}
246247

247248
/// Lex a full token including leading and trailing trivia.
248-
RC<syntax::RawTokenSyntax> fullLex();
249+
syntax::RawTokenInfo fullLex();
249250

250251
bool isKeepingComments() const {
251252
return RetainComments == CommentRetentionMode::ReturnAsTokens;

Diff for: include/swift/Parse/Parser.h

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "swift/AST/Module.h"
2626
#include "swift/AST/Pattern.h"
2727
#include "swift/AST/Stmt.h"
28+
#include "swift/Syntax/RawTokenSyntax.h"
29+
#include "swift/Syntax/SyntaxParsingContext.h"
2830
#include "swift/Basic/OptionSet.h"
2931
#include "swift/Parse/Lexer.h"
3032
#include "swift/Parse/LocalContext.h"
@@ -325,6 +327,9 @@ class Parser {
325327
/// This vector is managed by \c StructureMarkerRAII objects.
326328
llvm::SmallVector<StructureMarker, 16> StructureMarkers;
327329

330+
/// Current syntax parsing context where call backs should be directed to.
331+
syntax::SyntaxParsingContext *SyntaxContext;
332+
328333
public:
329334
Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
330335
PersistentParserState *PersistentState = nullptr);
@@ -1417,6 +1422,11 @@ tokenizeWithTrivia(const LangOptions &LangOpts,
14171422
unsigned Offset = 0,
14181423
unsigned EndOffset = 0);
14191424

1425+
1426+
void populateTokenSyntaxMap(const LangOptions &LangOpts,
1427+
const SourceManager &SM,
1428+
unsigned BufferID,
1429+
std::vector<syntax::RawTokenInfo> &Result);
14201430
} // end namespace swift
14211431

14221432
#endif

Diff for: include/swift/Syntax/Syntax.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ class Syntax {
127127
/// if it has one, otherwise 0.
128128
CursorIndex getIndexInParent() const;
129129

130+
/// Returns true if this syntax node represents a token.
131+
bool isToken() const;
132+
130133
/// Returns true if this syntax node represents a statement.
131134
bool isStmt() const;
132135

@@ -152,9 +155,6 @@ class Syntax {
152155
/// Returns true if the node is "present" in the source.
153156
bool isPresent() const;
154157

155-
156-
bool isToken() const;
157-
158158
/// Print the syntax node with full fidelity to the given output stream.
159159
void print(llvm::raw_ostream &OS) const;
160160

Diff for: include/swift/Syntax/SyntaxFactory.h.gyb

+4-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct SyntaxFactory {
5454
static Optional<Syntax>
5555
createSyntax(SyntaxKind Kind, llvm::ArrayRef<Syntax> Elements);
5656

57+
static SyntaxKind getUnknownKind(SyntaxKind Kind);
58+
5759
% for node in SYNTAX_NODES:
5860
% if node.children:
5961
% child_params = []
@@ -105,7 +107,7 @@ struct SyntaxFactory {
105107
llvm::Optional<TokenSyntax> TrailingComma = llvm::None);
106108

107109
/// Creates a TypeIdentifierSyntax with the provided name and leading/trailing
108-
/// trivia.
110+
/// trivia.
109111
static TypeIdentifierSyntax makeTypeIdentifier(OwnedString TypeName,
110112
const Trivia &LeadingTrivia = {}, const Trivia &TrailingTrivia = {});
111113

@@ -117,7 +119,7 @@ struct SyntaxFactory {
117119
/// Creates a TypeIdentifierSyntax for the `Any` type.
118120
static TypeIdentifierSyntax makeAnyTypeIdentifier(
119121
const Trivia &LeadingTrivia = {}, const Trivia &TrailingTrivia = {});
120-
122+
121123
/// Creates a TypeIdentifierSyntax for the `Self` type.
122124
static TypeIdentifierSyntax makeSelfTypeIdentifier(
123125
const Trivia &LeadingTrivia = {}, const Trivia &TrailingTrivia = {});

Diff for: include/swift/Syntax/SyntaxParsingContext.h

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//===----------- SyntaxParsingContext.h -==============----------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_SYNTAX_PARSING_CONTEXT_H
14+
#define SWIFT_SYNTAX_PARSING_CONTEXT_H
15+
16+
#include "swift/Syntax/RawTokenSyntax.h"
17+
#include "swift/Syntax/TokenSyntax.h"
18+
#include "swift/Syntax/References.h"
19+
#include "swift/Syntax/RawSyntax.h"
20+
#include "swift/Syntax/Syntax.h"
21+
#include "swift/Syntax/TokenKinds.h"
22+
#include "swift/Syntax/Trivia.h"
23+
24+
namespace swift {
25+
class SourceFile;
26+
27+
namespace syntax {
28+
29+
struct RawTokenInfo {
30+
SourceLoc Loc;
31+
RC<RawTokenSyntax> Token;
32+
};
33+
34+
enum class SyntaxParsingContextKind: uint8_t {
35+
Root,
36+
Child,
37+
};
38+
39+
/// The base class of different kinds of Syntax context that Parser should use to
40+
/// create syntax nodes.
41+
class SyntaxParsingContext {
42+
protected:
43+
SyntaxParsingContext(bool Enabled);
44+
SyntaxParsingContext(SyntaxParsingContext &Another);
45+
public:
46+
struct ContextInfo;
47+
ContextInfo &ContextData;
48+
49+
// Add a token syntax at the given source location to the context; this
50+
// token node can be used to build more complex syntax nodes in later call
51+
// back.
52+
virtual void addTokenSyntax(SourceLoc Loc) = 0;
53+
54+
// Get the context kind.
55+
virtual SyntaxParsingContextKind getKind() = 0;
56+
57+
// Create a syntax node of the given kind.
58+
virtual void makeNode(SyntaxKind Kind) = 0;
59+
virtual ~SyntaxParsingContext();
60+
61+
// Disable the building of syntax tree in the current context.
62+
void disable();
63+
};
64+
65+
// The start point of syntax tree parsing. This context is the root
66+
// of all other entity-specific contexts. This is the context Parser
67+
// has when the parser instance is firstly created.
68+
class SyntaxParsingContextRoot: public SyntaxParsingContext {
69+
public:
70+
struct GlobalInfo;
71+
72+
// Contains global information of the source file under parsing.
73+
GlobalInfo &GlobalData;
74+
SyntaxParsingContextRoot(SourceFile &SF, unsigned BufferID);
75+
~SyntaxParsingContextRoot();
76+
void addTokenSyntax(SourceLoc Loc) override {};
77+
void makeNode(SyntaxKind Kind) override {};
78+
SyntaxParsingContextKind getKind() override {
79+
return SyntaxParsingContextKind::Root;
80+
};
81+
};
82+
83+
// The base class for contexts that are created from a parent context.
84+
// The stack instance will set the context holder when the context
85+
// is firstly created and reset the context holder to the parent when
86+
// it's destructed.
87+
class SyntaxParsingContextChild: public SyntaxParsingContext {
88+
SyntaxParsingContext *Parent;
89+
SyntaxParsingContext *&ContextHolder;
90+
const SyntaxKind FinalKind;
91+
public:
92+
SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
93+
SyntaxKind FinalKind):
94+
SyntaxParsingContext(*ContextHolder), Parent(ContextHolder),
95+
ContextHolder(ContextHolder), FinalKind(FinalKind) {
96+
ContextHolder = this;
97+
}
98+
~SyntaxParsingContextChild();
99+
void makeNode(SyntaxKind Kind) override;
100+
void addTokenSyntax(SourceLoc Loc) override;
101+
SyntaxParsingContext* getParent() { return Parent; }
102+
SyntaxParsingContextRoot &getRoot();
103+
SyntaxParsingContextKind getKind() override {
104+
return SyntaxParsingContextKind::Child;
105+
};
106+
};
107+
}
108+
}
109+
#endif // SWIFT_SYNTAX_PARSING_CONTEXT_H
110+

Diff for: lib/AST/Module.cpp

+21-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "swift/AST/ProtocolConformance.h"
3535
#include "swift/Basic/Compiler.h"
3636
#include "swift/Basic/SourceManager.h"
37+
#include "swift/Syntax/SyntaxNodes.h"
38+
#include "swift/Syntax/SyntaxParsingContext.h"
3739
#include "clang/Basic/Module.h"
3840
#include "llvm/ADT/DenseMap.h"
3941
#include "llvm/ADT/DenseSet.h"
@@ -761,6 +763,23 @@ class SourceFile::Impl {
761763
}
762764
};
763765

766+
struct SourceFile::SourceFileSyntaxInfo {
767+
/// The root of the syntax tree representing the source file.
768+
Optional<syntax::SourceFileSyntax> SyntaxRoot;
769+
};
770+
771+
bool SourceFile::hasSyntaxRoot() const {
772+
return SyntaxInfo.SyntaxRoot.hasValue();
773+
}
774+
775+
syntax::SourceFileSyntax SourceFile::getSyntaxRoot() const {
776+
assert(hasSyntaxRoot() && "no syntax root is set.");
777+
return *SyntaxInfo.SyntaxRoot;
778+
}
779+
780+
void SourceFile::setSyntaxRoot(syntax::SourceFileSyntax &&Root) {
781+
SyntaxInfo.SyntaxRoot.emplace(Root);
782+
}
764783

765784
template<typename OP_DECL>
766785
static Optional<OP_DECL *>
@@ -1325,7 +1344,7 @@ SourceFile::SourceFile(ModuleDecl &M, SourceFileKind K,
13251344
bool KeepTokens)
13261345
: FileUnit(FileUnitKind::Source, M),
13271346
BufferID(bufferID ? *bufferID : -1),
1328-
Kind(K) {
1347+
Kind(K), SyntaxInfo(*new SourceFileSyntaxInfo()) {
13291348
M.getASTContext().addDestructorCleanup(*this);
13301349
performAutoImport(*this, ModImpKind);
13311350

@@ -1339,7 +1358,7 @@ SourceFile::SourceFile(ModuleDecl &M, SourceFileKind K,
13391358
}
13401359
}
13411360

1342-
SourceFile::~SourceFile() {}
1361+
SourceFile::~SourceFile() { delete &SyntaxInfo; }
13431362

13441363
bool FileUnit::walk(ASTWalker &walker) {
13451364
SmallVector<Decl *, 64> Decls;

Diff for: lib/Parse/Lexer.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "swift/AST/Identifier.h"
2121
#include "swift/Basic/LangOptions.h"
2222
#include "swift/Basic/SourceManager.h"
23-
#include "swift/Syntax/TokenSyntax.h"
23+
#include "swift/Syntax/SyntaxParsingContext.h"
2424
#include "llvm/Support/Compiler.h"
2525
#include "llvm/Support/MathExtras.h"
2626
#include "llvm/Support/MemoryBuffer.h"
@@ -737,11 +737,12 @@ static bool rangeContainsPlaceholderEnd(const char *CurPtr,
737737
return false;
738738
}
739739

740-
RC<syntax::RawTokenSyntax> Lexer::fullLex() {
740+
syntax::RawTokenInfo Lexer::fullLex() {
741741
if (NextToken.isEscapedIdentifier()) {
742742
LeadingTrivia.push_back(syntax::TriviaPiece::backtick());
743743
TrailingTrivia.push_front(syntax::TriviaPiece::backtick());
744744
}
745+
auto Loc = NextToken.getLoc();
745746
auto Result = syntax::RawTokenSyntax::make(NextToken.getKind(),
746747
OwnedString(NextToken.getText()).copy(),
747748
syntax::SourcePresence::Present,
@@ -751,7 +752,7 @@ RC<syntax::RawTokenSyntax> Lexer::fullLex() {
751752
if (NextToken.isNot(tok::eof)) {
752753
lexImpl();
753754
}
754-
return Result;
755+
return {Loc, Result};
755756
}
756757

757758
/// lexOperatorIdentifier - Match identifiers formed out of punctuation.

0 commit comments

Comments
 (0)