-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[ParseableInterfaces] Support inheriting default arguments in module interfaces via '= super' #24073
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
[ParseableInterfaces] Support inheriting default arguments in module interfaces via '= super' #24073
Changes from all commits
9639bce
b425987
c95252e
1d4b6df
1e10252
d4f1894
32497c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// swift-interface-format-version: 1.0 | ||
// swift-module-flags: -module-name InheritedDefaults | ||
|
||
// RUN: %empty-directory(%t) | ||
// RUN: %target-typecheck-verify-swift | ||
nathawes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import Swift | ||
|
||
public class Bar { | ||
// note associated with the expected error in (F) below | ||
public init(x: Int = 24, y: Int, z: Int = 42) // expected-note {{corresponding parameter declared here}} | ||
|
||
public init(a: Int, b: Int = 99) | ||
public convenience init(convInit: Int = 45) {} | ||
|
||
// note associated with the expected error in (D) below | ||
public convenience init(first: Int, second: Int = 88, third: Int, fourth: Int) // expected-note {{overridden declaration is here}} | ||
} | ||
|
||
public class Foo: Bar { | ||
|
||
// A) designated overriding designated - valid | ||
public override init(x: Int = super, y: Int, z: Int = super) | ||
|
||
// B) convenience shadowing convenience | ||
public convenience init(convInit: Int = super) // expected-error {{default value inheritance via 'super' is only valid on the parameters of designated initializers}} | ||
|
||
// C) convenience overriding designated | ||
public override convenience init(a: Int, b: Int = super) // expected-error {{default value inheritance via 'super' is only valid on the parameters of designated initializers}} | ||
|
||
// D) designated shadowing convenience | ||
public init(first: Int, second: Int = super, third: Int, fourth: Int) // expected-error {{default value inheritance via 'super' can only be used when overriding a designated initializer}} | ||
|
||
// E) not in initializer | ||
public subscript(k: Int = super) -> Int { get } // expected-error {{default value inheritance via 'super' is only valid on the parameters of designated initializers}} | ||
public func foo(z: Int = super) // expected-error {{default value inheritance via 'super' is only valid on the parameters of designated initializers}} | ||
} | ||
|
||
public class Baz: Bar { | ||
|
||
// F) Matching param not defaulted | ||
public override init(x: Int = super, y: Int = super, z: Int = super) // expected-error {{default value inheritance via 'super' requires that the corresponding parameter of the overridden designated initializer has a default value}} | ||
} | ||
|
||
public class Direct: Bar { | ||
public override init(x: Int = super, y: Int, z: Int = super) | ||
|
||
// G) Doesn't override anything | ||
public override init(other: Int = super, value: Int) // expected-error {{argument labels for initializer 'init(other:value:)' do not match those of overridden initializer 'init(a:b:)'}} | ||
// expected-error@-1 {{default value inheritance via 'super' can only be used when overriding a designated initializer}} | ||
} | ||
|
||
public class Indirect: Direct { | ||
|
||
// H) Chain of inherited defaults - valid all the way down | ||
public override init(x: Int = super, y: Int, z: Int = super) | ||
|
||
// I) Chain of inherited defaults - invalid further down (and diagnosed there) | ||
public override init(other: Int = super, value: Int) | ||
nathawes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
public enum Bob { | ||
case bar(p: Int) | ||
public init(foo: String = super /*comment*/) // expected-error {{default value inheritance via 'super' can only be used when overriding a designated initializer}} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// REQUIRES: executable_test | ||
// RUN: %empty-directory(%t) | ||
|
||
// 1) Build the 'Inherited' library and its interface from this file | ||
// | ||
// RUN: %target-build-swift-dylib(%t/%target-library-name(Inherited)) -emit-module-path %t/Inherited.swiftmodule -emit-parseable-module-interface-path %t/Inherited.swiftinterface -module-name Inherited %s | ||
// RUN: rm %t/Inherited.swiftmodule | ||
|
||
// 2) Check the interface includes the synthesized initializers of the base | ||
// class in the derived class explicitly and uses the '= super' syntax to | ||
// inherit its default arguments. | ||
// | ||
// RUN: cat %t/Inherited.swiftinterface | %FileCheck --check-prefix=INTERFACE %s | ||
// | ||
// INTERFACE: public class Base { | ||
// INTERFACE: public init(x: Swift.Int = 45, y: Swift.Int = 98) | ||
// INTERFACE: } | ||
// INTERFACE: public class Derived : Inherited.Base { | ||
// INTERFACE: override public init(x: Swift.Int = super, y: Swift.Int = super) | ||
// INTERFACE: } | ||
|
||
// 4) Generate a main.swift file that uses the 'Inherited' library and makes use | ||
// of the inherited default arguments | ||
// | ||
// RUN: echo "import Inherited" > %t/main.swift | ||
// RUN: echo "print(Derived().x)" >> %t/main.swift | ||
// RUN: echo "print(Derived().y)" >> %t/main.swift | ||
|
||
// 5) Build and run the executable, checking the defaulted arguments resulted in | ||
// the correct values being stored | ||
// | ||
// RUN: %target-build-swift -I%t -L%t -lInherited -o %t/main %target-rpath(%t) %t/main.swift -swift-version 5 | ||
// RUN: %target-codesign %t/main %t/%target-library-name(Inherited) | ||
// RUN: %target-run %t/main | %FileCheck --check-prefix=OUTPUT %s | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, look like this broke device testing. In order to make sure libInherited.dylib gets copied to the device, you have to pass it as an argument to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, you're way ahead of me. :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I wasn't sure what I was missing, but @harlanhaskins helped me out! |
||
// | ||
// OUTPUT: 45 | ||
// OUTPUT-NEXT: 98 | ||
|
||
public class Base { | ||
public let x: Int | ||
public let y: Int | ||
public init(x: Int = 45, y: Int = 98) { | ||
self.x = x | ||
self.y = y | ||
} | ||
} | ||
public class Derived: Base {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<ImportDecl>// RUN: rm -rf %t | ||
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t | ||
// RUN: diff -u %s %t | ||
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen -print-node-kind > %t.withkinds | ||
// RUN: diff -u %S/Outputs/round_trip_module_interface.swiftinterface.withkinds %t.withkinds | ||
// RUN: %swift-syntax-test -input-source-filename %s -eof > %t | ||
// RUN: diff -u %s %t | ||
// RUN: %swift-syntax-test -serialize-raw-tree -input-source-filename %s > %t.dump | ||
// RUN: %swift-syntax-test -deserialize-raw-tree -input-source-filename %t.dump -output-filename %t | ||
// RUN: diff -u %s %t | ||
|
||
import <AccessPathComponent>Swift</AccessPathComponent></ImportDecl><ClassDecl><DeclModifier> | ||
|
||
public </DeclModifier>class Bar <MemberDeclBlock>{<MemberDeclListItem><InitializerDecl><DeclModifier> | ||
public </DeclModifier>init<ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <IntegerLiteralExpr>24</IntegerLiteralExpr></InitializerClause>, </FunctionParameter><FunctionParameter>y: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>)</ParameterClause></InitializerDecl></MemberDeclListItem> | ||
}</MemberDeclBlock></ClassDecl><ClassDecl><DeclModifier> | ||
|
||
public </DeclModifier>class Foo<TypeInheritanceClause>: <InheritedType><SimpleTypeIdentifier>Bar </SimpleTypeIdentifier></InheritedType></TypeInheritanceClause><MemberDeclBlock>{<MemberDeclListItem><InitializerDecl><DeclModifier> | ||
public </DeclModifier><DeclModifier>override </DeclModifier>init<ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <SuperRefExpr>super</SuperRefExpr></InitializerClause>, </FunctionParameter><FunctionParameter>y: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>)</ParameterClause></InitializerDecl></MemberDeclListItem><MemberDeclListItem><SubscriptDecl><DeclModifier> | ||
public </DeclModifier>subscript<ParameterClause>(<FunctionParameter>k: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <SuperRefExpr>super</SuperRefExpr></InitializerClause></FunctionParameter>) </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><AccessorBlock>{ <AccessorDecl>get </AccessorDecl>}</AccessorBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><FunctionDecl><DeclModifier> | ||
public </DeclModifier>func foo<FunctionSignature><ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <SuperRefExpr>super</SuperRefExpr></InitializerClause></FunctionParameter>)</ParameterClause></FunctionSignature></FunctionDecl></MemberDeclListItem><MemberDeclListItem><FunctionDecl><DeclModifier> | ||
public </DeclModifier>func foo<FunctionSignature><ParameterClause>(<FunctionParameter>y: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <MemberAccessExpr><SuperRefExpr>super</SuperRefExpr>.init</MemberAccessExpr></InitializerClause></FunctionParameter>)</ParameterClause></FunctionSignature></FunctionDecl></MemberDeclListItem><MemberDeclListItem><FunctionDecl><DeclModifier> | ||
public </DeclModifier>func foo<FunctionSignature><ParameterClause>(<FunctionParameter>z: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <SubscriptExpr><SuperRefExpr>super</SuperRefExpr>[<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr></InitializerClause></FunctionParameter>)</ParameterClause></FunctionSignature></FunctionDecl></MemberDeclListItem> | ||
}</MemberDeclBlock></ClassDecl> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// RUN: rm -rf %t | ||
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t | ||
// RUN: diff -u %s %t | ||
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen -print-node-kind > %t.withkinds | ||
// RUN: diff -u %S/Outputs/round_trip_module_interface.swiftinterface.withkinds %t.withkinds | ||
// RUN: %swift-syntax-test -input-source-filename %s -eof > %t | ||
// RUN: diff -u %s %t | ||
// RUN: %swift-syntax-test -serialize-raw-tree -input-source-filename %s > %t.dump | ||
// RUN: %swift-syntax-test -deserialize-raw-tree -input-source-filename %t.dump -output-filename %t | ||
// RUN: diff -u %s %t | ||
|
||
import Swift | ||
|
||
public class Bar { | ||
public init(x: Int = 24, y: Int) | ||
} | ||
|
||
public class Foo: Bar { | ||
public override init(x: Int = super, y: Int) | ||
public subscript(k: Int = super) -> Int { get } | ||
public func foo(x: Int = super) | ||
public func foo(y: Int = super.init) | ||
public func foo(z: Int = super[1]) | ||
} |
Uh oh!
There was an error while loading. Please reload this page.