Skip to content

Commit 54553e7

Browse files
committed
[AST] Fix the cursor-info tests with these changes:
- Make sure VarDecls have an associated TypeLoc, like ParamDecls do, then use it for printing the VarDecl's type. This is done by moving ParamDecl's TypeLoc up to the VarDecl. This is useful for being able to display the parameter names of function types embedded in VarDecls. - Use the result TypeLoc of functions for printing. This enables printing parameter names of function types embedded in return types. - Make sure to annotate attributes while they are printed.
1 parent c16049a commit 54553e7

File tree

14 files changed

+102
-52
lines changed

14 files changed

+102
-52
lines changed

include/swift/AST/Decl.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4253,6 +4253,9 @@ class VarDecl : public AbstractStorageDecl {
42534253
setType(Ty);
42544254
}
42554255

4256+
/// This is the type specified, including location information.
4257+
TypeLoc typeLoc;
4258+
42564259
public:
42574260
VarDecl(bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name,
42584261
Type Ty, DeclContext *DC)
@@ -4267,6 +4270,9 @@ class VarDecl : public AbstractStorageDecl {
42674270
bool isUserAccessible() const {
42684271
return VarDeclBits.IsUserAccessible;
42694272
}
4273+
4274+
TypeLoc &getTypeLoc() { return typeLoc; }
4275+
TypeLoc getTypeLoc() const { return typeLoc; }
42704276

42714277
/// Retrieve the source range of the variable type, or an invalid range if the
42724278
/// variable's type is not explicitly written in the source.
@@ -4398,9 +4404,6 @@ class ParamDecl : public VarDecl {
43984404
SourceLoc ArgumentNameLoc;
43994405
SourceLoc LetVarInOutLoc;
44004406

4401-
/// This is the type specified, including location information.
4402-
TypeLoc typeLoc;
4403-
44044407
/// The default value, if any, along with whether this is varargs.
44054408
llvm::PointerIntPair<ExprHandle *, 1, bool> DefaultValueAndIsVariadic;
44064409

@@ -4434,9 +4437,6 @@ class ParamDecl : public VarDecl {
44344437
SourceLoc getArgumentNameLoc() const { return ArgumentNameLoc; }
44354438

44364439
SourceLoc getLetVarInOutLoc() const { return LetVarInOutLoc; }
4437-
4438-
TypeLoc &getTypeLoc() { return typeLoc; }
4439-
TypeLoc getTypeLoc() const { return typeLoc; }
44404440

44414441
bool isTypeLocImplicit() const { return IsTypeLocImplicit; }
44424442
void setIsTypeLocImplicit(bool val) { IsTypeLocImplicit = val; }

include/swift/AST/PrintOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ struct PrintOptions {
425425
result.AbstractAccessors = false;
426426
result.PrintForSIL = true;
427427
result.PrintInSILBody = true;
428+
result.PreferTypeRepr = false;
428429
return result;
429430
}
430431

lib/AST/ASTPrinter.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,8 +2516,10 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25162516
});
25172517
if (decl->hasType()) {
25182518
Printer << ": ";
2519-
// Use the non-repr external type, but reuse the TypeLoc printing code.
2520-
printTypeLoc(TypeLoc::withoutLoc(decl->getType()));
2519+
auto tyLoc = decl->getTypeLoc();
2520+
if (!tyLoc.getTypeRepr())
2521+
tyLoc = TypeLoc::withoutLoc(decl->getType());
2522+
printTypeLoc(tyLoc);
25212523
}
25222524

25232525
printAccessors(decl);
@@ -2777,10 +2779,19 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
27772779

27782780
Type ResultTy = decl->getResultType();
27792781
if (ResultTy && !ResultTy->isVoid()) {
2782+
TypeLoc ResultTyLoc = decl->getBodyResultTypeLoc();
2783+
if (!ResultTyLoc.getTypeRepr())
2784+
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
2785+
// FIXME: Hacky way to workaround the fact that 'Self' as return
2786+
// TypeRepr is not getting 'typechecked'. See
2787+
// \c resolveTopLevelIdentTypeComponent function in TypeCheckType.cpp.
2788+
if (auto *simId = dyn_cast_or_null<SimpleIdentTypeRepr>(ResultTyLoc.getTypeRepr())) {
2789+
if (simId->getIdentifier().str() == "Self")
2790+
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
2791+
}
27802792
Printer << " -> ";
2781-
// Use the non-repr external type, but reuse the TypeLoc printing code.
27822793
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
2783-
printTypeLoc(TypeLoc::withoutLoc(ResultTy));
2794+
printTypeLoc(ResultTyLoc);
27842795
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
27852796
}
27862797
}
@@ -3233,6 +3244,9 @@ void Decl::print(raw_ostream &os) const {
32333244
options.FunctionDefinitions = true;
32343245
options.TypeDefinitions = true;
32353246
options.VarInitializers = true;
3247+
// FIXME: Move all places where SIL printing is happening to explicit options.
3248+
// For example, see \c ProjectionPath::print.
3249+
options.PreferTypeRepr = false;
32363250

32373251
print(os, options);
32383252
}
@@ -3743,10 +3757,14 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37433757
if (Options.SkipAttributes)
37443758
return;
37453759

