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

refactor: address IntelliJ QAPlug plugin findings #5149

Merged
merged 35 commits into from
Nov 11, 2023

Conversation

jdrueckert
Copy link
Member

@jdrueckert jdrueckert commented Oct 22, 2023

  • make final fields static
  • remove unnecessary local before return
  • remove instanceof checks in catch clause
  • avoid throwing java.lang.Exception
  • remove null checks covered by instanceof check
  • remove toString on String objects
  • remove overrides that only call their super
  • remove unused private methods
  • remove unnecessary if statement nesting
  • remove unused local variables
  • use try-with-resources to close resources after use
  • use equals() to compare object references
  • fix broken javadoc references
  • fix disallowed self-closing and empty javadoc elements
  • fix bad use of symbols in javadoc
  • fix disallowed list item tag in javadoc without surrounding list
  • fix erroneous javadoc tags
  • fix emphasize tags in javadoc
  • remove illegal throws
  • remove unused imports

Related:
Terasology/CoreRendering#75
Terasology/Furnishings#17
Terasology/Health#105
Terasology/Inventory#51
Terasology/Behaviors#114
Terasology/CoreWorlds#45
Terasology/FlexiblePathfinding#32

Adds to #3859

Copy link
Contributor

@soloturn soloturn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

walked through the single commits to understand reasoning better. looks all ok to me. as the PR is big, it should be merged immediate as rebase etc is not so easy, in my opinion.

@@ -80,6 +80,12 @@ public void setDepthAuto() {
}
}

@Override
@SuppressWarnings("PMD.UselessOverridingMethod") // override elevates access modifier
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does "elevates access modifier" mean in this context, resp why one want to have it here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method is only calling its super and thus wouldn't be required, but the super method is protected while the overriding method is public, thereby elevating the accessibility of the method. Without the override, package-external entities would not be able to call the (super) method.

If we look at the jenkins build error in https://jenkins.terasology.io/job/Terasology/job/engine/job/PR-5149/3/console that's exactly the problem we see:

/home/jenkins/agent/workspace/Terasology_engine_PR-5149/engine/src/main/java/org/terasology/engine/rendering/nui/internal/NUIManagerInternal.java:421: error: setId(String) has protected access in AbstractWidget
        screen.setId(uri.toString());
              ^

NUIManagerInternal needs to call this method but is not able to without the override that allows the method to be called by package-external entities. Hence we need the override as it elevates the access modifier.

Note: Whether NUIManagerInternal should call this method or whether the super method should be public in the first place is a valid question but it goes beyond this refactoring here and I consciously decide to ignore this potential rabbit hole for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can make sense to have some methods protected on an interface/super class, and exposing them in sub-classes. For instance, if implementations are not in the same package but are supposed to handle internals.

Whether or not it makes sense here in particular is something we could double check again.

Copy link
Member

@skaldarnar skaldarnar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through all the commits now and left some comments (please split PRs like this into smaller chunks, maybe 5 commits at max, to allow for faster reviews).

