Skip to content

Commit 2301028

Browse files
authored
Fix IllegalArgumentException in KotlinParser when dependsOn paths are relative (#6882)
* Fix `IllegalArgumentException` in KotlinParser when dependsOn paths are relative `dependsOn` inputs created via `determinePath` have relative paths, but source inputs may have absolute paths. When `relativeTo` is absolute, resolve dependsOn paths against it so `Path.relativize` in `getRelativePath` doesn't throw `IllegalArgumentException` due to an absolute/relative mismatch. * Add test for dependsOn with absolute relativeTo and guard getRelativePath The new test demonstrates the IllegalArgumentException that occurs when dependsOn provides relative paths but relativeTo is absolute (e.g. a @tempdir). Also adds the absolute/relative mismatch guard directly in Parser.Input.getRelativePath, which is called from KotlinTreeParserVisitor.
1 parent 8b7a44f commit 2301028

3 files changed

Lines changed: 45 additions & 4 deletions

File tree

rewrite-core/src/main/java/org/openrewrite/Parser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,10 @@ public static List<Input> fromResource(String resource, String delimiter, @Nulla
208208
}
209209

210210
public Path getRelativePath(@Nullable Path relativeTo) {
211-
return relativeTo == null ? path : relativeTo.relativize(path);
211+
if (relativeTo == null || path.isAbsolute() != relativeTo.isAbsolute()) {
212+
return path;
213+
}
214+
return relativeTo.relativize(path);
212215
}
213216

214217
public EncodingDetectingInputStream getSource(ExecutionContext ctx) {

rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,28 @@ public Stream<SourceFile> parseInputs(Iterable<Input> sources, @Nullable Path re
165165
ParsingExecutionContextView pctx = ParsingExecutionContextView.view(ctx);
166166
ParsingEventListener parsingListener = pctx.getParsingListener();
167167

168-
Set<Path> dependsOnPaths = dependsOn == null ? emptySet() :
169-
dependsOn.stream().map(Input::getPath).collect(toSet());
168+
// dependsOn inputs have relative paths (from determinePath), but source inputs
169+
// may have absolute paths. Resolve dependsOn paths to match so that
170+
// Path.relativize in getRelativePath doesn't throw IllegalArgumentException.
171+
List<Input> resolvedDependsOn = dependsOn;
172+
if (dependsOn != null && relativeTo != null && relativeTo.isAbsolute()) {
173+
resolvedDependsOn = new ArrayList<>(dependsOn.size());
174+
for (Input dep : dependsOn) {
175+
if (!dep.getPath().isAbsolute()) {
176+
resolvedDependsOn.add(Input.fromString(relativeTo.resolve(dep.getPath()), dep.getSource(pctx).readFully()));
177+
} else {
178+
resolvedDependsOn.add(dep);
179+
}
180+
}
181+
}
182+
183+
Set<Path> dependsOnPaths = resolvedDependsOn == null ? emptySet() :
184+
resolvedDependsOn.stream().map(i -> i.getRelativePath(relativeTo)).collect(toSet());
170185

171186
// TODO: FIR and disposable may not be necessary using the IR.
172187
Disposable disposable = Disposer.newDisposable();
173188
CompiledSource compilerCus;
174-
List<Input> acceptedInputs = ListUtils.concatAll(dependsOn, acceptedInputs(sources).collect(toList()));
189+
List<Input> acceptedInputs = ListUtils.concatAll(resolvedDependsOn, acceptedInputs(sources).collect(toList()));
175190
try {
176191
compilerCus = parse(acceptedInputs, disposable, pctx);
177192
} catch (Throwable t) {

rewrite-kotlin/src/test/java/org/openrewrite/kotlin/KotlinParserTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
package org.openrewrite.kotlin;
1717

1818
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.io.TempDir;
1920
import org.openrewrite.test.RewriteTest;
2021

22+
import java.nio.file.Path;
23+
2124
import static org.openrewrite.kotlin.Assertions.kotlin;
2225

2326
class KotlinParserTest implements RewriteTest {
@@ -40,4 +43,24 @@ class MyClass
4043
);
4144
}
4245

46+
@Test
47+
void dependsOnWithAbsoluteRelativeTo(@TempDir Path tempDir) {
48+
rewriteRun(
49+
spec -> spec
50+
.relativeTo(tempDir)
51+
.parser(KotlinParser.builder().dependsOn("""
52+
package foo.bar
53+
54+
class MyClass
55+
""")),
56+
kotlin(
57+
"""
58+
import foo.bar.MyClass
59+
60+
val myClass: MyClass? = null
61+
"""
62+
)
63+
);
64+
}
65+
4366
}

0 commit comments

Comments
 (0)