-
Notifications
You must be signed in to change notification settings - Fork 205
[NFC, Incremental] Refactoring to facilitate replacing the inputDependencySourceMap with the right thing #664
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
[NFC, Incremental] Refactoring to facilitate replacing the inputDependencySourceMap with the right thing #664
Conversation
@swift-ci please test macOS Platform |
c679036
to
c2687c8
Compare
e7c52e9
to
b567bec
Compare
@swift-ci please test |
inputsAddedSincePriors } | ||
@_spi(Testing) public mutating func addEntry(_ input: TypedVirtualPath, | ||
_ dependencySource: DependencySource, | ||
`for` _ : AdditionPurpose) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: You don't need to quote keywords when they're external labels.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, will do.
// MARK: - Populating | ||
extension InputDependencySourceMap { | ||
public enum AdditionPurpose { | ||
case mocking, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document these. Their names alone don't reveal much at the point of usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okey-doke!
|
||
/// Returns: false on error | ||
func populateInputDependencySourceMap( | ||
`for` purpose: InputDependencySourceMap.AdditionPurpose |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Same here. Don't need the quotes around for
.
biMap[source] | ||
} | ||
|
||
@_spi(Testing) public func enumerateToSerializePriors( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name conflates the API's purpose with its usage. I think the swift-ier name is something closer to just enumerate(_:)
or forEach(_:)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it does. The conflation is quite deliberate here. The enclosing type is meant to operate at the level of intention. This level distinction paves the way for the greater structural change to come.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that, but Swift does not use the name of the API in the same way that Objective-C or Smalltalk might encourage the use of intention-revealing selectors.
|
||
// MARK: - Accessing | ||
extension InputDependencySourceMap { | ||
@_spi(Testing) public func getSourceIfKnown(for input: TypedVirtualPath) -> DependencySource? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just source(for:)
would do here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it would. And I'll remove the "get" prefix.
The idea here was to draw a very explicit distinction with ModuleDependencyGraph.getRequiredSource
. In an earlier draft, both were named getSource
and it was not easy to search for one as opposed to the other, because the only difference in usage was the result type. So, I decided to rename at least one, for the sake of clarity. Then, for the sake of symmetry (and clarity), I renamed them both.
So, I would rather keep the "IfKnown" part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... after eliminating the "get"s, the "IfKnown" etc., moves to the keyword. You'll see after I push. Does that look better?
biMap[input] | ||
} | ||
|
||
@_spi(Testing) public func getInputIfKnown(for source: DependencySource) -> TypedVirtualPath? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just input(for:)
as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some documentation of this new interface would be welcome. API notes are in-line.
Yes, I'll add. |
Thanks for the comments; they helped! Have addressed them, and now will fix the conflicts. |
4022e1a
to
41237bf
Compare
@swift-ci please test |
Thanks, @CodaFi , for productive comments. I've made the changes requested, modulo keeping some intentionality in the function names. This rev may not be there yet, so please let me know what you see. |
/// | ||
/// - Parameter source: A `DependencySource` (containing a swiftdeps file) | ||
/// - Returns: the corresponding input source file, or nil if none known. | ||
@_spi(Testing) public func input(ifKnownFor source: DependencySource) -> TypedVirtualPath? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ifKnownFor
has the same issue as below. Just for
suffices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see my comment for the next issue. I have a rule: Correlate salience with importance in order to ease the comprehension for new maintainer.
@@ -121,7 +121,8 @@ extension ModuleDependencyGraph.Tracer { | |||
path.compactMap { node in | |||
node.dependencySource.map { | |||
source in | |||
graph.inputDependencySourceMap[source].map { input in | |||
graph.inputDependencySourceMap.input(ifKnownFor: source).map { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason this is here? Seems superfluous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "ifKnownFor" is there because it makes two aspects more salient:
- That the function might not return a value. (In this use, it reinforces that the
map
is to handle an optional, rather than a collection.), and - That it depends on if the mapping is "known". I'd be happy to find a better word than "known". "Has been seen" feels too wordy.
/// - Parameter why: the purpose for this addition. Will be used for future restructuring. | ||
@_spi(Testing) public mutating func addEntry(_ input: TypedVirtualPath, | ||
_ dependencySource: DependencySource, | ||
for why: AdditionPurpose) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the for
parameter is dead. Is that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. As the documentation says, it will be used in the future. For now, it makes clear at the point-of-use what the purpose is.
} | ||
} | ||
extension OutputFileMap { | ||
fileprivate func getDependencySource( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit from before: get
prefixes usually imply indirect return values in Cocoa and Swift. Just dependencySource(for:diagnosticEngine:)
suffices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks--done!
if let source = ofm.getDependencySource(for: input, diagnosticEngine: diags) { | ||
inputDependencySourceMap.addEntry(input, source, for: purpose) | ||
} | ||
else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: OTBS here please
else { | |
if let source = ofm.getDependencySource(for: input, diagnosticEngine: diags) { | |
inputDependencySourceMap.addEntry(input, source, for: purpose) | |
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a look-up on "OTBS" and it came back with "off track horse betting"! :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the request is to put the else on the same line as the closing brace--no prob!
file: String = #file, | ||
line: Int = #line) -> DependencySource { | ||
guard let source = inputDependencySourceMap[input] else { | ||
@_spi(Testing) public func source(requiredFor input: TypedVirtualPath, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirement
part of this API is communicated by the type signature - being that it has a non-optional return value. You could reinforce this in documentation, but I think for
suffices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirement is in the function name, because it makes the required nature more salient at the point of use, without clicking to see the documentation, or the type of the assigned-to variable.
Consider: let foo = source(requiredFor: someInput)
vs let foo = source(for: someInput)
.
The first construction makes the required nature of the mapping more salient.
I have a rule: that when some distinction is important, I make it salient at the point of use, and the correlation between importance and salience trumps most other considerations.
@@ -329,7 +345,8 @@ extension ModuleDependencyGraph { | |||
) -> TransitivelyInvalidatedInputSet? { | |||
var invalidatedInputs = TransitivelyInvalidatedInputSet() | |||
for invalidatedSwiftDeps in collectSwiftDepsUsingInvalidated(nodes: directlyInvalidatedNodes) { | |||
guard let invalidatedInput = getInput(for: invalidatedSwiftDeps) else { | |||
guard let invalidatedInput = input(neededFor: invalidatedSwiftDeps) | |||
else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put this back if you could. This fits onto 80 columns just fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rule you follow in general for the "else" in a guard? 80-columns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
@CodaFi Thank you for your review. I have responded to your comments and made changes where I agree. You have a wealth of experience with Swift style, and that helps my code fit in. To clarify, I think we agree that this PR makes no functional change, and that (for me) is the most critical part of your review, because I don't want to break the driver. There are some remaining disagreements on function naming, but I think they follow from my practice of choosing salience at the point-of-use. If Xcode were better at showing inferred types, or Doxygen documentation, I'd be in agreement with you. Would you be able to approve this PR at this point? |
@swift-ci please test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remain unconvinced that this is a meaningful change, and moreover that the new API surface here is an improvement over the status quo. But this PR has also been blocked on my review and I don’t see a reason for that much, so
I understand. Thank you so very much for compromising here. |
A refactoring of
inputDependencySourceMap
prior to really fixing the below:See #662
Start on that.
rdar://77998890