Skip to content
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

Merged
merged 33 commits into from
Aug 5, 2020

Conversation

mernst
Copy link
Member

@mernst mernst commented Jul 29, 2020

Incorporates changes from #3527, which should be merged first.

*
* @return a string representation of this
*/
public String repr() {
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member Author

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.)

Copy link
Member

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?

Copy link
Member Author

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.

@@ -303,4 +305,32 @@ public String toString() {
String stringGraph = (String) res.get("stringGraph");
return stringGraph == null ? super.toString() : stringGraph;
Copy link
Member

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.

Copy link
Member Author

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.

@wmdietl wmdietl assigned mernst and unassigned wmdietl Jul 30, 2020
@mernst mernst assigned wmdietl and unassigned mernst Jul 30, 2020
@wmdietl wmdietl assigned mernst and unassigned wmdietl Jul 31, 2020
@mernst
Copy link
Member Author

mernst commented Jul 31, 2020

@wmdietl Thanks for the feedback. I think I have addressed it (except for a change to an existing toString() routine that I propose to defer to a later pull request). Could you see whether I did so? Thanks.

@mernst mernst assigned wmdietl and unassigned mernst Jul 31, 2020
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
Copy link
Member

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() {
Copy link
Member

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?

@wmdietl wmdietl assigned mernst and unassigned wmdietl Jul 31, 2020
@mernst mernst assigned wmdietl and unassigned mernst Jul 31, 2020
Copy link
Member

@wmdietl wmdietl left a 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.
Copy link
Member

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.

Copy link
Member Author

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 wmdietl assigned mernst and unassigned wmdietl Aug 4, 2020
@mernst
Copy link
Member Author

mernst commented Aug 5, 2020

@wmdietl Would you prefer that I rename all the repr methods to debugToString? That would be consistent with naming in some other parts of the Checker Framework. And it's less concise and therefore less obscure.

@mernst mernst merged commit a741394 into typetools:master Aug 5, 2020
@mernst mernst deleted the analysisresult-repr branch August 5, 2020 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants