mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[sourcekit] Synchronize cursor-info requests on generated interfaces
Cursor info requires access to the underlying AST, which is not thread-safe. This manifest as crashes when performing concurrent cursor-info requests on the same generated interface. We already prevented concurrent cursor-infos on regular Swift files by using the ASTManager, but generated interfaces use the InterfaceGenContext which may use either an ASTUnit or its own internal CompilerInstance. rdar://problem/27311624
This commit is contained in:
@@ -1024,24 +1024,26 @@ void SwiftLangSupport::getCursorInfo(
|
||||
SwiftArgs, OpArgs);
|
||||
}
|
||||
|
||||
SwiftInterfaceGenContext::ResolvedEntity Entity;
|
||||
Entity = IFaceGenRef->resolveEntityForOffset(Offset);
|
||||
if (Entity.isResolved()) {
|
||||
CompilerInvocation Invok;
|
||||
IFaceGenRef->applyTo(Invok);
|
||||
if (Entity.Mod) {
|
||||
passCursorInfoForModule(Entity.Mod, IFaceGenContexts, Invok, Receiver);
|
||||
IFaceGenRef->accessASTAsync([this, IFaceGenRef, Offset, Receiver] {
|
||||
SwiftInterfaceGenContext::ResolvedEntity Entity;
|
||||
Entity = IFaceGenRef->resolveEntityForOffset(Offset);
|
||||
if (Entity.isResolved()) {
|
||||
CompilerInvocation Invok;
|
||||
IFaceGenRef->applyTo(Invok);
|
||||
if (Entity.Mod) {
|
||||
passCursorInfoForModule(Entity.Mod, IFaceGenContexts, Invok,
|
||||
Receiver);
|
||||
} else {
|
||||
// FIXME: Should pass the main module for the interface but currently
|
||||
// it's not necessary.
|
||||
passCursorInfoForDecl(
|
||||
Entity.Dcl, /*MainModule*/ nullptr, Type(), Type(), Entity.IsRef,
|
||||
/*OrigBufferID=*/None, *this, Invok, {}, Receiver);
|
||||
}
|
||||
} else {
|
||||
// FIXME: Should pass the main module for the interface but currently
|
||||
// it's not necessary.
|
||||
passCursorInfoForDecl(Entity.Dcl, /*MainModule*/nullptr, Type(), Type(),
|
||||
Entity.IsRef,
|
||||
/*OrigBufferID=*/None, *this, Invok,
|
||||
{}, Receiver);
|
||||
Receiver({});
|
||||
}
|
||||
} else {
|
||||
Receiver({});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user