Skip to content

[indexer] Index parameter definitions with a distinct external argument label too (but not their refs) #8094

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/Index/IndexSymbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct IndexSymbol : IndexRelation {

SymbolInfo getSymbolInfoForDecl(const Decl *D);
SymbolSubKind getSubKindForAccessor(AccessorKind AK);
bool isLocalSymbol(const Decl *D);

using clang::index::printSymbolProperties;

Expand Down
28 changes: 28 additions & 0 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "swift/AST/ASTVisitor.h"
#include "swift/AST/Initializer.h"
#include "swift/AST/Module.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/Mangle.h"
#include "swift/Basic/ManglingUtils.h"
Expand Down Expand Up @@ -375,6 +376,29 @@ static bool isInPrivateOrLocalContext(const ValueDecl *D) {
return isInPrivateOrLocalContext(nominal);
}

static unsigned getUnnamedParamIndex(const Decl *D) {
unsigned UnnamedIndex = 0;
ArrayRef<ParameterList *> ParamLists;

if (auto AFD = dyn_cast<AbstractFunctionDecl>(D->getDeclContext())) {
ParamLists = AFD->getParameterLists();
} else if (auto ACE = dyn_cast<AbstractClosureExpr>(D->getDeclContext())) {
ParamLists = ACE->getParameterLists();
} else {
llvm_unreachable("unhandled param context");
}
for (auto ParamList : ParamLists) {
for (auto Param : *ParamList) {
if (!Param->hasName()) {
if (Param == D)
return UnnamedIndex;
++UnnamedIndex;
}
}
}
llvm_unreachable("param not found");
}

void ASTMangler::appendDeclName(const ValueDecl *decl) {
if (decl->getName().isOperator()) {
appendIdentifier(translateOperator(decl->getName().str()));
Expand All @@ -394,6 +418,10 @@ void ASTMangler::appendDeclName(const ValueDecl *decl) {
}

if (decl->getDeclContext()->isLocalContext()) {
if (isa<ParamDecl>(decl) && !decl->hasName()) {
// Mangle unnamed params with their ordering.
return appendOperator("L", Index(getUnnamedParamIndex(decl)));
}
// Mangle local declarations with a numeric discriminator.
return appendOperator("L", Index(decl->getLocalDiscriminator()));
}
Expand Down
4 changes: 3 additions & 1 deletion lib/AST/USRGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ static bool ShouldUseObjCUSR(const Decl *D) {
bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) {
using namespace Mangle;

if (!D->hasName() && (!isa<FuncDecl>(D) || cast<FuncDecl>(D)->getAccessorKind() == AccessorKind::NotAccessor))
if (!D->hasName() && !isa<ParamDecl>(D) &&
(!isa<FuncDecl>(D) ||
cast<FuncDecl>(D)->getAccessorKind() == AccessorKind::NotAccessor))
return true; // Ignore.
if (D->getModuleContext()->isBuiltinModule())
return true; // Ignore.
Expand Down
21 changes: 8 additions & 13 deletions lib/Index/Index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ printArtificialName(const swift::AbstractStorageDecl *ASD, AccessorKind AK, llvm
}

static bool printDisplayName(const swift::ValueDecl *D, llvm::raw_ostream &OS) {
if (!D->hasName()) {
if (!D->hasName() && !isa<ParamDecl>(D)) {
auto *FD = dyn_cast<FuncDecl>(D);
if (!FD || FD->getAccessorKind() == AccessorKind::NotAccessor)
return true;
Expand Down Expand Up @@ -396,22 +396,17 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
return SrcMgr.getLineAndColumn(Loc, BufferID);
}

bool shouldIndex(ValueDecl *D) const {
bool shouldIndex(ValueDecl *D, bool IsRef) const {
if (D->isImplicit())
return false;
if (isLocal(D))
if (isLocalSymbol(D) && (!isa<ParamDecl>(D) || IsRef))
return false;
if (D->isPrivateStdlibDecl())
return false;

return true;
}

bool isLocal(ValueDecl *D) const {
return D->getDeclContext()->getLocalContext() &&
(!isa<ParamDecl>(D) || cast<ParamDecl>(D)->getArgumentNameLoc().isValid());
}

void getModuleHash(SourceFileOrModule SFOrMod, llvm::raw_ostream &OS);
llvm::hash_code hashModule(llvm::hash_code code, SourceFileOrModule SFOrMod);
llvm::hash_code hashFileReference(llvm::hash_code code,
Expand Down Expand Up @@ -573,7 +568,7 @@ bool IndexSwiftASTWalker::startEntity(Decl *D, IndexSymbol &Info) {
}

bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
if (!shouldIndex(D))
if (!shouldIndex(D, /*IsRef=*/false))
return false;

SourceLoc Loc = D->getLoc();
Expand Down Expand Up @@ -626,7 +621,7 @@ bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {

bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isImplicit,
SymbolRoleSet Relations, Decl *Related) {
if (!shouldIndex(D))
if (!shouldIndex(D, /*IsRef=*/true))
return true;

IndexSymbol Info;
Expand Down Expand Up @@ -692,7 +687,7 @@ bool IndexSwiftASTWalker::reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet
bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
AccessorKind AccKind, bool IsRef,
SourceLoc Loc) {
if (!shouldIndex(D))
if (!shouldIndex(D, IsRef))
return true; // continue walking.

auto updateInfo = [this, D, AccKind](IndexSymbol &Info) {
Expand Down Expand Up @@ -760,7 +755,7 @@ bool IndexSwiftASTWalker::reportExtension(ExtensionDecl *D) {
NominalTypeDecl *NTD = D->getExtendedType()->getAnyNominal();
if (!NTD)
return true;
if (!shouldIndex(NTD))
if (!shouldIndex(NTD, /*IsRef=*/false))
return true;

IndexSymbol Info;
Expand Down Expand Up @@ -845,7 +840,7 @@ static bool hasUsefulRoleInSystemModule(SymbolRoleSet roles) {

bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
IndexSymbol &Info) {
if (!shouldIndex(D))
if (!shouldIndex(D, /*IsRef=*/true))
return true; // keep walking

if (isa<AbstractFunctionDecl>(D)) {
Expand Down
9 changes: 9 additions & 0 deletions lib/Index/IndexSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ SymbolInfo index::getSymbolInfoForDecl(const Decl *D) {
break;
}

if (isLocalSymbol(D)) {
info.Properties |= SymbolProperty::Local;
}

return info;
}

Expand All @@ -224,3 +228,8 @@ SymbolSubKind index::getSubKindForAccessor(AccessorKind AK) {

llvm_unreachable("Unhandled AccessorKind in switch.");
}

bool index::isLocalSymbol(const swift::Decl *D) {
return D->getDeclContext()->getLocalContext() &&
(!isa<ParamDecl>(D) || cast<ParamDecl>(D)->getArgumentNameLoc().isValid());
}
18 changes: 13 additions & 5 deletions test/Index/kinds.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,23 @@ class AClass {
// CHECK: [[@LINE-1]]:7 | class/Swift | AClass | s:14swift_ide_test6AClassC | Def | rel: 0

// InstanceMethod + Parameters
func instanceMethod(a: Int, b b: Int, _ c: Int, d _: Int, _: Int) {}
func instanceMethod(a: Int, b b: Int, _ c: Int, d _: Int, _: Int) {
// CHECK: [[@LINE-1]]:8 | instance-method/Swift | instanceMethod(a:b:_:d:_:) | s:14swift_ide_test6AClassC14instanceMethodySi1a_Si1bS2i1dSitF | Def,RelChild | rel: 1
// CHECK-NEXT: RelChild | class/Swift | AClass | s:14swift_ide_test6AClassC
// CHECK: [[@LINE-3]]:23 | param/Swift | a | s:14swift_ide_test6AClassC14instanceMethodySi1a_Si1bS2i1dSitFAEL_Siv | Def,RelChild | rel: 1
// CHECK-NEXT: RelChild | instance-method/Swift | instanceMethod(a:b:_:d:_:) | s:14swift_ide_test6AClassC14instanceMethodySi1a_Si1bS2i1dSitF
// CHECK-NOT: [[@LINE-5]]:33 | param/Swift | b | s:{{.*}} | Def,RelChild | rel: 1
// CHECK-NOT: [[@LINE-6]]:43 | param/Swift | c | s:{{.*}} | Def,RelChild | rel: 1
// CHECK-NOT: [[@LINE-7]]:53 | param/Swift | d | s:{{.*}} | Def,RelChild | rel: 1
// CHECK-NOT: [[@LINE-8]]:61 | param/Swift | _ | s:{{.*}} | Def,RelChild | rel: 1
// CHECK: [[@LINE-5]]:33 | param(local)/Swift | b | s:{{.*}} | Def,RelChild | rel: 1
// CHECK: [[@LINE-6]]:43 | param(local)/Swift | c | s:{{.*}} | Def,RelChild | rel: 1
// CHECK: [[@LINE-7]]:53 | param(local)/Swift | _ | s:{{.*}} | Def,RelChild | rel: 1
// CHECK: [[@LINE-8]]:61 | param/Swift | _ | s:{{.*}} | Def,RelChild | rel: 1

_ = a
// CHECK: [[@LINE-1]]:9 | param/Swift | a | s:{{.*}} | Ref,Read,RelCont | rel: 1
_ = b
// CHECK-NOT: [[@LINE-1]]:9 | param(local)/Swift | b | s:{{.*}} | Ref,Read,RelCont | rel: 1
_ = c
// CHECK-NOT: [[@LINE-1]]:9 | param(local)/Swift | c | s:{{.*}} | Ref,Read,RelCont | rel: 1
}

// ClassMethod
class func classMethod() {}
Expand Down