mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #63714 from ahoppen/ahoppen/ideinspectiontarget-charsourcerange
[IDE] Check whether an AST node contains the IDE inspection point based on `CharSourceRange`
This commit is contained in:
@@ -214,6 +214,13 @@ public:
|
|||||||
(isBeforeInBuffer(R.Start, Loc) && isBeforeInBuffer(Loc, R.End));
|
(isBeforeInBuffer(R.Start, Loc) && isBeforeInBuffer(Loc, R.End));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if range \c R contains the location \c Loc. The location
|
||||||
|
/// \c Loc should point at the beginning of the token.
|
||||||
|
bool rangeContainsTokenLoc(CharSourceRange R, SourceLoc Loc) const {
|
||||||
|
return Loc == R.getStart() || (isBeforeInBuffer(R.getStart(), Loc) &&
|
||||||
|
isBeforeInBuffer(Loc, R.getEnd()));
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if range \c Enclosing contains the range \c Inner.
|
/// Returns true if range \c Enclosing contains the range \c Inner.
|
||||||
bool rangeContains(SourceRange Enclosing, SourceRange Inner) const {
|
bool rangeContains(SourceRange Enclosing, SourceRange Inner) const {
|
||||||
return rangeContainsTokenLoc(Enclosing, Inner.Start) &&
|
return rangeContainsTokenLoc(Enclosing, Inner.Start) &&
|
||||||
@@ -221,10 +228,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if range \p R contains the code-completion location, if any.
|
/// Returns true if range \p R contains the code-completion location, if any.
|
||||||
bool rangeContainsIDEInspectionTarget(SourceRange R) const {
|
bool rangeContainsIDEInspectionTarget(CharSourceRange R) const {
|
||||||
return IDEInspectionTargetBufferID
|
if (!IDEInspectionTargetBufferID) {
|
||||||
? rangeContainsTokenLoc(R, getIDEInspectionTargetLoc())
|
return false;
|
||||||
: false;
|
}
|
||||||
|
return rangeContainsTokenLoc(R, getIDEInspectionTargetLoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the buffer ID for the specified *valid* location.
|
/// Returns the buffer ID for the specified *valid* location.
|
||||||
|
|||||||
@@ -126,6 +126,14 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns \c true if \p range is valid and contains the IDE inspection
|
||||||
|
/// target. This performs the underlying check based on \c CharSourceRange
|
||||||
|
/// to make sure we correctly return \c true if the ide inspection target
|
||||||
|
/// is inside a string literal that's the last token in \p range.
|
||||||
|
bool containsIDEInspectionTarget(SourceRange range,
|
||||||
|
const SourceManager &SourceMgr);
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
#endif // SWIFT_SEMA_COMPLETIONCONTEXTFINDER_H
|
#endif // SWIFT_SEMA_COMPLETIONCONTEXTFINDER_H
|
||||||
|
|||||||
@@ -8175,8 +8175,15 @@ BraceStmt *AbstractFunctionDecl::getBody(bool canSynthesize) const {
|
|||||||
|
|
||||||
// Don't allow getBody() to trigger parsing of an unparsed body containing the
|
// Don't allow getBody() to trigger parsing of an unparsed body containing the
|
||||||
// IDE inspection location.
|
// IDE inspection location.
|
||||||
|
// FIXME: We should be properly constructing the range of the the body as a
|
||||||
|
// CharSourceRange but we can't because we don't have access to the lexer
|
||||||
|
// here. Using the end location of the SourceRange works good enough here
|
||||||
|
// because the last token is a '}' and the IDE inspection point is not inside
|
||||||
|
// the closing brace.
|
||||||
if (getBodyKind() == BodyKind::Unparsed &&
|
if (getBodyKind() == BodyKind::Unparsed &&
|
||||||
ctx.SourceMgr.rangeContainsIDEInspectionTarget(getBodySourceRange())) {
|
ctx.SourceMgr.rangeContainsIDEInspectionTarget(
|
||||||
|
CharSourceRange(ctx.SourceMgr, getBodySourceRange().Start,
|
||||||
|
getBodySourceRange().End))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7986,8 +7986,10 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
|
|||||||
auto BodyPreviousLoc = PreviousLoc;
|
auto BodyPreviousLoc = PreviousLoc;
|
||||||
SourceRange BodyRange(Tok.getLoc());
|
SourceRange BodyRange(Tok.getLoc());
|
||||||
auto setIDEInspectionDelayedDeclStateIfNeeded = [&] {
|
auto setIDEInspectionDelayedDeclStateIfNeeded = [&] {
|
||||||
|
auto CharBodyRange =
|
||||||
|
Lexer::getCharSourceRangeFromSourceRange(SourceMgr, BodyRange);
|
||||||
if (!isIDEInspectionFirstPass() ||
|
if (!isIDEInspectionFirstPass() ||
|
||||||
!SourceMgr.rangeContainsIDEInspectionTarget(BodyRange)) {
|
!SourceMgr.rangeContainsIDEInspectionTarget(CharBodyRange)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (State->hasIDEInspectionDelayedDeclState())
|
if (State->hasIDEInspectionDelayedDeclState())
|
||||||
|
|||||||
@@ -1433,7 +1433,9 @@ Parser::parseExprPostfixSuffix(ParserResult<Expr> Result, bool isExprBasic,
|
|||||||
assert(activeElements.size() == 1 && activeElements[0].is<Expr *>());
|
assert(activeElements.size() == 1 && activeElements[0].is<Expr *>());
|
||||||
auto expr = activeElements[0].get<Expr *>();
|
auto expr = activeElements[0].get<Expr *>();
|
||||||
ParserStatus status(ICD);
|
ParserStatus status(ICD);
|
||||||
if (SourceMgr.rangeContainsIDEInspectionTarget(expr->getSourceRange()) &&
|
auto charRange = Lexer::getCharSourceRangeFromSourceRange(
|
||||||
|
SourceMgr, expr->getSourceRange());
|
||||||
|
if (SourceMgr.rangeContainsIDEInspectionTarget(charRange) &&
|
||||||
L->isCodeCompletion())
|
L->isCodeCompletion())
|
||||||
status.setHasCodeCompletion();
|
status.setHasCodeCompletion();
|
||||||
hasBindOptional |= exprsWithBindOptional.contains(expr);
|
hasBindOptional |= exprsWithBindOptional.contains(expr);
|
||||||
@@ -2826,7 +2828,9 @@ ParserResult<Expr> Parser::parseExprClosure() {
|
|||||||
SmallVector<ASTNode, 4> bodyElements;
|
SmallVector<ASTNode, 4> bodyElements;
|
||||||
Status |= parseBraceItems(bodyElements, BraceItemListKind::Brace);
|
Status |= parseBraceItems(bodyElements, BraceItemListKind::Brace);
|
||||||
|
|
||||||
if (SourceMgr.rangeContainsIDEInspectionTarget({leftBrace, PreviousLoc})) {
|
if (SourceMgr.rangeContainsIDEInspectionTarget(
|
||||||
|
Lexer::getCharSourceRangeFromSourceRange(SourceMgr,
|
||||||
|
{leftBrace, PreviousLoc}))) {
|
||||||
// Ignore 'IDEInspectionDelayedDeclState' inside closures.
|
// Ignore 'IDEInspectionDelayedDeclState' inside closures.
|
||||||
// Completions inside functions body inside closures at top level should
|
// Completions inside functions body inside closures at top level should
|
||||||
// be considered top-level completions.
|
// be considered top-level completions.
|
||||||
|
|||||||
@@ -16,9 +16,8 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "MiscDiagnostics.h"
|
#include "MiscDiagnostics.h"
|
||||||
#include "TypeChecker.h"
|
|
||||||
#include "TypeCheckAvailability.h"
|
#include "TypeCheckAvailability.h"
|
||||||
#include "swift/Sema/IDETypeChecking.h"
|
#include "TypeChecker.h"
|
||||||
#include "swift/AST/ASTPrinter.h"
|
#include "swift/AST/ASTPrinter.h"
|
||||||
#include "swift/AST/ASTVisitor.h"
|
#include "swift/AST/ASTVisitor.h"
|
||||||
#include "swift/AST/ASTWalker.h"
|
#include "swift/AST/ASTWalker.h"
|
||||||
@@ -27,14 +26,15 @@
|
|||||||
#include "swift/AST/ParameterList.h"
|
#include "swift/AST/ParameterList.h"
|
||||||
#include "swift/AST/TypeCheckRequests.h"
|
#include "swift/AST/TypeCheckRequests.h"
|
||||||
#include "swift/Sema/ConstraintSystem.h"
|
#include "swift/Sema/ConstraintSystem.h"
|
||||||
|
#include "swift/Sema/IDETypeChecking.h"
|
||||||
#include "swift/Sema/SolutionResult.h"
|
#include "swift/Sema/SolutionResult.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace constraints;
|
using namespace constraints;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "swift/Sema/CompletionContextFinder.h"
|
#include "swift/Sema/CompletionContextFinder.h"
|
||||||
|
#include "swift/Parse/Lexer.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
using Fallback = CompletionContextFinder::Fallback;
|
using Fallback = CompletionContextFinder::Fallback;
|
||||||
@@ -132,3 +133,11 @@ Optional<Fallback> CompletionContextFinder::getFallbackCompletionExpr() const {
|
|||||||
return Fallback{getCompletionExpr(), fallbackDC, separatePrecheck};
|
return Fallback{getCompletionExpr(), fallbackDC, separatePrecheck};
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool swift::containsIDEInspectionTarget(SourceRange range,
|
||||||
|
const SourceManager &SourceMgr) {
|
||||||
|
if (range.isInvalid())
|
||||||
|
return false;
|
||||||
|
auto charRange = Lexer::getCharSourceRangeFromSourceRange(SourceMgr, range);
|
||||||
|
return SourceMgr.rangeContainsIDEInspectionTarget(charRange);
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "swift/Basic/Statistic.h"
|
#include "swift/Basic/Statistic.h"
|
||||||
#include "swift/Sema/CSFix.h"
|
#include "swift/Sema/CSFix.h"
|
||||||
#include "swift/Sema/ConstraintGraph.h"
|
#include "swift/Sema/ConstraintGraph.h"
|
||||||
|
#include "swift/Sema/IDETypeChecking.h"
|
||||||
#include "swift/Sema/SolutionResult.h"
|
#include "swift/Sema/SolutionResult.h"
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
@@ -353,18 +354,14 @@ ConstraintSystem::getAlternativeLiteralTypes(KnownProtocolKind kind,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ConstraintSystem::containsIDEInspectionTarget(ASTNode node) const {
|
bool ConstraintSystem::containsIDEInspectionTarget(ASTNode node) const {
|
||||||
SourceRange range = node.getSourceRange();
|
return swift::containsIDEInspectionTarget(node.getSourceRange(),
|
||||||
if (range.isInvalid())
|
Context.SourceMgr);
|
||||||
return false;
|
|
||||||
return Context.SourceMgr.rangeContainsIDEInspectionTarget(range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConstraintSystem::containsIDEInspectionTarget(
|
bool ConstraintSystem::containsIDEInspectionTarget(
|
||||||
const ArgumentList *args) const {
|
const ArgumentList *args) const {
|
||||||
SourceRange range = args->getSourceRange();
|
return swift::containsIDEInspectionTarget(args->getSourceRange(),
|
||||||
if (range.isInvalid())
|
Context.SourceMgr);
|
||||||
return false;
|
|
||||||
return Context.SourceMgr.rangeContainsIDEInspectionTarget(range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstraintLocator *ConstraintSystem::getConstraintLocator(
|
ConstraintLocator *ConstraintSystem::getConstraintLocator(
|
||||||
|
|||||||
@@ -14,14 +14,13 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "swift/Subsystems.h"
|
|
||||||
#include "TypeChecker.h"
|
|
||||||
#include "TypeCheckObjC.h"
|
|
||||||
#include "TypeCheckType.h"
|
|
||||||
#include "CodeSynthesis.h"
|
#include "CodeSynthesis.h"
|
||||||
#include "MiscDiagnostics.h"
|
#include "MiscDiagnostics.h"
|
||||||
#include "swift/AST/ASTWalker.h"
|
#include "TypeCheckObjC.h"
|
||||||
|
#include "TypeCheckType.h"
|
||||||
|
#include "TypeChecker.h"
|
||||||
#include "swift/AST/ASTVisitor.h"
|
#include "swift/AST/ASTVisitor.h"
|
||||||
|
#include "swift/AST/ASTWalker.h"
|
||||||
#include "swift/AST/Attr.h"
|
#include "swift/AST/Attr.h"
|
||||||
#include "swift/AST/DiagnosticSuppression.h"
|
#include "swift/AST/DiagnosticSuppression.h"
|
||||||
#include "swift/AST/ExistentialLayout.h"
|
#include "swift/AST/ExistentialLayout.h"
|
||||||
@@ -37,13 +36,15 @@
|
|||||||
#include "swift/AST/Type.h"
|
#include "swift/AST/Type.h"
|
||||||
#include "swift/AST/TypeCheckRequests.h"
|
#include "swift/AST/TypeCheckRequests.h"
|
||||||
#include "swift/Basic/Defer.h"
|
#include "swift/Basic/Defer.h"
|
||||||
#include "swift/Basic/Statistic.h"
|
|
||||||
#include "swift/Basic/STLExtras.h"
|
#include "swift/Basic/STLExtras.h"
|
||||||
|
#include "swift/Basic/Statistic.h"
|
||||||
|
#include "swift/Parse/IDEInspectionCallbacks.h"
|
||||||
#include "swift/Parse/Lexer.h"
|
#include "swift/Parse/Lexer.h"
|
||||||
#include "swift/Sema/IDETypeChecking.h"
|
|
||||||
#include "swift/Sema/ConstraintSystem.h"
|
|
||||||
#include "swift/Sema/CompletionContextFinder.h"
|
#include "swift/Sema/CompletionContextFinder.h"
|
||||||
|
#include "swift/Sema/ConstraintSystem.h"
|
||||||
|
#include "swift/Sema/IDETypeChecking.h"
|
||||||
#include "swift/Strings.h"
|
#include "swift/Strings.h"
|
||||||
|
#include "swift/Subsystems.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/PointerUnion.h"
|
#include "llvm/ADT/PointerUnion.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
@@ -565,7 +566,7 @@ bool TypeChecker::typeCheckForCodeCompletion(
|
|||||||
{
|
{
|
||||||
auto range = target.getSourceRange();
|
auto range = target.getSourceRange();
|
||||||
if (range.isInvalid() ||
|
if (range.isInvalid() ||
|
||||||
!Context.SourceMgr.rangeContainsIDEInspectionTarget(range))
|
!containsIDEInspectionTarget(range, Context.SourceMgr))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user