Open sretake opened 11 months ago
When class C is not in the current project, stack overflow will occur in the following test example
@Test()
void foo(){
Launcher launcher = new Launcher();
launcher.getEnvironment().setComplianceLevel(11);
launcher.getEnvironment().setAutoImports(true);
launcher.addInputResource(new VirtualFile("" +
"import com.C;\n" +
"import java.util.List;\n" +
"import java.util.function.BiFunction;\n" +
"\n" +
"public class A {\n" +
" public void test( List<? extends C> list, BiFunction<C, B, Boolean> func) {\n" +
" list.stream().forEach(c -> {\n" +
" func.apply(c, null);\n" +
" });\n" +
" }\n" +
"}\n" +
"class B{ }" +
""));
CtModel ctModel = launcher.buildModel();
List<CtExecutableReference> elements = ctModel.getElements(new TypeFilter<>(CtExecutableReference.class));
for (CtExecutableReference element : elements) {
try{
element.getExecutableDeclaration();
}catch(StackOverflowError e){
e.printStackTrace();
}
}
}
When class C is in the current project, the following test cases are normal
@Test()
void foo(){
Launcher launcher = new Launcher();
launcher.getEnvironment().setComplianceLevel(11);
launcher.getEnvironment().setAutoImports(true);
launcher.addInputResource(new VirtualFile("" +
"import java.util.List;\n" +
"import java.util.function.BiFunction;\n" +
"\n" +
"public class A {\n" +
" public void test( List<? extends C> list, BiFunction<C, B, Boolean> func) {\n" +
" list.stream().forEach(c -> {\n" +
" func.apply(c, null);\n" +
" });\n" +
" }\n" +
"}\n" +
"class B{ }class C{}" +
""));
CtModel ctModel = launcher.buildModel();
List<CtExecutableReference> elements = ctModel.getElements(new TypeFilter<>(CtExecutableReference.class));
for (CtExecutableReference element : elements) {
try{
element.getExecutableDeclaration();
}catch(StackOverflowError e){
e.printStackTrace();
}
}
}
Can anyone answer me if it's actually a bug @alcides
I mean, it is kind of a bug but not really. It only happens in noclasspath mode, because in there JDT's type inference gives up:
As JDT is not able to resolve this to the apply(Object, Object)
method in the class, Spoon would need to make that translation on a best-effort basis. Sadly, during erasure computation for the parameter spoon enters an infinite loop. I am sure spoon could be more clever here, but it still won't really be able to answer that query correctly with the types provided by JDT.
The question is whether we want to try and make Spoon a bit smarter here and let it return from the call -- possibly returning garbage information. We could also make it return null
, I guess, but I am not sure how straightforward the required changes in spoon would be (if at all possible to detect).
thanks, i suggest you can return null
or throw SpoonException
instead of StackOverflowError
, because it will cause my program to crash.
Describe the bug
StackOverflowError occurred in CtExecutableReference.getExecutableDeclaration
Source code you are trying to analyze/transform
Source code for your Spoon processing
Actual output
Expected output
Spoon Version
10.4.3-beta-10
JVM Version
11
What operating system are you using?
windows 11