@@ -30,103 +30,215 @@ template <typename ParsedSyntaxNode> class ParsedSyntaxResult {
30
30
friend class ParsedSyntaxResult ;
31
31
32
32
private:
33
- ParsedRawSyntaxNode Raw;
34
- ParserStatus Status;
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;
35
37
36
- public:
37
- explicit ParsedSyntaxResult () : Raw(), Status() { setIsError (); }
38
+ ResultDataKind DK;
38
39
39
- ParsedSyntaxResult (ParserStatus Status) : Raw(), Status(Status) {
40
- assert (Status.isError ());
40
+ 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
+ }
41
57
}
42
58
43
- explicit ParsedSyntaxResult (ParsedRawSyntaxNode Raw)
44
- : Raw(Raw), Status() {}
45
-
46
- explicit ParsedSyntaxResult (ParsedSyntaxNode Node)
47
- : ParsedSyntaxResult(Node.getRaw()) {}
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
+ }
73
+ }
48
74
49
75
template <typename OtherParsedSyntaxNode,
50
76
typename Enable = typename std::enable_if<std::is_base_of<
51
77
ParsedSyntaxNode, OtherParsedSyntaxNode>::value>::type>
52
- ParsedSyntaxResult (ParsedSyntaxResult<OtherParsedSyntaxNode> other) {
53
- Raw = other.Raw ;
54
- Status = other.Status ;
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
+ }
55
92
}
56
93
57
94
bool isSuccess () const {
58
- return Status. isSuccess () ;
95
+ return DK == ResultDataKind::Success ;
59
96
}
60
97
61
98
bool isError () const {
62
- return Status.isError ();
63
- }
64
- void setIsError () {
65
- Status.setIsParseError ();
99
+ return DK == ResultDataKind::Error;
66
100
}
67
101
68
- bool hasCodeCompletion () const {
69
- return Status.hasCodeCompletion ();
70
- }
71
- void setHasCodeCompletion () {
72
- Status.setHasCodeCompletion ();
102
+ bool isCodeCompletion () const {
103
+ return DK == ResultDataKind::CodeCompletion;
73
104
}
74
105
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 ();
106
+ ParsedSyntaxNode getResult () const {
107
+ assert (isSuccess () && " unsuccessful parse doesn't have any result" );
108
+ return *SuccessNode;
83
109
}
84
110
85
- bool isNull () const {
86
- return Raw.isNull ();
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
+ }
87
121
}
88
-
122
+
89
123
ParserStatus getStatus () const {
90
- return Status;
124
+ ParserStatus S;
125
+ if (isError ())
126
+ S.setIsParseError ();
127
+ if (isCodeCompletion ())
128
+ S.setHasCodeCompletion ();
129
+ return S;
91
130
}
92
131
};
93
132
94
133
template <typename ParsedSyntaxNode>
95
134
static ParsedSyntaxResult<ParsedSyntaxNode>
96
- makeParsedResult (ParsedSyntaxNode node ) {
97
- return ParsedSyntaxResult<ParsedSyntaxNode>(node );
135
+ makeParsedSuccess (ParsedSyntaxNode Node ) {
136
+ return ParsedSyntaxResult<ParsedSyntaxNode>(Node );
98
137
}
99
138
100
139
template <typename ParsedSyntaxNode>
101
140
static ParsedSyntaxResult<ParsedSyntaxNode>
102
- makeParsedError (ParsedSyntaxNode node) {
103
- auto result = ParsedSyntaxResult<ParsedSyntaxNode>(node);
104
- result.setIsError ();
105
- return result;
141
+ makeParsedError (ArrayRef<ParsedSyntax> Nodes) {
142
+ return ParsedSyntaxResult<ParsedSyntaxNode>(Nodes, ResultDataKind::Error);
106
143
}
107
144
108
145
template <typename ParsedSyntaxNode>
109
- static ParsedSyntaxResult<ParsedSyntaxNode> makeParsedError () {
110
- return ParsedSyntaxResult<ParsedSyntaxNode>();
146
+ static ParsedSyntaxResult<ParsedSyntaxNode> makeParsedErrorEmpty () {
147
+ return ParsedSyntaxResult<ParsedSyntaxNode>({}, ResultDataKind::Error );
111
148
}
112
149
113
150
template <typename ParsedSyntaxNode>
114
151
static ParsedSyntaxResult<ParsedSyntaxNode>
115
- makeParsedCodeCompletion (ParsedSyntaxNode node) {
116
- auto result = ParsedSyntaxResult<ParsedSyntaxNode>(node);
117
- result.setHasCodeCompletion ();
118
- return result;
152
+ makeParsedCodeCompletion (ArrayRef<ParsedSyntax> Nodes) {
153
+ return ParsedSyntaxResult<ParsedSyntaxNode>(Nodes,
154
+ ResultDataKind::CodeCompletion);
119
155
}
120
156
121
157
template <typename ParsedSyntaxNode>
122
158
static ParsedSyntaxResult<ParsedSyntaxNode>
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;
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;
130
242
}
131
243
132
244
} // namespace swift
0 commit comments