Skip to content
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

Index expressible-by-literal expressions. #60432

Merged
merged 1 commit into from
Aug 30, 2022
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
16 changes: 8 additions & 8 deletions lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,12 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
->GetSubExpr()->getReferencedDecl(stopAtParenExpr)

NO_REFERENCE(Error);
NO_REFERENCE(NilLiteral);
NO_REFERENCE(IntegerLiteral);
NO_REFERENCE(FloatLiteral);
NO_REFERENCE(BooleanLiteral);
NO_REFERENCE(StringLiteral);
NO_REFERENCE(InterpolatedStringLiteral);
SIMPLE_REFERENCE(NilLiteral, getInitializer);
SIMPLE_REFERENCE(IntegerLiteral, getInitializer);
SIMPLE_REFERENCE(FloatLiteral, getInitializer);
SIMPLE_REFERENCE(BooleanLiteral, getInitializer);
SIMPLE_REFERENCE(StringLiteral, getInitializer);
SIMPLE_REFERENCE(InterpolatedStringLiteral, getInitializer);
Comment on lines +323 to +328
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change cursor info at all? Could add some tests for that (though I'm not sure anyone would think to jump to definition on a literal 😅). It would also be a little weird for eg. the collection cases since I (think) only the first character (eg. [) would actually return a result.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it doesn't; a quick check adding one of these to SourceKit/CursorInfo/cursor_info_expressions came back with <empty cursor info; internal diagnostic: "Resolved to incomplete expression or statement."> at the literal's location.

NO_REFERENCE(RegexLiteral);
NO_REFERENCE(ObjectLiteral);
NO_REFERENCE(MagicIdentifierLiteral);
Expand Down Expand Up @@ -371,8 +371,8 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
PASS_THROUGH_REFERENCE(OptionalTry, getSubExpr);

NO_REFERENCE(Tuple);
NO_REFERENCE(Array);
NO_REFERENCE(Dictionary);
SIMPLE_REFERENCE(Array, getInitializer);
SIMPLE_REFERENCE(Dictionary, getInitializer);

case ExprKind::Subscript: {
auto subscript = cast<SubscriptExpr>(this);
Expand Down
36 changes: 25 additions & 11 deletions lib/IDE/SourceEntityWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,18 +386,32 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
}
}

if (!isa<InOutExpr>(E) &&
!isa<LoadExpr>(E) &&
!isa<OpenExistentialExpr>(E) &&
if (!isa<InOutExpr>(E) && !isa<LoadExpr>(E) && !isa<OpenExistentialExpr>(E) &&
!isa<MakeTemporarilyEscapableExpr>(E) &&
!isa<CollectionUpcastConversionExpr>(E) &&
!isa<OpaqueValueExpr>(E) &&
!isa<SubscriptExpr>(E) &&
!isa<KeyPathExpr>(E) &&
E->isImplicit())
return { true, E };

if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
!isa<CollectionUpcastConversionExpr>(E) && !isa<OpaqueValueExpr>(E) &&
!isa<SubscriptExpr>(E) && !isa<KeyPathExpr>(E) && !isa<LiteralExpr>(E) &&
!isa<CollectionExpr>(E) && E->isImplicit())
return {true, E};

if (auto LE = dyn_cast<LiteralExpr>(E)) {
if (LE->getInitializer() &&
!passReference(LE->getInitializer().getDecl(), LE->getType(), {},
LE->getSourceRange(),
ReferenceMetaData(SemaReferenceKind::DeclRef, OpAccess,
/*isImplicit=*/true))) {
return doStopTraversal();
}
return {true, E};
} else if (auto CE = dyn_cast<CollectionExpr>(E)) {
if (CE->getInitializer() &&
!passReference(CE->getInitializer().getDecl(), CE->getType(), {},
CE->getSourceRange(),
ReferenceMetaData(SemaReferenceKind::DeclRef, OpAccess,
/*isImplicit=*/true))) {
return doStopTraversal();
}
return {true, E};
} else if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
if (auto *module = dyn_cast<ModuleDecl>(DRE->getDecl())) {
if (!passReference(ModuleEntity(module),
{module->getName(), E->getLoc()}))
Expand Down
7 changes: 7 additions & 0 deletions lib/IDE/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,13 @@ bool swift::ide::isBeingCalled(ArrayRef<Expr *> ExprStack) {
Expr *Target = ExprStack.back();
auto UnderlyingDecl = getReferencedDecl(Target).second;
for (Expr *E: reverse(ExprStack)) {
auto *LE = dyn_cast<LiteralExpr>(E);
if (LE && getReferencedDecl(LE).second == UnderlyingDecl)
return true;
auto *CE = dyn_cast<CollectionExpr>(E);
if (CE && getReferencedDecl(CE).second == UnderlyingDecl)
return true;

auto *AE = dyn_cast<ApplyExpr>(E);
if (!AE || AE->isImplicit())
continue;
Expand Down
135 changes: 135 additions & 0 deletions test/Index/index_expressible_by_literals.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s

struct CustomInteger: ExpressibleByIntegerLiteral {
init(integerLiteral: Int) {}
}
struct CustomFloat: ExpressibleByFloatLiteral {
init(floatLiteral: Double) {}
}
struct CustomBool: ExpressibleByBooleanLiteral {
init(booleanLiteral: Bool) {}
}
struct CustomNil: ExpressibleByNilLiteral {
init(nilLiteral: ()) {}
}
struct CustomString: ExpressibleByStringLiteral {
init(stringLiteral: StaticString) {}
}
struct CustomScalar: ExpressibleByUnicodeScalarLiteral {
init(unicodeScalarLiteral: Unicode.Scalar) {}
}
struct CustomCharacter: ExpressibleByExtendedGraphemeClusterLiteral {
init(extendedGraphemeClusterLiteral: Character) {}
}
struct CustomArray: ExpressibleByArrayLiteral {
init(arrayLiteral: Int...) {}
}
struct CustomDictionary: ExpressibleByDictionaryLiteral {
init(dictionaryLiteral: (Int, Int)...) {}
}
struct CustomInterpolation: ExpressibleByStringInterpolation {
init(stringInterpolation: StringInterpolation) {}
init(stringLiteral: String) {}
}

func customInteger() {
// CHECK: [[@LINE+2]]:26 | constructor/Swift | init(integerLiteral:) | s:14swift_ide_test13CustomIntegerV14integerLiteralACSi_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInteger() | s:14swift_ide_test13customIntegeryyF
let _: CustomInteger = 100
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(integerLiteral:) | s:14swift_ide_test13CustomIntegerV14integerLiteralACSi_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInteger() | s:14swift_ide_test13customIntegeryyF
_ = 100 as CustomInteger
// CHECK: [[@LINE+2]]:21 | constructor/Swift | init(integerLiteral:) | s:14swift_ide_test13CustomIntegerV14integerLiteralACSi_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInteger() | s:14swift_ide_test13customIntegeryyF
_ = CustomInteger(100)
}
func customFloat() {
// CHECK: [[@LINE+2]]:24 | constructor/Swift | init(floatLiteral:) | s:14swift_ide_test11CustomFloatV12floatLiteralACSd_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customFloat() | s:14swift_ide_test11customFloatyyF
let _: CustomFloat = -1.23
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(floatLiteral:) | s:14swift_ide_test11CustomFloatV12floatLiteralACSd_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customFloat() | s:14swift_ide_test11customFloatyyF
_ = -1.23 as CustomFloat
// CHECK: [[@LINE+2]]:19 | constructor/Swift | init(floatLiteral:) | s:14swift_ide_test11CustomFloatV12floatLiteralACSd_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customFloat() | s:14swift_ide_test11customFloatyyF
_ = CustomFloat(-1.23)
}
func customBool() {
// CHECK: [[@LINE+2]]:23 | constructor/Swift | init(booleanLiteral:) | s:14swift_ide_test10CustomBoolV14booleanLiteralACSb_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customBool() | s:14swift_ide_test10customBoolyyF
let _: CustomBool = true
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(booleanLiteral:) | s:14swift_ide_test10CustomBoolV14booleanLiteralACSb_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customBool() | s:14swift_ide_test10customBoolyyF
_ = false as CustomBool
// CHECK: [[@LINE+2]]:18 | constructor/Swift | init(booleanLiteral:) | s:14swift_ide_test10CustomBoolV14booleanLiteralACSb_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customBool() | s:14swift_ide_test10customBoolyyF
_ = CustomBool(true)
}
func customNil() {
// CHECK: [[@LINE+2]]:22 | constructor/Swift | init(nilLiteral:) | s:14swift_ide_test9CustomNilV10nilLiteralACyt_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customNil() | s:14swift_ide_test9customNilyyF
let _: CustomNil = nil
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(nilLiteral:) | s:14swift_ide_test9CustomNilV10nilLiteralACyt_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customNil() | s:14swift_ide_test9customNilyyF
_ = nil as CustomNil
}
func customString() {
// CHECK: [[@LINE+2]]:25 | constructor/Swift | init(stringLiteral:) | s:14swift_ide_test12CustomStringV13stringLiteralACs06StaticE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customString() | s:14swift_ide_test12customStringyyF
let _: CustomString = "abc"
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(stringLiteral:) | s:14swift_ide_test12CustomStringV13stringLiteralACs06StaticE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customString() | s:14swift_ide_test12customStringyyF
_ = "abc" as CustomString
// CHECK: [[@LINE+2]]:20 | constructor/Swift | init(stringLiteral:) | s:14swift_ide_test12CustomStringV13stringLiteralACs06StaticE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customString() | s:14swift_ide_test12customStringyyF
_ = CustomString("abc")
}
func customScalar() {
// CHECK: [[@LINE+2]]:25 | constructor/Swift | init(unicodeScalarLiteral:) | s:14swift_ide_test12CustomScalarV07unicodeE7LiteralACs7UnicodeO0E0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customScalar() | s:14swift_ide_test12customScalaryyF
let _: CustomScalar = "a"
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(unicodeScalarLiteral:) | s:14swift_ide_test12CustomScalarV07unicodeE7LiteralACs7UnicodeO0E0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customScalar() | s:14swift_ide_test12customScalaryyF
_ = "a" as CustomScalar
// CHECK: [[@LINE+2]]:20 | constructor/Swift | init(unicodeScalarLiteral:) | s:14swift_ide_test12CustomScalarV07unicodeE7LiteralACs7UnicodeO0E0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customScalar() | s:14swift_ide_test12customScalaryyF
_ = CustomScalar("a")
}
func customCharacter() {
// CHECK: [[@LINE+2]]:28 | constructor/Swift | init(extendedGraphemeClusterLiteral:) | s:14swift_ide_test15CustomCharacterV30extendedGraphemeClusterLiteralACSJ_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customCharacter() | s:14swift_ide_test15customCharacteryyF
let _: CustomCharacter = "a"
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(extendedGraphemeClusterLiteral:) | s:14swift_ide_test15CustomCharacterV30extendedGraphemeClusterLiteralACSJ_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customCharacter() | s:14swift_ide_test15customCharacteryyF
_ = "a" as CustomCharacter
// CHECK: [[@LINE+2]]:23 | constructor/Swift | init(extendedGraphemeClusterLiteral:) | s:14swift_ide_test15CustomCharacterV30extendedGraphemeClusterLiteralACSJ_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customCharacter() | s:14swift_ide_test15customCharacteryyF
_ = CustomCharacter("a")
}
func customArray() {
// CHECK: [[@LINE+2]]:24 | constructor/Swift | init(arrayLiteral:) | s:14swift_ide_test11CustomArrayV12arrayLiteralACSid_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customArray() | s:14swift_ide_test11customArrayyyF
let _: CustomArray = [1, 2, 3]
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(arrayLiteral:) | s:14swift_ide_test11CustomArrayV12arrayLiteralACSid_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customArray() | s:14swift_ide_test11customArrayyyF
_ = [1, 2, 3] as CustomArray
}
func customDictionary() {
// CHECK: [[@LINE+2]]:29 | constructor/Swift | init(dictionaryLiteral:) | s:14swift_ide_test16CustomDictionaryV17dictionaryLiteralACSi_Sitd_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customDictionary() | s:14swift_ide_test16customDictionaryyyF
let _: CustomDictionary = [1: 1, 2: 2, 3: 3]
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(dictionaryLiteral:) | s:14swift_ide_test16CustomDictionaryV17dictionaryLiteralACSi_Sitd_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customDictionary() | s:14swift_ide_test16customDictionaryyyF
_ = [1: 1, 2: 2, 3: 3] as CustomDictionary
}
func customInterpolation() {
// CHECK: [[@LINE+2]]:32 | constructor/Swift | init(stringInterpolation:) | s:14swift_ide_test19CustomInterpolationV06stringE0ACs013DefaultStringE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInterpolation() | s:14swift_ide_test19customInterpolationyyF
let _: CustomInterpolation = "a\(0)b"
// CHECK: [[@LINE+2]]:7 | constructor/Swift | init(stringInterpolation:) | s:14swift_ide_test19CustomInterpolationV06stringE0ACs013DefaultStringE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInterpolation() | s:14swift_ide_test19customInterpolationyyF
_ = "a\(0)b" as CustomInterpolation
// CHECK: [[@LINE+2]]:27 | constructor/Swift | init(stringInterpolation:) | s:14swift_ide_test19CustomInterpolationV06stringE0ACs013DefaultStringE0V_tcfc | Ref,Call,Impl,RelCall,RelCont |
// CHECK-NEXT: RelCall,RelCont | function/Swift | customInterpolation() | s:14swift_ide_test19customInterpolationyyF
_ = CustomInterpolation("a\(0)b")
}
7 changes: 7 additions & 0 deletions test/SourceKit/Indexing/index_big_array.swift.response
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
key.usr: "s:Sf",
key.line: 1,
key.column: 23
},
{
key.kind: source.lang.swift.ref.function.constructor,
key.usr: "s:Sa12arrayLiteralSayxGxd_tcfc",
key.line: 1,
key.column: 32,
key.is_implicit: 1
}
]
}