[IDE][Index][test] Update sourcekit/indexing support for latest property wrapper changes

The backing property for 'foo' is now '_foo', and the projected value '$foo'.
This updates Indexing to report occurrences of foo within both $foo and
_foo occurrences (rather than just $foo - the old _foo).

FindRelatedIdents was similarlar updated, so it reports 'foo' ranges in both
_foo and $foo.

CursorInfo now reports the USR, documentation, and location of foo when invoked
occurrences of $foo or _foo, but now leaves the name, type, and annotated
declaration of _foo/$foo as is. Having the same USR ensures rename invoked on
any of them will still rename via foo. Reporting foo's documentation comment
instead is just to present something more useful to the user.
This commit is contained in:
Nathan Hawes
2019-06-27 17:38:24 -07:00
parent c547e6885e
commit e08a6c1994
15 changed files with 201 additions and 66 deletions

View File

@@ -408,6 +408,15 @@ static void printAnnotatedDeclaration(const ValueDecl *VD,
while (VD->isImplicit() && VD->getOverriddenDecl())
VD = VD->getOverriddenDecl();
// If this is a property wrapper backing property (_foo) or projected value
// ($foo) and the wrapped property is not implicit, still print it.
if (auto *VarD = dyn_cast<VarDecl>(VD)) {
if (auto *Wrapped = VarD->getOriginalWrappedProperty()) {
if (!Wrapped->isImplicit())
PO.TreatAsExplicitDeclList.push_back(VD);
}
}
// Wrap this up in XML, as that's what we'll use for documentation comments.
OS<<"<Declaration>";
VD->print(Printer, PO);
@@ -430,6 +439,14 @@ void SwiftLangSupport::printFullyAnnotatedDeclaration(const ValueDecl *VD,
while (VD->isImplicit() && VD->getOverriddenDecl())
VD = VD->getOverriddenDecl();
// If this is a property wrapper backing property (_foo) or projected value
// ($foo) and the wrapped property is not implicit, still print it.
if (auto *VarD = dyn_cast<VarDecl>(VD)) {
if (auto *Wrapped = VarD->getOriginalWrappedProperty()) {
if (!Wrapped->isImplicit())
PO.TreatAsExplicitDeclList.push_back(VD);
}
}
VD->print(Printer, PO);
}
@@ -736,10 +753,19 @@ static bool passCursorInfoForDecl(SourceFile* SF,
}
unsigned NameEnd = SS.size();
// If VD is the syntehsized property wrapper backing storage (_foo) or
// projected value ($foo) of a property (foo), use that property's USR instead
// so that a rename refactoring renames all three (foo, $foo, and _foo).
const ValueDecl* OriginalProperty = VD;
if (auto *VarD = dyn_cast<VarDecl>(VD)) {
if (auto *Wrapped = VarD->getOriginalWrappedProperty())
OriginalProperty = Wrapped;
}
unsigned USRBegin = SS.size();
{
llvm::raw_svector_ostream OS(SS);
SwiftLangSupport::printUSR(VD, OS);
SwiftLangSupport::printUSR(OriginalProperty, OS);
if (InSynthesizedExtension) {
OS << LangSupport::SynthesizedUSRSeparator;
SwiftLangSupport::printUSR(BaseType->getAnyNominal(), OS);
@@ -770,10 +796,13 @@ static bool passCursorInfoForDecl(SourceFile* SF,
}
unsigned MangledContainerTypeEnd = SS.size();
// If VD is the syntehsized property wrapper backing storage (_foo) or
// projected value ($foo) of a property (foo), use that property's
// documentation instead.
unsigned DocCommentBegin = SS.size();
{
llvm::raw_svector_ostream OS(SS);
ide::getDocumentationCommentAsXML(VD, OS);
ide::getDocumentationCommentAsXML(OriginalProperty, OS);
}
unsigned DocCommentEnd = SS.size();
@@ -905,9 +934,12 @@ static bool passCursorInfoForDecl(SourceFile* SF,
StringRef LocalizationKey = StringRef(SS.begin() + LocalizationBegin,
LocalizationEnd - LocalizationBegin);
// If VD is the syntehsized property wrapper backing storage (_foo) or
// projected value ($foo) of a property (foo), base the location on that
// property instead.
llvm::Optional<std::pair<unsigned, unsigned>> DeclarationLoc;
StringRef Filename;
getLocationInfo(VD, DeclarationLoc, Filename);
getLocationInfo(OriginalProperty, DeclarationLoc, Filename);
if (DeclarationLoc.hasValue()) {
DeclarationLoc = tryRemappingLocToLatestSnapshot(Lang,
*DeclarationLoc,
@@ -1875,6 +1907,13 @@ public:
// case .third(let x)
// print(x)
Dcl = V->getCanonicalVarDecl();
// If we have a prioperty wrapper backing property or projected value, use
// the wrapped property instead (i.e. if this is _foo or $foo, pretend
// it's foo).
if (auto *Wrapped = V->getOriginalWrappedProperty()) {
Dcl = Wrapped;
}
} else {
Dcl = D;
}
@@ -1893,6 +1932,7 @@ private:
return passId(Range);
return true;
}
bool visitDeclReference(ValueDecl *D, CharSourceRange Range,
TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef, Type T,
ReferenceMetaData Data) override {
@@ -1902,10 +1942,12 @@ private:
if (auto *V = dyn_cast<VarDecl>(D)) {
D = V->getCanonicalVarDecl();
// If we have a backing property of a property wrapper, use the wrapped
// property instead (i.e. if this is $foo, pretend it's foo).
// If we have a prioperty wrapper backing property or projected value, use
// the wrapped property for comparison instead (i.e. if this is _foo or
// $foo, pretend it's foo).
if (auto *Wrapped = V->getOriginalWrappedProperty()) {
assert(Range.getByteLength() > 1 && Range.str().front() == '$');
assert(Range.getByteLength() > 1 &&
(Range.str().front() == '_' || Range.str().front() == '$'));
D = Wrapped;
Range = CharSourceRange(Range.getStart().getAdvancedLoc(1), Range.getByteLength() - 1);
}