mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Enable indexing for refs to synthesized declarations.
Based on feedback in PR https://github.com/swiftlang/swift/pull/69460, enabling indexing for synthesized decls because they are usable by users and make sense to appear in the indexstore. Sets `synthesized` on some additional decls: - derived `hashInto(...)` - Objc properties and methods derived from Objc protocols https://github.com/apple/swift/issues/67446
This commit is contained in:
@@ -9151,6 +9151,9 @@ ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl,
|
||||
|
||||
auto updateMirroredDecl = [&](Decl *result) {
|
||||
result->setImplicit();
|
||||
if (auto VD = dyn_cast<ValueDecl>(result)) {
|
||||
VD->setSynthesized();
|
||||
}
|
||||
|
||||
// Map the Clang attributes onto Swift attributes.
|
||||
importAttributes(decl, result);
|
||||
|
||||
@@ -1085,7 +1085,8 @@ private:
|
||||
D = cast<VarDecl>(D)->getCanonicalVarDecl();
|
||||
}
|
||||
|
||||
if (D->isImplicit() && !shouldIndexImplicitDecl(D, IsRef))
|
||||
if (!D->isSynthesized() && D->isImplicit() &&
|
||||
!shouldIndexImplicitDecl(D, IsRef))
|
||||
return false;
|
||||
|
||||
// Do not handle non-public imported decls.
|
||||
|
||||
@@ -251,6 +251,7 @@ deriveComparable_lt(
|
||||
/*ThrownType=*/Type(),
|
||||
/*GenericParams=*/nullptr, params, boolTy, parentDC);
|
||||
comparableDecl->setUserAccessible(false);
|
||||
comparableDecl->setSynthesized();
|
||||
|
||||
// Add the @_implements(Comparable, < (_:_:)) attribute
|
||||
if (generatedIdentifier != C.Id_LessThanOperator) {
|
||||
|
||||
@@ -410,6 +410,7 @@ deriveEquatable_eq(
|
||||
/*Throws=*/false, /*ThrownType=*/Type(),
|
||||
/*GenericParams=*/nullptr, params, boolTy, parentDC);
|
||||
eqDecl->setUserAccessible(false);
|
||||
eqDecl->setSynthesized();
|
||||
|
||||
// Add the @_implements(Equatable, ==(_:_:)) attribute
|
||||
if (generatedIdentifier != C.Id_EqualsOperator) {
|
||||
@@ -546,6 +547,7 @@ deriveHashable_hashInto(
|
||||
/*Async=*/false,
|
||||
/*Throws=*/false, /*ThrownType=*/Type(),
|
||||
/*GenericParams=*/nullptr, params, returnType, parentDC);
|
||||
hashDecl->setSynthesized();
|
||||
hashDecl->setBodySynthesizer(bodySynthesizer);
|
||||
hashDecl->copyFormalAccessFrom(derived.Nominal,
|
||||
/*sourceIsParentContext=*/true);
|
||||
|
||||
@@ -13,8 +13,8 @@ struct GenericTangentVectorMember<T: Differentiable>: Differentiable,
|
||||
// CHECK-AST: internal var x: T.TangentVector
|
||||
// CHECK-AST: internal static func + (lhs: GenericTangentVectorMember<T>, rhs: GenericTangentVectorMember<T>) -> GenericTangentVectorMember<T>
|
||||
// CHECK-AST: internal static func - (lhs: GenericTangentVectorMember<T>, rhs: GenericTangentVectorMember<T>) -> GenericTangentVectorMember<T>
|
||||
// CHECK-AST: @_implements(Equatable, ==(_:_:)) internal static func __derived_struct_equals(_ a: GenericTangentVectorMember<T>, _ b: GenericTangentVectorMember<T>) -> Bool
|
||||
// CHECK-AST: internal typealias TangentVector = GenericTangentVectorMember<T>
|
||||
// CHECK-AST: @_implements(Equatable, ==(_:_:)) internal static func __derived_struct_equals(_ a: GenericTangentVectorMember<T>, _ b: GenericTangentVectorMember<T>) -> Bool
|
||||
// CHECK-AST: internal init(x: T.TangentVector)
|
||||
// CHECK-AST: internal static var zero: GenericTangentVectorMember<T> { get }
|
||||
|
||||
|
||||
44
test/Index/index_imported_objc.swift
Normal file
44
test/Index/index_imported_objc.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %empty-directory(%t/mods)
|
||||
// RUN: split-file %s %t
|
||||
|
||||
// RUN: %target-swift-ide-test -print-indexed-symbols -enable-objc-interop -source-filename %t/ObjcUser.swift -Xcc -fmodule-map-file=%t/module.modulemap | %FileCheck -dump-input=always %t/ObjcUser.swift
|
||||
|
||||
//--- objc_decls.h
|
||||
#import <Foundation/Foundation.h>
|
||||
@protocol MemberAdding<NSObject>
|
||||
@property int protocolAddedProperty;
|
||||
-(void)protocolAddedMethod;
|
||||
@end
|
||||
|
||||
@interface ObjCClass : NSObject
|
||||
@property int baseClassProperty;
|
||||
@end
|
||||
|
||||
@interface ObjCClass (category) <MemberAdding>
|
||||
@property int categoryAddedProperty;
|
||||
@end
|
||||
|
||||
//--- module.modulemap
|
||||
module objc_decls {
|
||||
header "objc_decls.h"
|
||||
export *
|
||||
}
|
||||
|
||||
//--- ObjcUser.swift
|
||||
import objc_decls
|
||||
func test() { // CHECK: [[@LINE]]:6 | function/Swift | test() | [[s:.*]] | Def | rel: 0
|
||||
let c = ObjCClass()
|
||||
let _ = c.baseClassProperty
|
||||
// CHECK: [[@LINE-1]]:13 | instance-property/Swift | baseClassProperty | c:objc(cs)ObjCClass(py)baseClassProperty | Ref,Read,Dyn,RelRec,RelCont | rel: 2
|
||||
let _ = c.categoryAddedProperty
|
||||
// CHECK: [[@LINE-1]]:13 | instance-property/Swift | categoryAddedProperty | c:objc(cs)ObjCClass(py)categoryAddedProperty | Ref,Read,Dyn,RelRec,RelCont | rel: 2
|
||||
// CHECK: [[@LINE-2]]:13 | instance-method/acc-get/Swift | getter:categoryAddedProperty | c:@CM@objc_decls@@objc(cs)ObjCClass(im)categoryAddedProperty | Ref,Call,Dyn,Impl,RelRec,RelCall,RelCont | rel: 2
|
||||
let _ = c.protocolAddedProperty
|
||||
// CHECK: [[@LINE-1]]:13 | instance-property/Swift | protocolAddedProperty | c:objc(pl)MemberAdding(py)protocolAddedProperty | Ref,Read,Dyn,RelRec,RelCont | rel: 2
|
||||
// CHECK: [[@LINE-2]]:13 | instance-method/acc-get/Swift | getter:protocolAddedProperty | c:@CM@objc_decls@@objc(cs)ObjCClass(im)protocolAddedProperty | Ref,Call,Dyn,Impl,RelRec,RelCall,RelCont | rel: 2
|
||||
c.protocolAddedMethod()
|
||||
// CHECK: [[@LINE-1]]:5 | instance-method/Swift | protocolAddedMethod() | c:objc(pl)MemberAdding(im)protocolAddedMethod | Ref,Call,Dyn,RelRec,RelCall,RelCont | rel: 2
|
||||
}
|
||||
17
test/Index/index_refs_to_synthesized_decls.swift
Normal file
17
test/Index/index_refs_to_synthesized_decls.swift
Normal file
@@ -0,0 +1,17 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
//
|
||||
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck -check-prefix=CHECK %s
|
||||
|
||||
public struct CustomFoo: Equatable, Hashable {
|
||||
public let a: Int
|
||||
public let b: String
|
||||
}
|
||||
func testFoo() {
|
||||
var hasher = Hasher()
|
||||
let f = CustomFoo(a: 0, b: "b")
|
||||
// CHECK: [[@LINE+1]]:7 | instance-method/Swift | hash(into:) | s:14swift_ide_test9CustomFooV4hash4intoys6HasherVz_tF | {{.*}}Ref
|
||||
f.hash(into: &hasher)
|
||||
hasher.finalize()
|
||||
// CHECK: [[@LINE+1]]:11 | static-method/Swift | __derived_struct_equals(_:_:) | s:14swift_ide_test9CustomFooV23__derived_struct_equalsySbAC_ACtFZ | {{.*}}Ref
|
||||
_ = f == CustomFoo(a: 0, b: "b")
|
||||
}
|
||||
@@ -319,7 +319,11 @@ struct SomeStruct {
|
||||
// CHECK-NEXT: RelCont | static-property/Swift | staticProperty | {{.*}}
|
||||
|
||||
lazy var lazyProperty: Int = { 1 }()
|
||||
// CHECK: [[@LINE-1]]:28 | struct/Swift | Int | {{.*}} | Ref,RelCont | rel: 1
|
||||
// CHECK: [[@LINE-1]]:14 | instance-method/acc-get/Swift | getter:lazyProperty | s:14swift_ide_test10SomeStructV12lazyPropertySivg | Def,Impl,RelChild,RelAcc | rel: 1
|
||||
// CHECK-NEXT: RelChild,RelAcc | instance-property/Swift | lazyProperty | s:14swift_ide_test10SomeStructV12lazyPropertySivp
|
||||
// CHECK: [[@LINE-3]]:14 | instance-method/acc-set/Swift | setter:lazyProperty | s:14swift_ide_test10SomeStructV12lazyPropertySivs | Def,Impl,RelChild,RelAcc | rel: 1
|
||||
// CHECK-NEXT: RelChild,RelAcc | instance-property/Swift | lazyProperty | s:14swift_ide_test10SomeStructV12lazyPropertySivp
|
||||
// CHECK: [[@LINE-5]]:28 | struct/Swift | Int | {{.*}} | Ref,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | instance-property/Swift | lazyProperty | {{.*}}
|
||||
|
||||
@Wrapped
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
let y: String
|
||||
|
||||
// CHECK: nonisolated public static func == (a: Library.X1, b: Library.X1) -> Swift.Bool
|
||||
// CHECK: nonisolated public func hash(into hasher: inout Swift.Hasher)
|
||||
// CHECK: nonisolated public func encode(to encoder: any Swift.Encoder) throws
|
||||
// CHECK: nonisolated public func hash(into hasher: inout Swift.Hasher)
|
||||
// CHECK: nonisolated public var hashValue: Swift.Int
|
||||
// CHECK: nonisolated public init(from decoder: any Swift.Decoder) throws
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ final class Final<T> {
|
||||
// CHECK: init(x: T)
|
||||
// CHECK: enum CodingKeys : CodingKey {
|
||||
// CHECK: case x
|
||||
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Final<T>.CodingKeys, _ b: Final<T>.CodingKeys) -> Bool
|
||||
// CHECK: func hash(into hasher: inout Hasher)
|
||||
// CHECK: init?(stringValue: String)
|
||||
// CHECK: init?(intValue: Int)
|
||||
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Final<T>.CodingKeys, _ b: Final<T>.CodingKeys) -> Bool
|
||||
// CHECK: func hash(into hasher: inout Hasher)
|
||||
// CHECK: var hashValue: Int { get }
|
||||
// CHECK: var intValue: Int? { get }
|
||||
// CHECK: var stringValue: String { get }
|
||||
@@ -30,10 +30,10 @@ class Nonfinal<T> {
|
||||
// CHECK: init(x: T)
|
||||
// CHECK: enum CodingKeys : CodingKey {
|
||||
// CHECK: case x
|
||||
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Nonfinal<T>.CodingKeys, _ b: Nonfinal<T>.CodingKeys) -> Bool
|
||||
// CHECK: func hash(into hasher: inout Hasher)
|
||||
// CHECK: init?(stringValue: String)
|
||||
// CHECK: init?(intValue: Int)
|
||||
// CHECK: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Nonfinal<T>.CodingKeys, _ b: Nonfinal<T>.CodingKeys) -> Bool
|
||||
// CHECK: func hash(into hasher: inout Hasher)
|
||||
// CHECK: var hashValue: Int { get }
|
||||
// CHECK: var intValue: Int? { get }
|
||||
// CHECK: var stringValue: String { get }
|
||||
@@ -54,10 +54,10 @@ class Nonfinal<T> {
|
||||
|
||||
// Make sure that CodingKeys members are actually emitted.
|
||||
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}21__derived_enum_equalsySbAFyx_G_AHtFZ : $@convention(method) <T> (Final<T>.CodingKeys, Final<T>.CodingKeys, @thin Final<T>.CodingKeys.Type) -> Bool {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}4hash4intoys6HasherVz_tF : $@convention(method) <T> (@inout Hasher, Final<T>.CodingKeys) -> () {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}11stringValueAFyx_GSgSS_tcfC : $@convention(method) <T> (@owned String, @thin Final<T>.CodingKeys.Type) -> Optional<Final<T>.CodingKeys> {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}8intValueAFyx_GSgSi_tcfC : $@convention(method) <T> (Int, @thin Final<T>.CodingKeys.Type) -> Optional<Final<T>.CodingKeys> {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}21__derived_enum_equalsySbAFyx_G_AHtFZ : $@convention(method) <T> (Final<T>.CodingKeys, Final<T>.CodingKeys, @thin Final<T>.CodingKeys.Type) -> Bool {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}4hash4intoys6HasherVz_tF : $@convention(method) <T> (@inout Hasher, Final<T>.CodingKeys) -> () {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}9hashValueSivg : $@convention(method) <T> (Final<T>.CodingKeys) -> Int {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}8intValueSiSgvg : $@convention(method) <T> (Final<T>.CodingKeys) -> Optional<Int> {
|
||||
// CHECK-LABEL: sil private [ossa] @$s29synthesized_conformance_class5FinalC10CodingKeys{{.*}}11stringValueSSvg : $@convention(method) <T> (Final<T>.CodingKeys) -> @owned String {
|
||||
|
||||
@@ -9,11 +9,11 @@ struct Struct<T> {
|
||||
// CHECK: @_hasStorage var x: T { get set }
|
||||
// CHECK: enum CodingKeys : CodingKey {
|
||||
// CHECK: case x
|
||||
// CHECK: init?(stringValue: String)
|
||||
// CHECK: init?(intValue: Int)
|
||||
// CHECK-FRAGILE: @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: Struct<T>.CodingKeys, _ b: Struct<T>.CodingKeys) -> Bool
|
||||
// CHECK-RESILIENT: static func == (a: Struct<T>.CodingKeys, b: Struct<T>.CodingKeys) -> Bool
|
||||
// CHECK: func hash(into hasher: inout Hasher)
|
||||
// CHECK: init?(stringValue: String)
|
||||
// CHECK: init?(intValue: Int)
|
||||
// CHECK: var hashValue: Int { get }
|
||||
// CHECK: var intValue: Int? { get }
|
||||
// CHECK: var stringValue: String { get }
|
||||
|
||||
@@ -52,19 +52,6 @@ enum HasAssociatedValues: Hashable {
|
||||
// CHECK: case c
|
||||
case c
|
||||
|
||||
// CHECK: internal func hash(into hasher: inout Hasher) {
|
||||
// CHECK-NEXT: switch self {
|
||||
// CHECK-NEXT: case .a(let a0):
|
||||
// CHECK-NEXT: hasher.combine(0)
|
||||
// CHECK-NEXT: hasher.combine(a0)
|
||||
// CHECK-NEXT: case .b(let a0):
|
||||
// CHECK-NEXT: hasher.combine(1)
|
||||
// CHECK-NEXT: hasher.combine(a0)
|
||||
// CHECK-NEXT: case .c:
|
||||
// CHECK-NEXT: hasher.combine(2)
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: @_implements(Equatable, ==(_:_:)) internal static func __derived_enum_equals(_ a: HasAssociatedValues, _ b: HasAssociatedValues) -> Bool {
|
||||
// CHECK-NEXT: switch (a, b) {
|
||||
// CHECK-NEXT: case (.a(let l0), .a(let r0)):
|
||||
@@ -84,6 +71,19 @@ enum HasAssociatedValues: Hashable {
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: internal func hash(into hasher: inout Hasher) {
|
||||
// CHECK-NEXT: switch self {
|
||||
// CHECK-NEXT: case .a(let a0):
|
||||
// CHECK-NEXT: hasher.combine(0)
|
||||
// CHECK-NEXT: hasher.combine(a0)
|
||||
// CHECK-NEXT: case .b(let a0):
|
||||
// CHECK-NEXT: hasher.combine(1)
|
||||
// CHECK-NEXT: hasher.combine(a0)
|
||||
// CHECK-NEXT: case .c:
|
||||
// CHECK-NEXT: hasher.combine(2)
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: internal var hashValue: Int {
|
||||
// CHECK-NEXT: get {
|
||||
// CHECK-NEXT: return _hashValue(for: self)
|
||||
@@ -145,16 +145,6 @@ enum HasAssociatedValuesAndUnavailableElement: Hashable {
|
||||
@available(*, unavailable)
|
||||
case b(String)
|
||||
|
||||
// CHECK: internal func hash(into hasher: inout Hasher) {
|
||||
// CHECK-NEXT: switch self {
|
||||
// CHECK-NEXT: case .a(let a0):
|
||||
// CHECK-NEXT: hasher.combine(0)
|
||||
// CHECK-NEXT: hasher.combine(a0)
|
||||
// CHECK-NEXT: case .b:
|
||||
// CHECK-NEXT: _diagnoseUnavailableCodeReached{{.*}}()
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: @_implements(Equatable, ==(_:_:)) internal static func __derived_enum_equals(_ a: HasAssociatedValuesAndUnavailableElement, _ b: HasAssociatedValuesAndUnavailableElement) -> Bool {
|
||||
// CHECK-NEXT: switch (a, b) {
|
||||
// CHECK-NEXT: case (.a(let l0), .a(let r0)):
|
||||
@@ -169,6 +159,17 @@ enum HasAssociatedValuesAndUnavailableElement: Hashable {
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
// CHECK: internal func hash(into hasher: inout Hasher) {
|
||||
// CHECK-NEXT: switch self {
|
||||
// CHECK-NEXT: case .a(let a0):
|
||||
// CHECK-NEXT: hasher.combine(0)
|
||||
// CHECK-NEXT: hasher.combine(a0)
|
||||
// CHECK-NEXT: case .b:
|
||||
// CHECK-NEXT: _diagnoseUnavailableCodeReached{{.*}}()
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: internal var hashValue: Int {
|
||||
// CHECK-NEXT: get {
|
||||
// CHECK-NEXT: return _hashValue(for: self)
|
||||
|
||||
Reference in New Issue
Block a user