-
Notifications
You must be signed in to change notification settings - Fork 53
FIX (GraphEngine): @W-12696959@: UnusedMethodRule now fully supports constructors. #1020
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
| // This means we need to do more, but what that "more" is depends on whether we're looking | ||
| // at an inner or outer type. | ||
| boolean typeIsInner = constructedType.contains("."); | ||
| if (typeIsInner) { |
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 contents of this if branch are very similar to those of the one at line 316, but I couldn't see a way to cleanly refactor them into a single method. In the fullness of time, we may want to revisit that.
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.
How about extracting a method and passing in NodeType.<vertex_type>, inner class name, and outer class name as input?
The name-splitting could become a util method in ClassUtil.
| * @param referencedType - The outer type with which inner types may collide | ||
| * @return - {@code unfilteredResults}, with all colliding references removed | ||
| */ | ||
| private <T extends BaseSFVertex> List<T> removeInnerTypeCollisions( |
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 else-branch from getInvocationsOnType and getConstructionsOfType are identical, and have been refactored into their own method.
| */ | ||
| @ValueSource(ints = {0, 1}) | ||
| @ParameterizedTest(name = "{displayName}: Arity {0}") | ||
| public void constructorCalledViaNew_expectNoViolation(Integer arity) { |
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.
New test for simply calling a constructor for one class in another class. This sort of thing is arguably covered by the tests for inner classes, but I felt that having an explicit test for it did no harm.
| @ValueSource(strings = {"OuterClass.InnerClass", "InnerClass"}) | ||
| @ParameterizedTest(name = "{displayName}: OuterClass.InnerClass constructed as new {0}()") |
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 syntax with which the variable was declared ended up not impacting how the rule executes, so I removed the ability to configure that and cut the number of cases.
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.
How about we leave the initial set of ways of calling so that we'll know if there's ever a regression while making changes?
| @Disabled | ||
| public void innerConstructorUsedBySiblingInner_expectNoViolation( | ||
| String variable, String constructor) { | ||
| @ValueSource(strings = {"OuterClass.InnerClass", "InnerClass"}) |
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.
As above, variable declaration didn't terribly matter, so it was hardcoded.
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.
Same as above. If we have a change in mechanism, the additional cases will be helpful to look for regressions.
| */ | ||
| @ValueSource(ints = {0, 1}) | ||
| @ParameterizedTest(name = "{displayName}: Constructor of arity {0}") | ||
| public void externalReferenceSyntaxCollision_expectViolation(Integer arity) { |
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 seemed valuable to have tests for this kind of name ambiguity, so I added one.
| + " }\n" | ||
| // Use the engine directive to prevent this method from tripping the rule. | ||
| + " /* sfge-disable-stack UnusedMethodRule */" | ||
| + " /* sfge-disable-stack UnusedMethodRule */\n" |
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 missing newline meant that this directive was actually on the same line as the constructor and therefore wasn't being applied. Since public constructors weren't supported yet, that caused no problems. Adding support for public constructors caused the tests to start failing, and adding the newline fixes that.
This PR does the following:
UnusedMethodRulenow properly detects invocations of private/protected constructors via thenewkeyword (Thereby also resolving issue [BUG] SFGE reports false positives for constructors only called within a given class #1001)UnusedMethodRulenow fully support public constructors