<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">Le 23 févr. 2016 à 09:18, plx via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Feb 22, 2016, at 6:51 PM, Kyle Sherman via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Thank you everyone for the feedback. I think that suppressing the warnings generated by this is something that Swift doesn’t support at all right now. Therefore, I think that if/when the ability to suppress warnings is added, it will work for this as well. I don’t think this proposal needs to say anything about being able to suppress the warning, because it would be done at the call site anyway.<div class=""><br class=""></div><div class="">@plx: Given the examples you provided and my thoughts above, I think in this case you would just see the warning and just need to ignore it, because you know that you are doing it correctly. I think that is probably best at this point. The real solution would be to really enforce that member variables are not mutated according to the start/end parameter, but I don’t think that is really necessary as the warning can be ignored in these cases.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I do understand your point, but at the same time I wouldn’t be able to really use this feature until either “local warning suppression” (as a general feature, e.g. a Swift form of `#pragma clang diagnostic push` and so on...) or call-site annotations (e.g. as could be used to say “this counts as super(begin)”).</div><div class=""><br class=""></div><div class="">This is a policy issue (e.g. a policy of “all checked-in code must compile w/out warnings”) and not really a language issue specific to this feature, but it’d still a blocker in (for me) in terms of actually making use of such annotations.</div><div class=""><br class=""></div><div class="">One thing I want to make explicit is that even if it’s just @requireSuper w/out the positional features, the closure example is problematic:</div><div class=""><br class=""></div><div class="">// assume @requireSuper has been added</div><div class="">override func layoutSubviews() {</div><div class=""> self.performMeasuredAction(“layout”) {</div><div class=""> super.layoutSubviews()</div><div class=""> self.layoutLocalSubviews()</div><div class=""> }</div><div class="">}</div><div class=""><br class=""></div><div class="">…does `performMeasuredAction` actually call that closure? </div><div class=""><br class=""></div><div class="">How would the compiler know?</div><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div><div>I think that what was discussed under Guaranteed closure execution (aka @noescape(once)) (<a href="https://github.com/zneak/swift-evolution/blob/master/proposals/00xx-noescape-once.md" class="">https://github.com/zneak/swift-evolution/blob/master/proposals/00xx-noescape-once.md</a>) could be able to detect that the super requirement is met in this particular scenario.</div><div><br class=""></div><div>Dany</div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="">Anyways I think even the most basic version of a feature like this is a win, but practically-speaking it’s a win I may not be able to use in general w/out a corresponding feature to annotate call sites (or locally suppress warnings, etc.).</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">@haravikk: I still don’t see a reason to have a parameter for saying that it is required, since as we both agreed, it makes sense that only when the attribute is defined, is it required. Having the attribute declared but not have required would basically be invalid. I think baking it into the name like I originally suggested is probably best, as @super by itself is probably not explicit enough. The naming of these attributes and casing are being debated in a different thread, so I think I will just submit my suggestion with the idea that it can be corrected to fit what they decide in the other thread.</div><div class=""><br class=""></div><div class="">Here is an updated version of the proposal. If no one has any other comments. Please review and let me know, because I would like to submit it for a review after I get comments on this version.</div><div class=""><br class=""></div><div class=""><span id="docs-internal-guid-a38d8475-0b9b-ebfa-bca1-ccdb5adf0fc4" class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"># Enforcing Calling Super</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">* Proposal: [SE-NNNN](<a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md</a>)</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">* Author(s): [Kyle Sherman](<a href="https://github.com/drumnkyle" class="">https://github.com/drumnkyle</a>)</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">* Status: **Awaiting review**</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">* Review manager: TBD</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">## Introduction</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">Many times when creating a subclass the superclass has reasons for certain overridden methods to call the superclass’s version of the method. This change would enforce that the subclass called the superclass's method in its overridden version at compile time. Also, it would optionally enforce that the superclass's version would be called either before any other implementation in the method (similar to initialization rules) or as the last line in the method.</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">Swift-evolution thread: [link to the discussion thread for that proposal](<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010509.html" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010509.html</a>)</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"><br class="kix-line-break"></span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">## Motivation</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">A concrete example of the type of problem this solves can be taken from simple iOS code. When creating a subclass of UIViewController, you often need to override methods like viewDidLoad or viewWillAppear. You are supposed to call super.viewDidLoad or super.viewWillAppear, respectively, in your overridden implementation. If you don't, you will have undefined behavior and run into issues. Of course, this type of situation can be extrapolated to any class created in Swift. </span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">Currently, the only way this can be enforced is by commenting the superclass's code and making a note in the documentation. Quite obviously this can cause many issues as mistakes can be made by new developers quite easily who didn't look at the documentation for the method or even seasoned developers who simply overlooked this small detail. </span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">## Proposed solution</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"><br class="kix-line-break"></span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">The solution proposed here would be to use an attribute similar to @available and @noescape in order to convey this information. Optionally, the developer can also choose to specify that the super method must be called as the first line or last line of the overridden method. </span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">The compiler would use the information from the attribute to ensure that any overridden version of the method must call super at the appropriate time according to the information given in the attribute. The compiler would also need to ensure that any method that was going to use this attribute had the same access control level as the class that contains it.</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">This solution will be much safer than what is currently available, because there is currently no way to enforce super being called in an overridden method. This bug happens constantly for iOS developers.</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">## Detailed design</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"><br class="kix-line-break"></span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">A possible implementation of this may look like this:</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">```</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">class MyClass {</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"> @requiresSuper func foo1() { }</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"> @requiresSuper(start) func foo2() { }</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"> @requiresSuper(end) func foo3() { }</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">}</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">```</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">Now, if the developer were to create a subclass and not call the super method, the compiler should display a warning. The warnings that should be displayed should be similar to: </span></div><ol class="" style="margin-top: 0pt; margin-bottom: 0pt;"><li dir="ltr" class="" style="list-style-type: decimal; font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline;"><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; vertical-align: baseline; white-space: pre-wrap;">Overridden method must call the superclass’s implementation</span></div></li><li dir="ltr" class="" style="list-style-type: decimal; font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline;"><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; vertical-align: baseline; white-space: pre-wrap;">Overridden method must call the superclass’s implementation as the first line of the method.</span></div></li><li dir="ltr" class="" style="list-style-type: decimal; font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline;"><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; vertical-align: baseline; white-space: pre-wrap;">Overridden method must call the superclass’s implementation as the last line of the method.</span></div></li></ol><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">for the cases of `@requiresSuper`, `@requiresSuper(start)`, and `@requiresSuper(end)` respectively.</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">The compiler would also need to display an error in this case where the access control of the method is stricter than that of the class:</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">```</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">public class MyClass {</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"> @requiresSuper func foo() { }</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">}</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">```</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">The compiler should show a warning, such as “A method using @requiresSuper must have access control set to be at least as accessible as the class that contains it”.</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">There can also be a simple fix-it that adds in the call to the super’s method. The specifics of the exact name and syntax is flexible as long as it has the 3 features proposed and produces a warning.</span></div><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">## Impact on existing code</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">The good thing about this change is that it will not have any impact on existing Swift code. This is an optional attribute provided by the developer. Therefore, if the attribute is not used, nothing is changed.</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">Unfortunately, there is no good way to automatically migrate code to use this new attribute, because the information would have only been embedded in comments previously. Implementation of this feature by the developer is completely optional. Therefore, existing code will be unaffected and no migration of code will be necessary. However, when APIs are updated to use this new feature, some code will not compile if the developer did not use the APIs correctly. This should be a welcomed compilation error as it will result in less buggy code at runtime. The impact of this change is similar to adding nullability attributes to Objective-C.</span></div><br class=""><div class="" style="line-height: 1.38; margin-top: 0pt; margin-bottom: 0pt;"><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">It will be impossible to migrate code automatically, because this information cannot be derived in any way aside from reading comments if and only if the API author documented it.</span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"><br class="kix-line-break"></span><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">## Alternatives considered</span></div><br class=""><span class="" style="font-size: 14.666666666666666px; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;">The alternative would simply be to not implement this feature.</span></span><br class=""><div class=""><br class=""></div><div class="">> I hope we will be able to use something like the clang diagnostic macro's to do that...<div class="">><span class="Apple-converted-space"> </span><br class="">> Sent from my iPhone<br class="">><span class="Apple-converted-space"> </span><br class="">> On 18 Feb 2016, at 15:02, plx via swift-evolution<<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>(<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>)>wrote:<br class="">><span class="Apple-converted-space"> </span><br class="">> > I think something like this making it into Swift at some point would be great, even if it’s just the `@requiresSuper` form; the positional variants would be even better.<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > However, I think any proposal like this will be *unusable* unless it *also* includes some way of explicitly marking a specific super-call as “OK, despite how it looks!”…and this is true even if you spec the feature out to only produce warnings, b/c even then you may want to silence those warnings at specific, “known-no-problem” call sites.<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > Here are two concrete examples:<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > // suppose `updateConstraints` has `@super(end)` applied to it:<br class="">> > override func updateConstraints() {<br class="">> > // figure out where a bug is coming from:<br class="">> > debugLog(“<ISSUE 124>#before constraints.horizontal: \(self.constraintsAffectingLayoutForAxis(.Horizontal))”)<br class="">> > debugLog(“<ISSUE 124>#beforeconstraints.vertical: \(self.constraintsAffectingLayoutForAxis(.Vertical))”)<br class="">> > self.updateMyLocalConstraints()<br class="">> > debugLog(“<ISSUE 124>#after constraints.horizontal: \(self.constraintsAffectingLayoutForAxis(.Horizontal))”)<br class="">> > debugLog(“<ISSUE 124>#afterconstraints.vertical: \(self.constraintsAffectingLayoutForAxis(.Vertical))”)<br class="">> > super.updateConstraints() //<- not last call, but actually ok<br class="">> > debugLog(“<ISSUE 124>#final constraints.horizontal: \(self.constraintsAffectingLayoutForAxis(.Horizontal))”)<br class="">> > debugLog(“<ISSUE 124>#finalconstraints.vertical: \(self.constraintsAffectingLayoutForAxis(.Vertical))”)<br class="">> > }<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > // suppose `layoutSubviews` has `@super(begin)` applied to it:<br class="">> > override func layoutSubviews() {<br class="">> > // capture timing info in debug runs:<br class="">> > #if DEBUG<br class="">> > self.performTimedBlock(“updateConstraints”) {<br class="">> > super.layoutSubviews() //<- not “first call”, but actually ok<br class="">> > self.layoutMyCustomSubviews()<br class="">> > }<br class="">> > #else<br class="">> > super.layoutSubviews()<br class="">> > self.layoutMyCustomSubviews()<br class="">> > #endif<br class="">> > }<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > …and I picked these because they’re examples where we are actually obeying the “spirit" of the @super annotation.<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > Such an annotation could either be applied to the method (something like: `@force(@super(end):true)`?), or perhaps an annotation applied to the specific call-site…but right now, I don’t think Swift has anything at all that uses a "call-site” attribute.<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > Are there any?<br class="">> ><span class="Apple-converted-space"> </span><br class="">> > > On Feb 17, 2016, at 12:02 PM, Kyle Sherman via swift-evolution<<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>(<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>)>wrote:<br class="">> > > I just saw that there was a discussion started about this topic just recently while I was developing this idea with my colleague Peter Livesey. So, I figured I would submit this proposal for discussion.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > The link to the original discussion is here:https://<a href="http://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010310.html" class="">lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010310.html</a><br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > The subject was: “Replace the override keyword by ‘extend’ and ‘replace’ or add an annotation like @SuppressSuperCall”<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > -Kyle<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > # Enforcing Calling Super<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > * Proposal: [SE-NNNN](<a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md</a>)<br class="">> > > * Author(s): [Swift Developer](<a href="https://github.com/swiftdev" class="">https://github.com/swiftdev</a>)<br class="">> > > * Status: **Awaiting review**<br class="">> > > * Review manager: TBD<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > ## Introduction<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > Many times when creating a subclass the superclass has reasons for certain overridden methods to call the superclass’s version of the method. This change would enforce that the subclass called the superclass's method in its overridden version at compile time. Also, it would optionally enforce that the superclass's version would be called before any other implementation in the method (similar to initialization rules).<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > Swift-evolution thread: [link to the discussion thread for that proposal](<a href="https://lists.swift.org/pipermail/swift-evolution" class="">https://lists.swift.org/pipermail/swift-evolution</a>)<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > ## Motivation<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > A concrete example of the type of problem this solves can be taken from simple iOS code. When creating a subclass of UIViewController, you often need to override methods like viewDidLoad or viewWillAppear. You are supposed to call super.viewDidLoad or super.viewWillAppear, respectively, in your overridden implementation. If you don't, you will have undefined behavior and run into issues. Of course, this type of situation can be extrapolated to any class created in Swift.<br class="">> > > Currently, the only way this can be enforced is by commenting the superclass's code and making a note in the documentation. Quite obviously this can cause many issues as mistakes can be made by new developers quite easily who didn't look at the documentation for the method or even seasoned developers who simply overlooked this small detail.<br class="">> > > ## Proposed solution<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > The solution proposed here would be to use an annotation similar to @available and @noescape in order to convey this information. Optionally, the developer can also choose to specify that the super method must be called as the first line or last line of the overridden method.<br class="">> > > The compiler would use the information from the annotation to ensure that any overridden version of the method must call super at the appropriate time according to the information given in the annotation. The compiler would also need to ensure that any method that was going to use this annotation had the same access control level as the class that contains it.<br class="">> > > This solution will be much safer than what is currently available, because there is currently no way to enforce super being called in an overridden method. This bug happens constantly for iOS developers.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > ## Detailed design<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > A possible implementation of this may look like this:<br class="">> > > ```<br class="">> > > class MyClass {<br class="">> > > @requiredSuper func foo1() { }<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > @requiredSuper(start) func foo2() { }<br class="">> > > @requiredSuper(end) func foo3() { }<br class="">> > > }<br class="">> > > ```<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > Now, if the developer were to create a subclass and not call the super method, the compiler should display an error. The errors that should be displayed should be similar to:<br class="">> > > Overridden method must call the superclass’s implementation<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > Overridden method must call the superclass’s implementation as the first line of the method.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > Overridden method must call the superclass’s implementation as the last line of the method.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > for the cases of `@requiredSuper`, `@requiredSuper(start)`, and `@requiredSuper(end)` respectively.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > The compiler would also need to display an error in this case where the access control of the method is stricter than that of the class:<br class="">> > > ```<br class="">> > > public class MyClass {<br class="">> > > @requiredSuper func foo() { }<br class="">> > > }<br class="">> > > ```<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > The compiler should show an error, such as “A method using @requiredSuper must have access control set to be at least as accessible as the class that contains it”.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > ## Impact on existing code<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > Implementation of this feature by the developer is completely optional. Therefore, existing code will be unaffected and no migration of code will be necessary. However, when APIs are updated to use this new feature, some code will not compile if the developer did not use the APIs correctly. This should be a welcomed compilation error as it will result in less buggy code at runtime. The impact of this change is similar to adding nullability annotations to Objective-C.<br class="">> > > It will be impossible to migrate code automatically, because this information cannot be derived in any way aside from reading comments if and only if the API author documented it.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > ## Alternatives considered<br class="">> > > The alternative would simply be to not implement this feature.<br class="">> > ><span class="Apple-converted-space"> </span><br class="">> > > _______________________________________________<br class="">> > > swift-evolution mailing list<br class="">> > ><span class="Apple-converted-space"> </span><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>(<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>)<br class="">> > ><span class="Apple-converted-space"> </span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">> ><span class="Apple-converted-space"> </span><br class="">> > _______________________________________________<br class="">> > swift-evolution mailing list<br class="">> ><span class="Apple-converted-space"> </span><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>(<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>)<br class="">> ><span class="Apple-converted-space"> </span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">><span class="Apple-converted-space"> </span><br class="">><span class="Apple-converted-space"> </span><br class="">><span class="Apple-converted-space"> </span></div></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></body></html>