@@ -34,6 +34,7 @@
public class ClientConnectionHandler extends ChannelInboundHandlerAdapter {

private static final Logger logger = LoggerFactory.getLogger(ClientConnectionHandler.class);
private static final long timeoutThreshold = 120000;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be names with all-caps then (TIMEOUT_THRESHOLD)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the logger we don't really apply the all-caps constant practice anywhere. if we want to do it consistently, then we should probably do it for the logger as well, right?

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'll not do this within this PR, but we can start refactoring accordingly on everything we actively work on if we think it makes sense

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the all caps notation is specifically used for constant values like this threshold.

I personally think that just being static and final does not make something a constant as in mathematics, so I'm in favor of not being too strict about consistency for this. I prefer logger.info(...) over LOGGER.info(...), but on the other hand would prefer wait(TIMEOUT) over wait(timeout).

DisplayNameComponent displayNameComponent = instigatorClientInfo.getComponent(DisplayNameComponent.class);
return displayNameComponent.name;
return instigatorClientInfo.getComponent(DisplayNameComponent.class).name;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'm not sure about this one. Technically it is possible, yes, but I don't like that there are so many .s in that one line.

On the other hand, it is in line with the two statements above, where we also do

someObject.getComponent(MyComponent.calss).someField;

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'll leave it as is for now.

Comment on lines -75 to -80
if (message.getType() == CoreMessageType.CHAT || message.getType() == CoreMessageType.NOTIFICATION) {

if (message.getType() == CoreMessageType.CHAT || message.getType() == CoreMessageType.NOTIFICATION
&& !nuiManager.isOpen(CHAT_UI) && !nuiManager.isOpen(CONSOLE_UI)) {
// show overlay only if chat and console are hidden
if (!nuiManager.isOpen(CHAT_UI) && !nuiManager.isOpen(CONSOLE_UI)) {
overlay.setVisible(true);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that I sometimes use constructs like this to put emphasis on the logical control flow, trusting in the compiler to be smart about the details.

I find long if conditions with many parts hard to read and to understand, and one has to put quite a lot thought into breaking it up when changing the control flow.

Therefore, I'm not a huge fan of some these changes in particular, but I'm not going to argue about this. Let's see how it plays out.

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'll leave it as is for now

@@ -92,6 +92,7 @@ private void updateGamepadMappings() {
if (!GLFW.glfwUpdateGamepadMappings(gamecontrolleDB)) {
logger.error("Cannot update GLFW's gamepad mapping, gamepads may not work correctly");
}
inputStream.close();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use try with resources instead of manually closing. This hopefully applies to most of the occurrences of this warning.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -80,6 +80,12 @@ public void setDepthAuto() {
}
}

@Override
@SuppressWarnings("PMD.UselessOverridingMethod") // override elevates access modifier
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can make sense to have some methods protected on an interface/super class, and exposing them in sub-classes. For instance, if implementations are not in the same package but are supposed to handle internals.

Whether or not it makes sense here in particular is something we could double check again.

@@ -11,8 +11,8 @@
import java.lang.annotation.Target;

/**
* Marks a {@link TypeHandler} to be automatically registered at a
* {@link TypeHandlerLibrary TypeHandlerLibrary} on environment change.
* Marks a {@link org.terasology.persistence.typeHandling.TypeHandler} to be automatically registered at a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really necessary? I thought that JavaDoc would be smart enough to reuse imports and allow for shorthand links within the same package 🤔 How does this render?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

javadoc complained about an unknown reference and auto-generated the long version when I re-added it 🤷‍♀️

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do you "auto-generate" something with javadoc?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally in an IDE like IntelliJ if you start by entering /** atop a method then IntelliJ will generate the whole Javadoc block (if you shift-enter or something?) including defined parameters etc. There are probably similar tricks when you have other interactions with Javadoc.

Plus the whole copilot madness which can just be eerily close to generating a pile of stuff correctly or oh-so-far from it at times :-)

}

protected AbstractBlockFamily(BlockFamilyDefinition definition, BlockBuilderHelper blockBuilder) {
protected AbstractBlockFamily(BlockFamilyDefinition definition) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change unrelated to the commit message - is that on purpose?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes and no - I saw that blockBuilder isn't used and wanted to change something about it but then I thought I'd ask soundwave about the intent of the changes first - still waiting to hear back... wanted to put the change in a separate PR, but seems they snuck their way in here unfortunately...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverted

Comment on lines -116 to -118
* 1. "Game" -> "Game"
* 2. "Game" -> "Game 1"
* 3. "Game 1" -> "Game 2"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not even here (in <pre>)? 😔 Maybe needs another {@code ... or so, never understood how that really works...

@@ -33,9 +33,9 @@
* whether the field is applicable for that block. For example:
*
* <pre>
* @ExtraDataSystem
* {@code @ExtraDataSystem}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can put the {@code right next to the <pre> and close it only in the end.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, {@code ...} (same as other @... tags) unfortunately doesn't work across multiple lines.

@jdrueckert jdrueckert merged commit 1cef7c1 into develop Nov 11, 2023
9 checks passed
@jdrueckert jdrueckert deleted the chore/qaplug-findings branch November 11, 2023 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Category: Test/QA Requests, Issues and Changes targeting tests and quality assurance Topic: Stabilization Requests, Issues and Changes related to improving stablity and reducing flakyness Type: Refactoring Request for or implementation of pure and automatic refactorings, e.g. renaming, to improve clarity
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants