Skip to content

Commit a239768

Browse files
committed
[NFC] Parse: Refactor for recursive MemberTypeRepr representation
1 parent fd4094c commit a239768

File tree

4 files changed

+75
-41
lines changed

4 files changed

+75
-41
lines changed

include/swift/AST/TypeRepr.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,14 @@ class DeclRefTypeRepr : public TypeRepr {
336336
explicit DeclRefTypeRepr(TypeReprKind K) : TypeRepr(K) {}
337337

338338
public:
339+
static DeclRefTypeRepr *create(const ASTContext &C, TypeRepr *Base,
340+
DeclNameLoc NameLoc, DeclNameRef Name);
341+
342+
static DeclRefTypeRepr *create(const ASTContext &C, TypeRepr *Base,
343+
DeclNameLoc NameLoc, DeclNameRef Name,
344+
ArrayRef<TypeRepr *> GenericArgs,
345+
SourceRange AngleBrackets);
346+
339347
/// Returns the root qualifier. For example, `A` for `A.B.C`. The root
340348
/// qualifier of a `IdentTypeRepr` is itself.
341349
TypeRepr *getRoot();

include/swift/Parse/Parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,12 +1463,13 @@ class Parser {
14631463
/// \endverbatim
14641464
ParserResult<TypeRepr> parseQualifiedDeclNameBaseType();
14651465

1466-
/// Parse an identifier type, e.g 'Foo' or 'Bar<Int>'.
1466+
/// Parse a single type identifier, possibly followed by a generic argument
1467+
/// list, e.g `Foo` or `Bar<Int>`.
14671468
///
14681469
/// \verbatim
14691470
/// type-identifier: identifier generic-args?
14701471
/// \endverbatim
1471-
ParserResult<IdentTypeRepr> parseTypeIdentifier();
1472+
ParserResult<DeclRefTypeRepr> parseTypeIdentifier(TypeRepr *Base);
14721473

14731474
/// Parse a dotted type, e.g. 'Foo<X>.Y.Z', 'P.Type', '[X].Y'.
14741475
ParserResult<TypeRepr> parseTypeDotted(ParserResult<TypeRepr> Base);

lib/AST/TypeRepr.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,43 @@ SourceLoc TypeRepr::findAttrLoc(TypeAttrKind kind) const {
154154
return SourceLoc();
155155
}
156156

157+
DeclRefTypeRepr *DeclRefTypeRepr::create(const ASTContext &C, TypeRepr *Base,
158+
DeclNameLoc NameLoc,
159+
DeclNameRef Name) {
160+
return create(C, Base, NameLoc, Name, {}, SourceRange());
161+
}
162+
163+
DeclRefTypeRepr *DeclRefTypeRepr::create(const ASTContext &C, TypeRepr *Base,
164+
DeclNameLoc NameLoc, DeclNameRef Name,
165+
ArrayRef<TypeRepr *> GenericArgs,
166+
SourceRange AngleBrackets) {
167+
IdentTypeRepr *identTR = nullptr;
168+
if (AngleBrackets.isInvalid() && GenericArgs.empty()) {
169+
identTR = new (C) SimpleIdentTypeRepr(NameLoc, Name);
170+
} else {
171+
identTR = GenericIdentTypeRepr::create(C, NameLoc, Name, GenericArgs,
172+
AngleBrackets);
173+
}
174+
175+
if (Base) {
176+
if (auto *memberTR = dyn_cast<MemberTypeRepr>(Base)) {
177+
llvm::SmallVector<IdentTypeRepr *> newComponents;
178+
{
179+
auto components = memberTR->getMemberComponents();
180+
newComponents.append(components.begin(), components.end());
181+
}
182+
newComponents.push_back(identTR);
183+
184+
return cast<DeclRefTypeRepr>(
185+
MemberTypeRepr::create(C, memberTR->getRoot(), newComponents));
186+
} else {
187+
return cast<DeclRefTypeRepr>(MemberTypeRepr::create(C, Base, {identTR}));
188+
}
189+
} else {
190+
return identTR;
191+
}
192+
}
193+
157194
TypeRepr *DeclRefTypeRepr::getRoot() {
158195
return const_cast<TypeRepr *>(
159196
const_cast<const DeclRefTypeRepr *>(this)->getRoot());

lib/Parse/ParseType.cpp

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,11 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
203203
status, PackTypeRepr::create(Context, keywordLoc,
204204
SourceRange(lbLoc, rbLoc), elements));
205205
} else {
206-
ty = parseTypeIdentifier();
207-
if (auto *ITR = cast_or_null<IdentTypeRepr>(ty.getPtrOrNull())) {
206+
ty = parseTypeIdentifier(/*Base=*/nullptr);
207+
if (auto *repr = ty.getPtrOrNull()) {
208208
if (Tok.is(tok::code_complete) && !Tok.isAtStartOfLine()) {
209209
if (CodeCompletionCallbacks) {
210-
CodeCompletionCallbacks->completeTypeSimpleWithoutDot(ITR);
210+
CodeCompletionCallbacks->completeTypeSimpleWithoutDot(repr);
211211
}
212212

213213
ty.setHasCodeCompletionAndIsError();
@@ -771,14 +771,14 @@ ParserResult<TypeRepr> Parser::parseQualifiedDeclNameBaseType() {
771771
}
772772

773773
ParserStatus Status;
774-
SmallVector<IdentTypeRepr *, 4> ComponentsR;
774+
DeclRefTypeRepr *Result = nullptr;
775775
SourceLoc EndLoc;
776776
while (true) {
777-
auto IdentResult = parseTypeIdentifier();
778-
if (IdentResult.isParseErrorOrHasCompletion())
779-
return IdentResult;
777+
auto PartialResult = parseTypeIdentifier(/*Base=*/Result);
778+
if (PartialResult.isParseErrorOrHasCompletion())
779+
return PartialResult;
780780

781-
ComponentsR.push_back(cast<IdentTypeRepr>(IdentResult.get()));
781+
Result = PartialResult.get();
782782

783783
// Treat 'Foo.<anything>' as an attempt to write a dotted type
784784
// unless <anything> is 'Type'.
@@ -811,31 +811,26 @@ ParserResult<TypeRepr> Parser::parseQualifiedDeclNameBaseType() {
811811
break;
812812
}
813813

814-
DeclRefTypeRepr *DeclRefTR = nullptr;
815-
if (!ComponentsR.empty()) {
816-
DeclRefTR = MemberTypeRepr::create(Context, ComponentsR);
817-
}
818-
819814
if (Status.hasCodeCompletion()) {
820815
if (Tok.isNot(tok::code_complete)) {
821816
// We have a dot.
822817
consumeToken();
823818
if (CodeCompletionCallbacks) {
824-
CodeCompletionCallbacks->completeTypeSimpleWithDot(DeclRefTR);
819+
CodeCompletionCallbacks->completeTypeSimpleWithDot(Result);
825820
}
826821
} else {
827822
if (CodeCompletionCallbacks) {
828-
CodeCompletionCallbacks->completeTypeSimpleWithoutDot(DeclRefTR);
823+
CodeCompletionCallbacks->completeTypeSimpleWithoutDot(Result);
829824
}
830825
}
831826
// Eat the code completion token because we handled it.
832827
consumeToken(tok::code_complete);
833828
}
834829

835-
return makeParserResult(Status, DeclRefTR);
830+
return makeParserResult(Status, Result);
836831
}
837832

838-
ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
833+
ParserResult<DeclRefTypeRepr> Parser::parseTypeIdentifier(TypeRepr *Base) {
839834
// FIXME: We should parse e.g. 'X.var'. Almost any keyword is a valid member
840835
// component.
841836
DeclNameLoc Loc;
@@ -846,7 +841,7 @@ ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
846841
return makeParserError();
847842

848843
ParserStatus Status;
849-
IdentTypeRepr *IdTR;
844+
DeclRefTypeRepr *Result;
850845

851846
if (startsWithLess(Tok)) {
852847
SourceLoc LAngle, RAngle;
@@ -855,20 +850,20 @@ ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
855850
if (ArgsStatus.isErrorOrHasCompletion())
856851
return ArgsStatus;
857852

858-
IdTR = GenericIdentTypeRepr::create(Context, Loc, Name, GenericArgs,
859-
SourceRange(LAngle, RAngle));
853+
Result = DeclRefTypeRepr::create(Context, Base, Loc, Name, GenericArgs,
854+
SourceRange(LAngle, RAngle));
860855
} else {
861-
IdTR = new (Context) SimpleIdentTypeRepr(Loc, Name);
856+
Result = DeclRefTypeRepr::create(Context, Base, Loc, Name);
862857
}
863858

864-
return makeParserResult(IdTR);
859+
return makeParserResult(Result);
865860
}
866861

867862
ParserResult<TypeRepr> Parser::parseTypeDotted(ParserResult<TypeRepr> Base) {
868863
assert(Base.isNonNull());
869864
assert(Tok.isAny(tok::period, tok::period_prefix));
870865

871-
SmallVector<IdentTypeRepr *, 4> MemberComponents;
866+
TypeRepr *Result = Base.get();
872867

873868
while (Tok.isAny(tok::period, tok::period_prefix)) {
874869
if (peekToken().is(tok::code_complete)) {
@@ -881,32 +876,25 @@ ParserResult<TypeRepr> Parser::parseTypeDotted(ParserResult<TypeRepr> Base) {
881876

882877
if (Tok.isContextualKeyword("Type") ||
883878
Tok.isContextualKeyword("Protocol")) {
884-
TypeRepr *MetaBase =
885-
MemberTypeRepr::create(Context, Base.get(), MemberComponents);
886879
if (Tok.getRawText() == "Type") {
887-
Base = makeParserResult(Base,
888-
new (Context) MetatypeTypeRepr(
889-
MetaBase, consumeToken(tok::identifier)));
880+
Result = new (Context)
881+
MetatypeTypeRepr(Result, consumeToken(tok::identifier));
890882
} else {
891-
Base = makeParserResult(Base,
892-
new (Context) ProtocolTypeRepr(
893-
MetaBase, consumeToken(tok::identifier)));
883+
Result = new (Context)
884+
ProtocolTypeRepr(Result, consumeToken(tok::identifier));
894885
}
895886

896-
// Start anew with a metatype base.
897-
MemberComponents.clear();
898887
continue;
899888
}
900889

901-
auto IdentResult = parseTypeIdentifier();
902-
if (IdentResult.isParseErrorOrHasCompletion())
903-
return IdentResult | ParserStatus(Base);
890+
auto PartialResult = parseTypeIdentifier(/*Base=*/Result);
891+
if (PartialResult.isParseErrorOrHasCompletion())
892+
return PartialResult | ParserStatus(Base);
904893

905-
MemberComponents.push_back(cast<IdentTypeRepr>(IdentResult.get()));
894+
Result = PartialResult.get();
906895
}
907896

908-
return makeParserResult(
909-
Base, MemberTypeRepr::create(Context, Base.get(), MemberComponents));
897+
return makeParserResult(Base, Result);
910898
}
911899

912900
/// parseTypeSimpleOrComposition

0 commit comments

Comments
 (0)