Skip to content

Commit c16049a

Browse files
committed
[AST] Preserve parameter names in TypeReprs of function types.
Also fixup 'test/SourceKit/CodeExpand/code-expand.swift' and use the syntax for adding parameter names with an underscore for first name.
1 parent 63eb78b commit c16049a

File tree

5 files changed

+44
-11
lines changed

5 files changed

+44
-11
lines changed

include/swift/AST/TypeRepr.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,32 +580,47 @@ class TupleTypeRepr : public TypeRepr {
580580
friend class TypeRepr;
581581
};
582582

583-
/// \brief A named element of a tuple type.
583+
/// \brief A named element of a tuple type or a named parameter of a function
584+
/// type.
584585
/// \code
585-
/// (x: Foo = 0)
586+
/// (x: Foo)
587+
/// (_ x: Foo) -> ()
586588
/// \endcode
587589
class NamedTypeRepr : public TypeRepr {
588590
Identifier Id;
589591
TypeRepr *Ty;
590592
SourceLoc IdLoc;
593+
SourceLoc UnderscoreLoc;
591594

592595
public:
596+
/// Used for a named element of a tuple type.
593597
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc)
594598
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc) {
595599
}
600+
/// Used for a named parameter of a function type.
601+
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc,
602+
SourceLoc underscoreLoc)
603+
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc),
604+
UnderscoreLoc(underscoreLoc) {
605+
}
596606

597607
bool hasName() const { return !Id.empty(); }
598608
Identifier getName() const { return Id; }
599609
TypeRepr *getTypeRepr() const { return Ty; }
600610
SourceLoc getNameLoc() const { return IdLoc; }
611+
SourceLoc getUnderscoreLoc() const { return UnderscoreLoc; }
612+
613+
bool isNamedParameter() const { return UnderscoreLoc.isValid(); }
601614

602615
static bool classof(const TypeRepr *T) {
603616
return T->getKind() == TypeReprKind::Named;
604617
}
605618
static bool classof(const NamedTypeRepr *T) { return true; }
606619

607620
private:
608-
SourceLoc getStartLocImpl() const { return IdLoc; }
621+
SourceLoc getStartLocImpl() const {
622+
return UnderscoreLoc.isValid() ? UnderscoreLoc : IdLoc;
623+
}
609624
SourceLoc getEndLocImpl() const { return Ty->getEndLoc(); }
610625
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
611626
friend class TypeRepr;

lib/AST/TypeRepr.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ TypeRepr *CloneVisitor::visitTupleTypeRepr(TupleTypeRepr *T) {
198198

199199
TypeRepr *CloneVisitor::visitNamedTypeRepr(NamedTypeRepr *T) {
200200
return new (Ctx) NamedTypeRepr(T->getName(), visit(T->getTypeRepr()),
201-
T->getNameLoc());
201+
T->getNameLoc(), T->getUnderscoreLoc());
202202
}
203203

204204
TypeRepr *CloneVisitor::visitProtocolCompositionTypeRepr(
@@ -411,9 +411,19 @@ void TupleTypeRepr::printImpl(ASTPrinter &Printer,
411411

412412
void NamedTypeRepr::printImpl(ASTPrinter &Printer,
413413
const PrintOptions &Opts) const {
414-
if (!Id.empty()) {
415-
Printer.printName(Id, PrintNameContext::TupleElement);
414+
if (isNamedParameter()) {
415+
// Printing empty Identifier is same as printing '_'.
416+
Printer.printName(Identifier(), PrintNameContext::FunctionParameterExternal);
417+
if (!Id.empty()) {
418+
Printer << " ";
419+
Printer.printName(Id, PrintNameContext::FunctionParameterLocal);
420+
}
416421
Printer << ": ";
422+
} else {
423+
if (!Id.empty()) {
424+
Printer.printName(Id, PrintNameContext::TupleElement);
425+
Printer << ": ";
426+
}
417427
}
418428
printTypeRepr(Ty, Printer, Opts);
419429
}

lib/Parse/ParseType.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,12 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
711711
else
712712
diag.fixItReplace(SourceRange(firstNameLoc), "_");
713713
}
714+
715+
if (firstNameLoc.isValid() || secondNameLoc.isValid()) {
716+
// Form the named parameter type representation.
717+
ElementsR[i] = new (Context) NamedTypeRepr(secondName, ElementsR[i],
718+
secondNameLoc, firstNameLoc);
719+
}
714720
}
715721
}
716722

lib/Sema/TypeCheckType.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,13 +2427,17 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
24272427
elementOptions |= TR_FunctionInput;
24282428

24292429
for (auto tyR : repr->getElements()) {
2430-
if (NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR)) {
2430+
NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR);
2431+
if (namedTyR && !(options & TR_ImmediateFunctionInput)) {
24312432
Type ty = resolveType(namedTyR->getTypeRepr(), elementOptions);
24322433
if (!ty || ty->is<ErrorType>()) return ty;
24332434

24342435
elements.push_back(TupleTypeElt(ty, namedTyR->getName()));
24352436
} else {
2436-
Type ty = resolveType(tyR, elementOptions);
2437+
// FIXME: Preserve and serialize parameter names in function types, maybe
2438+
// with a new sugar type.
2439+
Type ty = resolveType(namedTyR ? namedTyR->getTypeRepr() : tyR,
2440+
elementOptions);
24372441
if (!ty || ty->is<ErrorType>()) return ty;
24382442

24392443
elements.push_back(TupleTypeElt(ty));

test/SourceKit/CodeExpand/code-expand.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// REQUIRES: se_0111_complete
2-
31
// RUN: %sourcekitd-test -req=expand-placeholder %s | FileCheck %s
42

53
foo(x: <#T##() -> Void#>)
@@ -17,7 +15,7 @@ anArr.indexOfObjectPassingTest(<#T##predicate: ((AnyObject!, Int, UnsafePointer<
1715
// CHECK-NEXT: <#code#>
1816
// CHECK-NEXT: }
1917

20-
anArr.indexOfObjectPassingTest(<#T##predicate: ((obj: AnyObject!, idx: Int, stop: UnsafePointer<ObjCBool>) -> Bool)?##((obj: AnyObject!, idx: Int, stop: UnsafePointer<ObjCBool>) -> Bool)?#>)
18+
anArr.indexOfObjectPassingTest(<#T##predicate: ((_ obj: AnyObject!, _ idx: Int, _ stop: UnsafePointer<ObjCBool>) -> Bool)?##((_ obj: AnyObject!, _ idx: Int, _ stop: UnsafePointer<ObjCBool>) -> Bool)?#>)
2119
// CHECK: anArr.indexOfObjectPassingTest { (obj, idx, stop) -> Bool in
2220
// CHECK-NEXT: <#code#>
2321
// CHECK-NEXT: }

0 commit comments

Comments
 (0)