[AST] Factor out Expr::getNameLoc

There are a bunch of AST nodes that can have
associated DeclNameLocs, make sure we cover them
all. I don't think this makes a difference for
`unwrapPropertyWrapperParameterTypes` since the
extra cases should be invalid, but for cursor info
it ensures we handle UnresolvedMemberExprs.
This commit is contained in:
Hamish Knight
2024-12-05 15:55:19 +00:00
parent dd97862305
commit c4efa0d5f0
5 changed files with 40 additions and 28 deletions

View File

@@ -552,6 +552,10 @@ public:
/// \c nullptr.
ArgumentList *getArgs() const;
/// If the expression has a DeclNameLoc, returns it. Otherwise, returns
/// an nullp DeclNameLoc.
DeclNameLoc getNameLoc() const;
/// Produce a mapping from each subexpression to its parent
/// expression, with the provided expression serving as the root of
/// the parent map.

View File

@@ -859,6 +859,25 @@ ArgumentList *Expr::getArgs() const {
return nullptr;
}
DeclNameLoc Expr::getNameLoc() const {
if (auto *DRE = dyn_cast<DeclRefExpr>(this))
return DRE->getNameLoc();
if (auto *UDRE = dyn_cast<UnresolvedDeclRefExpr>(this))
return UDRE->getNameLoc();
if (auto *ODRE = dyn_cast<OverloadedDeclRefExpr>(this))
return ODRE->getNameLoc();
if (auto *UDE = dyn_cast<UnresolvedDotExpr>(this))
return UDE->getNameLoc();
if (auto *UME = dyn_cast<UnresolvedMemberExpr>(this))
return UME->getNameLoc();
if (auto *MRE = dyn_cast<MemberRefExpr>(this))
return MRE->getNameLoc();
if (auto *DRME = dyn_cast<DynamicMemberRefExpr>(this))
return DRME->getNameLoc();
return DeclNameLoc();
}
llvm::DenseMap<Expr *, Expr *> Expr::getParentMap() {
class RecordingTraversal : public ASTWalker {
public:

View File

@@ -214,23 +214,6 @@ private:
return Action::Continue();
}
/// Retrieve the name location for an expression that supports cursor info.
DeclNameLoc getExprNameLoc(Expr *E) {
if (auto *DRE = dyn_cast<DeclRefExpr>(E))
return DRE->getNameLoc();
if (auto *UDRE = dyn_cast<UnresolvedDeclRefExpr>(E))
return UDRE->getNameLoc();
if (auto *ODRE = dyn_cast<OverloadedDeclRefExpr>(E))
return ODRE->getNameLoc();
if (auto *UDE = dyn_cast<UnresolvedDotExpr>(E))
return UDE->getNameLoc();
return DeclNameLoc();
}
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
if (auto closure = dyn_cast<ClosureExpr>(E)) {
DeclContextStack.push_back(closure);
@@ -247,7 +230,7 @@ private:
}
}
if (getExprNameLoc(E).getBaseNameLoc() != LocToResolve)
if (E->getNameLoc().getBaseNameLoc() != LocToResolve)
return Action::Continue(E);
assert(Result == nullptr);

View File

@@ -706,16 +706,8 @@ unwrapPropertyWrapperParameterTypes(ConstraintSystem &cs, AbstractFunctionDecl *
SmallVector<AnyFunctionType::Param, 4> adjustedParamTypes;
DeclNameLoc nameLoc;
auto *ref = getAsExpr(locator.getAnchor());
if (auto *declRef = dyn_cast<DeclRefExpr>(ref)) {
nameLoc = declRef->getNameLoc();
} else if (auto *dotExpr = dyn_cast<UnresolvedDotExpr>(ref)) {
nameLoc = dotExpr->getNameLoc();
} else if (auto *overloadedRef = dyn_cast<OverloadedDeclRefExpr>(ref)) {
nameLoc = overloadedRef->getNameLoc();
} else if (auto *memberExpr = dyn_cast<UnresolvedMemberExpr>(ref)) {
nameLoc = memberExpr->getNameLoc();
}
if (auto *ref = getAsExpr(locator.getAnchor()))
nameLoc = ref->getNameLoc();
for (unsigned i : indices(*paramList)) {
Identifier argLabel;

View File

@@ -0,0 +1,14 @@
struct S {
static func foo(_ x: Int) -> S {}
static func foo(_ x: String) -> S {}
}
// https://github.com/swiftlang/swift/issues/77981 - Make sure we can resolve
// solver-based cursor info for UnresolvedMemberExprs.
func bar() {
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):15 %s -- %s | %FileCheck %s
let _: S = .foo()
}
// CHECK-DAG: source.lang.swift.ref.function.method.static (2:15-2:28)
// CHECK-DAG: source.lang.swift.ref.function.method.static (3:15-3:31)