3746-
if (info.isAutoClosure())
3747-
Printer << "@autoclosure ";
3748-
if (inParameterPrinting && !info.isNoEscape())
3749-
Printer << "@escaping ";
3760+
if (info.isAutoClosure()) {
3761+
Printer.printAttrName("@autoclosure");
3762+
Printer << " ";
3763+
}
3764+
if (inParameterPrinting && !info.isNoEscape()) {
3765+
Printer.printAttrName("@escaping");
3766+
Printer << " ";
3767+
}
37503768

37513769
if (Options.PrintFunctionRepresentationAttrs) {
37523770
// TODO: coalesce into a single convention attribute.

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3722,10 +3722,10 @@ ParamDecl::ParamDecl(ParamDecl *PD)
37223722
ArgumentName(PD->getArgumentName()),
37233723
ArgumentNameLoc(PD->getArgumentNameLoc()),
37243724
LetVarInOutLoc(PD->getLetVarInOutLoc()),
3725-
typeLoc(PD->getTypeLoc()),
37263725
DefaultValueAndIsVariadic(PD->DefaultValueAndIsVariadic),
37273726
IsTypeLocImplicit(PD->IsTypeLocImplicit),
37283727
defaultArgumentKind(PD->defaultArgumentKind) {
3728+
typeLoc = PD->getTypeLoc();
37293729
}
37303730

37313731

lib/AST/TypeRepr.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,26 @@ void AttributedTypeRepr::printAttrs(llvm::raw_ostream &OS) const {
276276
void AttributedTypeRepr::printAttrs(ASTPrinter &Printer) const {
277277
const TypeAttributes &Attrs = getAttrs();
278278

279-
if (Attrs.has(TAK_autoclosure)) Printer << "@autoclosure ";
280-
if (Attrs.has(TAK_escaping)) Printer << "@escaping ";
279+
if (Attrs.has(TAK_autoclosure)) {
280+
Printer.printAttrName("@autoclosure");
281+
Printer << " ";
282+
}
283+
if (Attrs.has(TAK_escaping)) {
284+
Printer.printAttrName("@escaping");
285+
Printer << " ";
286+
}
281287

282-
if (Attrs.has(TAK_thin)) Printer << "@thin ";
283-
if (Attrs.has(TAK_thick)) Printer << "@thick ";
288+
if (Attrs.has(TAK_thin)) {
289+
Printer.printAttrName("@thin");
290+
Printer << " ";
291+
}
292+
if (Attrs.has(TAK_thick)) {
293+
Printer.printAttrName("@thick");
294+
Printer << " ";
295+
}
284296
if (Attrs.convention.hasValue()) {
285-
Printer << "@convention(" << Attrs.convention.getValue() << ") ";
297+
Printer.printAttrName("@convention");
298+
Printer << "(" << Attrs.convention.getValue() << ") ";
286299
}
287300
}
288301

lib/Sema/TypeCheckPattern.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,8 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc,
855855
bool hadError = validateTypedPattern(*this, dc, TP, options, resolver);
856856
Pattern *subPattern = TP->getSubPattern();
857857
if (coercePatternToType(subPattern, dc, P->getType(),
858-
options|TR_FromNonInferredPattern, resolver))
858+
options|TR_FromNonInferredPattern, resolver,
859+
TP->getTypeLoc()))
859860
hadError = true;
860861
else {
861862
TP->setSubPattern(subPattern);
@@ -994,7 +995,12 @@ static bool coercePatternViaConditionalDowncast(TypeChecker &tc,
994995
/// Perform top-down type coercion on the given pattern.
995996
bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
996997
TypeResolutionOptions options,
997-
GenericTypeResolver *resolver) {
998+
GenericTypeResolver *resolver,
999+
TypeLoc tyLoc) {
1000+
if (tyLoc.isNull()) {
1001+
tyLoc = TypeLoc::withoutLoc(type);
1002+
}
1003+
9981004
TypeResolutionOptions subOptions = options - TR_EnumPatternPayload;
9991005
switch (P->getKind()) {
10001006
// For parens and vars, just set the type annotation and propagate inwards.
@@ -1088,7 +1094,9 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
10881094
else if (!var->isInvalid())
10891095
type = var->getType();
10901096
P->setType(type);
1091-
1097+
var->getTypeLoc() = tyLoc;
1098+
var->getTypeLoc().setType(var->getType());
1099+
10921100
// If we are inferring a variable to have type AnyObject.Type,
10931101
// "()", or optional thereof, emit a diagnostic. In the first 2 cases, the
10941102
// coder probably forgot a cast and expected a concrete type. In the later

lib/Sema/TypeCheckType.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,11 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
888888
comp->getIdentifier() == TC.Context.Id_Self) {
889889
auto func = cast<FuncDecl>(DC);
890890
assert(func->hasDynamicSelf() && "Not marked as having dynamic Self?");
891-
891+
892+
// FIXME: The passed-in TypeRepr should get 'typechecked' as well.
893+
// The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
894+
// while the 'Self' type is more than just a reference to a TypeDecl.
895+
892896
return func->getDynamicSelf();
893897
}
894898

lib/Sema/TypeChecker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,8 @@ class TypeChecker final : public LazyResolver {
13781378
/// \returns true if an error occurred, false otherwise.
13791379
bool coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
13801380
TypeResolutionOptions options,
1381-
GenericTypeResolver *resolver = nullptr);
1381+
GenericTypeResolver *resolver = nullptr,
1382+
TypeLoc tyLoc = TypeLoc());
13821383
bool typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
13831384
Type type);
13841385

