Skip to content

Commit

Permalink
Skip ProceedOnErrorTransTypes whenever possible
Browse files Browse the repository at this point in the history
Keep track in the context of the files that have compile errors
so we only use ProceedOnErrorTransTypes on those and ignore it
for files without errors (as it can cause some other issues, eg
with XLargeTests being very slow)

Workaround for eclipse-jdtls#1008
  • Loading branch information
mickaelistria committed Dec 6, 2024
1 parent b9f6e9e commit 5a95452
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Stream;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
Expand Down Expand Up @@ -54,10 +57,12 @@
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Context.Key;
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.Pair;

public class JavacCompiler extends Compiler {
public static final Key<Set<JavaFileObject>> FILES_WITH_ERRORS_KEY = new Key<>();
JavacConfig compilerConfig;
IProblemFactory problemFactory;

Expand Down Expand Up @@ -107,8 +112,13 @@ public void compile(ICompilationUnit[] sourceUnits) {
ProceedOnErrorTransTypes.preRegister(javacContext);
ProceedOnErrorGen.preRegister(javacContext);
JavacProblemConverter problemConverter = new JavacProblemConverter(this.compilerConfig.compilerOptions(), javacContext);
Set<JavaFileObject> sourceWithErrors = new HashSet<>();
javacContext.put(FILES_WITH_ERRORS_KEY, sourceWithErrors);
javacContext.put(DiagnosticListener.class, diagnostic -> {
if (diagnostic.getSource() instanceof JavaFileObject fileObject) {
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
sourceWithErrors.add(fileObject);
}
JavacProblem javacProblem = problemConverter.createJavacProblem(diagnostic);
if (javacProblem != null) {
ICompilationUnit originalUnit = this.fileObjectToCUMap.get(fileObject);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.comp.TransTypes;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Context.Factory;

Expand All @@ -24,20 +25,46 @@ public static void preRegister(Context context) {
context.put(transTypesKey, (Factory<TransTypes>) c -> new ProceedOnErrorTransTypes(c));
}

private boolean needsProceedOnError;
private Context context;

protected ProceedOnErrorTransTypes(Context context) {
super(context);
this.context = context;
}

@Override
public void visitClassDef(JCClassDecl def) {
this.needsProceedOnError = hasErrors(def);
super.visitClassDef(def);
this.needsProceedOnError = false;
}

private boolean hasErrors(JCClassDecl def) {
return this.context.get(JavacCompiler.FILES_WITH_ERRORS_KEY).contains(def.sym.sourcefile);
}

@Override
public void visitApply(JCMethodInvocation tree) {
if (tree.type.isErroneous()) {
return;
}
tree.meth = translate(tree.meth, null);
Symbol meth = TreeInfo.symbol(tree.meth);
if (!(meth.baseSymbol() instanceof MethodSymbol)) {
//workaround: guard against ClassCastException when referencing non existing member
return;
if (this.needsProceedOnError) {
// The next lines of code should allow to generate
// classes with errors, but they are sometimes
// causing infinite processing for files that
// have no errors (eg with XLargeTests).
// So at the moment we guard them by `needProceedOnError`
// but those lines must be considered fragile and made
// more bullet proof; concretely then need to work with
// XLargeTest.
// Cf https://github.com/eclipse-jdtls/eclipse-jdt-core-incubator/issues/1008
if (tree.type.isErroneous()) {
return;
}
tree.meth = translate(tree.meth, null);
Symbol meth = TreeInfo.symbol(tree.meth);
if (!(meth.baseSymbol() instanceof MethodSymbol)) {
//workaround: guard against ClassCastException when referencing non existing member
return;
}
}
super.visitApply(tree);
}
Expand Down

0 comments on commit 5a95452

Please sign in to comment.