-
Notifications
You must be signed in to change notification settings - Fork 911
my first refactoring session #361
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
Conversation
tried to attend to the highlighted items, guided by the IDE
for (DataObject dob:DataObject.getRegistry().getModified()) { | ||
SaveCookie cookie = dob.getCookie(SaveCookie.class); | ||
for (DataObject dataObject : DataObject.getRegistry().getModified()) { | ||
SaveCookie cookie = dataObject.getLookup().lookup(SaveCookie.class); |
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 appears there was a change here:
Before: dataObject.getCookie(SaveCookie.class)
After: dataObject.getLookup().lookup(SaveCookie.class)
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.
getLookup().lookup(SaveCookie.class) is the proper way.
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.
Oh, okay. Corroborating, I see that NetBeans provides an automatic fix which rewrites the getCookie() call to getLookup().lookup(SaveCookie.class)
.
@Override | ||
public void stop(ProgressEvent event) { | ||
// do not rely on plugins; | ||
/* do not rely on plugins; */ |
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.
Why the change to a multiline comment?
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 using the toggle comment feature with a hotkey, it will use single line comments on each line of the whole selected block. So, the thought was, that a multi-line comment would better reflect the true nature of a comment, and not just some blending out.
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.
Line comment was specifically invented for realy short notes and it's faster to type than /* - */ pair. I don't see a point to change it for one-liners. Maybe for long multilines.
It would be more useful to extend the toggle comment feature to:
- make a block comment (maybe a different hotkey or an additional modifier)
- turn block of line comments into block comment or vice versa
Whether to use multilines or block comments depend on personal or group development style - it's not a defect to fix.
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.
A different hotkey is not a good idea for me. I have reconfigured some actions to use the F1 to F12 keys. And since that is just not enough, I have started to use the Ctrl key in combination with some characters. Just so, that I can easily reach them both, with my left hand only, and without broken fingers. At this side of the keyboard there aren't much unused keys left for reconfiguration. And it would feel unnatural to use two different keystrokes for similar actions. The /**/ commentation mode is already used for documentation. Why not keep it like that, and use // mostly for partial code changes? Since "do not rely on plugins;" can not be evaluated by the compiler, I would recomment using /**/ commentation mode.
if (wrapper != null) { | ||
unsetWrappers(commit, wrapper); | ||
if (undoableWrapper != null) { | ||
undoableWrapper.setActive(false, null); |
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.
Should if (undoableWrapper != null) { undoableWrapper.setActive(false, null); }
be within a finally block?
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's ok as it is.
wrapper.close(); | ||
for (Transaction commit : SPIAccessor.DEFAULT.getCommits(bag)) { | ||
SPIAccessor.DEFAULT.sum(commit); | ||
undoableWrapper.setActive(false, null); |
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.
Similar to before, should undoableWrapper.setActive(false, null);
be within a finally block?
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 was not before. Probably it will be of use, if you explain it to me.
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.
Sorry, I was unclear. By "similar to before", I meant "similar to my previous comment up above".
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.
My apologies. I'm not able to answer that question. I would add things without concrete knowledge about what I'm actually doing.
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.
Which is very true.
} | ||
|
||
while (it.hasPrevious()) { | ||
undoableWrapper.close(); |
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.
Should undoableWrapper.close();
be within a finally block?
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.
Probably. Under the circumstance, that the code from within line 228 to 232 throws an unexpected exception. I'm not sure, if that is even possible. But it is a potential pitfall. I like your approach.
} | ||
}); | ||
if (undoableWrapper != null) { | ||
undoableWrapper.close(); |
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.
Should if (undoableWrapper != null) { undoableWrapper.close(); }
be within a finally block?
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.
There are several nested try and finally block in the source. I haven't touched the overall structure of it.
long time = System.currentTimeMillis(); | ||
|
||
final long start = System.currentTimeMillis(); | ||
Iterator it = internalList.iterator(); |
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 type of it
could be Iterator<RefactoringElementImplementation>
.
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's ok as it is.
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 this PR is to improve readability, it should use type params when possible to eliminate (unnecessary) typecasts. Please add it.
try { | ||
ListIterator it = internalList.listIterator(internalList.size()); | ||
fireProgressListenerStart(0, internalList.size()+1); | ||
ListIterator internalListIterator = internalList.listIterator(internalList.size()); |
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 type of internalListIterator
could be ListIterator<RefactoringElementImplementation>
. This should allow the type cast a few lines down to be removed.
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 shall be done. Thank you!
if (element.isEnabled() && !((element.getStatus() == RefactoringElement.GUARDED) || (element.getStatus() == RefactoringElement.READ_ONLY))) { | ||
element.undoChange(); | ||
} | ||
RefactoringElementImplementation element = (RefactoringElementImplementation) internalListIterator.previous(); |
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 type cast to RefactoringElementImplementation
could be removed after parameterizing internalListIterator
.
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.
Well spotted. Not bad!
public Iterator<RefactoringElement> iterator() { | ||
return new Iterator() { | ||
//private final Iterator<RefactoringElementImplementation> inner = internalList.iterator(); | ||
|
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.
Maybe delete the trailing spaces 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.
It's a new anonymous inner class implementation, right? The members can be separated by a newline from the enclosing curly braces. But they don't have to?
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'm fine with the blank lines. It just looked like you were deleting end-of-line whitespace, so the 16 trailing spaces on the new line 350 could be deleted as well.
boolean enabled = element.isEnabled(); | ||
boolean guarded = element.getStatus() == RefactoringElement.GUARDED; | ||
boolean readOnly = element.getStatus() == RefactoringElement.READ_ONLY; | ||
if (enabled && !(guarded || readOnly)) { |
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.
Hi Carsten, this computes "enabled", "guarded" and "readOnly" even when "element.isEnabled()" is false. The original expression
element.isEnabled() && !((element.getStatus() == RefactoringElement.GUARDED) || (element.getStatus() == RefactoringElement.READ_ONLY))
does not, though.
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.
Right, vieiro. I wanted to improve readability, and it resulted in a performance decrease. Haven't even noticed. My bad. Performance is also affected by the added private function call. Before the change, it was done with a redundant inlining of code. Which isn't to bad, but it is not easy to understand.
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.
you can count on private methods calls being inlined by optimizing VM, this is not counted as perf decrease.
You can also can
if (!element.isEnabled()) {
return;
}
// ....
if (readOnly || guarded) {
return;
}
or
if (!enabled || guarded || readOnly) {
return;
}
Which saves you complex conditions and nested blocks.
Hi @cp7781. Thanks for the PR. Are these changes related to an issue? if so then would you please add an issue to JIRA? |
Thank you for speaking for me, Antonio Vieiro. |
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.
Overall, I would rather avoid "beautification only" PRs like this. If one examines history later (when analyzing a bug), such "whitespace only" changes add processing time to verify that no semantic change was introduced.
There are only a few changes which in fact improve readability (simple loops onto forEach etc, curly braces in ifs).
boolean enabled = element.isEnabled(); | ||
boolean guarded = element.getStatus() == RefactoringElement.GUARDED; | ||
boolean readOnly = element.getStatus() == RefactoringElement.READ_ONLY; | ||
if (enabled && !(guarded || readOnly)) { |
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.
you can count on private methods calls being inlined by optimizing VM, this is not counted as perf decrease.
You can also can
if (!element.isEnabled()) {
return;
}
// ....
if (readOnly || guarded) {
return;
}
or
if (!enabled || guarded || readOnly) {
return;
}
Which saves you complex conditions and nested blocks.
UndoableWrapper undoableWrapper = MimeLookup.getLookup("").lookup(UndoableWrapper.class); | ||
commits.forEach(commit -> { | ||
if (undoableWrapper != null) { | ||
undoableWrapper.setActive(true, this); |
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 inline setWrappers ? Wouldn't it be better the other way around, to move null check into (un)setWrappers ?
long time = System.currentTimeMillis(); | ||
|
||
final long start = System.currentTimeMillis(); | ||
Iterator it = internalList.iterator(); |
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 this PR is to improve readability, it should use type params when possible to eliminate (unnecessary) typecasts. Please add it.
fileChange.performChange(); | ||
} | ||
} | ||
SPIAccessor.DEFAULT.getFileChanges(bag).stream().filter(fileChange -> fileChange.isEnabled()).forEachOrdered(fileChange -> fileChange.performChange()); |
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.
Well, I sort of doubt that this stream syntax improves readability over (more verbose) for
or forEach
. But please make a breakline between the individual processing steps, like this:
SPIAccessor.DEFAULT.getFileChanges(bag).stream().
filter(fileChange -> fileChange.isEnabled()).
forEachOrdered(fileChange -> fileChange.performChange());
Which can be usually scanned faster. Debugging of streamized code is a real pain, BTW.
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.
You are right. Would prefer, if the dot is placed at the new line, in front of the method call.
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.
Right. I think that placing the dot first and indenting twice is more standard:
SPIAccessor.DEFAULT.getFileChanges(bag).stream()
.filter(fileChange -> fileChange.isEnabled())
.forEachOrdered(fileChange -> fileChange.performChange());
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, thanks. I have bad old habits
time = System.currentTimeMillis() - time; | ||
timer.log(Level.FINE, "refactoringSession.doRefactoring", new Object[] { description, RefactoringSession.this, time } ); | ||
final long timeTaken = System.currentTimeMillis() - start; | ||
timer.log(Level.FINE, "refactoringSession.doRefactoring", new Object[]{description, RefactoringSession.this, timeTaken}); |
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.
Considering most of the PR fixes whitespaces, there should be whitespaces before/after { to separate from type and array content, and before }.
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 don't know, what a PR fix is. But to separate things, to get a better overview, seems to be a good idea.
} | ||
UndoableWrapper wrapper = MimeLookup.getLookup("").lookup(UndoableWrapper.class); | ||
SPIAccessor.DEFAULT.getCommits(bag).forEach(commit -> SPIAccessor.DEFAULT.check(commit, true)); | ||
UndoableWrapper undoableWrapper = MimeLookup.getLookup("").lookup(UndoableWrapper.class); |
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.
// NOI18N marker missing.
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.
There is no string, which needs to be translated. Why adding a comment?
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 // NOI18N
indicates that the string does not need to be translated.
I believe that some devs have a plugin which places warnings on all strings that are not marked "NOI18N" as a way of verifying that all strings either do not need translation or are localizable.
public RefactoringElement next() { | ||
if (index < internalList.size()) { | ||
return new RefactoringElement(internalList.get(index++)); | ||
RefactoringElementImplementation implementation = internalList.get(index); |
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.
Coding style in effect does not prohibit pre/postfix increments.
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.
No. That was not the intention. Prefix or postfix operators make loops far more readable in less abstract languages. Java has inherited, adopted and changed the culture, how humans understand code.
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.
OK, then why this change of one-liner return to 3 lines, when the original code did not violate coding conventions ?
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 may have seen white rabbits. Changed it back, and no complaints at all. Sometimes, mysterious things happen, and I just try to get used to it, alright? You are right. Thank you for the support.
A lot of people are spending a lot of time reviewing this pull request. It is unclear why this pull request exists. It seems this is a cosmetic refactoring of a random file in the Apache NetBeans Git repo. We do need to set up guidelines for pull requests and surely one of those will be that we need to have an issue number related to a pull request, i.e., an actual problem that we'd like to have fixed, before fixing it. |
The project needs far more developers refactoring their work constantly. Especially at the core product. If the overall structure crumbles and falls, it will be just another waste of time in the history of mankind. |
I think that fixing all of the warnings actually helps. When bug fixing, it is distracting to see all of the yellow warning indicator lines in the sidebar. It makes it more difficult to see what you've changed, as the light green, light blue, and pink added/changed/deleted indicator lines are hidden by the yellow lines. It also makes it more difficult to see the locations of breakpoints that you have set. For example, here is the bar for a file in which I have set two breakpoints and made changes to two parts of the file: One other benefit to general cleanup (in particular, supplying type information on generics) is that it cuts down on the voluminous output of build warnings. I have experimented with submitting the "cleanups" in the same patch as a bug fix (e.g. PR #287), but I don't like this approach. One must be in the mood for examining a lot of small changes that result from cleanup. This work is distracting from reviewing the meat of the patch. |
Sure, cleanup also opens the possibility to oversimplify important parts. Chances are pretty good, that art and skilled craftsmanship end in the trash bin. Lost forever, because the translation of the translation, done by novices like me, without real responsibility, becomes to complicated. That is, what will happen. Either take it for granted, or keep your eyes open the whole night. |
the refactoring methods work on three different class member collections, which all contain some sort of RefactoringElement; it is not completely clear, why they are there, and what they are doing; looks like file changes, commits, and a mysterious inner list; one of the refactoring method is full of try and finally blocks, but they don't catch exceptions by itself;
Hi, |
Cosmetics sound pretty good. Don't they? It's not just fonts and stuff. Good morning, spain. |
Can anyone tell me, were to get rid of that unit tests? I mean, now it looks like there is a reference somewhere, which needs to be fixed. And actually, I don't want to write unit tests for unit test routines, just because it means business. |
I think 22e386e needs to be reverted, or please explain why you deleted those unit tests. Also, I think 1ce564b is starting to go overboard. Some thoughts:
One final thought: I think that commit messages should not be cutesy or contain jokes (e.g. "against the order of maw") because the developers working on this project come from different backgrounds and may not get all of the references. I had to search "order of maw" to figure out that it is a Warcraft reference (I think? still not sure...). |
This reverts commit 22e386e.
For now, I wouldn't mind those tests, Daniel. There is some package missing, or something. And it turns red, if the plugin is opened. Just want to fix that.
Order of maw means breakfast. I had toast, honey and milk. And a nice girl was talking to me meanwhile. Life is just to good for waking up early. |
Keep in mind that usage of Lambda expression also totally breaks fix-and-continue during debugging. It's a nice syntax suggar but until Hotspot folks fix the VM, class with lambdas does not allow to incrementally fix the code. As for unit tests: they run on the master. So the only sane approach is to fix the code so that tests run again. But this PR is WIP, so OK. But before the PR is reviewed, I recommend to discard that commit from history. The PR starts being hard to read, mixing (intentionally just) formatting changes with refactorings which actually have potential to break something. I recommend to separate those two actions into either separate commits, or separate PRs - it's easier to verify that refactoring did not change semantic if 90% of file is not whitespace-changed. As for commit messages (personal opinion): I will not approve PR with messages like "for the queen", "fixing errors" (which actually deletes test code), or "order of maw". I believe that added confusion which outweights the fun of reading them. |
Debugging, like making use of assert statements, is a relic of the past. Modern software in general has become far way to complex for being used with such features. But take it as my humble opinion. I've almost no idea, how a real project would look like, and what possibly can be done, if used cleverly by a true master. |
So, just to make sure. The tags |
be warned though, several days ago an account named skylot appeared out of nowhere on my profile stars;
I contacted support, but they couldn't tell me anything but to change my password;
here, have a look: https://github.com/skylot
someone, who has a decompiler as project; oh my god, that's far beyond my skill level