Skip to content

Commit a7d6612

Browse files
authored
Merge pull request swiftlang#27046 from rintaro/syntaxparse-refactor-type
[SyntaxParse] Refactor parsing facilities
2 parents 111fb37 + 4a3a95b commit a7d6612

File tree

9 files changed

+347
-406
lines changed

9 files changed

+347
-406
lines changed

include/swift/Parse/ASTGen.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ class ASTGen {
9797

9898
static SourceLoc advanceLocBegin(const SourceLoc &Loc,
9999
const syntax::Syntax &Node);
100-
static SourceLoc advanceLocEnd(const SourceLoc &Loc,
101-
const syntax::TokenSyntax &Token);
102-
static SourceLoc advanceLocAfter(const SourceLoc &Loc,
103-
const syntax::Syntax &Node);
104100

105101
static MagicIdentifierLiteralExpr::Kind getMagicIdentifierLiteralKind(tok Kind);
106102

include/swift/Parse/Parser.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,25 @@ class Parser {
695695
/// plain Tok.is(T1) check).
696696
bool skipUntilTokenOrEndOfLine(tok T1);
697697

698+
void ignoreToken();
699+
void ignoreToken(tok Kind) {
700+
assert(Tok.is(Kind));
701+
ignoreToken();
702+
}
703+
bool ignoreIf(tok Kind) {
704+
if (!Tok.is(Kind))
705+
return false;
706+
ignoreToken();
707+
return true;
708+
}
709+
void ignoreSingle();
710+
void ignoreUntil(tok Kind);
711+
712+
/// Ignore tokens until a token that starts with '>', and return true it if
713+
/// found. Applies heuristics that are suitable when trying to find the end
714+
/// of a list of generic parameters, generic arguments.
715+
bool ignoreUntilGreaterInTypeList();
716+
698717
/// If the parser is generating only a syntax tree, try loading the current
699718
/// node from a previously generated syntax tree.
700719
/// Returns \c true if the node has been loaded and inserted into the current
@@ -1153,10 +1172,13 @@ class Parser {
11531172

11541173
using TypeASTResult = ParserResult<TypeRepr>;
11551174
using TypeResult = ParsedSyntaxResult<ParsedTypeSyntax>;
1156-
using TypeErrorResult = ParsedSyntaxResult<ParsedUnknownTypeSyntax>;
11571175

11581176
LayoutConstraint parseLayoutConstraint(Identifier LayoutConstraintID);
11591177

1178+
TypeResult parseTypeSyntax();
1179+
TypeResult parseTypeSyntax(Diag<> MessageID, bool HandleCodeCompletion = true,
1180+
bool IsSILFuncDecl = false);
1181+
11601182
TypeASTResult parseType();
11611183
TypeASTResult parseType(Diag<> MessageID, bool HandleCodeCompletion = true,
11621184
bool IsSILFuncDecl = false);
@@ -1183,8 +1205,8 @@ class Parser {
11831205
TypeResult parseOptionalType(ParsedTypeSyntax Base);
11841206
TypeResult parseImplicitlyUnwrappedOptionalType(ParsedTypeSyntax Base);
11851207

1186-
TypeErrorResult parseTypeArray(ParsedTypeSyntax Base, SourceLoc BaseLoc);
1187-
TypeErrorResult parseOldStyleProtocolComposition();
1208+
TypeResult parseTypeArray(ParsedTypeSyntax Base, SourceLoc BaseLoc);
1209+
TypeResult parseOldStyleProtocolComposition();
11881210

11891211
bool isOptionalToken(const Token &T) const;
11901212
ParsedTokenSyntax consumeOptionalTokenSyntax();

include/swift/Parse/SyntaxParserResult.h

Lines changed: 55 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -30,215 +30,103 @@ template <typename ParsedSyntaxNode> class ParsedSyntaxResult {
3030
friend class ParsedSyntaxResult;
3131

3232
private:
33-
// todo [gsoc]: use some kind of a proper sum type
34-
llvm::Optional<ParsedSyntaxNode> SuccessNode;
35-
llvm::Optional<llvm::SmallVector<ParsedSyntax, 0>> ErrorNodes;
36-
llvm::Optional<llvm::SmallVector<ParsedSyntax, 0>> CodeCompletionNodes;
37-
38-
ResultDataKind DK;
33+
ParsedRawSyntaxNode Raw;
34+
ParserStatus Status;
3935

4036
public:
41-
explicit ParsedSyntaxResult(ParsedSyntaxNode Node)
42-
: SuccessNode(Node), DK(ResultDataKind::Success) {}
43-
44-
ParsedSyntaxResult(ArrayRef<ParsedSyntax> Nodes,
45-
ResultDataKind Kind)
46-
: DK(Kind) {
47-
switch (DK) {
48-
case ResultDataKind::Error:
49-
ErrorNodes.emplace(Nodes.begin(), Nodes.end());
50-
break;
51-
case ResultDataKind::CodeCompletion:
52-
CodeCompletionNodes.emplace(Nodes.begin(), Nodes.end());
53-
break;
54-
default:
55-
llvm_unreachable("success cannot contain multiple nodes");
56-
}
57-
}
37+
explicit ParsedSyntaxResult() : Raw(), Status() { setIsError(); }
5838

59-
ParsedSyntaxResult(const ParsedSyntaxResult &Other) {
60-
DK = Other.DK;
61-
62-
switch (DK) {
63-
case ResultDataKind::Success:
64-
SuccessNode = Other.SuccessNode;
65-
break;
66-
case ResultDataKind::Error:
67-
ErrorNodes = Other.ErrorNodes;
68-
break;
69-
case ResultDataKind::CodeCompletion:
70-
CodeCompletionNodes = Other.CodeCompletionNodes;
71-
break;
72-
}
39+
ParsedSyntaxResult(ParserStatus Status) : Raw(), Status(Status) {
40+
assert(Status.isError());
7341
}
7442

43+
explicit ParsedSyntaxResult(ParsedRawSyntaxNode Raw)
44+
: Raw(Raw), Status() {}
45+
46+
explicit ParsedSyntaxResult(ParsedSyntaxNode Node)
47+
: ParsedSyntaxResult(Node.getRaw()) {}
48+
7549
template <typename OtherParsedSyntaxNode,
7650
typename Enable = typename std::enable_if<std::is_base_of<
7751
ParsedSyntaxNode, OtherParsedSyntaxNode>::value>::type>
78-
ParsedSyntaxResult(ParsedSyntaxResult<OtherParsedSyntaxNode> Other) {
79-
DK = Other.DK;
80-
81-
switch (DK) {
82-
case ResultDataKind::Success:
83-
SuccessNode = *Other.SuccessNode;
84-
break;
85-
case ResultDataKind::Error:
86-
ErrorNodes = *Other.ErrorNodes;
87-
break;
88-
case ResultDataKind::CodeCompletion:
89-
CodeCompletionNodes = *Other.CodeCompletionNodes;
90-
break;
91-
}
52+
ParsedSyntaxResult(ParsedSyntaxResult<OtherParsedSyntaxNode> other) {
53+
Raw = other.Raw;
54+
Status = other.Status;
9255
}
9356

9457
bool isSuccess() const {
95-
return DK == ResultDataKind::Success;
58+
return Status.isSuccess();
9659
}
9760

9861
bool isError() const {
99-
return DK == ResultDataKind::Error;
62+
return Status.isError();
63+
}
64+
void setIsError() {
65+
Status.setIsParseError();
10066
}
10167

102-
bool isCodeCompletion() const {
103-
return DK == ResultDataKind::CodeCompletion;
68+
bool hasCodeCompletion() const {
69+
return Status.hasCodeCompletion();
70+
}
71+
void setHasCodeCompletion() {
72+
Status.setHasCodeCompletion();
10473
}
10574

106-
ParsedSyntaxNode getResult() const {
107-
assert(isSuccess() && "unsuccessful parse doesn't have any result");
108-
return *SuccessNode;
75+
ParsedSyntaxNode get() const {
76+
assert(!isNull());
77+
return ParsedSyntaxNode(Raw);
78+
}
79+
Optional<ParsedSyntaxNode> getOrNull() const {
80+
if (isNull())
81+
return None;
82+
return get();
10983
}
11084

111-
ArrayRef<ParsedSyntax> getUnknownNodes() const {
112-
assert(!isSuccess() && "successful parse doesn't contain unknown nodes");
113-
switch (DK) {
114-
case ResultDataKind::Error:
115-
return *ErrorNodes;
116-
case ResultDataKind::CodeCompletion:
117-
return *CodeCompletionNodes;
118-
default:
119-
llvm_unreachable("cannot get here");
120-
}
85+
bool isNull() const {
86+
return Raw.isNull();
12187
}
122-
88+
12389
ParserStatus getStatus() const {
124-
ParserStatus S;
125-
if (isError())
126-
S.setIsParseError();
127-
if (isCodeCompletion())
128-
S.setHasCodeCompletion();
129-
return S;
90+
return Status;
13091
}
13192
};
13293

13394
template <typename ParsedSyntaxNode>
13495
static ParsedSyntaxResult<ParsedSyntaxNode>
135-
makeParsedSuccess(ParsedSyntaxNode Node) {
136-
return ParsedSyntaxResult<ParsedSyntaxNode>(Node);
96+
makeParsedResult(ParsedSyntaxNode node) {
97+
return ParsedSyntaxResult<ParsedSyntaxNode>(node);
13798
}
13899

139100
template <typename ParsedSyntaxNode>
140101
static ParsedSyntaxResult<ParsedSyntaxNode>
141-
makeParsedError(ArrayRef<ParsedSyntax> Nodes) {
142-
return ParsedSyntaxResult<ParsedSyntaxNode>(Nodes, ResultDataKind::Error);
102+
makeParsedError(ParsedSyntaxNode node) {
103+
auto result = ParsedSyntaxResult<ParsedSyntaxNode>(node);
104+
result.setIsError();
105+
return result;
143106
}
144107

145108
template <typename ParsedSyntaxNode>
146-
static ParsedSyntaxResult<ParsedSyntaxNode> makeParsedErrorEmpty() {
147-
return ParsedSyntaxResult<ParsedSyntaxNode>({}, ResultDataKind::Error);
109+
static ParsedSyntaxResult<ParsedSyntaxNode> makeParsedError() {
110+
return ParsedSyntaxResult<ParsedSyntaxNode>();
148111
}
149112

150113
template <typename ParsedSyntaxNode>
151114
static ParsedSyntaxResult<ParsedSyntaxNode>
152-
makeParsedCodeCompletion(ArrayRef<ParsedSyntax> Nodes) {
153-
return ParsedSyntaxResult<ParsedSyntaxNode>(Nodes,
154-
ResultDataKind::CodeCompletion);
115+
makeParsedCodeCompletion(ParsedSyntaxNode node) {
116+
auto result = ParsedSyntaxResult<ParsedSyntaxNode>(node);
117+
result.setHasCodeCompletion();
118+
return result;
155119
}
156120

157121
template <typename ParsedSyntaxNode>
158122
static ParsedSyntaxResult<ParsedSyntaxNode>
159-
makeParsedResult(ArrayRef<ParsedSyntax> Nodes,
160-
ParserStatus Status) {
161-
return Status.hasCodeCompletion()
162-
? makeParsedCodeCompletion<ParsedSyntaxNode>(Nodes)
163-
: makeParsedError<ParsedSyntaxNode>(Nodes);
164-
}
165-
166-
template <typename Syntax, typename AST> class SyntaxParserResult {
167-
llvm::Optional<Syntax> SyntaxNode;
168-
ParserResult<AST> ASTResult;
169-
170-
template <typename T, typename U> friend class SyntaxParserResult;
171-
172-
public:
173-
SyntaxParserResult(std::nullptr_t = nullptr)
174-
: SyntaxNode(None), ASTResult(nullptr) {}
175-
SyntaxParserResult(ParserStatus Status)
176-
: SyntaxNode(None), ASTResult(Status) {}
177-
SyntaxParserResult(llvm::Optional<Syntax> SyntaxNode, AST *ASTNode)
178-
: SyntaxNode(SyntaxNode), ASTResult(ASTNode) {}
179-
SyntaxParserResult(ParserStatus Status, llvm::Optional<Syntax> SyntaxNode,
180-
AST *ASTNode)
181-
: SyntaxNode(SyntaxNode), ASTResult(makeParserResult(Status, ASTNode)) {}
182-
183-
/// Convert from a different but compatible parser result.
184-
template <typename U, typename Enabler = typename std::enable_if<
185-
std::is_base_of<AST, U>::value>::type>
186-
SyntaxParserResult(SyntaxParserResult<Syntax, U> Other)
187-
: SyntaxNode(Other.SyntaxNode), ASTResult(Other.ASTResult) {}
188-
189-
190-
bool isNull() const { return ASTResult.isNull(); }
191-
bool isNonNull() const { return ASTResult.isNonNull(); }
192-
bool isParseError() const { return ASTResult.isParseError(); }
193-
bool hasCodeCompletion() const { return ASTResult.hasCodeCompletion(); }
194-
195-
void setIsParseError() { return ASTResult.setIsParserError(); }
196-
void setHasCodeCompletion() { return ASTResult.setHasCodeCompletion(); }
197-
198-
const ParserResult<AST> &getASTResult() { return ASTResult; }
199-
200-
AST *getAST() const { return ASTResult.get(); }
201-
202-
bool hasSyntax() const {
203-
return SyntaxNode.hasValue();
204-
}
205-
206-
Syntax getSyntax() const {
207-
assert(SyntaxNode.hasValue() && "getSyntax from None value");
208-
return *SyntaxNode;
209-
}
210-
211-
SyntaxParserResult<Syntax, AST> &
212-
operator=(SyntaxParserResult<Syntax, AST> R){
213-
std::swap(*this, R);
214-
return *this;
215-
};
216-
};
217-
218-
/// Create a successful parser result.
219-
template <typename Syntax, typename AST>
220-
static inline SyntaxParserResult<Syntax, AST>
221-
makeSyntaxResult(llvm::Optional<Syntax> SyntaxNode, AST *ASTNode) {
222-
return SyntaxParserResult<Syntax, AST>(SyntaxNode, ASTNode);
223-
}
224-
225-
/// Create a result with the specified status.
226-
template <typename Syntax, typename AST>
227-
static inline SyntaxParserResult<Syntax, AST>
228-
makeSyntaxResult(ParserStatus Status, llvm::Optional<Syntax> SyntaxNode,
229-
AST *ASTNode) {
230-
return SyntaxParserResult<Syntax, AST>(Status, SyntaxNode, ASTNode);
231-
}
232-
233-
/// Create a result (null or non-null) with error and code completion bits set.
234-
template <typename Syntax, typename AST>
235-
static inline SyntaxParserResult<Syntax, AST>
236-
makeSyntaxCodeCompletionResult(AST *Result = nullptr) {
237-
SyntaxParserResult<Syntax, AST> SR;
238-
if (Result)
239-
SR = SyntaxParserResult<Syntax, AST>(None, Result);
240-
SR.setHasCodeCompletion();
241-
return SR;
123+
makeParsedResult(ParsedSyntaxNode node, ParserStatus Status) {
124+
auto result = ParsedSyntaxResult<ParsedSyntaxNode>(node);
125+
if (Status.hasCodeCompletion())
126+
result.setHasCodeCompletion();
127+
else if (Status.isError())
128+
result.setIsError();
129+
return result;
242130
}
243131

244132
} // namespace swift

0 commit comments

Comments
 (0)