Skip to content

Commit 83183ab

Browse files
authored
RangeInfo: Add a new range info kind that describes part of a parent expression. rdar://32039874 (#9707)
1 parent 8876655 commit 83183ab

File tree

5 files changed

+95
-9
lines changed

5 files changed

+95
-9
lines changed

include/swift/IDE/Utils.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ enum class RangeKind : int8_t{
222222
SingleDecl,
223223

224224
MultiStatement,
225+
PartOfExpression,
225226
};
226227

227228
struct DeclaredDecl {
@@ -260,9 +261,12 @@ struct ResolvedRangeInfo {
260261
ArrayRef<DeclaredDecl> DeclaredDecls;
261262
ArrayRef<ReferencedDecl> ReferencedDecls;
262263
DeclContext* RangeContext;
264+
Expr* CommonExprParent;
265+
263266
ResolvedRangeInfo(RangeKind Kind, ReturnTyAndWhetherExit ExitInfo,
264267
CharSourceRange Content, DeclContext* RangeContext,
265-
bool HasSingleEntry, bool ThrowingUnhandledError,
268+
Expr *CommonExprParent, bool HasSingleEntry,
269+
bool ThrowingUnhandledError,
266270
OrphanKind Orphan, ArrayRef<ASTNode> ContainedNodes,
267271
ArrayRef<DeclaredDecl> DeclaredDecls,
268272
ArrayRef<ReferencedDecl> ReferencedDecls): Kind(Kind),
@@ -272,9 +276,11 @@ struct ResolvedRangeInfo {
272276
Orphan(Orphan), ContainedNodes(ContainedNodes),
273277
DeclaredDecls(DeclaredDecls),
274278
ReferencedDecls(ReferencedDecls),
275-
RangeContext(RangeContext) {}
279+
RangeContext(RangeContext),
280+
CommonExprParent(CommonExprParent) {}
276281
ResolvedRangeInfo(CharSourceRange Content) :
277-
ResolvedRangeInfo(RangeKind::Invalid, {nullptr, false}, Content, nullptr,
282+
ResolvedRangeInfo(RangeKind::Invalid, {nullptr, false}, Content,
283+
nullptr, /*Commom Expr Parent*/nullptr,
278284
/*Single entry*/true, /*unhandled error*/false,
279285
OrphanKind::None, {}, {}, {}) {}
280286
void print(llvm::raw_ostream &OS);

lib/IDE/SwiftSourceDocInfo.cpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ void ResolvedRangeInfo::print(llvm::raw_ostream &OS) {
221221
case RangeKind::SingleExpression: OS << "SingleExpression"; break;
222222
case RangeKind::SingleDecl: OS << "SingleDecl"; break;
223223
case RangeKind::MultiStatement: OS << "MultiStatement"; break;
224+
case RangeKind::PartOfExpression: OS << "PartOfExpression"; break;
224225
case RangeKind::SingleStatement: OS << "SingleStatement"; break;
225226
case RangeKind::Invalid: OS << "Invalid"; break;
226227
}
@@ -244,6 +245,12 @@ void ResolvedRangeInfo::print(llvm::raw_ostream &OS) {
244245
OS << "</Context>\n";
245246
}
246247

248+
if (CommonExprParent) {
249+
OS << "<Parent>";
250+
OS << Expr::getKindName(CommonExprParent->getKind());
251+
OS << "</Parent>\n";
252+
}
253+
247254
if (!HasSingleEntry) {
248255
OS << "<Entry>Multi</Entry>\n";
249256
}
@@ -394,6 +401,7 @@ struct RangeResolver::Implementation {
394401
switch(Kind) {
395402
case RangeKind::Invalid:
396403
case RangeKind::SingleDecl:
404+
case RangeKind::PartOfExpression:
397405
llvm_unreachable("cannot get type.");
398406

399407
// For a single expression, its type is apparent.
@@ -453,23 +461,29 @@ struct RangeResolver::Implementation {
453461
return ResolvedRangeInfo(RangeKind::SingleExpression,
454462
resolveNodeType(Node, RangeKind::SingleExpression),
455463
Content,
456-
getImmediateContext(), SingleEntry,
464+
getImmediateContext(),
465+
/*Common Parent Expr*/nullptr,
466+
SingleEntry,
457467
UnhandledError, Kind,
458468
llvm::makeArrayRef(ContainedASTNodes),
459469
llvm::makeArrayRef(DeclaredDecls),
460470
llvm::makeArrayRef(ReferencedDecls));
461471
else if (Node.is<Stmt*>())
462472
return ResolvedRangeInfo(RangeKind::SingleStatement,
463473
resolveNodeType(Node, RangeKind::SingleStatement),
464-
Content, getImmediateContext(), SingleEntry,
474+
Content, getImmediateContext(),
475+
/*Common Parent Expr*/nullptr,
476+
SingleEntry,
465477
UnhandledError, Kind,
466478
llvm::makeArrayRef(ContainedASTNodes),
467479
llvm::makeArrayRef(DeclaredDecls),
468480
llvm::makeArrayRef(ReferencedDecls));
469481
else {
470482
assert(Node.is<Decl*>());
471483
return ResolvedRangeInfo(RangeKind::SingleDecl, {nullptr, false}, Content,
472-
getImmediateContext(), SingleEntry,
484+
getImmediateContext(),
485+
/*Common Parent Expr*/nullptr,
486+
SingleEntry,
473487
UnhandledError, Kind,
474488
llvm::makeArrayRef(ContainedASTNodes),
475489
llvm::makeArrayRef(DeclaredDecls),
@@ -523,6 +537,22 @@ struct RangeResolver::Implementation {
523537
}
524538

525539
void leave(ASTNode Node) {
540+
if (!hasResult() && !Node.isImplicit() && nodeContainSelection(Node)) {
541+
if (auto Parent = Node.is<Expr*>() ? Node.get<Expr*>() : nullptr) {
542+
Result = {
543+
RangeKind::PartOfExpression, {nullptr, false}, Content,
544+
getImmediateContext(),
545+
Parent,
546+
hasSingleEntryPoint(ContainedASTNodes),
547+
hasUnhandledError(ContainedASTNodes),
548+
getOrphanKind(ContainedASTNodes),
549+
llvm::makeArrayRef(ContainedASTNodes),
550+
llvm::makeArrayRef(DeclaredDecls),
551+
llvm::makeArrayRef(ReferencedDecls)
552+
};
553+
}
554+
}
555+
526556
assert(ContextStack.back().Parent.getOpaqueValue() == Node.getOpaqueValue());
527557
ContextStack.pop_back();
528558
}
@@ -690,12 +720,13 @@ struct RangeResolver::Implementation {
690720
analyzeDecl(D);
691721
auto &DCInfo = getCurrentDC();
692722
switch (getRangeMatchKind(Node.getSourceRange())) {
693-
case RangeMatchKind::NoneMatch:
723+
case RangeMatchKind::NoneMatch: {
694724
// PatternBindingDecl is not visited; we need to explicitly analyze here.
695725
if (auto *VA = dyn_cast_or_null<VarDecl>(D))
696726
if (auto PBD = VA->getParentPatternBinding())
697727
analyze(PBD);
698728
break;
729+
}
699730
case RangeMatchKind::RangeMatch: {
700731
postAnalysis(Node);
701732

@@ -726,13 +757,13 @@ struct RangeResolver::Implementation {
726757
/* Last node has the type */
727758
resolveNodeType(DCInfo.EndMatches.back(),
728759
RangeKind::MultiStatement), Content,
729-
getImmediateContext(), hasSingleEntryPoint(ContainedASTNodes),
760+
getImmediateContext(), nullptr,
761+
hasSingleEntryPoint(ContainedASTNodes),
730762
hasUnhandledError(ContainedASTNodes),
731763
getOrphanKind(ContainedASTNodes),
732764
llvm::makeArrayRef(ContainedASTNodes),
733765
llvm::makeArrayRef(DeclaredDecls),
734766
llvm::makeArrayRef(ReferencedDecls)};
735-
return;
736767
}
737768
}
738769

@@ -746,6 +777,17 @@ struct RangeResolver::Implementation {
746777
return true;
747778
}
748779

780+
bool nodeContainSelection(ASTNode Node) {
781+
// If the selection starts before the node, return false.
782+
if (SM.isBeforeInBuffer(Start, Node.getStartLoc()))
783+
return false;
784+
// If the node ends before the selection, return false.
785+
if (SM.isBeforeInBuffer(Lexer::getLocForEndOfToken(SM, Node.getEndLoc()), End))
786+
return false;
787+
// Contained.
788+
return true;
789+
}
790+
749791
bool shouldAnalyze(ASTNode Node) {
750792
// Avoid analyzing implicit nodes.
751793
if (Node.isImplicit())

test/IDE/range_info_expr.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,43 @@ public class CC {
1010
return 0
1111
}
1212
}
13+
func getSelf() -> CC {
14+
return self
15+
}
16+
func getSelf(_ i : Int) -> CC {
17+
return self
18+
}
19+
}
20+
21+
func foo1(_ c : CC) -> CC{
22+
_ = c.getSelf().getSelf().getSelf().getSelf()
23+
_ = c.getSelf(1).getSelf(1).getSelf(1).getSelf(1)
24+
return c.getSelf()
1325
}
1426

1527
// RUN: %target-swift-ide-test -range -pos=7:8 -end-pos=7:19 -source-filename %s | %FileCheck %s -check-prefix=CHECK-BOOL
1628
// CHECK-BOOL: <Type>Bool</Type>
29+
30+
// RUN: %target-swift-ide-test -range -pos=22:39 -end-pos=22:48 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR
31+
// RUN: %target-swift-ide-test -range -pos=22:29 -end-pos=22:38 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR
32+
// RUN: %target-swift-ide-test -range -pos=22:19 -end-pos=22:28 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR
33+
// RUN: %target-swift-ide-test -range -pos=22:9 -end-pos=22:18 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR
34+
35+
// RUN: %target-swift-ide-test -range -pos=23:42 -end-pos=23:52 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR1
36+
// RUN: %target-swift-ide-test -range -pos=23:31 -end-pos=23:41 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR1
37+
// RUN: %target-swift-ide-test -range -pos=23:20 -end-pos=23:30 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR1
38+
// RUN: %target-swift-ide-test -range -pos=23:9 -end-pos=23:19 -source-filename %s | %FileCheck %s -check-prefix=CHECK-PART-EXPR1
39+
40+
// CHECK-PART-EXPR: <Kind>PartOfExpression</Kind>
41+
// CHECK-PART-EXPR-NEXT: <Content>getSelf()</Content>
42+
// CHECK-PART-EXPR-NEXT: <Context>swift_ide_test.(file).foo1(_:)</Context>
43+
// CHECK-PART-EXPR-NEXT: <Parent>Call</Parent>
44+
// CHECK-PART-EXPR-NEXT: <ASTNodes>2</ASTNodes>
45+
// CHECK-PART-EXPR-NEXT: <end>
46+
47+
// CHECK-PART-EXPR1: <Kind>PartOfExpression</Kind>
48+
// CHECK-PART-EXPR2: <Content>getSelf(1)</Content>
49+
// CHECK-PART-EXPR2: <Context>swift_ide_test.(file).foo1(_:)</Context>
50+
// CHECK-PART-EXPR2: <Parent>Call</Parent>
51+
// CHECK-PART-EXPR2: <ASTNodes>2</ASTNodes>
52+
// CHECK-PART-EXPR2: <end>

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ getUIDForRangeKind(swift::ide::RangeKind Kind) {
567567
case swift::ide::RangeKind::SingleStatement: return KindRangeSingleStatement;
568568
case swift::ide::RangeKind::SingleDecl: return KindRangeSingleDeclaration;
569569
case swift::ide::RangeKind::MultiStatement: return KindRangeMultiStatement;
570+
case swift::ide::RangeKind::PartOfExpression: return KindRangeInvalid;
570571
case swift::ide::RangeKind::Invalid: return KindRangeInvalid;
571572
}
572573

tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,7 @@ static void resolveRange(SwiftLangSupport &Lang,
13571357
Receiver(Result);
13581358
return;
13591359
}
1360+
case RangeKind::PartOfExpression:
13601361
case RangeKind::Invalid:
13611362
if (!getPreviousASTSnaps().empty()) {
13621363
// Attempt again using the up-to-date AST.

0 commit comments

Comments
 (0)