test/IDE/complete_from_stdlib.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func protocolExtCollection2<C : Collection where C.Index : BidirectionalIndex>(_
106106
// PRIVATE_NOMINAL_MEMBERS_3: Begin completions
107107
// PRIVATE_NOMINAL_MEMBERS_3-DAG: Decl[InstanceMethod]/Super: map({#(transform): (C.Iterator.Element) throws -> T##(C.Iterator.Element) throws -> T#})[' rethrows'][#[T]#]{{; name=.+}}
108108
// PRIVATE_NOMINAL_MEMBERS_3-DAG: Decl[InstanceVar]/Super: lazy[#LazySequence<Collection>#]{{; name=.+}}
109-
// PRIVATE_NOMINAL_MEMBERS_3-DAG: index({#where: (C.Iterator.Element) throws -> Bool##(C.Iterator.Element) throws -> Bool#})[' rethrows'][#C.Index?#]{{; name=.+}}
109+
// PRIVATE_NOMINAL_MEMBERS_3-DAG: index({#where: (C.Iterator.Element) throws -> Bool##(C.Iterator.Element) throws -> Bool#})[' rethrows'][#Comparable?#]{{; name=.+}}
110110
// PRIVATE_NOMINAL_MEMBERS_3: End completions
111111
// NEGATIVE_PRIVATE_NOMINAL_MEMBERS_3-NOT: Decl{{.*}}: index({#({{.*}}): Self.Iterator.Element
112112

test/IDE/print_ast_tc_decls.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,10 +1145,15 @@ protocol d2700_ProtocolWithAssociatedType1 {
11451145
func returnsTA1() -> TA1
11461146
}
11471147

1148-
// PASS_COMMON: {{^}}protocol d2700_ProtocolWithAssociatedType1 {{{$}}
1149-
// PASS_COMMON-NEXT: {{^}} associatedtype TA1{{$}}
1150-
// PASS_COMMON-NEXT: {{^}} func returnsTA1() -> Self.TA1{{$}}
1151-
// PASS_COMMON-NEXT: {{^}}}{{$}}
1148+
// PREFER_TYPE_PRINTING: {{^}}protocol d2700_ProtocolWithAssociatedType1 {{{$}}
1149+
// PREFER_TYPE_PRINTING-NEXT: {{^}} associatedtype TA1{{$}}
1150+
// PREFER_TYPE_PRINTING-NEXT: {{^}} func returnsTA1() -> Self.TA1{{$}}
1151+
// PREFER_TYPE_PRINTING-NEXT: {{^}}}{{$}}
1152+
1153+
// PREFER_TYPEREPR_PRINTING: {{^}}protocol d2700_ProtocolWithAssociatedType1 {{{$}}
1154+
// PREFER_TYPEREPR_PRINTING-NEXT: {{^}} associatedtype TA1{{$}}
1155+
// PREFER_TYPEREPR_PRINTING-NEXT: {{^}} func returnsTA1() -> TA1{{$}}
1156+
// PREFER_TYPEREPR_PRINTING-NEXT: {{^}}}{{$}}
11521157

11531158
struct d2800_ProtocolWithAssociatedType1Impl : d2700_ProtocolWithAssociatedType1 {
11541159
func returnsTA1() -> Int {

0 commit comments

Comments
 (0)