Skip to content

[RangeInfo] When reporting referenced decls, also report the types of these references. #6405

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
Dec 20, 2016
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
12 changes: 10 additions & 2 deletions include/swift/IDE/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,23 @@ enum class RangeKind : int8_t{
MultiStatement,
};

struct ReferencedDecl {
ValueDecl *VD;
Type Ty;
ReferencedDecl(ValueDecl* VD, Type Ty) : VD(VD), Ty(Ty) {}
ReferencedDecl() : ReferencedDecl(nullptr, Type()) {}
bool operator==(const ReferencedDecl& other);
};

struct ResolvedRangeInfo {
RangeKind Kind;
Type Ty;
StringRef Content;
ArrayRef<ValueDecl*> DeclaredDecls;
ArrayRef<ValueDecl*> ReferencedDecls;
ArrayRef<ReferencedDecl> ReferencedDecls;
ResolvedRangeInfo(RangeKind Kind, Type Ty, StringRef Content,
ArrayRef<ValueDecl*> DeclaredDecls,
ArrayRef<ValueDecl*> ReferencedDecls): Kind(Kind),
ArrayRef<ReferencedDecl> ReferencedDecls): Kind(Kind),
Ty(Ty), Content(Content), DeclaredDecls(DeclaredDecls),
ReferencedDecls(ReferencedDecls) {}
ResolvedRangeInfo() :
Expand Down
32 changes: 19 additions & 13 deletions lib/IDE/SwiftSourceDocInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,19 @@ void ResolvedRangeInfo::print(llvm::raw_ostream &OS) {
for (auto *VD : DeclaredDecls) {
OS << "<Declared>" << VD->getNameStr() << "</Declared>\n";
}
for (auto *VD : ReferencedDecls) {
OS << "<Referenced>" << VD->getNameStr() << "</Referenced>\n";
for (auto &RD : ReferencedDecls) {
OS << "<Referenced>" << RD.VD->getNameStr() << "</Referenced>";
OS << "<Type>";
RD.Ty->print(OS);
OS << "</Type>\n";
}
OS << "<end>\n";
}

bool ReferencedDecl::operator==(const ReferencedDecl& Other) {
return VD == Other.VD && Ty.getPointer() == Other.Ty.getPointer();
}

struct RangeResolver::Implementation {
SourceFile &File;
ASTContext &Ctx;
Expand Down Expand Up @@ -243,13 +250,7 @@ struct RangeResolver::Implementation {
}

std::vector<ValueDecl*> DeclaredDecls;
std::vector<ValueDecl*> ReferencedDecls;

void pushBackDeclUniquely(std::vector<ValueDecl*> &Bag, ValueDecl* VD) {
if (std::find(Bag.begin(), Bag.end(), VD) == Bag.end()) {
Bag.push_back(VD);
}
}
std::vector<ReferencedDecl> ReferencedDecls;

ResolvedRangeInfo getSingleNodeKind(ASTNode Node) {
assert(!Node.isNull());
Expand Down Expand Up @@ -341,6 +342,8 @@ struct RangeResolver::Implementation {

static Implementation *createInstance(SourceFile &File, SourceLoc Start,
SourceLoc End) {
if (Start.isInvalid() || End.isInvalid())
return nullptr;
SourceManager &SM = File.getASTContext().SourceMgr;
unsigned BufferId = File.getBufferID().getValue();
unsigned StartOff = SM.getLocOffsetInBuffer(Start, BufferId);
Expand All @@ -355,7 +358,7 @@ struct RangeResolver::Implementation {
if (auto *VD = dyn_cast_or_null<ValueDecl>(D)) {
if (isContainedInSelection(CharSourceRange(SM, VD->getStartLoc(),
VD->getEndLoc())))
pushBackDeclUniquely(DeclaredDecls, VD);
DeclaredDecls.push_back(VD);
}

auto &DCInfo = getCurrentDC();
Expand Down Expand Up @@ -400,7 +403,7 @@ struct RangeResolver::Implementation {
return ResolvedRangeInfo();
}

void analyzeDeclRef(ValueDecl *VD, CharSourceRange Range) {
void analyzeDeclRef(ValueDecl *VD, CharSourceRange Range, Type Ty) {
if (!isContainedInSelection(Range))
return;

Expand All @@ -409,7 +412,10 @@ struct RangeResolver::Implementation {
return;

// Collect referenced decls in the range.
pushBackDeclUniquely(ReferencedDecls, VD);
ReferencedDecl RD(VD, Ty);
if (std::find(ReferencedDecls.begin(), ReferencedDecls.end(), RD) ==
ReferencedDecls.end())
ReferencedDecls.push_back(RD);
}

private:
Expand Down Expand Up @@ -483,7 +489,7 @@ bool RangeResolver::walkToDeclPost(Decl *D) {
bool RangeResolver::
visitDeclReference(ValueDecl *D, CharSourceRange Range, TypeDecl *CtorTyRef,
Type T) {
Impl->analyzeDeclRef(D, Range);
Impl->analyzeDeclRef(D, Range, T);
return true;
}

Expand Down
57 changes: 52 additions & 5 deletions test/IDE/range_info_basics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,37 @@ func foo2() {
print(b + c)
}

struct S1 {
var a = 3
func foo() -> Int { return 0 }
mutating func increment() -> S1 {
a = a + 1
return self
}
}

func foo3(s: inout S1) -> Int {
let b = s.a
let c = s.foo() + b
s = s.increment()
return c + b
}

func foo4(s: S1) -> Int {
let b = s.a
let c = s.foo() + b
return c + b
}

// RUN: %target-swift-ide-test -range -pos=8:1 -end-pos 8:32 -source-filename %s | %FileCheck %s -check-prefix=CHECK1
// RUN: %target-swift-ide-test -range -pos=9:1 -end-pos 9:26 -source-filename %s | %FileCheck %s -check-prefix=CHECK2
// RUN: %target-swift-ide-test -range -pos=10:1 -end-pos 10:27 -source-filename %s | %FileCheck %s -check-prefix=CHECK3
// RUN: %target-swift-ide-test -range -pos=3:1 -end-pos=4:26 -source-filename %s | %FileCheck %s -check-prefix=CHECK4
// RUN: %target-swift-ide-test -range -pos=3:1 -end-pos=5:13 -source-filename %s | %FileCheck %s -check-prefix=CHECK5
// RUN: %target-swift-ide-test -range -pos=4:1 -end-pos=5:13 -source-filename %s | %FileCheck %s -check-prefix=CHECK6
// RUN: %target-swift-ide-test -range -pos=14:1 -end-pos=17:15 -source-filename %s | %FileCheck %s -check-prefix=CHECK7
// RUN: %target-swift-ide-test -range -pos=31:1 -end-pos=33:15 -source-filename %s | %FileCheck %s -check-prefix=CHECK8
// RUN: %target-swift-ide-test -range -pos=37:1 -end-pos=39:15 -source-filename %s | %FileCheck %s -check-prefix=CHECK9

// CHECK1: <Kind>SingleDecl</Kind>
// CHECK1-NEXT: <Content>func foo1() -> Int { return 0 }</Content>
Expand All @@ -43,20 +67,20 @@ func foo2() {
// CHECK4: <Kind>MultiStatement</Kind>
// CHECK4-NEXT: <Content>aaa = aaa + 3
// CHECK4-NEXT: if aaa == 3 { aaa = 4 }</Content>
// CHECK4-NEXT: <Referenced>aaa</Referenced>
// CHECK4-NEXT: <Referenced>aaa</Referenced><Type>@lvalue Int</Type>
// CHECK4-NEXT: <end>

// CHECK5: <Kind>MultiStatement</Kind>
// CHECK5-NEXT: <Content>aaa = aaa + 3
// CHECK5-NEXT: if aaa == 3 { aaa = 4 }
// CHECK5-NEXT: return aaa</Content>
// CHECK5-NEXT: <Referenced>aaa</Referenced>
// CHECK5-NEXT: <Referenced>aaa</Referenced><Type>@lvalue Int</Type>
// CHECK5-NEXT: <end>

// CHECK6: <Kind>MultiStatement</Kind>
// CHECK6-NEXT: if aaa == 3 { aaa = 4 }
// CHECK6-NEXT: return aaa</Content>
// CHECK6-NEXT: <Referenced>aaa</Referenced>
// CHECK6-NEXT: <Referenced>aaa</Referenced><Type>@lvalue Int</Type>
// CHECK6-NEXT: <end>

// CHECK7: <Kind>MultiStatement</Kind>
Expand All @@ -66,6 +90,29 @@ func foo2() {
// CHECK7-NEXT: print(b + c)</Content>
// CHECK7-NEXT: <Declared>b</Declared>
// CHECK7-NEXT: <Declared>c</Declared>
// CHECK7-NEXT: <Referenced>a</Referenced>
// CHECK7-NEXT: <Referenced>b</Referenced>
// CHECK7-NEXT: <Referenced>a</Referenced><Type>Int</Type>
// CHECK7-NEXT: <Referenced>b</Referenced><Type>@lvalue Int</Type>
// CHECK7-NEXT: <end>

// CHECK8: <Kind>MultiStatement</Kind>
// CHECK8-NEXT: <Content>let c = s.foo() + b
// CHECK8-NEXT: s = s.increment()
// CHECK8-NEXT: return c + b</Content>
// CHECK8-NEXT: <Declared>c</Declared>
// CHECK8-NEXT: <Referenced>s</Referenced><Type>@lvalue S1</Type>
// CHECK8-NEXT: <Referenced>foo</Referenced><Type>(S1) -> () -> Int</Type>
// CHECK8-NEXT: <Referenced>b</Referenced><Type>Int</Type>
// CHECK8-NEXT: <Referenced>increment</Referenced><Type>(inout S1) -> () -> S1</Type>
// CHECK8-NEXT: <end>

// CHECK9: <Kind>MultiStatement</Kind>
// CHECK9-NEXT: <Content>let b = s.a
// CHECK9-NEXT: let c = s.foo() + b
// CHECK9-NEXT: return c + b</Content>
// CHECK9-NEXT: <Declared>b</Declared>
// CHECK9-NEXT: <Declared>c</Declared>
// CHECK9-NEXT: <Referenced>s</Referenced><Type>S1</Type>
// CHECK9-NEXT: <Referenced>a</Referenced><Type>Int</Type>
// CHECK9-NEXT: <Referenced>foo</Referenced><Type>(S1) -> () -> Int</Type>
// CHECK9-NEXT: <Referenced>b</Referenced><Type>Int</Type>
// CHECK9-NEXT: <end>