diff --git a/test/SourceKit/Macros/macro_basic.swift b/test/SourceKit/Macros/macro_basic.swift index 65df7f7b6933f..f90da3ab11df7 100644 --- a/test/SourceKit/Macros/macro_basic.swift +++ b/test/SourceKit/Macros/macro_basic.swift @@ -181,6 +181,25 @@ macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition" // ATTACHED_EXPAND-NEXT: source.edit.kind.active: // ATTACHED_EXPAND-NEXT: 21:1-21:15 "" +//##-- Cursor info on the attribute expanded by @myTypeWrapper +// RUN: %sourcekitd-test -req=cursor -cursor-action -req-opts=retrieve_symbol_graph=1 -offset=2 @__swiftmacro_9MacroUser1SV13myTypeWrapperfMA_.swift -primary-file %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=NESTED_ATTACHED_CURSOR %s +// NESTED_ATTACHED_CURSOR: source.lang.swift.ref.macro +// NESTED_ATTACHED_CURSOR-SAME: macro_basic.swift:10:27-10:43 +// NESTED_ATTACHED_CURSOR-LABEL: SYMBOL GRAPH BEGIN +// NESTED_ATTACHED_CURSOR: "identifier": { +// NESTED_ATTACHED_CURSOR-NEXT: "interfaceLanguage": "swift", +// NESTED_ATTACHED_CURSOR-NEXT: "precise": "s:9MacroUser16accessViaStorageyycfm" +// NESTED_ATTACHED_CURSOR-NEXT: }, +// NESTED_ATTACHED_CURSOR-NEXT: "kind": { +// NESTED_ATTACHED_CURSOR-NEXT: "displayName": "Macro", +// NESTED_ATTACHED_CURSOR-NEXT: "identifier": "swift.macro" +// NESTED_ATTACHED_CURSOR-NEXT: }, +// NESTED_ATTACHED_CURSOR: SYMBOL GRAPH END +// NESTED_ATTACHED_CURSOR-LABEL: ACTIONS BEGIN +// NESTED_ATTACHED_CURSOR: source.refactoring.kind.expand.macro +// NESTED_ATTACHED_CURSOR-NEXT: Expand Macro +// NESTED_ATTACHED_CURSOR:ACTIONS END + //##-- Refactoring on the attribute expanded by @myTypeWrapper // RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=1:2 @__swiftmacro_9MacroUser1SV13myTypeWrapperfMA_.swift -primary-file %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=NESTED_ATTACHED_EXPAND %s // NESTED_ATTACHED_EXPAND: source.edit.kind.active: diff --git a/tools/SourceKit/include/SourceKit/Core/LangSupport.h b/tools/SourceKit/include/SourceKit/Core/LangSupport.h index e05fd1336a0f7..aaadf55e6353b 100644 --- a/tools/SourceKit/include/SourceKit/Core/LangSupport.h +++ b/tools/SourceKit/include/SourceKit/Core/LangSupport.h @@ -640,10 +640,10 @@ enum class SemanticRefactoringKind { struct SemanticRefactoringInfo { SemanticRefactoringKind Kind; - // The name of the source file to start the refactoring in. Empty if it is - // the primary file (in which case the primary file from the AST is used). - // This must match the buffer identifier stored in the source manager. - StringRef SourceFile; + // The name of the input buffer to start the refactoring in. This must either + // be empty (in which case the primary file for the AST is used), or exactly + // match the buffer identifier stored in the source manager. + StringRef InputBufferName; unsigned Line; unsigned Column; unsigned Length; @@ -982,14 +982,15 @@ class LangSupport { EditorConsumer &Consumer) = 0; virtual void getCursorInfo( - StringRef Filename, unsigned Offset, unsigned Length, bool Actionables, - bool SymbolGraph, bool CancelOnSubsequentRequest, - ArrayRef Args, Optional vfsOptions, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + unsigned Length, bool Actionables, bool SymbolGraph, + bool CancelOnSubsequentRequest, ArrayRef Args, + Optional vfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) = 0; virtual void - getDiagnostics(StringRef InputFile, ArrayRef Args, + getDiagnostics(StringRef PrimaryFilePath, ArrayRef Args, Optional VfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> @@ -1003,26 +1004,28 @@ class LangSupport { Receiver) = 0; virtual void getRangeInfo( - StringRef Filename, unsigned Offset, unsigned Length, - bool CancelOnSubsequentRequest, ArrayRef Args, - SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + unsigned Length, bool CancelOnSubsequentRequest, + ArrayRef Args, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) = 0; virtual void getCursorInfoFromUSR( - StringRef Filename, StringRef USR, bool CancelOnSubsequentRequest, - ArrayRef Args, Optional vfsOptions, + StringRef PrimaryFilePath, StringRef InputBufferName, StringRef USR, + bool CancelOnSubsequentRequest, ArrayRef Args, + Optional vfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) = 0; virtual void findRelatedIdentifiersInFile( - StringRef Filename, unsigned Offset, bool CancelOnSubsequentRequest, - ArrayRef Args, SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + bool CancelOnSubsequentRequest, ArrayRef Args, + SourceKitCancellationToken CancellationToken, std::function &)> Receiver) = 0; virtual void findActiveRegionsInFile( - StringRef Filename, ArrayRef Args, - SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) = 0; @@ -1052,16 +1055,17 @@ class LangSupport { SourceKitCancellationToken CancellationToken, CategorizedRenameRangesReceiver Receiver) = 0; - virtual void semanticRefactoring(StringRef PrimaryFile, + virtual void semanticRefactoring(StringRef PrimaryFilePath, SemanticRefactoringInfo Info, ArrayRef Args, SourceKitCancellationToken CancellationToken, CategorizedEditsReceiver Receiver) = 0; virtual void collectExpressionTypes( - StringRef FileName, ArrayRef Args, - ArrayRef ExpectedProtocols, bool FullyQualified, - bool CanonicalType, SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, ArrayRef ExpectedProtocols, + bool FullyQualified, bool CanonicalType, + SourceKitCancellationToken CancellationToken, std::function &)> Receiver) = 0; @@ -1069,8 +1073,9 @@ class LangSupport { /// the source file. If `Offset` or `Length` are empty, variable types for /// the entire document are collected. virtual void collectVariableTypes( - StringRef FileName, ArrayRef Args, - Optional Offset, Optional Length, bool FullyQualified, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, Optional Offset, + Optional Length, bool FullyQualified, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) = 0; diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h index 40968bdc159bf..8b6d732ea723f 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h +++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h @@ -632,9 +632,9 @@ class SwiftLangSupport : public LangSupport { void editorExpandPlaceholder(StringRef Name, unsigned Offset, unsigned Length, EditorConsumer &Consumer) override; - void getCursorInfo(StringRef Filename, unsigned Offset, unsigned Length, - bool Actionables, bool SymbolGraph, - bool CancelOnSubsequentRequest, + void getCursorInfo(StringRef PrimaryFilePath, StringRef InputBufferName, + unsigned Offset, unsigned Length, bool Actionables, + bool SymbolGraph, bool CancelOnSubsequentRequest, ArrayRef Args, Optional vfsOptions, SourceKitCancellationToken CancellationToken, @@ -642,7 +642,7 @@ class SwiftLangSupport : public LangSupport { Receiver) override; void - getDiagnostics(StringRef InputFile, ArrayRef Args, + getDiagnostics(StringRef PrimaryFilePath, ArrayRef Args, Optional VfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> @@ -655,27 +655,29 @@ class SwiftLangSupport : public LangSupport { override; void getRangeInfo( - StringRef Filename, unsigned Offset, unsigned Length, - bool CancelOnSubsequentRequest, ArrayRef Args, - SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + unsigned Length, bool CancelOnSubsequentRequest, + ArrayRef Args, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) override; void getCursorInfoFromUSR( - StringRef Filename, StringRef USR, bool CancelOnSubsequentRequest, - ArrayRef Args, Optional vfsOptions, + StringRef PrimaryFilePath, StringRef InputBufferName, StringRef USR, + bool CancelOnSubsequentRequest, ArrayRef Args, + Optional vfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) override; void findRelatedIdentifiersInFile( - StringRef Filename, unsigned Offset, bool CancelOnSubsequentRequest, - ArrayRef Args, SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + bool CancelOnSubsequentRequest, ArrayRef Args, + SourceKitCancellationToken CancellationToken, std::function &)> Receiver) override; void findActiveRegionsInFile( - StringRef Filename, ArrayRef Args, - SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) override; @@ -695,20 +697,23 @@ class SwiftLangSupport : public LangSupport { CategorizedRenameRangesReceiver Receiver) override; void collectExpressionTypes( - StringRef FileName, ArrayRef Args, - ArrayRef ExpectedProtocols, bool FullyQualified, - bool CanonicalType, SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, ArrayRef ExpectedProtocols, + bool FullyQualified, bool CanonicalType, + SourceKitCancellationToken CancellationToken, std::function &)> Receiver) override; void collectVariableTypes( - StringRef FileName, ArrayRef Args, - Optional Offset, Optional Length, bool FullyQualified, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, Optional Offset, + Optional Length, bool FullyQualified, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) override; - void semanticRefactoring(StringRef PrimaryFile, SemanticRefactoringInfo Info, + void semanticRefactoring(StringRef PrimaryFilePath, + SemanticRefactoringInfo Info, ArrayRef Args, SourceKitCancellationToken CancellationToken, CategorizedEditsReceiver Receiver) override; diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp index 443b7c94f918c..18a0f2078003f 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp @@ -636,7 +636,8 @@ mapOffsetToNewerSnapshot(unsigned Offset, static void mapLocToLatestSnapshot( SwiftLangSupport &Lang, LocationInfo &Location, ArrayRef PreviousASTSnaps) { - auto EditorDoc = Lang.getEditorDocuments()->findByPath(Location.Filename); + auto EditorDoc = Lang.getEditorDocuments()->findByPath(Location.Filename, + /*IsRealpath=*/true); if (!EditorDoc) return; @@ -1434,9 +1435,9 @@ class CursorRangeInfoConsumer : public SwiftASTConsumer { CursorRangeInfoConsumer(StringRef InputFile, unsigned Offset, unsigned Length, SwiftLangSupport &Lang, SwiftInvocationRef ASTInvok, bool TryExistingAST, bool CancelOnSubsequentRequest) - : Lang(Lang), ASTInvok(ASTInvok),InputFile(InputFile.str()), Offset(Offset), - Length(Length), TryExistingAST(TryExistingAST), - CancelOnSubsequentRequest(CancelOnSubsequentRequest) {} + : Lang(Lang), ASTInvok(ASTInvok), InputFile(InputFile.str()), + Offset(Offset), Length(Length), TryExistingAST(TryExistingAST), + CancelOnSubsequentRequest(CancelOnSubsequentRequest) {} bool canUseASTWithSnapshots(ArrayRef Snapshots) override { if (!TryExistingAST) { @@ -1451,7 +1452,8 @@ class CursorRangeInfoConsumer : public SwiftASTConsumer { // blocked waiting on the AST to be fully typechecked. ImmutableTextSnapshotRef InputSnap; - if (auto EditorDoc = Lang.getEditorDocuments()->findByPath(InputFile)) + if (auto EditorDoc = Lang.getEditorDocuments()->findByPath( + InputFile, /*IsRealpath=*/true)) InputSnap = EditorDoc->getLatestSnapshot(); if (!InputSnap) return false; @@ -1492,6 +1494,33 @@ class CursorRangeInfoConsumer : public SwiftASTConsumer { } }; +static SourceFile *retrieveInputFile(StringRef inputBufferName, + const CompilerInstance &CI, + bool haveRealPath = false) { + // Don't bother looking up if we have the same file as the primary file or + // we weren't given a separate input file + if (inputBufferName.empty() || + CI.getPrimarySourceFile()->getFilename() == inputBufferName) + return CI.getPrimarySourceFile(); + + // Otherwise, try to find the given buffer identifier + const SourceManager &SM = CI.getSourceMgr(); + Optional inputBufferID = + SM.getIDForBufferIdentifier(inputBufferName); + if (!inputBufferID) { + // If that failed, try again with symlinks resolved (unless we've already + // done that) + if (haveRealPath) + return nullptr; + std::string realPath = + SwiftLangSupport::resolvePathSymlinks(inputBufferName); + return retrieveInputFile(realPath, CI, /*haveRealPath=*/true); + } + + return CI.getMainModule()->getSourceFileContainingLocation( + SM.getRangeForBuffer(*inputBufferID).getStart()); +} + static void resolveCursor( SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset, unsigned Length, bool Actionables, bool SymbolGraph, @@ -1523,13 +1552,21 @@ static void resolveCursor( void handlePrimaryAST(ASTUnitRef AstUnit) override { auto &CompIns = AstUnit->getCompilerInstance(); + + SourceFile *SF = retrieveInputFile(InputFile, CompIns); + if (!SF) { + Receiver(RequestResult::fromError( + "Unable to find input file")); + return; + } + SourceManager &SM = CompIns.getSourceMgr(); - unsigned BufferID = AstUnit->getPrimarySourceFile().getBufferID().value(); + unsigned BufferID = SF->getBufferID().value(); SourceLoc Loc = Lexer::getLocForStartOfToken(SM, BufferID, Offset); if (Loc.isInvalid()) { Receiver(RequestResult::fromError( - "Unable to resolve the start of the token.")); + "Unable to find initial lookup location")); return; } @@ -1555,8 +1592,8 @@ static void resolveCursor( Range.Column = Pair.second; Range.Length = Length; bool CollectRangeStartRefactorings = false; - collectAvailableRefactorings(&AstUnit->getPrimarySourceFile(), Range, - CollectRangeStartRefactorings, Kinds, {}); + collectAvailableRefactorings(SF, Range, CollectRangeStartRefactorings, + Kinds, {}); for (RefactoringKind Kind : Kinds) { Actions.emplace_back(SwiftLangSupport::getUIDForRefactoringKind(Kind), getDescriptiveRefactoringKindName(Kind), @@ -1574,10 +1611,9 @@ static void resolveCursor( // Fall through to collect cursor based refactorings } - auto *File = &AstUnit->getPrimarySourceFile(); ResolvedCursorInfoPtr CursorInfo = - evaluateOrDefault(File->getASTContext().evaluator, - CursorInfoRequest{CursorInfoOwner(File, Loc)}, + evaluateOrDefault(CompIns.getASTContext().evaluator, + CursorInfoRequest{CursorInfoOwner(SF, Loc)}, new ResolvedCursorInfo()); CompilerInvocation CompInvok; @@ -1670,7 +1706,7 @@ static void resolveCursor( } static void computeDiagnostics( - SwiftLangSupport &Lang, StringRef InputFile, SwiftInvocationRef Invok, + SwiftLangSupport &Lang, SwiftInvocationRef Invok, llvm::IntrusiveRefCntPtr FileSystem, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { @@ -1684,8 +1720,7 @@ static void computeDiagnostics( : Receiver(Receiver) {} void handlePrimaryAST(ASTUnitRef AstUnit) override { - unsigned BufferID = - AstUnit->getPrimarySourceFile().getBufferID().value(); + unsigned BufferID = *AstUnit->getPrimarySourceFile().getBufferID(); auto &DiagConsumer = AstUnit->getEditorDiagConsumer(); auto Diagnostics = DiagConsumer.getDiagnosticsForBuffer(BufferID); Receiver(RequestResult::fromResult(Diagnostics)); @@ -1731,19 +1766,24 @@ static void resolveName( void handlePrimaryAST(ASTUnitRef AstUnit) override { auto &CompIns = AstUnit->getCompilerInstance(); - unsigned BufferID = AstUnit->getPrimarySourceFile().getBufferID().value(); - SourceLoc Loc = - Lexer::getLocForStartOfToken(CompIns.getSourceMgr(), BufferID, Offset); + SourceFile *SF = retrieveInputFile(InputFile, CompIns); + if (!SF) { + Receiver(RequestResult::fromError( + "Unable to find input file")); + return; + } + + SourceLoc Loc = Lexer::getLocForStartOfToken(CompIns.getSourceMgr(), + *SF->getBufferID(), Offset); if (Loc.isInvalid()) { Receiver(RequestResult::fromError( "Unable to resolve the start of the token.")); return; } - auto *File = &AstUnit->getPrimarySourceFile(); ResolvedCursorInfoPtr CursorInfo = - evaluateOrDefault(File->getASTContext().evaluator, - CursorInfoRequest{CursorInfoOwner(File, Loc)}, + evaluateOrDefault(CompIns.getASTContext().evaluator, + CursorInfoRequest{CursorInfoOwner(SF, Loc)}, new ResolvedCursorInfo()); if (CursorInfo->isInvalid()) { NameTranslatingInfo Info; @@ -1835,10 +1875,19 @@ resolveRange(SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset, void handlePrimaryAST(ASTUnitRef AstUnit) override { // FIXME: Implement tracing - auto *File = &AstUnit->getPrimarySourceFile(); - ResolvedRangeInfo Info = evaluateOrDefault(File->getASTContext().evaluator, - RangeInfoRequest(RangeInfoOwner({File, Offset, Length})), - ResolvedRangeInfo()); + auto &CompIns = AstUnit->getCompilerInstance(); + + SourceFile *SF = retrieveInputFile(InputFile, CompIns); + if (!SF) { + Receiver( + RequestResult::fromError("Unable to find input file")); + return; + } + + ResolvedRangeInfo Info = evaluateOrDefault( + CompIns.getASTContext().evaluator, + RangeInfoRequest(RangeInfoOwner({SF, Offset, Length})), + ResolvedRangeInfo()); CompilerInvocation CompInvok; ASTInvok->applyTo(CompInvok); @@ -1938,18 +1987,19 @@ static void deliverCursorInfoResults( } void SwiftLangSupport::getCursorInfo( - StringRef InputFile, unsigned Offset, unsigned Length, bool Actionables, - bool SymbolGraph, bool CancelOnSubsequentRequest, - ArrayRef Args, Optional vfsOptions, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + unsigned Length, bool Actionables, bool SymbolGraph, + bool CancelOnSubsequentRequest, ArrayRef Args, + Optional vfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { std::string error; - auto fileSystem = getFileSystem(vfsOptions, InputFile, error); + auto fileSystem = getFileSystem(vfsOptions, PrimaryFilePath, error); if (!fileSystem) return Receiver(RequestResult::fromError(error)); - if (auto IFaceGenRef = IFaceGenContexts.get(InputFile)) { + if (auto IFaceGenRef = IFaceGenContexts.get(PrimaryFilePath)) { IFaceGenRef->accessASTAsync([this, IFaceGenRef, Offset, Actionables, SymbolGraph, Receiver] { SwiftInterfaceGenContext::ResolvedEntity Entity; @@ -1991,7 +2041,7 @@ void SwiftLangSupport::getCursorInfo( std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, InputFile, fileSystem, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, fileSystem, Error); if (!Error.empty()) { LOG_WARN_FUNC("error creating ASTInvocation: " << Error); } @@ -2001,14 +2051,18 @@ void SwiftLangSupport::getCursorInfo( } bool SolverBasedProducedResult = false; - std::string InputFileError; - llvm::SmallString<64> RealInputFilePath; - fileSystem->getRealPath(InputFile, RealInputFilePath); - std::unique_ptr UnresolvedInputFile = - getASTManager()->getMemoryBuffer(RealInputFilePath, fileSystem, - InputFileError); - // The solver-based implementation doesn't support range based cursor info. - if (UnresolvedInputFile && Length == 0) { + // Solver based cursor info cannot handle generated buffers or range based + // cursor info. + std::unique_ptr InputBuffer; + if (InputBufferName.empty() && Length == 0) { + std::string InputFileError; + llvm::SmallString<128> RealInputFilePath; + fileSystem->getRealPath(PrimaryFilePath, RealInputFilePath); + InputBuffer = getASTManager()->getMemoryBuffer(RealInputFilePath, + fileSystem, InputFileError); + } + + if (InputBuffer) { auto SolverBasedReceiver = [&](const RequestResult &Res) { SolverBasedProducedResult = true; Receiver(Res); @@ -2018,7 +2072,7 @@ void SwiftLangSupport::getCursorInfo( Invok->applyTo(CompInvok); performWithParamsToCompletionLikeOperation( - UnresolvedInputFile.get(), Offset, + InputBuffer.get(), Offset, /*InsertCodeCompletionToken=*/false, Args, fileSystem, CancellationToken, [&](CancellableResult ParmsResult) { @@ -2037,19 +2091,20 @@ void SwiftLangSupport::getCursorInfo( } if (!SolverBasedProducedResult) { - resolveCursor(*this, InputFile, Offset, Length, Actionables, SymbolGraph, - Invok, /*TryExistingAST=*/true, CancelOnSubsequentRequest, - fileSystem, CancellationToken, Receiver); + resolveCursor(*this, InputBufferName, Offset, Length, Actionables, + SymbolGraph, Invok, /*TryExistingAST=*/true, + CancelOnSubsequentRequest, fileSystem, CancellationToken, + Receiver); } } void SwiftLangSupport::getDiagnostics( - StringRef InputFile, ArrayRef Args, + StringRef PrimaryFilePath, ArrayRef Args, Optional VfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { std::string FileSystemError; - auto FileSystem = getFileSystem(VfsOptions, InputFile, FileSystemError); + auto FileSystem = getFileSystem(VfsOptions, PrimaryFilePath, FileSystemError); if (!FileSystem) { Receiver(RequestResult::fromError(FileSystemError)); return; @@ -2057,7 +2112,7 @@ void SwiftLangSupport::getDiagnostics( std::string InvocationError; SwiftInvocationRef Invok = ASTMgr->getTypecheckInvocation( - Args, InputFile, FileSystem, InvocationError); + Args, PrimaryFilePath, FileSystem, InvocationError); if (!InvocationError.empty()) { LOG_WARN_FUNC("error creating ASTInvocation: " << InvocationError); } @@ -2066,16 +2121,15 @@ void SwiftLangSupport::getDiagnostics( return; } - computeDiagnostics(*this, InputFile, Invok, FileSystem, CancellationToken, - Receiver); + computeDiagnostics(*this, Invok, FileSystem, CancellationToken, Receiver); } void SwiftLangSupport::getRangeInfo( - StringRef InputFile, unsigned Offset, unsigned Length, - bool CancelOnSubsequentRequest, ArrayRef Args, - SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + unsigned Length, bool CancelOnSubsequentRequest, + ArrayRef Args, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { - if (IFaceGenContexts.get(InputFile)) { + if (IFaceGenContexts.get(InputBufferName)) { // FIXME: return range info for generated interfaces. Receiver(RequestResult::fromError( "Range info for generated interfaces is not implemented.")); @@ -2083,7 +2137,7 @@ void SwiftLangSupport::getRangeInfo( } std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, InputFile, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error); if (!Invok) { LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error); Receiver(RequestResult::fromError(Error)); @@ -2093,8 +2147,9 @@ void SwiftLangSupport::getRangeInfo( Receiver(RequestResult::fromError("Invalid range length.")); return; } - resolveRange(*this, InputFile, Offset, Length, Invok, /*TryExistingAST=*/true, - CancelOnSubsequentRequest, CancellationToken, Receiver); + resolveRange(*this, InputBufferName, Offset, Length, Invok, + /*TryExistingAST=*/true, CancelOnSubsequentRequest, + CancellationToken, Receiver); } void SwiftLangSupport::getNameInfo( @@ -2283,17 +2338,18 @@ static void resolveCursorFromUSR( } void SwiftLangSupport::getCursorInfoFromUSR( - StringRef filename, StringRef USR, bool CancelOnSubsequentRequest, - ArrayRef Args, Optional vfsOptions, + StringRef PrimaryFilePath, StringRef InputBufferName, StringRef USR, + bool CancelOnSubsequentRequest, ArrayRef Args, + Optional vfsOptions, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { std::string error; - auto fileSystem = getFileSystem(vfsOptions, filename, error); + auto fileSystem = getFileSystem(vfsOptions, PrimaryFilePath, error); if (!fileSystem) return Receiver(RequestResult::fromError(error)); - if (auto IFaceGenRef = IFaceGenContexts.get(filename)) { + if (auto IFaceGenRef = IFaceGenContexts.get(PrimaryFilePath)) { LOG_WARN_FUNC("Info from usr for generated interface not implemented yet."); CursorInfoData Info; Info.InternalDiagnostic = "Info for generated interfaces not implemented."; @@ -2303,16 +2359,16 @@ void SwiftLangSupport::getCursorInfoFromUSR( std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, filename, fileSystem, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, fileSystem, Error); if (!Invok) { LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error); Receiver(RequestResult::fromError(Error)); return; } - resolveCursorFromUSR(*this, filename, USR, Invok, /*TryExistingAST=*/true, - CancelOnSubsequentRequest, fileSystem, CancellationToken, - Receiver); + resolveCursorFromUSR(*this, InputBufferName, USR, Invok, + /*TryExistingAST=*/true, CancelOnSubsequentRequest, + fileSystem, CancellationToken, Receiver); } //===----------------------------------------------------------------------===// @@ -2457,13 +2513,14 @@ class RelatedIdScanner : public SourceEntityWalker { } // end anonymous namespace void SwiftLangSupport::findRelatedIdentifiersInFile( - StringRef InputFile, unsigned Offset, bool CancelOnSubsequentRequest, - ArrayRef Args, SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset, + bool CancelOnSubsequentRequest, ArrayRef Args, + SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, InputFile, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error); if (!Invok) { LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error); Receiver(RequestResult::fromError(Error)); @@ -2471,34 +2528,42 @@ void SwiftLangSupport::findRelatedIdentifiersInFile( } class RelatedIdConsumer : public SwiftASTConsumer { + std::string InputFile; unsigned Offset; std::function &)> Receiver; SwiftInvocationRef Invok; public: - RelatedIdConsumer(unsigned Offset, - std::function &)> Receiver, - SwiftInvocationRef Invok) - : Offset(Offset), Receiver(std::move(Receiver)), Invok(Invok) { } + RelatedIdConsumer( + StringRef InputFile, unsigned Offset, + std::function &)> Receiver, + SwiftInvocationRef Invok) + : InputFile(InputFile.str()), Offset(Offset), + Receiver(std::move(Receiver)), Invok(Invok) {} // FIXME: Don't silently eat errors here. void handlePrimaryAST(ASTUnitRef AstUnit) override { auto &CompInst = AstUnit->getCompilerInstance(); - auto &SrcFile = AstUnit->getPrimarySourceFile(); + auto *SrcFile = retrieveInputFile(InputFile, CompInst); + if (!SrcFile) { + Receiver(RequestResult::fromError( + "Unable to find input file")); + return; + } SmallVector, 8> Ranges; auto Action = [&]() { - unsigned BufferID = SrcFile.getBufferID().value(); + unsigned BufferID = SrcFile->getBufferID().value(); SourceLoc Loc = Lexer::getLocForStartOfToken(CompInst.getSourceMgr(), BufferID, Offset); if (Loc.isInvalid()) return; ResolvedCursorInfoPtr CursorInfo = - evaluateOrDefault(SrcFile.getASTContext().evaluator, - CursorInfoRequest{CursorInfoOwner(&SrcFile, Loc)}, + evaluateOrDefault(CompInst.getASTContext().evaluator, + CursorInfoRequest{CursorInfoOwner(SrcFile, Loc)}, new ResolvedCursorInfo()); auto ValueRefCursorInfo = dyn_cast(CursorInfo); @@ -2539,7 +2604,8 @@ void SwiftLangSupport::findRelatedIdentifiersInFile( continue; } - RelatedIdScanner Scanner(SrcFile, BufferID, Dcl, RangesSet, Worklist); + RelatedIdScanner Scanner(*SrcFile, BufferID, Dcl, RangesSet, + Worklist); if (auto *Case = getCaseStmtOfCanonicalVar(Dcl)) { Scanner.walk(Case); @@ -2550,7 +2616,7 @@ void SwiftLangSupport::findRelatedIdentifiersInFile( Dcl->getDeclContext()->getLocalContext()) { Scanner.walk(LocalDC); } else { - Scanner.walk(SrcFile); + Scanner.walk(*SrcFile); } } @@ -2592,7 +2658,8 @@ void SwiftLangSupport::findRelatedIdentifiersInFile( } }; - auto Consumer = std::make_shared(Offset, Receiver, Invok); + auto Consumer = std::make_shared(InputBufferName, Offset, + Receiver, Invok); /// FIXME: When request cancellation is implemented and Xcode adopts it, /// don't use 'OncePerASTToken'. static const char OncePerASTToken = 0; @@ -2607,16 +2674,14 @@ void SwiftLangSupport::findRelatedIdentifiersInFile( namespace { class IfConfigScanner : public SourceEntityWalker { - SmallVectorImpl &Infos; - SourceManager &SourceMgr; unsigned BufferID = -1; + SmallVectorImpl &Infos; bool Cancelled = false; public: - explicit IfConfigScanner(SourceFile &SrcFile, unsigned BufferID, + explicit IfConfigScanner(unsigned BufferID, SmallVectorImpl &Infos) - : Infos(Infos), SourceMgr(SrcFile.getASTContext().SourceMgr), - BufferID(BufferID) {} + : BufferID(BufferID), Infos(Infos) {} private: bool walkToDeclPre(Decl *D, CharSourceRange Range) override { @@ -2625,7 +2690,8 @@ class IfConfigScanner : public SourceEntityWalker { if (auto *IfDecl = dyn_cast(D)) { for (auto &Clause : IfDecl->getClauses()) { - unsigned Offset = SourceMgr.getLocOffsetInBuffer(Clause.Loc, BufferID); + unsigned Offset = D->getASTContext().SourceMgr.getLocOffsetInBuffer( + Clause.Loc, BufferID); Infos.emplace_back(Offset, Clause.isActive); } } @@ -2637,13 +2703,13 @@ class IfConfigScanner : public SourceEntityWalker { } // end anonymous namespace void SwiftLangSupport::findActiveRegionsInFile( - StringRef InputFile, ArrayRef Args, - SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, InputFile, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error); if (!Invok) { LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error); Receiver(RequestResult::fromError(Error)); @@ -2651,23 +2717,29 @@ void SwiftLangSupport::findActiveRegionsInFile( } class IfConfigConsumer : public SwiftASTConsumer { + std::string InputFile; std::function &)> Receiver; SwiftInvocationRef Invok; public: IfConfigConsumer( + StringRef InputFile, std::function &)> Receiver, SwiftInvocationRef Invok) - : Receiver(std::move(Receiver)), Invok(Invok) {} + : InputFile(InputFile.str()), Receiver(std::move(Receiver)), + Invok(Invok) {} void handlePrimaryAST(ASTUnitRef AstUnit) override { - auto &SrcFile = AstUnit->getPrimarySourceFile(); - SmallVector Configs; - auto BufferID = SrcFile.getBufferID(); - if (!BufferID) + auto *SF = retrieveInputFile(InputFile, AstUnit->getCompilerInstance()); + if (!SF) { + Receiver(RequestResult::fromError( + "Unable to find input file")); return; - IfConfigScanner Scanner(SrcFile, *BufferID, Configs); - Scanner.walk(SrcFile); + } + + SmallVector Configs; + IfConfigScanner Scanner(*SF->getBufferID(), Configs); + Scanner.walk(SF); // Sort by offset so nested decls are reported // in source order (not tree order). @@ -2690,7 +2762,8 @@ void SwiftLangSupport::findActiveRegionsInFile( } }; - auto Consumer = std::make_shared(Receiver, Invok); + auto Consumer = + std::make_shared(InputBufferName, Receiver, Invok); ASTMgr->processASTAsync(Invok, std::move(Consumer), /*OncePerASTToken=*/nullptr, CancellationToken, llvm::vfs::getRealFileSystem()); @@ -2710,12 +2783,12 @@ static RefactoringKind getIDERefactoringKind(SemanticRefactoringInfo Info) { } void SwiftLangSupport::semanticRefactoring( - StringRef PrimaryFile, SemanticRefactoringInfo Info, + StringRef PrimaryFilePath, SemanticRefactoringInfo Info, ArrayRef Args, SourceKitCancellationToken CancellationToken, CategorizedEditsReceiver Receiver) { std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, PrimaryFile, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error); if (!Invok) { LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error); Receiver(RequestResult>::fromError(Error)); @@ -2736,20 +2809,17 @@ void SwiftLangSupport::semanticRefactoring( RequestRefactoringEditConsumer EditConsumer(Receiver); auto &CompIns = AstUnit->getCompilerInstance(); - auto &SM = CompIns.getSourceMgr(); RefactoringOptions Opts(getIDERefactoringKind(Info)); - Optional BufferID; - if (Info.SourceFile.empty()) { - BufferID = AstUnit->getPrimarySourceFile().getBufferID(); - } else { - BufferID = SM.getIDForBufferIdentifier(Info.SourceFile); - } - if (!BufferID) + SourceFile *SF = retrieveInputFile(Info.InputBufferName, CompIns); + if (!SF) { + Receiver(RequestResult>::fromError( + "Unable to find input file")); return; + } - Opts.Range.BufferID = *BufferID; + Opts.Range.BufferID = *SF->getBufferID(); Opts.Range.Line = Info.Line; Opts.Range.Column = Info.Column; Opts.Range.Length = Info.Length; @@ -2778,14 +2848,15 @@ void SwiftLangSupport::semanticRefactoring( } void SwiftLangSupport::collectExpressionTypes( - StringRef FileName, ArrayRef Args, - ArrayRef ExpectedProtocols, bool FullyQualified, - bool CanonicalType, SourceKitCancellationToken CancellationToken, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, ArrayRef ExpectedProtocols, + bool FullyQualified, bool CanonicalType, + SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, FileName, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error); if (!Invok) { LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error); Receiver(RequestResult::fromError(Error)); @@ -2794,6 +2865,7 @@ void SwiftLangSupport::collectExpressionTypes( assert(Invok); class ExpressionTypeCollector: public SwiftASTConsumer { std::function &)> Receiver; + std::string InputFile; std::vector ExpectedProtocols; bool FullyQualified; bool CanonicalType; @@ -2801,13 +2873,20 @@ void SwiftLangSupport::collectExpressionTypes( ExpressionTypeCollector( std::function &)> Receiver, - ArrayRef ExpectedProtocols, bool FullyQualified, - bool CanonicalType) - : Receiver(std::move(Receiver)), + StringRef InputFile, ArrayRef ExpectedProtocols, + bool FullyQualified, bool CanonicalType) + : Receiver(std::move(Receiver)), InputFile(InputFile.str()), ExpectedProtocols(ExpectedProtocols.vec()), FullyQualified(FullyQualified), CanonicalType(CanonicalType) {} void handlePrimaryAST(ASTUnitRef AstUnit) override { - auto *SF = AstUnit->getCompilerInstance().getPrimarySourceFile(); + SourceFile *SF = + retrieveInputFile(InputFile, AstUnit->getCompilerInstance()); + if (!SF) { + Receiver(RequestResult::fromError( + "Unable to find input file")); + return; + } + std::vector Scratch; llvm::SmallString<256> TypeBuffer; llvm::raw_svector_ostream OS(TypeBuffer); @@ -2833,7 +2912,8 @@ void SwiftLangSupport::collectExpressionTypes( } }; auto Collector = std::make_shared( - Receiver, ExpectedProtocols, FullyQualified, CanonicalType); + Receiver, InputBufferName, ExpectedProtocols, FullyQualified, + CanonicalType); /// FIXME: When request cancellation is implemented and Xcode adopts it, /// don't use 'OncePerASTToken'. static const char OncePerASTToken = 0; @@ -2843,13 +2923,14 @@ void SwiftLangSupport::collectExpressionTypes( } void SwiftLangSupport::collectVariableTypes( - StringRef FileName, ArrayRef Args, Optional Offset, + StringRef PrimaryFilePath, StringRef InputBufferName, + ArrayRef Args, Optional Offset, Optional Length, bool FullyQualified, SourceKitCancellationToken CancellationToken, std::function &)> Receiver) { std::string Error; SwiftInvocationRef Invok = - ASTMgr->getTypecheckInvocation(Args, FileName, Error); + ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error); if (!Invok) { LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error); Receiver(RequestResult::fromError(Error)); @@ -2860,6 +2941,7 @@ void SwiftLangSupport::collectVariableTypes( class VariableTypeCollectorASTConsumer : public SwiftASTConsumer { private: std::function &)> Receiver; + std::string InputFile; Optional Offset; Optional Length; bool FullyQualified; @@ -2868,14 +2950,19 @@ void SwiftLangSupport::collectVariableTypes( VariableTypeCollectorASTConsumer( std::function &)> Receiver, - Optional Offset, Optional Length, - bool FullyQualified) - : Receiver(std::move(Receiver)), Offset(Offset), Length(Length), - FullyQualified(FullyQualified) {} + StringRef InputFile, Optional Offset, + Optional Length, bool FullyQualified) + : Receiver(std::move(Receiver)), InputFile(InputFile), Offset(Offset), + Length(Length), FullyQualified(FullyQualified) {} void handlePrimaryAST(ASTUnitRef AstUnit) override { auto &CompInst = AstUnit->getCompilerInstance(); - auto *SF = CompInst.getPrimarySourceFile(); + SourceFile *SF = retrieveInputFile(InputFile, CompInst); + if (!SF) { + Receiver(RequestResult::fromError( + "Unable to find input file")); + return; + } // Construct the range for which variable types are to be queried. If // offset/length are unset, the (default) range will be used, which @@ -2914,7 +3001,7 @@ void SwiftLangSupport::collectVariableTypes( }; auto Collector = std::make_shared( - Receiver, Offset, Length, FullyQualified); + Receiver, InputBufferName, Offset, Length, FullyQualified); /// FIXME: When request cancellation is implemented and Xcode adopts it, /// don't use 'OncePerASTToken'. static const char OncePerASTToken = 0; diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp index 22aef88e5ba81..2db2dc7206c92 100644 --- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp +++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp @@ -533,8 +533,6 @@ static void setRefactoringFields(sourcekitd_object_t &Req, TestOptions Opts, sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestSemanticRefactoring); sourcekitd_request_dictionary_set_uid(Req, KeyActionUID, RefactoringKind); - sourcekitd_request_dictionary_set_string(Req, KeyPrimaryFile, - Opts.PrimaryFile.c_str()); sourcekitd_request_dictionary_set_string(Req, KeyName, Opts.Name.c_str()); sourcekitd_request_dictionary_set_int64(Req, KeyLine, line); sourcekitd_request_dictionary_set_int64(Req, KeyColumn, col); @@ -1121,6 +1119,11 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) { Opts.SourceFile.c_str()); } + if (!Opts.PrimaryFile.empty()) { + sourcekitd_request_dictionary_set_string(Req, KeyPrimaryFile, + Opts.PrimaryFile.c_str()); + } + if (Opts.SourceText) { sourcekitd_request_dictionary_set_string(Req, KeySourceText, Opts.SourceText->c_str()); diff --git a/tools/SourceKit/tools/sourcekitd/lib/Service/Requests.cpp b/tools/SourceKit/tools/sourcekitd/lib/Service/Requests.cpp index 3f146b2b07cdc..1d4715d46adf5 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/Service/Requests.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/Service/Requests.cpp @@ -204,13 +204,16 @@ static void reportRangeInfo(const RequestResult &Result, ResponseRece static void reportNameInfo(const RequestResult &Result, ResponseReceiver Rec); -static void findRelatedIdents(StringRef Filename, int64_t Offset, +static void findRelatedIdents(StringRef PrimaryFilePath, + StringRef InputBufferName, int64_t Offset, bool CancelOnSubsequentRequest, ArrayRef Args, SourceKitCancellationToken CancellationToken, ResponseReceiver Rec); -static void findActiveRegions(StringRef Filename, ArrayRef Args, +static void findActiveRegions(StringRef PrimaryFilePath, + StringRef InputBufferName, + ArrayRef Args, SourceKitCancellationToken CancellationToken, ResponseReceiver Rec); @@ -454,34 +457,44 @@ getInputBufForRequestOrEmitError(const RequestDict &Req, return buf; } -/// Get 'key.primary_file' value as a string. If it's missing, reply with an -/// error and return \c None. +/// Retrieves `key.primary_file` value as a string, or `key.sourcefile` if +/// missing. If both are missing, reply with an error and return \c None. /// -/// Fallsback to 'key.sourcefile' for compatibility. +/// The "primary file" is the file to mark as `-primary-file` when building +/// the corresponding AST for this request. The "input file" is the file to +/// resolve any offset or line/column in. These were (prior to +/// \c GeneratedSourceInfo) always the same, but the input file is now able to +/// be a generated buffer name (where that buffer is created during the AST +/// build). static Optional -getPrimaryFileForRequestOrEmitError(const RequestDict &Req, - ResponseReceiver Rec) { - Optional PrimaryFile = Req.getString(KeyPrimaryFile); - if (!PrimaryFile) { +getPrimaryFilePathForRequestOrEmitError(const RequestDict &Req, + ResponseReceiver Rec) { + Optional PrimaryFilePath = Req.getString(KeyPrimaryFile); + if (!PrimaryFilePath) { // Fallback to the old key.sourcefile - PrimaryFile = Req.getString(KeySourceFile); - if (!PrimaryFile) { - Rec(createErrorRequestInvalid("missing 'key.primary_file'")); + PrimaryFilePath = Req.getString(KeySourceFile); + if (!PrimaryFilePath) { + Rec(createErrorRequestInvalid( + "missing 'key.primary_file' and 'key.sourcefile'")); } } - return PrimaryFile; + return PrimaryFilePath; } -/// Get 'key.source_file' value as a string. If it's missing, reply with an -/// error and return \c None. -static Optional -getSourceFileForRequestOrEmitError(const RequestDict &Req, - ResponseReceiver Rec) { - Optional SourceFile = Req.getString(KeySourceFile); - if (!SourceFile) { - Rec(createErrorRequestInvalid("missing 'key.sourcefile'")); - } - return SourceFile; +/// Retrieves `key.sourcefile` only if it is different to `key.primary_file`. +/// Returns an empty string if it's the same or if it was missing. Callers are +/// expected to pull the primary file from the AST if the input file is +/// empty. +/// +/// See \c getPrimaryFilePathForRequestOrEmitError for an explanation of primary +/// vs input file. +static StringRef getInputBufferNameForRequest(const RequestDict &Req, + ResponseReceiver Rec) { + Optional PrimaryFilePath = Req.getString(KeyPrimaryFile); + Optional InputBufferName = Req.getString(KeySourceFile); + if (!PrimaryFilePath || PrimaryFilePath == InputBufferName) + return ""; + return InputBufferName.value_or(""); } /// Get compiler arguments from 'key.compilerargs' in \p Req . If the key is @@ -1378,13 +1391,15 @@ static void handleRequestIndex(const RequestDict &Req, return; handleSemanticRequest(Req, Rec, [Req, Rec]() { - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; - return Rec(indexSource(*SourceFile, Args)); + return Rec(indexSource(*PrimaryFilePath, Args)); }); } @@ -1396,9 +1411,13 @@ handleRequestCursorInfo(const RequestDict &Req, LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); Optional vfsOptions = getVFSOptions(Req); - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + + StringRef InputBufferName = getInputBufferNameForRequest(Req, Rec); + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; @@ -1417,8 +1436,8 @@ handleRequestCursorInfo(const RequestDict &Req, int64_t SymbolGraph = false; Req.getInt64(KeyRetrieveSymbolGraph, SymbolGraph, /*isOptional=*/true); return Lang.getCursorInfo( - *SourceFile, Offset, Length, Actionables, SymbolGraph, - CancelOnSubsequentRequest, Args, std::move(vfsOptions), + *PrimaryFilePath, InputBufferName, Offset, Length, Actionables, + SymbolGraph, CancelOnSubsequentRequest, Args, std::move(vfsOptions), CancellationToken, [Rec](const RequestResult &Result) { reportCursorInfo(Result, Rec); @@ -1426,8 +1445,8 @@ handleRequestCursorInfo(const RequestDict &Req, } if (auto USR = Req.getString(KeyUSR)) { return Lang.getCursorInfoFromUSR( - *SourceFile, *USR, CancelOnSubsequentRequest, Args, - std::move(vfsOptions), CancellationToken, + *PrimaryFilePath, InputBufferName, *USR, CancelOnSubsequentRequest, + Args, std::move(vfsOptions), CancellationToken, [Rec](const RequestResult &Result) { reportCursorInfo(Result, Rec); }); @@ -1446,12 +1465,18 @@ static void handleRequestRangeInfo(const RequestDict &Req, handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + + StringRef InputBufferName = getInputBufferNameForRequest(Req, Rec); + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; + int64_t Offset; int64_t Length; // For backwards compatibility, the default is 1. @@ -1460,11 +1485,12 @@ static void handleRequestRangeInfo(const RequestDict &Req, /*isOptional=*/true); if (!Req.getInt64(KeyOffset, Offset, /*isOptional=*/false)) { if (!Req.getInt64(KeyLength, Length, /*isOptional=*/false)) { - return Lang.getRangeInfo( - *SourceFile, Offset, Length, CancelOnSubsequentRequest, Args, - CancellationToken, [Rec](const RequestResult &Result) { - reportRangeInfo(Result, Rec); - }); + return Lang.getRangeInfo(*PrimaryFilePath, InputBufferName, Offset, + Length, CancelOnSubsequentRequest, Args, + CancellationToken, + [Rec](const RequestResult &Result) { + reportRangeInfo(Result, Rec); + }); } } @@ -1481,9 +1507,13 @@ handleRequestSemanticRefactoring(const RequestDict &Req, return; handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { - auto PrimaryFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!PrimaryFile) + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + + StringRef InputBufferName = getInputBufferNameForRequest(Req, Rec); + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; @@ -1505,24 +1535,18 @@ handleRequestSemanticRefactoring(const RequestDict &Req, if (Info.Kind == SemanticRefactoringKind::None) return Rec(createErrorRequestInvalid("'key.actionuid' isn't recognized")); - auto SourceFile = getSourceFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) - return; - if (!Req.getInt64(KeyLine, Line, /*isOptional=*/false)) { if (!Req.getInt64(KeyColumn, Column, /*isOptional=*/false)) { Req.getInt64(KeyLength, Length, /*isOptional=*/true); if (auto N = Req.getString(KeyName)) Info.PreferredName = *N; LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); - if (*PrimaryFile != *SourceFile) { - Info.SourceFile = *SourceFile; - } + Info.InputBufferName = InputBufferName; Info.Line = Line; Info.Column = Column; Info.Length = Length; return Lang.semanticRefactoring( - *PrimaryFile, Info, Args, CancellationToken, + *PrimaryFilePath, Info, Args, CancellationToken, [Rec](const RequestResult> &Result) { Rec(createCategorizedEditsResponse(Result)); }); @@ -1541,9 +1565,14 @@ handleRequestCollectExpressionType(const RequestDict &Req, handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + + StringRef InputBufferName = getInputBufferNameForRequest(Req, Rec); + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; @@ -1556,8 +1585,8 @@ handleRequestCollectExpressionType(const RequestDict &Req, int64_t CanonicalTy = false; Req.getInt64(KeyCanonicalizeType, CanonicalTy, /*isOptional=*/true); return Lang.collectExpressionTypes( - *SourceFile, Args, ExpectedProtocols, FullyQualified, CanonicalTy, - CancellationToken, + *PrimaryFilePath, InputBufferName, Args, ExpectedProtocols, + FullyQualified, CanonicalTy, CancellationToken, [Rec](const RequestResult &Result) { reportExpressionTypeInfo(Result, Rec); }); @@ -1573,12 +1602,18 @@ handleRequestCollectVariableType(const RequestDict &Req, handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + + StringRef InputBufferName = getInputBufferNameForRequest(Req, Rec); + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; + Optional Offset = Req.getOptionalInt64(KeyOffset).transform( [](int64_t v) -> unsigned { return v; }); Optional Length = Req.getOptionalInt64(KeyLength).transform( @@ -1586,7 +1621,8 @@ handleRequestCollectVariableType(const RequestDict &Req, int64_t FullyQualified = false; Req.getInt64(KeyFullyQualified, FullyQualified, /*isOptional=*/true); return Lang.collectVariableTypes( - *SourceFile, Args, Offset, Length, FullyQualified, CancellationToken, + *PrimaryFilePath, InputBufferName, Args, Offset, Length, FullyQualified, + CancellationToken, [Rec](const RequestResult &Result) { reportVariableTypeInfo(Result, Rec); }); @@ -1601,12 +1637,14 @@ handleRequestFindLocalRenameRanges(const RequestDict &Req, return; handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + auto PrimaryFilePath = getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; + int64_t Line = 0, Column = 0, Length = 0; if (Req.getInt64(KeyLine, Line, /*isOptional=*/false)) return Rec(createErrorRequestInvalid("'key.line' is required")); @@ -1616,7 +1654,7 @@ handleRequestFindLocalRenameRanges(const RequestDict &Req, LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); return Lang.findLocalRenameRanges( - *SourceFile, Line, Column, Length, Args, CancellationToken, + *PrimaryFilePath, Line, Column, Length, Args, CancellationToken, [Rec](const RequestResult> &Result) { Rec(createCategorizedRenameRangesResponse(Result)); }); @@ -1631,12 +1669,14 @@ handleRequestNameTranslation(const RequestDict &Req, return; handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + auto PrimaryFilePath = getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; + LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); int64_t Offset; if (Req.getInt64(KeyOffset, Offset, /*isOptional=*/false)) { @@ -1677,7 +1717,7 @@ handleRequestNameTranslation(const RequestDict &Req, llvm::transform(Selectors, std::back_inserter(Input.ArgNames), [](const char *C) { return StringRef(C); }); return Lang.getNameInfo( - *SourceFile, Offset, Input, Args, CancellationToken, + *PrimaryFilePath, Offset, Input, Args, CancellationToken, [Rec](const RequestResult &Result) { reportNameInfo(Result, Rec); }); @@ -1692,12 +1732,17 @@ handleRequestRelatedIdents(const RequestDict &Req, return; handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + + StringRef InputBufferName = getInputBufferNameForRequest(Req, Rec); + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; + int64_t Offset; if (Req.getInt64(KeyOffset, Offset, /*isOptional=*/false)) return Rec(createErrorRequestInvalid("missing 'key.offset'")); @@ -1707,8 +1752,9 @@ handleRequestRelatedIdents(const RequestDict &Req, Req.getInt64(KeyCancelOnSubsequentRequest, CancelOnSubsequentRequest, /*isOptional=*/true); - return findRelatedIdents(*SourceFile, Offset, CancelOnSubsequentRequest, - Args, CancellationToken, Rec); + return findRelatedIdents(*PrimaryFilePath, InputBufferName, Offset, + CancelOnSubsequentRequest, Args, CancellationToken, + Rec); }); } @@ -1720,14 +1766,19 @@ handleRequestActiveRegions(const RequestDict &Req, return; handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { - auto SourceFile = getSourceFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + Optional PrimaryFilePath = + getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + + StringRef InputBufferName = getInputBufferNameForRequest(Req, Rec); + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; - return findActiveRegions(*SourceFile, Args, CancellationToken, Rec); + return findActiveRegions(*PrimaryFilePath, InputBufferName, Args, + CancellationToken, Rec); }); } @@ -1737,14 +1788,16 @@ handleRequestDiagnostics(const RequestDict &Req, ResponseReceiver Rec) { handleSemanticRequest(Req, Rec, [Req, CancellationToken, Rec]() { Optional vfsOptions = getVFSOptions(Req); - auto SourceFile = getPrimaryFileForRequestOrEmitError(Req, Rec); - if (!SourceFile) + auto PrimaryFilePath = getPrimaryFilePathForRequestOrEmitError(Req, Rec); + if (!PrimaryFilePath) return; + SmallVector Args; if (getCompilerArgumentsForRequestOrEmitError(Req, Args, Rec)) return; + LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); - Lang.getDiagnostics(*SourceFile, Args, std::move(vfsOptions), + Lang.getDiagnostics(*PrimaryFilePath, Args, std::move(vfsOptions), CancellationToken, [Rec](const RequestResult &Result) { reportDiagnostics(Result, Rec); @@ -2598,15 +2651,16 @@ reportVariableTypeInfo(const RequestResult &Result, // FindRelatedIdents //===----------------------------------------------------------------------===// -static void findRelatedIdents(StringRef Filename, int64_t Offset, +static void findRelatedIdents(StringRef PrimaryFilePath, + StringRef InputBufferName, int64_t Offset, bool CancelOnSubsequentRequest, ArrayRef Args, SourceKitCancellationToken CancellationToken, ResponseReceiver Rec) { LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); Lang.findRelatedIdentifiersInFile( - Filename, Offset, CancelOnSubsequentRequest, Args, CancellationToken, - [Rec](const RequestResult &Result) { + PrimaryFilePath, InputBufferName, Offset, CancelOnSubsequentRequest, Args, + CancellationToken, [Rec](const RequestResult &Result) { if (Result.isCancelled()) return Rec(createErrorRequestCancelled()); if (Result.isError()) @@ -2630,13 +2684,15 @@ static void findRelatedIdents(StringRef Filename, int64_t Offset, // FindActiveRegions //===----------------------------------------------------------------------===// -static void findActiveRegions(StringRef Filename, ArrayRef Args, +static void findActiveRegions(StringRef PrimaryFilePath, + StringRef InputBufferName, + ArrayRef Args, SourceKitCancellationToken CancellationToken, ResponseReceiver Rec) { LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); Lang.findActiveRegionsInFile( - Filename, Args, CancellationToken, + PrimaryFilePath, InputBufferName, Args, CancellationToken, [Rec](const RequestResult &Result) { if (Result.isCancelled()) return Rec(createErrorRequestCancelled()); diff --git a/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp b/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp index ff2fef79f1036..2ce72abede215 100644 --- a/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp +++ b/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp @@ -163,7 +163,7 @@ class CursorInfoTest : public ::testing::Test { TestCursorInfo TestInfo; getLang().getCursorInfo( - DocName, Offset, /*Length=*/0, /*Actionables=*/false, + DocName, DocName, Offset, /*Length=*/0, /*Actionables=*/false, /*SymbolGraph=*/false, CancelOnSubsequentRequest, Args, /*vfsOptions=*/None, CancellationToken, [&](const RequestResult &Result) { @@ -448,7 +448,7 @@ TEST_F(CursorInfoTest, CursorInfoCancelsPreviousRequest) { // cancelled as the next cursor info (which is faster) gets requested. Semaphore FirstCursorInfoSema(0); getLang().getCursorInfo( - SlowDocName, SlowOffset, /*Length=*/0, /*Actionables=*/false, + SlowDocName, SlowDocName, SlowOffset, /*Length=*/0, /*Actionables=*/false, /*SymbolGraph=*/false, /*CancelOnSubsequentRequest=*/true, ArgsForSlow, /*vfsOptions=*/None, /*CancellationToken=*/nullptr, [&](const RequestResult &Result) { @@ -491,7 +491,7 @@ TEST_F(CursorInfoTest, CursorInfoCancellation) { // cancelled as the next cursor info (which is faster) gets requested. Semaphore CursorInfoSema(0); getLang().getCursorInfo( - SlowDocName, SlowOffset, /*Length=*/0, /*Actionables=*/false, + SlowDocName, SlowDocName, SlowOffset, /*Length=*/0, /*Actionables=*/false, /*SymbolGraph=*/false, /*CancelOnSubsequentRequest=*/false, ArgsForSlow, /*vfsOptions=*/None, /*CancellationToken=*/CancellationToken, [&](const RequestResult &Result) {