Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static SourceRemapper getSourceRemapper(String sourceFile, SourceMap sourceMap)
}
StratumExt stratumDebug = sourceMap.getStratum("KotlinDebug");
if (stratumDebug == null) {
throw new IllegalArgumentException("No stratumDebug found for KotlinDebug");
stratumDebug = new StratumExt("KotlinDebug");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid emitting mixed mappings for no-debug Kotlin SMAPs

When a Kotlin class has a SourceDebugExtension but omits KotlinDebug (the added f4 case generates SymbolExtraction16$f4$$inlined$groupingBy$1 with SourceFile: _Collections.kt and only a Kotlin stratum), this empty stratum sends every line through the main-stratum fallback. That fallback can map some bytecode lines to the app file while leaving others in the Kotlin library file, but SymbolExtractor still labels the entire scope with classNode.sourceFile, so we now emit nonsensical/mixed file-line ranges instead of just avoiding the exception. Classes with no KotlinDebug need to be skipped or remapped with a consistent source file.

Useful? React with 👍 / 👎.

}
return new KotlinSourceRemapper(stratumMain, stratumDebug);
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ public void noKotlinDebug() {
StratumExt stratumMainMock = mock(StratumExt.class);
when(sourceMapMock.getStratum(eq("Kotlin"))).thenReturn(stratumMainMock);
when(sourceMapMock.getStratum(eq("KotlinDebug"))).thenReturn(null);
IllegalArgumentException illegalArgumentException =
assertThrows(
IllegalArgumentException.class,
() -> SourceRemapper.getSourceRemapper("foo.kt", sourceMapMock));
assertEquals("No stratumDebug found for KotlinDebug", illegalArgumentException.getMessage());
SourceRemapper sourceRemapper = SourceRemapper.getSourceRemapper("foo.kt", sourceMapMock);
assertNotNull(sourceRemapper);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -995,13 +995,13 @@ public void symbolExtraction16() throws IOException, URISyntaxException {
KotlinHelper.compileAndLoad(CLASS_NAME, resource.getFile(), filesToDelete);
Object companion = Reflect.onClass(testClass).get("Companion");
int result = Reflect.on(companion).call("main", "").get();
assertEquals(48, result);
assertEquals(73, result);
} finally {
filesToDelete.forEach(File::delete);
}
assertEquals(2, symbolSinkMock.jarScopes.size());
assertEquals(4, symbolSinkMock.jarScopes.size());
Scope classScope = symbolSinkMock.jarScopes.get(0).getScopes().get(0);
assertScope(classScope, ScopeType.CLASS, CLASS_NAME, 6, 23, SOURCE_FILE, 5, 1);
assertScope(classScope, ScopeType.CLASS, CLASS_NAME, 6, 28, SOURCE_FILE, 6, 1);
assertLangSpecifics(
classScope.getLanguageSpecifics(),
asList("public", "final"),
Expand All @@ -1026,12 +1026,15 @@ public void symbolExtraction16() throws IOException, URISyntaxException {
Scope f3MethodScope = classScope.getScopes().get(3);
assertScope(f3MethodScope, ScopeType.METHOD, "f3", 21, 23, SOURCE_FILE, 1, 1);
assertLineRanges(f3MethodScope, "21-23");
Scope f4MethodScope = classScope.getScopes().get(4);
assertScope(f4MethodScope, ScopeType.METHOD, "f4", 27, 28, SOURCE_FILE, 1, 1);
assertLineRanges(f4MethodScope, "27-28");
assertScope(
classScope.getScopes().get(4), ScopeType.METHOD, "<clinit>", 0, 0, SOURCE_FILE, 0, 0);
classScope.getScopes().get(5), ScopeType.METHOD, "<clinit>", 0, 0, SOURCE_FILE, 0, 0);

Scope companionClassScope = symbolSinkMock.jarScopes.get(1).getScopes().get(0);
assertScope(
companionClassScope, ScopeType.CLASS, CLASS_NAME + "$Companion", 28, 29, SOURCE_FILE, 3, 0);
companionClassScope, ScopeType.CLASS, CLASS_NAME + "$Companion", 33, 34, SOURCE_FILE, 3, 0);
assertLangSpecifics(
classScope.getLanguageSpecifics(),
asList("public", "final"),
Expand All @@ -1049,8 +1052,8 @@ public void symbolExtraction16() throws IOException, URISyntaxException {
0,
0);
Scope mainMethodScope = companionClassScope.getScopes().get(1);
assertScope(mainMethodScope, ScopeType.METHOD, "main", 28, 29, SOURCE_FILE, 1, 1);
assertLineRanges(mainMethodScope, "28-29");
assertScope(mainMethodScope, ScopeType.METHOD, "main", 33, 34, SOURCE_FILE, 1, 1);
assertLineRanges(mainMethodScope, "33-34");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ class SymbolExtraction16 {
return value
}

fun f4(value: Int): Int {
val set = setOf(Person("john", "doe"), Person("agent", "smith"))
return set.groupingBy { it.firstName }.eachCount().toMutableMap().size
}

companion object {
fun main(arg: String): Int {
val c = SymbolExtraction16()
return c.f1(31) + c.f2(17)
return c.f1(31) + c.f2(17) + c.f3(23) + c.f4(0)
}
}
}

data class Person(val firstName: String, val lastName: String)