Skip to content

Commit 99c6521

Browse files
authored
Merge pull request #27024 from rintaro/syntaxparse-endloc-composition
[SyntaxParse] Fix the end location for CompositionTypeRepr
2 parents 3ddfcae + 9612f44 commit 99c6521

File tree

6 files changed

+52
-1
lines changed

6 files changed

+52
-1
lines changed

include/swift/Syntax/Syntax.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace syntax {
3939

4040
struct SyntaxVisitor;
4141
class SourceFileSyntax;
42+
class TokenSyntax;
4243

4344
template <typename SyntaxNode>
4445
SyntaxNode make(RC<RawSyntax> Raw) {
@@ -168,6 +169,15 @@ class Syntax {
168169
/// Returns true if the node is "present" in the source.
169170
bool isPresent() const;
170171

172+
173+
/// Returns the first non-missing token in this syntax. Returns None if there
174+
/// is no non-missing token.
175+
Optional<TokenSyntax> getFirstToken();
176+
177+
/// Returns the last non-missing token in this syntax. Returns None if there
178+
/// is no non-missing token.
179+
Optional<TokenSyntax> getLastToken();
180+
171181
/// Print the syntax node with full fidelity to the given output stream.
172182
void print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts = SyntaxPrintOptions()) const;
173183

include/swift/Syntax/SyntaxData.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ class SyntaxData final
149149
/// node does not contain non-missing tokens.
150150
RC<SyntaxData> getFirstToken() const;
151151

152+
/// Get the last non-missing token node in this tree. Return nullptr if this
153+
/// node does not contain non-missing tokens.
154+
RC<SyntaxData> getLastToken() const;
155+
152156
~SyntaxData() {
153157
for (auto &I : getChildren())
154158
I.~AtomicCache<SyntaxData>();

lib/Parse/ASTGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ TypeRepr *ASTGen::generate(CompositionTypeSyntax Type, SourceLoc &Loc) {
306306

307307
auto FirstTypeLoc = advanceLocBegin(Loc, FirstElem);
308308
auto FirstAmpersandLoc = advanceLocBegin(Loc, *FirstElem.getAmpersand());
309-
auto LastTypeLoc = advanceLocBegin(Loc, LastElem);
309+
auto LastTypeLoc = advanceLocBegin(Loc, *LastElem.getLastToken());
310310
return CompositionTypeRepr::create(Context, ElemTypes, FirstTypeLoc,
311311
{FirstAmpersandLoc, LastTypeLoc});
312312
}

lib/Syntax/Syntax.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "swift/Syntax/Syntax.h"
1414
#include "swift/Syntax/SyntaxData.h"
1515
#include "swift/Syntax/SyntaxVisitor.h"
16+
#include "swift/Syntax/TokenSyntax.h"
1617

1718
using namespace swift;
1819
using namespace swift::syntax;
@@ -96,3 +97,15 @@ llvm::Optional<Syntax> Syntax::getChild(const size_t N) const {
9697
return llvm::None;
9798
return Syntax {Root, ChildData.get()};
9899
}
100+
101+
Optional<TokenSyntax> Syntax::getFirstToken() {
102+
if (auto tok = getData().getFirstToken())
103+
return TokenSyntax(Root, tok.get());
104+
return None;
105+
}
106+
107+
Optional<TokenSyntax> Syntax::getLastToken() {
108+
if (auto tok = getData().getLastToken())
109+
return TokenSyntax(Root, tok.get());
110+
return None;
111+
}

lib/Syntax/SyntaxData.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ RC<SyntaxData> SyntaxData::getFirstToken() const {
105105
return nullptr;
106106
}
107107

108+
RC<SyntaxData> SyntaxData::getLastToken() const {
109+
if (getRaw()->isToken()) {
110+
// Get a reference counted version of this
111+
assert(hasParent() && "The syntax tree should not conisist only of the root");
112+
return getParent()->getChild(getIndexInParent());
113+
}
114+
for (size_t I = getNumChildren(); I != 0; --I) {
115+
if (auto Child = getChild(I - 1)) {
116+
if (Child->getRaw()->isMissing())
117+
continue;
118+
if (Child->getRaw()->isToken()) {
119+
return Child;
120+
} else if (auto Token = Child->getLastToken()) {
121+
return Token;
122+
}
123+
}
124+
}
125+
return nullptr;
126+
}
127+
108128
AbsolutePosition SyntaxData::getAbsolutePositionBeforeLeadingTrivia() const {
109129
if (PositionCache.hasValue())
110130
return *PositionCache;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: not %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s
2+
3+
typealias A = B & protocol<C, D>
4+
// CHECK: (typealias range=[{{.+}}.swift:[[@LINE-1]]:1 - line:[[@LINE-1]]:32] "A" {{.*}})

0 commit comments

Comments
 (0)