Skip to content

Commit ee26b4b

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 ab42032 commit ee26b4b

File tree

12 files changed

+353
-358
lines changed

12 files changed

+353
-358
lines changed

include/swift/IDE/CursorInfo.h

+1-1
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

+2-1
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

+6-7
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

+83-122
Original file line numberDiff line numberDiff line change
@@ -131,53 +131,15 @@ 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;
140+
protected:
141+
ResolvedCursorInfo(CursorInfoKind Kind, SourceFile *SF, SourceLoc Loc)
142+
: Kind(Kind), SF(SF), Loc(Loc) {}
181143

182144
public:
183145
ResolvedCursorInfo() = default;
@@ -200,142 +162,141 @@ struct ResolvedCursorInfo {
200162
bool isInvalid() const { return Kind == CursorInfoKind::Invalid; }
201163
};
202164

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

193+
public:
207194
ResolvedValueRefCursorInfo() = default;
208-
explicit ResolvedValueRefCursorInfo(const ResolvedCursorInfo &Base,
209-
ValueDecl *ValueD, TypeDecl *CtorTyRef,
210-
ExtensionDecl *ExtTyRef, bool IsRef,
211-
Type Ty, Type ContainerType)
212-
: ResolvedCursorInfo(Base) {
213-
assert(Base.getKind() == CursorInfoKind::Invalid &&
214-
"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;
222-
}
195+
explicit ResolvedValueRefCursorInfo(
196+
SourceFile *SF, SourceLoc Loc, ValueDecl *ValueD, TypeDecl *CtorTyRef,
197+
ExtensionDecl *ExtTyRef, bool IsRef, Type Ty, Type ContainerType,
198+
Optional<std::pair<const CustomAttr *, Decl *>> CustomAttrRef,
199+
bool IsKeywordArgument, bool IsDynamic,
200+
SmallVector<NominalTypeDecl *> ReceiverTypes,
201+
SmallVector<ValueDecl *> ShorthandShadowedDecls)
202+
: ResolvedCursorInfo(CursorInfoKind::ValueRef, SF, Loc), ValueD(ValueD),
203+
CtorTyRef(CtorTyRef), ExtTyRef(ExtTyRef), IsRef(IsRef), Ty(Ty),
204+
ContainerType(ContainerType), CustomAttrRef(CustomAttrRef),
205+
IsKeywordArgument(IsKeywordArgument), IsDynamic(IsDynamic),
206+
ReceiverTypes(ReceiverTypes),
207+
ShorthandShadowedDecls(ShorthandShadowedDecls) {}
223208

224-
ValueDecl *getValueD() const { return ValueRefInfo.ValueD; }
225-
void setValueD(ValueDecl *ValueD) { ValueRefInfo.ValueD = ValueD; }
209+
ValueDecl *getValueD() const { return ValueD; }
226210

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

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

231-
bool isRef() const { return ValueRefInfo.IsRef; }
232-
void setIsRef(bool IsRef) { ValueRefInfo.IsRef = IsRef; }
215+
bool isRef() const { return IsRef; }
233216

234-
Type getType() const { return ValueRefInfo.Ty; }
217+
Type getType() const { return Ty; }
235218

236-
Type getContainerType() const { return ValueRefInfo.ContainerType; }
237-
void setContainerType(Type Ty) { ValueRefInfo.ContainerType = Ty; }
219+
Type getContainerType() const { return ContainerType; }
238220

239-
bool isKeywordArgument() const { return ValueRefInfo.IsKeywordArgument; }
221+
bool isKeywordArgument() const { return IsKeywordArgument; }
240222
void setIsKeywordArgument(bool IsKeywordArgument) {
241-
ValueRefInfo.IsKeywordArgument = IsKeywordArgument;
223+
this->IsKeywordArgument = IsKeywordArgument;
242224
}
243225

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

247228
ArrayRef<NominalTypeDecl *> getReceiverTypes() const {
248-
return ValueRefInfo.ReceiverTypes;
249-
}
250-
void setReceiverTypes(const SmallVector<NominalTypeDecl *> &ReceiverTypes) {
251-
ValueRefInfo.ReceiverTypes = ReceiverTypes;
229+
return this->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;
269-
}
270-
void setCustomAttrRef(Optional<std::pair<const CustomAttr *, Decl *>> ref) {
271-
ValueRefInfo.CustomAttrRef = ref;
243+
return CustomAttrRef;
272244
}
273245

274246
static bool classof(const ResolvedCursorInfo *Info) {
275247
return Info->getKind() == CursorInfoKind::ValueRef;
276248
}
277249
};
278250

