-
Notifications
You must be signed in to change notification settings - Fork 348
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
Routines to format AnalysisResult objects for debugging/logging #3522
Conversation
* | ||
* @return a string representation of this | ||
*/ | ||
public String repr() { |
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.
Is there a reason to not simply override toString
? That would be easier to find for people.
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 is much more verbose. It would clutter most output and is useful for debugging. I have updated the description.
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.
At the moment there is no toString
method, so currently nothing useful is output at all.
So it's not clear what output this would clutter - at the moment any output is brief but useless.
What output are you concerned about?
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 is not the case that nothing useful is output. Object.toString
outputs the run-time class name and a unique identifier. Users may prefer that to dozens of lines of output. If toString
is overridden, users don't have a way to get less information. Creating a different method gives each user the option of how much output to put in logs.
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.
Another customary difference between toString()
and repr()
is that toString()
reflects the abstraction or client view, whereas repr()
shows the implementation or representation. (Not every implementation of toString()
and repr()
follows the convention perfectly.)
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 is the first class where we add a repr
method, so I would like to understand what the motivation is and don't understand what you mean with "customary".
I see 483 matches for such a repr
function on GitHub for Java code. This seems popular in Python code.
In general it seems more useful to output concrete information instead of what Object.toString
gives. If the behavior of Object.toString
is really desired in some place, one can simply call getClass
and hashCode
instead.
So far in similar classes we have overriden toString
. What makes these classes special to not do the same?
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 is the first class where we add a
repr
method, so I would like to understand what the motivation is
I added text from this conversation to the developer manual.
In general it seems more useful to output concrete information instead of what
Object.toString
gives.
It is useful to give clients a choice about what information to output.
So far in similar classes we have overriden
toString
. What makes these classes special to not do the same?
The difference is not the classes, the difference is the methods.
dataflow/src/main/java/org/checkerframework/dataflow/analysis/AnalysisResult.java
Outdated
Show resolved
Hide resolved
dataflow/src/main/java/org/checkerframework/dataflow/analysis/AnalysisResult.java
Outdated
Show resolved
Hide resolved
dataflow/src/main/java/org/checkerframework/dataflow/analysis/AnalysisResult.java
Outdated
Show resolved
Hide resolved
dataflow/src/main/java/org/checkerframework/dataflow/cfg/ControlFlowGraph.java
Outdated
Show resolved
Hide resolved
@@ -303,4 +305,32 @@ public String toString() { | |||
String stringGraph = (String) res.get("stringGraph"); | |||
return stringGraph == null ? super.toString() : stringGraph; |
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.
If stringGraph
is null, you could use repr
instead of the un-helpful super implementation.
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.
That's a change to toString()
, and repr()
is more about the internal implementation. (Also, this pull request doesn't make any changes to toString()
.) Should the code instead throw BugInCF
if stringGraph
is null? A separate pull request could do that.
dataflow/src/main/java/org/checkerframework/dataflow/cfg/ControlFlowGraph.java
Outdated
Show resolved
Hide resolved
@wmdietl Thanks for the feedback. I think I have addressed it (except for a change to an existing |
for (Map.Entry<Tree, Set<Node>> entry : treeLookup.entrySet()) { | ||
for (Node n : entry.getValue()) { | ||
if (!nodeValues.containsKey(n)) { | ||
SystemUtil.sleep(100); // without this, printf output is sometimes interleaved |
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 printf
output is this referring to? Throwing a BugInCF
outputs the message using the compiler messager and should happen one at a time. In general, the compiler is single-threaded and a sleep
seems very inappropriate.
Is this maybe from running gradle concurrently?
How can I reproduce this issue?
As this checkRep
method isn't called anywhere, how about moving this method to a separate PR?
* | ||
* @return a string representation of this | ||
*/ | ||
public String repr() { |
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 is the first class where we add a repr
method, so I would like to understand what the motivation is and don't understand what you mean with "customary".
I see 483 matches for such a repr
function on GitHub for Java code. This seems popular in Python code.
In general it seems more useful to output concrete information instead of what Object.toString
gives. If the behavior of Object.toString
is really desired in some place, one can simply call getClass
and hashCode
instead.
So far in similar classes we have overriden toString
. What makes these classes special to not do the same?
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.
For classes that do not have a toString
method, I'm not convinced that adding only a repr
method will be the most intuitive behavior, but I'm fine with this (modulo the inconsistency in javadoc).
@@ -157,4 +158,32 @@ public void setAssignmentContext(AssignmentContext assignmentContext) { | |||
} | |||
return transitiveOperands; | |||
} | |||
|
|||
/** | |||
* Returns a verbose printed representation of this, useful for debugging. |
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.
For consistency, in a few places in this PR, I would replace the printed
with string
.
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 agree. That was for consistency with existing methods' documentation, but I have changed those too.
@wmdietl Would you prefer that I rename all the |
Incorporates changes from #3527, which should be merged first.