@@ -178,6 +178,63 @@ RangeSelector transformer::encloseNodes(std::string BeginID,
178178 return transformer::enclose (node (std::move (BeginID)), node (std::move (EndID)));
179179}
180180
181+ RangeSelector transformer::merge (RangeSelector First, RangeSelector Second) {
182+ return [First,
183+ Second](const MatchResult &Result) -> Expected<CharSourceRange> {
184+ Expected<CharSourceRange> FirstRange = First (Result);
185+ if (!FirstRange)
186+ return FirstRange.takeError ();
187+ Expected<CharSourceRange> SecondRange = Second (Result);
188+ if (!SecondRange)
189+ return SecondRange.takeError ();
190+
191+ SourceLocation FirstB = FirstRange->getBegin ();
192+ SourceLocation FirstE = FirstRange->getEnd ();
193+ SourceLocation SecondB = SecondRange->getBegin ();
194+ SourceLocation SecondE = SecondRange->getEnd ();
195+ // Result begin loc is the minimum of the begin locs of the two ranges.
196+ SourceLocation B =
197+ Result.SourceManager ->isBeforeInTranslationUnit (FirstB, SecondB)
198+ ? FirstB
199+ : SecondB;
200+ if (FirstRange->isTokenRange () && SecondRange->isTokenRange ()) {
201+ // Both ranges are token ranges. Just take the maximum of their end locs.
202+ SourceLocation E =
203+ Result.SourceManager ->isBeforeInTranslationUnit (FirstE, SecondE)
204+ ? SecondE
205+ : FirstE;
206+ return CharSourceRange::getTokenRange (B, E);
207+ }
208+
209+ if (FirstRange->isTokenRange ()) {
210+ // The end of the first range is a token. Need to resolve the token to a
211+ // char range.
212+ FirstE = Lexer::getLocForEndOfToken (FirstE, /* Offset=*/ 0 ,
213+ *Result.SourceManager ,
214+ Result.Context ->getLangOpts ());
215+ if (FirstE.isInvalid ())
216+ return invalidArgumentError (
217+ " merge: can't resolve first token range to valid source range" );
218+ }
219+ if (SecondRange->isTokenRange ()) {
220+ // The end of the second range is a token. Need to resolve the token to a
221+ // char range.
222+ SecondE = Lexer::getLocForEndOfToken (SecondE, /* Offset=*/ 0 ,
223+ *Result.SourceManager ,
224+ Result.Context ->getLangOpts ());
225+ if (SecondE.isInvalid ())
226+ return invalidArgumentError (
227+ " merge: can't resolve second token range to valid source range" );
228+ }
229+ // Result end loc is the maximum of the end locs of the two ranges.
230+ SourceLocation E =
231+ Result.SourceManager ->isBeforeInTranslationUnit (FirstE, SecondE)
232+ ? SecondE
233+ : FirstE;
234+ return CharSourceRange::getCharRange (B, E);
235+ };
236+ }
237+
181238RangeSelector transformer::member (std::string ID) {
182239 return [ID](const MatchResult &Result) -> Expected<CharSourceRange> {
183240 Expected<DynTypedNode> Node = getNode (Result.Nodes , ID);
0 commit comments