251+
typedef llvm::IntrusiveRefCntPtr<ResolvedValueRefCursorInfo>
252+
ResolvedValueRefCursorInfoPtr;
253+
279254
struct ResolvedModuleRefCursorInfo : public ResolvedCursorInfo {
280-
// IMPORTANT: Don't add stored properties here. See comment on
281-
// ResolvedCursorInfo.
282-
283-
ResolvedModuleRefCursorInfo(const ResolvedCursorInfo &Base, ModuleEntity Mod)
284-
: ResolvedCursorInfo(Base) {
285-
assert(Base.getKind() == CursorInfoKind::Invalid &&
286-
"Can only specialize from invalid");
287-
Kind = CursorInfoKind::ModuleRef;
288-
ModuleRefInfo.Mod = Mod;
289-
}
255+
private:
256+
ModuleEntity Mod;
290257

291-
ModuleEntity getMod() const { return ModuleRefInfo.Mod; }
258+
public:
259+
ResolvedModuleRefCursorInfo(SourceFile *SF, SourceLoc Loc, ModuleEntity Mod)
260+
: ResolvedCursorInfo(CursorInfoKind::ModuleRef, SF, Loc), Mod(Mod) {}
261+
262+
ModuleEntity getMod() const { return Mod; }
292263

293264
static bool classof(const ResolvedCursorInfo *Info) {
294265
return Info->getKind() == CursorInfoKind::ModuleRef;
295266
}
296267
};
297268

298269
struct ResolvedExprStartCursorInfo : public ResolvedCursorInfo {
299-
// IMPORTANT: Don't add stored properties here. See comment on
300-
// ResolvedCursorInfo.
301-
302-
ResolvedExprStartCursorInfo(const ResolvedCursorInfo &Base,
303-
Expr *TrailingExpr)
304-
: ResolvedCursorInfo(Base) {
305-
assert(Base.getKind() == CursorInfoKind::Invalid &&
306-
"Can only specialize from invalid");
307-
Kind = CursorInfoKind::ExprStart;
308-
ExprStartInfo.TrailingExpr = TrailingExpr;
309-
}
270+
private:
271+
Expr *TrailingExpr = nullptr;
272+
273+
public:
274+
ResolvedExprStartCursorInfo(SourceFile *SF, SourceLoc Loc, Expr *TrailingExpr)
275+
: ResolvedCursorInfo(CursorInfoKind::ExprStart, SF, Loc),
276+
TrailingExpr(TrailingExpr) {}
310277

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

313280
static bool classof(const ResolvedCursorInfo *Info) {
314281
return Info->getKind() == CursorInfoKind::ExprStart;
315282
}
316283
};
317284

318285
struct ResolvedStmtStartCursorInfo : public ResolvedCursorInfo {
319-
// IMPORTANT: Don't add stored properties here. See comment on
320-
// ResolvedCursorInfo.
321-
322-
ResolvedStmtStartCursorInfo(const ResolvedCursorInfo &Base,
323-
Stmt *TrailingStmt)
324-
: ResolvedCursorInfo(Base) {
325-
assert(Base.getKind() == CursorInfoKind::Invalid &&
326-
"Can only specialize from invalid");
327-
Kind = CursorInfoKind::StmtStart;
328-
StmtStartInfo.TrailingStmt = TrailingStmt;
329-
}
286+
Stmt *TrailingStmt = nullptr;
287+
288+
ResolvedStmtStartCursorInfo(SourceFile *SF, SourceLoc Loc, Stmt *TrailingStmt)
289+
: ResolvedCursorInfo(CursorInfoKind::StmtStart, SF, Loc),
290+
TrailingStmt(TrailingStmt) {}
330291

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

333294
static bool classof(const ResolvedCursorInfo *Info) {
334295
return Info->getKind() == CursorInfoKind::StmtStart;
335296
}
336297
};
337298

338-
void simple_display(llvm::raw_ostream &out, const ResolvedCursorInfo &info);
299+
void simple_display(llvm::raw_ostream &out, ResolvedCursorInfoPtr info);
339300

340301
struct UnresolvedLoc {
341302
SourceLoc Loc;

include/swift/IDETool/IDEInspectionInstance.h

+1-1
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

+1-1
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)