Skip to content

Commit 015dedb

Browse files
committed
[SourceKit] Pass ResolvedCursorInfo as shared pointer instead of by value
This allows us to model the `ResolvedCursorInfo` types as a proper type hierarchy instead of having to store all values in the base `ResolvedCursorInfo` type. rdar://102853071
1 parent 0dd1e36 commit 015dedb

File tree

12 files changed

+330
-326
lines changed

12 files changed

+330
-326
lines changed

include/swift/IDE/CursorInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace ide {
2626
class CursorInfoConsumer {
2727
public:
2828
virtual ~CursorInfoConsumer() {}
29-
virtual void handleResults(const ResolvedCursorInfo &) = 0;
29+
virtual void handleResults(ResolvedCursorInfoPtr) = 0;
3030
};
3131

3232
/// Create a factory for code completion callbacks.

include/swift/IDE/IDERequestIDZone.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
SWIFT_REQUEST(IDE, CollectOverriddenDeclsRequest,
1919
ArrayRef<ValueDecl *>(OverridenDeclsOwner), Cached,
2020
NoLocationInfo)
21-
SWIFT_REQUEST(IDE, CursorInfoRequest, ide::ResolvedCursorInfo(CursorInfoOwner),
21+
SWIFT_REQUEST(IDE, CursorInfoRequest,
22+
ide::ResolvedCursorInfoPtr(CursorInfoOwner),
2223
Cached, NoLocationInfo)
2324
SWIFT_REQUEST(IDE, ProvideDefaultImplForRequest,
2425
ArrayRef<ValueDecl *>(ValueDecl *), Cached,

include/swift/IDE/IDERequests.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,19 @@ struct CursorInfoOwner {
5757
void simple_display(llvm::raw_ostream &out, const CursorInfoOwner &owner);
5858

5959
/// Resolve cursor info at a given location.
60-
class CursorInfoRequest:
61-
public SimpleRequest<CursorInfoRequest,
62-
ide::ResolvedCursorInfo(CursorInfoOwner),
63-
RequestFlags::Cached>
64-
{
60+
class CursorInfoRequest
61+
: public SimpleRequest<CursorInfoRequest,
62+
ide::ResolvedCursorInfoPtr(CursorInfoOwner),
63+
RequestFlags::Cached> {
6564
public:
6665
using SimpleRequest::SimpleRequest;
6766

6867
private:
6968
friend SimpleRequest;
7069

7170
// Evaluation.
72-
ide::ResolvedCursorInfo evaluate(Evaluator &evaluator,
73-
CursorInfoOwner CI) const;
71+
ide::ResolvedCursorInfoPtr evaluate(Evaluator &evaluator,
72+
CursorInfoOwner CI) const;
7473

7574
public:
7675
// Caching

include/swift/IDE/Utils.h

Lines changed: 93 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -131,54 +131,12 @@ enum class CursorInfoKind {
131131

132132
/// Base class of more specialized \c ResolvedCursorInfos that also represents
133133
/// and \c Invalid cursor info.
134-
/// Subclasses of \c ResolvedCursorInfo cannot add new stored properies because
135-
/// \c ResolvedCursorInfo is being passed around as its base class and thus any
136-
/// properties in subclasses would get lost.
137-
struct ResolvedCursorInfo {
134+
struct ResolvedCursorInfo : public llvm::RefCountedBase<ResolvedCursorInfo> {
138135
protected:
139136
CursorInfoKind Kind = CursorInfoKind::Invalid;
140137
SourceFile *SF = nullptr;
141138
SourceLoc Loc;
142139

143-
// Technically, these structs could form a union (because only one of them is
144-
// active at a time). But I had issues with C++ complaining about copy
145-
// constructors and gave up. At the moment it's only wasting 3 words for non
146-
// ValueRef data.
147-
struct {
148-
ValueDecl *ValueD = nullptr;
149-
TypeDecl *CtorTyRef = nullptr;
150-
ExtensionDecl *ExtTyRef = nullptr;
151-
bool IsRef = true;
152-
Type Ty;
153-
Type ContainerType;
154-
Optional<std::pair<const CustomAttr *, Decl *>> CustomAttrRef = None;
155-
156-
bool IsKeywordArgument = false;
157-
/// It this is a ref, whether it is "dynamic". See \c ide::isDynamicRef.
158-
bool IsDynamic = false;
159-
/// If this is a dynamic ref, the types of the base (multiple in the case of
160-
/// protocol composition).
161-
SmallVector<NominalTypeDecl *> ReceiverTypes;
162-
/// Declarations that were shadowed by \c ValueD using a shorthand syntax
163-
/// that names both the newly declared variable and the referenced variable
164-
/// by the same identifier in the source text. This includes shorthand
165-
/// closure captures (`[foo]`) and shorthand if captures
166-
/// (`if let foo {`). Ordered from innermost to outermost shadows.
167-
///
168-
/// Decls that are shadowed using shorthand syntax should be reported as
169-
/// additional cursor info results.
170-
SmallVector<ValueDecl *> ShorthandShadowedDecls;
171-
} ValueRefInfo;
172-
struct {
173-
ModuleEntity Mod;
174-
} ModuleRefInfo;
175-
struct {
176-
Expr *TrailingExpr = nullptr;
177-
} ExprStartInfo;
178-
struct {
179-
Stmt *TrailingStmt = nullptr;
180-
} StmtStartInfo;
181-
182140
public:
183141
ResolvedCursorInfo() = default;
184142
ResolvedCursorInfo(SourceFile *SF) : SF(SF) {}
@@ -200,142 +158,172 @@ struct ResolvedCursorInfo {
200158
bool isInvalid() const { return Kind == CursorInfoKind::Invalid; }
201159
};
202160

161+
typedef llvm::IntrusiveRefCntPtr<ResolvedCursorInfo> ResolvedCursorInfoPtr;
162+
203163
struct ResolvedValueRefCursorInfo : public ResolvedCursorInfo {
204-
// IMPORTANT: Don't add stored properties here. See comment on
205-
// ResolvedCursorInfo.
164+
private:
165+
ValueDecl *ValueD = nullptr;
166+
TypeDecl *CtorTyRef = nullptr;
167+
ExtensionDecl *ExtTyRef = nullptr;
168+
bool IsRef = true;
169+
Type Ty;
170+
Type ContainerType;
171+
Optional<std::pair<const CustomAttr *, Decl *>> CustomAttrRef = None;
172+
173+
bool IsKeywordArgument = false;
174+
/// It this is a ref, whether it is "dynamic". See \c ide::isDynamicRef.
175+
bool IsDynamic = false;
176+
/// If this is a dynamic ref, the types of the base (multiple in the case of
177+
/// protocol composition).
178+
SmallVector<NominalTypeDecl *> ReceiverTypes;
179+
/// Declarations that were shadowed by \c ValueD using a shorthand syntax
180+
/// that names both the newly declared variable and the referenced variable
181+
/// by the same identifier in the source text. This includes shorthand
182+
/// closure captures (`[foo]`) and shorthand if captures
183+
/// (`if let foo {`). Ordered from innermost to outermost shadows.
184+
///
185+
/// Decls that are shadowed using shorthand syntax should be reported as
186+
/// additional cursor info results.
187+
SmallVector<ValueDecl *> ShorthandShadowedDecls;
206188

189+
public:
207190
ResolvedValueRefCursorInfo() = default;
208-
explicit ResolvedValueRefCursorInfo(const ResolvedCursorInfo &Base,
191+
explicit ResolvedValueRefCursorInfo(ResolvedCursorInfoPtr Base,
209192
ValueDecl *ValueD, TypeDecl *CtorTyRef,
210193
ExtensionDecl *ExtTyRef, bool IsRef,
211194
Type Ty, Type ContainerType)
212-
: ResolvedCursorInfo(Base) {
213-
assert(Base.getKind() == CursorInfoKind::Invalid &&
195+
: ResolvedCursorInfo(*Base), ValueD(ValueD), CtorTyRef(CtorTyRef),
196+
ExtTyRef(ExtTyRef), IsRef(IsRef), Ty(Ty), ContainerType(ContainerType) {
197+
assert(Base->getKind() == CursorInfoKind::Invalid &&
214198
"Can only specialize from invalid");
215-
Kind = CursorInfoKind::ValueRef;
216-
ValueRefInfo.ValueD = ValueD;
217-
ValueRefInfo.CtorTyRef = CtorTyRef;
218-
ValueRefInfo.ExtTyRef = ExtTyRef;
219-
ValueRefInfo.IsRef = IsRef;
220-
ValueRefInfo.Ty = Ty;
221-
ValueRefInfo.ContainerType = ContainerType;
199+
this->Kind = CursorInfoKind::ValueRef;
222200
}
223201

224-
ValueDecl *getValueD() const { return ValueRefInfo.ValueD; }
225-
void setValueD(ValueDecl *ValueD) { ValueRefInfo.ValueD = ValueD; }
202+
ValueDecl *getValueD() const { return ValueD; }
203+
void setValueD(ValueDecl *ValueD) { this->ValueD = ValueD; }
226204

227-
ExtensionDecl *getExtTyRef() const { return ValueRefInfo.ExtTyRef; }
205+
ExtensionDecl *getExtTyRef() const { return ExtTyRef; }
228206

229-
TypeDecl *getCtorTyRef() const { return ValueRefInfo.CtorTyRef; }
207+
TypeDecl *getCtorTyRef() const { return CtorTyRef; }
230208

231-
bool isRef() const { return ValueRefInfo.IsRef; }
232-
void setIsRef(bool IsRef) { ValueRefInfo.IsRef = IsRef; }
209+
bool isRef() const { return IsRef; }
210+
void setIsRef(bool IsRef) { this->IsRef = IsRef; }
233211

234-
Type getType() const { return ValueRefInfo.Ty; }
212+
Type getType() const { return Ty; }
235213

236-
Type getContainerType() const { return ValueRefInfo.ContainerType; }
237-
void setContainerType(Type Ty) { ValueRefInfo.ContainerType = Ty; }
214+
Type getContainerType() const { return ContainerType; }
215+
void setContainerType(Type Ty) { this->ContainerType = Ty; }
238216

239-
bool isKeywordArgument() const { return ValueRefInfo.IsKeywordArgument; }
217+
bool isKeywordArgument() const { return IsKeywordArgument; }
240218
void setIsKeywordArgument(bool IsKeywordArgument) {
241-
ValueRefInfo.IsKeywordArgument = IsKeywordArgument;
219+
this->IsKeywordArgument = IsKeywordArgument;
242220
}
243221

244-
bool isDynamic() const { return ValueRefInfo.IsDynamic; }
245-
void setIsDynamic(bool IsDynamic) { ValueRefInfo.IsDynamic = IsDynamic; }
222+
bool isDynamic() const { return this->IsDynamic; }
223+
void setIsDynamic(bool IsDynamic) { this->IsDynamic = IsDynamic; }
246224

247225
ArrayRef<NominalTypeDecl *> getReceiverTypes() const {
248-
return ValueRefInfo.ReceiverTypes;
226+
return this->ReceiverTypes;
249227
}
250228
void setReceiverTypes(const SmallVector<NominalTypeDecl *> &ReceiverTypes) {
251-
ValueRefInfo.ReceiverTypes = ReceiverTypes;
229+
this->ReceiverTypes = ReceiverTypes;
252230
}
253231

254232
ArrayRef<ValueDecl *> getShorthandShadowedDecls() const {
255-
return ValueRefInfo.ShorthandShadowedDecls;
233+
return this->ShorthandShadowedDecls;
256234
};
257235
void setShorthandShadowedDecls(
258236
const SmallVector<ValueDecl *> &ShorthandShadowedDecls) {
259-
ValueRefInfo.ShorthandShadowedDecls = ShorthandShadowedDecls;
237+
this->ShorthandShadowedDecls = ShorthandShadowedDecls;
260238
};
261239

262-
ValueDecl *typeOrValue() {
263-
return ValueRefInfo.CtorTyRef ? ValueRefInfo.CtorTyRef
264-
: ValueRefInfo.ValueD;
265-
}
240+
ValueDecl *typeOrValue() { return CtorTyRef ? CtorTyRef : ValueD; }
266241

267242
Optional<std::pair<const CustomAttr *, Decl *>> getCustomAttrRef() const {
268-
return ValueRefInfo.CustomAttrRef;
243+
return CustomAttrRef;
269244
}
270245
void setCustomAttrRef(Optional<std::pair<const CustomAttr *, Decl *>> ref) {
271-
ValueRefInfo.CustomAttrRef = ref;
246+
CustomAttrRef = ref;
272247
}
273248

274249
static bool classof(const ResolvedCursorInfo *Info) {
275250
return Info->getKind() == CursorInfoKind::ValueRef;
276251
}
277252
};
278253

254+
typedef llvm::IntrusiveRefCntPtr<ResolvedValueRefCursorInfo>
255+
ResolvedValueRefCursorInfoPtr;
256+
279257
struct ResolvedModuleRefCursorInfo : public ResolvedCursorInfo {
280-
// IMPORTANT: Don't add stored properties here. See comment on
281-
// ResolvedCursorInfo.
258+
private:
259+
ModuleEntity Mod;
282260

283-
ResolvedModuleRefCursorInfo(const ResolvedCursorInfo &Base, ModuleEntity Mod)
284-
: ResolvedCursorInfo(Base) {
285-
assert(Base.getKind() == CursorInfoKind::Invalid &&
261+
public:
262+
ResolvedModuleRefCursorInfo(ResolvedCursorInfoPtr Base, ModuleEntity Mod)
263+
: ResolvedCursorInfo(*Base), Mod(Mod) {
264+
assert(Base->getKind() == CursorInfoKind::Invalid &&
286265
"Can only specialize from invalid");
287-
Kind = CursorInfoKind::ModuleRef;
288-
ModuleRefInfo.Mod = Mod;
266+
this->Kind = CursorInfoKind::ModuleRef;
289267
}
290268

291-
ModuleEntity getMod() const { return ModuleRefInfo.Mod; }
269+
ModuleEntity getMod() const { return Mod; }
292270

293271
static bool classof(const ResolvedCursorInfo *Info) {
294272
return Info->getKind() == CursorInfoKind::ModuleRef;
295273
}
296274
};
297275

276+
typedef llvm::IntrusiveRefCntPtr<ResolvedModuleRefCursorInfo>
277+
ResolvedModuleRefCursorInfoPtr;
278+
298279
struct ResolvedExprStartCursorInfo : public ResolvedCursorInfo {
299-
// IMPORTANT: Don't add stored properties here. See comment on
300-
// ResolvedCursorInfo.
280+
private:
281+
Expr *TrailingExpr = nullptr;
301282

302-
ResolvedExprStartCursorInfo(const ResolvedCursorInfo &Base,
303-
Expr *TrailingExpr)
304-
: ResolvedCursorInfo(Base) {
305-
assert(Base.getKind() == CursorInfoKind::Invalid &&
283+
public:
284+
ResolvedExprStartCursorInfo(ResolvedCursorInfoPtr Base, Expr *TrailingExpr)
285+
: ResolvedCursorInfo(*Base), TrailingExpr(TrailingExpr) {
286+
assert(Base->getKind() == CursorInfoKind::Invalid &&
306287
"Can only specialize from invalid");
307-
Kind = CursorInfoKind::ExprStart;
308-
ExprStartInfo.TrailingExpr = TrailingExpr;
288+
this->Kind = CursorInfoKind::ExprStart;
309289
}
310290

311-
Expr *getTrailingExpr() const { return ExprStartInfo.TrailingExpr; }
291+
Expr *getTrailingExpr() const { return TrailingExpr; }
312292

313293
static bool classof(const ResolvedCursorInfo *Info) {
314294
return Info->getKind() == CursorInfoKind::ExprStart;
315295
}
316296
};
317297

298+
typedef llvm::IntrusiveRefCntPtr<ResolvedExprStartCursorInfo>
299+
ResolvedExprStartCursorInfoPtr;
300+
318301
struct ResolvedStmtStartCursorInfo : public ResolvedCursorInfo {
319-
// IMPORTANT: Don't add stored properties here. See comment on
320-
// ResolvedCursorInfo.
302+
Stmt *TrailingStmt = nullptr;
321303

322-
ResolvedStmtStartCursorInfo(const ResolvedCursorInfo &Base,
323-
Stmt *TrailingStmt)
324-
: ResolvedCursorInfo(Base) {
325-
assert(Base.getKind() == CursorInfoKind::Invalid &&
304+
ResolvedStmtStartCursorInfo(ResolvedCursorInfoPtr Base, Stmt *TrailingStmt)
305+
: ResolvedCursorInfo(*Base), TrailingStmt(TrailingStmt) {
306+
assert(Base->getKind() == CursorInfoKind::Invalid &&
326307
"Can only specialize from invalid");
327-
Kind = CursorInfoKind::StmtStart;
328-
StmtStartInfo.TrailingStmt = TrailingStmt;
308+
this->Kind = CursorInfoKind::StmtStart;
329309
}
330310

331-
Stmt *getTrailingStmt() const { return StmtStartInfo.TrailingStmt; }
311+
Stmt *getTrailingStmt() const { return TrailingStmt; }
332312

333313
static bool classof(const ResolvedCursorInfo *Info) {
334314
return Info->getKind() == CursorInfoKind::StmtStart;
335315
}
336316
};
337317

338-
void simple_display(llvm::raw_ostream &out, const ResolvedCursorInfo &info);
318+
typedef llvm::IntrusiveRefCntPtr<ResolvedStmtStartCursorInfo>
319+
ResolvedStmtStartCursorInfoPtr;
320+
321+
void simple_display(llvm::raw_ostream &out, ResolvedCursorInfoPtr info);
322+
323+
template <typename T>
324+
llvm::IntrusiveRefCntPtr<T> dyn_cast_cursor_info(ResolvedCursorInfoPtr Ptr) {
325+
return llvm::IntrusiveRefCntPtr<T>(dyn_cast<T>(Ptr.get()));
326+
}
339327

340328
struct UnresolvedLoc {
341329
SourceLoc Loc;

include/swift/IDETool/IDEInspectionInstance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct ConformingMethodListResults {
8282
/// The results returned from \c IDEInspectionInstance::cursorInfo.
8383
struct CursorInfoResults {
8484
/// The actual results. If \c nullptr, no results were found.
85-
const ResolvedCursorInfo *Result;
85+
ResolvedCursorInfoPtr Result;
8686
/// Whether an AST was reused to produce the results.
8787
bool DidReuseAST;
8888
};

include/swift/Refactoring/Refactoring.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ void collectAvailableRefactorings(
136136
llvm::SmallVectorImpl<RefactoringKind> &Kinds,
137137
llvm::ArrayRef<DiagnosticConsumer *> DiagConsumers);
138138

139-
void collectAvailableRefactorings(const ResolvedCursorInfo &CursorInfo,
139+
void collectAvailableRefactorings(ResolvedCursorInfoPtr CursorInfo,
140140
llvm::SmallVectorImpl<RefactoringKind> &Kinds,
141141
bool ExcludeRename);
142142

0 commit comments

Comments
 (0)