-
Notifications
You must be signed in to change notification settings - Fork 3
[#164] fix error found in #164 #165
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,9 +1,12 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| package io.github.bmarwell.jfmt.commands; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| import io.github.bmarwell.jfmt.imports.ImportOrderConfiguration; | ||||||||||||||||||||||||||||||||||||||||||||
| import io.github.bmarwell.jfmt.imports.ImportOrderProcessorException; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.nio.file.Path; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Iterator; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Locale; | ||||||||||||||||||||||||||||||||||||||||||||
| import org.eclipse.jdt.core.dom.ASTNode; | ||||||||||||||||||||||||||||||||||||||||||||
| import org.eclipse.jdt.core.dom.CompilationUnit; | ||||||||||||||||||||||||||||||||||||||||||||
| import org.eclipse.jdt.core.dom.ImportDeclaration; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -27,7 +30,7 @@ public ImportOrderProcessor(ImportOrderConfiguration importOrderTokens) { | |||||||||||||||||||||||||||||||||||||||||||
| * Rewrites the imports in the provided document according to the configured order. | ||||||||||||||||||||||||||||||||||||||||||||
| * If there are no imports, this method is a no-op. | ||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||
| public void rewriteImportsIfAny(CompilationUnit compilationUnit, IDocument workingDoc) | ||||||||||||||||||||||||||||||||||||||||||||
| public void rewriteImportsIfAny(Path javaFile, CompilationUnit compilationUnit, IDocument workingDoc) | ||||||||||||||||||||||||||||||||||||||||||||
| throws BadLocationException { | ||||||||||||||||||||||||||||||||||||||||||||
| @SuppressWarnings("unchecked") | ||||||||||||||||||||||||||||||||||||||||||||
| List<ImportDeclaration> imports = new ArrayList<>((List<ImportDeclaration>) compilationUnit.imports()); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -42,7 +45,7 @@ public void rewriteImportsIfAny(CompilationUnit compilationUnit, IDocument worki | |||||||||||||||||||||||||||||||||||||||||||
| List<ImportOrderGroup> groups = buildGroupsFromConfig(p); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| String rendered = renderGroups(groups); | ||||||||||||||||||||||||||||||||||||||||||||
| replaceImportsInDocument(compilationUnit, workingDoc, rendered); | ||||||||||||||||||||||||||||||||||||||||||||
| replaceImportsInDocument(javaFile, compilationUnit, workingDoc, rendered); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| private Partition partitionImports(List<ImportDeclaration> imports) { | ||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -144,7 +147,21 @@ private String renderGroups(List<ImportOrderGroup> groups) { | |||||||||||||||||||||||||||||||||||||||||||
| return sb.toString(); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| private void replaceImportsInDocument(CompilationUnit compilationUnit, IDocument workingDoc, String rendered) | ||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||
| * @param javaFile | ||||||||||||||||||||||||||||||||||||||||||||
| * @param compilationUnit | ||||||||||||||||||||||||||||||||||||||||||||
| * @param workingDoc | ||||||||||||||||||||||||||||||||||||||||||||
| * @param rendered | ||||||||||||||||||||||||||||||||||||||||||||
| * the newly rendered import block | ||||||||||||||||||||||||||||||||||||||||||||
| * @throws BadLocationException | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+150
to
+157
|
||||||||||||||||||||||||||||||||||||||||||||
| /** | |
| * | |
| * @param javaFile | |
| * @param compilationUnit | |
| * @param workingDoc | |
| * @param rendered | |
| * the newly rendered import block | |
| * @throws BadLocationException | |
| /** | |
| * Replaces the import block in the document. | |
| * | |
| * @param javaFile | |
| * the path to the Java source file being processed | |
| * @param compilationUnit | |
| * the parsed compilation unit containing the imports | |
| * @param workingDoc | |
| * the document being modified | |
| * @param rendered | |
| * the newly rendered import block | |
| * @throws BadLocationException | |
| * if the import block cannot be replaced at the calculated position |
Copilot
AI
Nov 17, 2025
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 substring call workingDoc.get().substring(importStart, importEnd) may throw StringIndexOutOfBoundsException if importEnd exceeds the document length after the workingDoc.replace() call on line 180. This can happen because the document has already been modified before this error handling code runs.
Consider using a safer approach:
int docLength = workingDoc.get().length();
int safeEnd = Math.min(importEnd, docLength);
workingDoc.get().substring(importStart, safeEnd)Or capture the original substring before the replace operation if that's what you intend to show in the error message.
| workingDoc.get().substring(importStart, importEnd) | |
| workingDoc.get().substring(importStart, Math.min(importEnd, workingDoc.get().length())) |
Copilot
AI
Nov 17, 2025
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 exception handling for IllegalArgumentException lacks test coverage. Consider adding a test case that triggers this error path to ensure the ImportOrderProcessorException is thrown correctly with the expected error message and context.
This would help verify:
- The exception message format is correct
- The file path is properly included in the exception
- The original
IllegalArgumentExceptionis wrapped as the cause
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,21 @@ | ||||||||||||||||||||
| package io.github.bmarwell.jfmt.imports; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import java.nio.file.Path; | ||||||||||||||||||||
| import java.util.StringJoiner; | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
||||||||||||||||||||
| /** | |
| * Exception thrown when the import order processor encounters an error | |
| * while rewriting imports in a Java source file. | |
| * <p> | |
| * This exception provides the path of the file being processed and the underlying cause. | |
| */ |
Copilot
AI
Nov 17, 2025
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 constructor lacks documentation. Add a JavaDoc comment describing the parameters.
Example:
/**
* Creates a new import order processor exception.
*
* @param path the path to the Java file being processed
* @param message the error message
* @param cause the underlying cause of the error
*/
public ImportOrderProcessorException(Path path, String message, Throwable cause) {| /** | |
| * Creates a new import order processor exception. | |
| * | |
| * @param path the path to the Java file being processed | |
| * @param message the error message | |
| * @param cause the underlying cause of the error | |
| */ |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -2,6 +2,8 @@ | |||
|
|
||||
| import java.io.InputStream; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.Map; | ||||
| import org.eclipse.jdt.core.JavaCore; | ||||
| import org.eclipse.jdt.core.dom.AST; | ||||
|
|
@@ -20,6 +22,8 @@ private ImportOrderTestUtil() { | |||
| // Utility class | ||||
| } | ||||
|
|
||||
| record TestResource(Path path, String contents) {} | ||||
|
|
||||
|
Comment on lines
+25
to
+26
|
||||
| record TestResource(Path path, String contents) {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package io.github.bmarwell.jfmt.imports; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
|
||
| import org.junit.jupiter.api.BeforeAll; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| final class Issue164Test extends ImportOrderProcessorTestBase { | ||
|
|
||
| @BeforeAll | ||
| static void loadSource() { | ||
| source = ImportOrderTestUtil.loadTestResource("imports/Issue164TestDatasource.java"); | ||
| } | ||
|
|
||
| @Override | ||
| protected String getProfileName() { | ||
| return "defaultorder"; | ||
| } | ||
|
|
||
| @Test | ||
| void is_correctly_formatted() { | ||
| // given | ||
| String expected = """ | ||
| import invalid.tool.dao.JpaUserDao; | ||
| import invalid.tool.dao.UserDao; | ||
| import jakarta.persistence.EntityManager; | ||
| import jakarta.persistence.EntityTransaction; | ||
| import jakarta.persistence.Parameter; | ||
| import jakarta.persistence.Query; | ||
| import jakarta.persistence.TypedQuery; | ||
| import jakarta.persistence.criteria.CriteriaQuery; | ||
| import java.util.function.Supplier; | ||
| import org.eclipse.persistence.internal.helper.DatabaseField; | ||
| import org.eclipse.persistence.internal.jpa.EJBQueryImpl; | ||
| import org.eclipse.persistence.jpa.JpaEntityManager; | ||
| import org.eclipse.persistence.queries.DatabaseQuery; | ||
| import org.eclipse.persistence.sessions.DatabaseRecord; | ||
| import org.eclipse.persistence.sessions.Session;"""; | ||
|
|
||
| // when | ||
| String actual = runAndGetImportBlock(); | ||
|
|
||
| // then | ||
| assertTrue(actual.startsWith(expected), "Import block should have been as expected but was: " + actual); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package invalid.tool.test.junit5; | ||
|
|
||
| import invalid.tool.dao.UserDao; | ||
| import invalid.tool.dao.JpaUserDao; | ||
|
|
||
| import org.eclipse.persistence.internal.helper.DatabaseField; | ||
| import org.eclipse.persistence.internal.jpa.EJBQueryImpl; | ||
| import org.eclipse.persistence.jpa.JpaEntityManager; | ||
| import org.eclipse.persistence.queries.DatabaseQuery; | ||
| import org.eclipse.persistence.sessions.DatabaseRecord; | ||
| import org.eclipse.persistence.sessions.Session; | ||
|
|
||
| import java.util.function.Supplier; | ||
| import jakarta.persistence.EntityManager; | ||
| import jakarta.persistence.EntityTransaction; | ||
| import jakarta.persistence.Parameter; | ||
| import jakarta.persistence.Query; | ||
| import jakarta.persistence.TypedQuery; | ||
| import jakarta.persistence.criteria.CriteriaQuery; | ||
|
|
||
| final class Issue164TestDatasource implements TestDataSource { | ||
| @Override | ||
| public <RET> RET executeInTransaction(final Supplier<RET> function) { | ||
| return executeInTransaction(function, this.em); | ||
| } | ||
|
|
||
| @Override | ||
| public void executeInTransaction(final Runnable function) { | ||
| throw new UnsupportedOperationException("removed for testing."); | ||
| } | ||
|
|
||
| private static <RET> RET executeInTransaction(final Supplier<RET> function, final EntityManager entityManager) { | ||
| throw new UnsupportedOperationException("removed for testing."); | ||
| } | ||
|
|
||
| } | ||
bmarwell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 JavaDoc for
rewriteImportsIfAnymethod is incomplete. It should document the newjavaFileparameter and the newImportOrderProcessorExceptionthat can be thrown.Suggested update: