mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ModuleInterface] Add printing for new attributes
Specially print @_hasMissingDesignatedInitializers and @_inheritsConvenienceInitializers in module interfaces Fixes rdar://51249311
This commit is contained in:
committed by
Robert Widmann
parent
283854a012
commit
511db0c90a
@@ -990,6 +990,22 @@ void PrintAST::printAttributes(const Decl *D) {
|
||||
Printer << " ";
|
||||
}
|
||||
}
|
||||
|
||||
// If the declaration has designated inits that won't be visible to
|
||||
// clients, or if it inherits superclass convenience initializers,
|
||||
// then print those attributes specially.
|
||||
if (auto CD = dyn_cast<ClassDecl>(D)) {
|
||||
if (Options.PrintImplicitAttrs) {
|
||||
if (CD->inheritsSuperclassInitializers()) {
|
||||
Printer.printAttrName("@_inheritsConvenienceInitializers");
|
||||
Printer << " ";
|
||||
}
|
||||
if (CD->hasMissingDesignatedInitializers()) {
|
||||
Printer.printAttrName("@_hasMissingDesignatedInitializers");
|
||||
Printer << " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D->getAttrs().print(Printer, Options, D);
|
||||
|
||||
@@ -452,7 +452,7 @@ class d0120_TestClassBase {
|
||||
}
|
||||
|
||||
class d0121_TestClassDerived : d0120_TestClassBase {
|
||||
// PASS_COMMON-LABEL: {{^}}class d0121_TestClassDerived : d0120_TestClassBase {{{$}}
|
||||
// PASS_COMMON-LABEL: {{^}}@_inheritsConvenienceInitializers {{()?}}class d0121_TestClassDerived : d0120_TestClassBase {{{$}}
|
||||
|
||||
required init() { super.init() }
|
||||
// PASS_COMMON-NEXT: {{^}} required init(){{$}}
|
||||
@@ -611,8 +611,8 @@ struct d0200_EscapedIdentifiers {
|
||||
// PASS_ONE_LINE_TYPEREPR-DAG: {{^}} typealias `protocol` = `class`{{$}}
|
||||
|
||||
class `extension` : `class` {}
|
||||
// PASS_ONE_LINE_TYPE-DAG: {{^}} class `extension` : d0200_EscapedIdentifiers.`class` {{{$}}
|
||||
// PASS_ONE_LINE_TYPEREPR-DAG: {{^}} class `extension` : `class` {{{$}}
|
||||
// PASS_ONE_LINE_TYPE-DAG: {{^}} @_inheritsConvenienceInitializers class `extension` : d0200_EscapedIdentifiers.`class` {{{$}}
|
||||
// PASS_ONE_LINE_TYPEREPR-DAG: {{^}} @_inheritsConvenienceInitializers class `extension` : `class` {{{$}}
|
||||
// PASS_COMMON: {{^}} @objc deinit{{$}}
|
||||
// PASS_COMMON-NEXT: {{^}} {{(override )?}}init(){{$}}
|
||||
// PASS_COMMON-NEXT: {{^}} }{{$}}
|
||||
@@ -748,7 +748,7 @@ class d0260_ExplodePattern_TestClassBase {
|
||||
}
|
||||
|
||||
class d0261_ExplodePattern_TestClassDerived : d0260_ExplodePattern_TestClassBase {
|
||||
// PASS_EXPLODE_PATTERN-LABEL: {{^}}class d0261_ExplodePattern_TestClassDerived : d0260_ExplodePattern_TestClassBase {{{$}}
|
||||
// PASS_EXPLODE_PATTERN-LABEL: {{^}}@_inheritsConvenienceInitializers class d0261_ExplodePattern_TestClassDerived : d0260_ExplodePattern_TestClassBase {{{$}}
|
||||
|
||||
override final var baseProp2: Int {
|
||||
get {
|
||||
@@ -791,13 +791,13 @@ class ClassWithInheritance2 : FooProtocol, BarProtocol {}
|
||||
// PASS_ONE_LINE-DAG: {{^}}class ClassWithInheritance2 : FooProtocol, BarProtocol {{{$}}
|
||||
|
||||
class ClassWithInheritance3 : FooClass {}
|
||||
// PASS_ONE_LINE-DAG: {{^}}class ClassWithInheritance3 : FooClass {{{$}}
|
||||
// PASS_ONE_LINE-DAG: {{^}}@_inheritsConvenienceInitializers class ClassWithInheritance3 : FooClass {{{$}}
|
||||
|
||||
class ClassWithInheritance4 : FooClass, FooProtocol {}
|
||||
// PASS_ONE_LINE-DAG: {{^}}class ClassWithInheritance4 : FooClass, FooProtocol {{{$}}
|
||||
// PASS_ONE_LINE-DAG: {{^}}@_inheritsConvenienceInitializers class ClassWithInheritance4 : FooClass, FooProtocol {{{$}}
|
||||
|
||||
class ClassWithInheritance5 : FooClass, FooProtocol, BarProtocol {}
|
||||
// PASS_ONE_LINE-DAG: {{^}}class ClassWithInheritance5 : FooClass, FooProtocol, BarProtocol {{{$}}
|
||||
// PASS_ONE_LINE-DAG: {{^}}@_inheritsConvenienceInitializers class ClassWithInheritance5 : FooClass, FooProtocol, BarProtocol {{{$}}
|
||||
|
||||
class ClassWithInheritance6 : QuxProtocol, SubFooProtocol {
|
||||
typealias Qux = Int
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Compile the imported module to a .swiftinterface and ensure the convenience
|
||||
// init delegates through the subclasses correctly.
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift-dylib(%t/%target-library-name(Module)) %S/inherits-superclass-initializers.swift -emit-module-path %t/Module.swiftmodule -emit-module-interface-path %t/Module.swiftinterface -module-name Module -enable-library-evolution
|
||||
// RUN: rm %t/Module.swiftmodule
|
||||
// RUN: %target-build-swift %s -I %t -L %t -lModule -o %t/main %target-rpath(%t)
|
||||
// RUN: %target-codesign %t/main %t/%target-library-name(Module)
|
||||
// RUN: %target-run %t/main %t/%target-library-name(Module) | %FileCheck %s
|
||||
|
||||
// Make sure the same error is emitted when importing a .swiftmodule
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift-dylib(%t/%target-library-name(Module)) %S/inherits-superclass-initializers.swift -emit-module-path %t/Module.swiftmodule -module-name Module -enable-library-evolution
|
||||
// RUN: %target-build-swift %s -I %t -L %t -lModule -o %t/main %target-rpath(%t)
|
||||
// RUN: %target-codesign %t/main %t/%target-library-name(Module)
|
||||
// RUN: %target-run %t/main %t/%target-library-name(Module) | %FileCheck %s
|
||||
|
||||
import Module
|
||||
|
||||
_ = Base()
|
||||
// CHECK: secret init from Base
|
||||
|
||||
_ = Sub()
|
||||
// CHECK: secret init from Sub
|
||||
// CHECK: secret init from Base
|
||||
|
||||
_ = SubSub()
|
||||
// CHECK: secret init from SubSub
|
||||
// CHECK: secret init from Sub
|
||||
// CHECK: secret init from Base
|
||||
|
||||
test()
|
||||
// CHECK: secret init from Sub
|
||||
// CHECK: secret init from Base
|
||||
|
||||
// CHECK: secret init from SubSub
|
||||
// CHECK: secret init from Sub
|
||||
// CHECK: secret init from Base
|
||||
|
||||
// CHECK-NOT: public init
|
||||
60
test/ModuleInterface/inherits-superclass-initializers.swift
Normal file
60
test/ModuleInterface/inherits-superclass-initializers.swift
Normal file
@@ -0,0 +1,60 @@
|
||||
// Note: this test has a client: inherits-superclass-initializers-client.swift
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %s -emit-module-interface-path %t/Module.swiftinterface -module-name Module -enable-library-evolution
|
||||
// RUN: %FileCheck %s < %t/Module.swiftinterface
|
||||
|
||||
// CHECK: @_hasMissingDesignatedInitializers open class Base {
|
||||
open class Base {
|
||||
// CHECK-NEXT: public init(arg: Swift.Int)
|
||||
public init(arg: Int) {
|
||||
print("public init from Base")
|
||||
}
|
||||
// CHECK-NOT: init(secret: Swift.Int)
|
||||
internal init(secret: Int) {
|
||||
print("secret init from Base")
|
||||
}
|
||||
|
||||
// CHECK: convenience public init()
|
||||
public convenience init() {
|
||||
self.init(secret: 4)
|
||||
}
|
||||
|
||||
// CHECK: }
|
||||
}
|
||||
|
||||
// CHECK: @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers public class Sub : Module.Base {
|
||||
public class Sub : Base {
|
||||
// CHECK: override public init(arg: Swift.Int)
|
||||
public override init(arg: Int) {
|
||||
print("public init from Sub")
|
||||
super.init(arg: arg)
|
||||
}
|
||||
// CHECK-NOT: init(secret: Swift.Int)
|
||||
internal override init(secret: Int) {
|
||||
print("secret init from Sub")
|
||||
super.init(secret: secret)
|
||||
}
|
||||
// CHECK: }
|
||||
}
|
||||
|
||||
// CHECK: @_inheritsConvenienceInitializers @_hasMissingDesignatedInitializers public class SubSub : Module.Sub {
|
||||
public class SubSub: Sub {
|
||||
// CHECK: override public init(arg: Swift.Int)
|
||||
public override init(arg: Int) {
|
||||
print("public init from SubSub")
|
||||
super.init(arg: arg)
|
||||
}
|
||||
// CHECK-NOT: init(secret: Swift.Int)
|
||||
internal override init(secret: Int) {
|
||||
print("secret init from SubSub")
|
||||
super.init(secret: secret)
|
||||
}
|
||||
// CHECK: }
|
||||
}
|
||||
|
||||
@inlinable public func test() {
|
||||
_ = Sub()
|
||||
_ = SubSub()
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Compile the imported module to a .swiftinterface and ensure the convenience
|
||||
// init cannot be called.
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend -typecheck %S/non-public-designated-inits.swift -emit-module-interface-path %t/Module.swiftinterface -module-name Module -enable-library-evolution
|
||||
// RUN: %target-swift-frontend -typecheck -verify %s -I %t
|
||||
|
||||
// Make sure the same error is emitted when importing a .swiftmodule
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend -emit-module -o %t/Module.swiftmodule %S/non-public-designated-inits.swift -module-name Module -enable-library-evolution
|
||||
// RUN: %target-swift-frontend -typecheck -verify %s -I %t
|
||||
|
||||
import Module
|
||||
|
||||
open class B : A {
|
||||
var x: Int
|
||||
|
||||
public override init(_ x: Int) {
|
||||
self.x = x
|
||||
super.init(x)
|
||||
}
|
||||
}
|
||||
|
||||
print(B(hi: ())) // expected-error {{cannot convert value of type '()' to expected argument type 'Int'}}
|
||||
// expected-error @-1 {{extraneous argument label 'hi:' in call}}
|
||||
21
test/ModuleInterface/non-public-designated-inits.swift
Normal file
21
test/ModuleInterface/non-public-designated-inits.swift
Normal file
@@ -0,0 +1,21 @@
|
||||
// Note: This test has a client: non-public-designated-inits-client.swift
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %s -emit-module-interface-path %t/Module.swiftinterface -module-name Module -enable-library-evolution
|
||||
// RUN: %FileCheck %s < %t/Module.swiftinterface
|
||||
|
||||
// CHECK: @_hasMissingDesignatedInitializers open class A {
|
||||
open class A {
|
||||
// This is a non-public designated init, which means the convenience
|
||||
// init should not be inheritable.
|
||||
init() {}
|
||||
|
||||
// CHECK-NEXT: public init(_: Swift.Int)
|
||||
public init(_: Int) {}
|
||||
|
||||
// CHECK-NEXT: convenience public init(hi: ())
|
||||
public convenience init(hi: ()) { self.init() }
|
||||
|
||||
// CHECK: }
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
// CHECK: @objc public class MyObject : CoreData.NSManagedObject {
|
||||
// CHECK: @objc @_inheritsConvenienceInitializers public class MyObject : CoreData.NSManagedObject {
|
||||
public class MyObject: NSManagedObject {
|
||||
// CHECK: @objc @NSManaged dynamic public var myVar: Swift.String {
|
||||
// CHECK-NEXT: @objc get
|
||||
|
||||
@@ -1534,7 +1534,7 @@ class infer_instanceVar2<
|
||||
}
|
||||
|
||||
class infer_instanceVar3 : Class_ObjC1 {
|
||||
// CHECK-LABEL: @objc class infer_instanceVar3 : Class_ObjC1 {
|
||||
// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class infer_instanceVar3 : Class_ObjC1 {
|
||||
|
||||
var v1: Int = 0
|
||||
// CHECK-LABEL: @objc @_hasInitialValue var v1: Int
|
||||
@@ -1599,13 +1599,13 @@ protocol infer_throughConformanceProto1 {
|
||||
}
|
||||
|
||||
class infer_class1 : PlainClass {}
|
||||
// CHECK-LABEL: {{^}}class infer_class1 : PlainClass {
|
||||
// CHECK-LABEL: {{^}}@_inheritsConvenienceInitializers class infer_class1 : PlainClass {
|
||||
|
||||
class infer_class2 : Class_ObjC1 {}
|
||||
// CHECK-LABEL: @objc class infer_class2 : Class_ObjC1 {
|
||||
// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class infer_class2 : Class_ObjC1 {
|
||||
|
||||
class infer_class3 : infer_class2 {}
|
||||
// CHECK-LABEL: @objc class infer_class3 : infer_class2 {
|
||||
// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class infer_class3 : infer_class2 {
|
||||
|
||||
class infer_class4 : Protocol_Class1 {}
|
||||
// CHECK-LABEL: {{^}}class infer_class4 : Protocol_Class1 {
|
||||
|
||||
Reference in New Issue
Block a user