@@ -37,19 +37,22 @@ namespace {
37
37
38
38
struct FoundResult {
39
39
SourceRange TokenRange;
40
- bool Optional; // Range has a trailing ? or ! included
40
+ bool Optional; // Range includes a trailing ? or !, e.g. [SomeType!]
41
41
bool Suffixable; // No need to wrap parens when adding optionality
42
+ bool Suffixed; // Range is followed by a trailing ? or !, e.g. [SomeType]!
42
43
bool isValid () const { return TokenRange.isValid (); }
43
44
};
44
45
45
46
class ChildIndexFinder : public TypeReprVisitor <ChildIndexFinder, FoundResult> {
46
47
ArrayRef<uint8_t > ChildIndices;
48
+ bool ParentIsOptional;
47
49
48
50
public:
49
51
ChildIndexFinder (ArrayRef<uint8_t > ChildIndices) :
50
52
ChildIndices (ChildIndices) {}
51
53
52
54
FoundResult findChild (AbstractFunctionDecl *Parent) {
55
+ ParentIsOptional = false ;
53
56
auto NextIndex = consumeNext ();
54
57
if (!NextIndex) {
55
58
if (auto Func = dyn_cast<FuncDecl>(Parent))
@@ -60,9 +63,9 @@ class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
60
63
if (!Optional)
61
64
End = Init->getNameLoc ();
62
65
return {SourceRange (Init->getNameLoc (), End), Optional,
63
- /* suffixable=*/ true };
66
+ /* suffixable=*/ true , /* suffixed= */ false };
64
67
}
65
- return {SourceRange (), false , false };
68
+ return {SourceRange (), false , false , false };
66
69
}
67
70
68
71
for (auto *Params: Parent->getParameterLists ()) {
@@ -100,7 +103,7 @@ class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
100
103
101
104
FoundResult findChild (TypeLoc Loc) {
102
105
if (!Loc.hasLocation ())
103
- return {SourceRange (), false , false };
106
+ return {SourceRange (), false , false , false };
104
107
return visit (Loc.getTypeRepr ());
105
108
}
106
109
@@ -110,12 +113,16 @@ class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
110
113
FoundResult handleParent (TypeRepr *Parent, const ArrayRef<T> Children,
111
114
bool Optional = false , bool Suffixable = true ) {
112
115
if (!hasNextIndex ())
113
- return {Parent->getSourceRange (), Optional, Suffixable};
116
+ return {
117
+ Parent->getSourceRange (),
118
+ Optional, Suffixable, /* Suffixed=*/ ParentIsOptional
119
+ };
114
120
auto NextIndex = consumeNext ();
115
121
if (isUserTypeAlias (Parent))
116
- return {SourceRange (), false , false };
122
+ return {SourceRange (), false , false , false };
117
123
assert (NextIndex < Children.size ());
118
124
TypeRepr *Child = Children[NextIndex];
125
+ ParentIsOptional = Optional;
119
126
return visit (Child);
120
127
}
121
128
@@ -137,7 +144,7 @@ class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
137
144
}
138
145
139
146
FoundResult visitErrorTypeRepr (ErrorTypeRepr *T) {
140
- return {SourceRange (), false , false };
147
+ return {SourceRange (), false , false , false };
141
148
}
142
149
143
150
FoundResult visitAttributedTypeRepr (AttributedTypeRepr *T) {
@@ -159,8 +166,10 @@ class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
159
166
FoundResult visitTupleTypeRepr (TupleTypeRepr *T) {
160
167
// Single element TupleTypeReprs may be arbitrarily nested so don't count
161
168
// as their own index level
162
- if (T->getNumElements () == 1 )
169
+ if (T->getNumElements () == 1 ) {
170
+ ParentIsOptional = false ;
163
171
return visit (T->getElement (0 ));
172
+ }
164
173
return handleParent (T, T->getElements ());
165
174
}
166
175
@@ -425,6 +434,10 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
425
434
}
426
435
}
427
436
437
+ bool typeReplacementMayNeedParens (StringRef Replacement) const {
438
+ return Replacement.contains (' &' ) || Replacement.contains (" ->" );
439
+ }
440
+
428
441
bool walkToDeclPre (Decl *D, CharSourceRange Range) override {
429
442
if (D->isImplicit ())
430
443
return true ;
@@ -465,6 +478,10 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
465
478
break ;
466
479
case ide::api::NodeAnnotation::TypeRewritten:
467
480
Editor.replace (Result.TokenRange , DiffItem->RightComment );
481
+ if (Result.Suffixed && typeReplacementMayNeedParens (DiffItem->RightComment )) {
482
+ Editor.insertBefore (Result.TokenRange .Start , " (" );
483
+ Editor.insertAfterToken (Result.TokenRange .End , " )" );
484
+ }
468
485
break ;
469
486
default :
470
487
break ;
0 commit comments