Skip to content

Kotlin rules in java avoid multiple concat statements#694

Draft
stokpop wants to merge 16 commits into
pmd7from
kotlin-rules-in-java-AvoidMultipleConcatStatements
Draft

Kotlin rules in java avoid multiple concat statements#694
stokpop wants to merge 16 commits into
pmd7from
kotlin-rules-in-java-AvoidMultipleConcatStatements

Conversation

@stokpop

@stokpop stokpop commented Feb 23, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

stokpop and others added 14 commits February 22, 2026 12:50
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Bump pmd.version from 7.16.0 to 7.21.0
- Add KotlinAstUtil with 6 static helpers for Java-based Kotlin rules:
  getIdentifierText, typeContainsName, isDirectChildOfFunctionBody,
  getLhsVarName, findParamNamesOfType, findFunctionNamesReturningType
- Refactor AvoidMultipleConcatStatementsRule to use KotlinAstUtil,
  removing the two private findString* methods and all inline repetition

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…leConcatStatements' into kotlin-rules-in-java-AvoidMultipleConcatStatements

# Conflicts:
#	src/main/java/com/jpinpoint/perf/lang/kotlin/util/KotlinAstUtil.java
@stokpop stokpop requested a review from jborgers February 27, 2026 10:58
@sonarqubecloud

Copy link
Copy Markdown

@jborgers jborgers left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Added some review comments. Fix Sonar warnings, and can do a code review with coPilot, including best practices and performance first?

// --- .toRegex() calls ---
for (KotlinParser.KtNavigationSuffix navSuffix :
node.descendants(KotlinParser.KtNavigationSuffix.class)
.filter(ns -> KotlinAstUtil.isDirectDescendantOfFunctionDeclaration(ns, node))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This performs multiple full AST scans per function.
PMD visitors run on every function in every file on the entire project, so this compounds significantly.
Solution: Collect each AST node type once:

List<KtNavigationSuffix> navSuffixes = collectNavSuffixes(node);
List<KtPostfixUnaryExpression> postfixExprs = collectPostfixUnaryExpressions(node);

Precollect each node type once per function and reuse them across checks.
This reduces traversal cost from O(N × 4–8) → O(N).
(also for all other occurences in this file)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Interesting view, let me have a look on what overhead is and how to make it better.

* <li>Condition 6: arg contains string concatenation (+) with a class var field</li>
* </ul>
*/
private static boolean isRegexArgDynamic(KotlinParser.KtPostfixUnaryExpression pue,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Several methods (e.g. isRegexArgDynamic, isToRegexDynamic) do:

AST navigation
identifier extraction
“business” rule logic
set membership checks
multiple nested thematic checks (call suffix, string template, additive expr, etc.)

This mixing is a big maintainability smell.
Fix:
Split helpers into micro-checks:

isDynamicBecauseOfParam(...)
isDynamicBecauseOfLocalVar(...)
isDynamicBecauseOfMethodCall(...)
isDynamicBecauseOfTemplate(...)

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.

2 participants