From 4516c31ed788997d542d5f3c45d159949862c2b0 Mon Sep 17 00:00:00 2001 From: Mickael Istria Date: Tue, 21 Jan 2025 16:02:05 +0100 Subject: [PATCH] Improve some proceedOnError generation --- .../jdt/internal/javac/ProceedOnErrorGen.java | 28 ++++++-- .../javac/ProceedOnErrorTransTypes.java | 72 +++++++++++++------ 2 files changed, 76 insertions(+), 24 deletions(-) diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorGen.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorGen.java index 6e37c28e091..81b7c466d62 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorGen.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorGen.java @@ -19,6 +19,7 @@ import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCArrayAccess; import com.sun.tools.javac.tree.JCTree.JCAssign; +import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCErroneous; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; @@ -28,6 +29,7 @@ import com.sun.tools.javac.tree.JCTree.JCLiteral; import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCNewClass; +import com.sun.tools.javac.tree.JCTree.JCParens; import com.sun.tools.javac.tree.JCTree.JCThrow; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.Context; @@ -82,7 +84,7 @@ public void visitLiteral(JCLiteral tree) { @Override public void visitNewClass(JCNewClass tree) { - if (tree.type == null || tree.type.isErroneous()) { + if (tree.type == null || tree.type.isErroneous() || tree.args.stream().anyMatch(arg -> arg.type == null || arg.type.isErroneous())) { visitErroneous(null); } else { super.visitNewClass(tree); @@ -91,7 +93,7 @@ public void visitNewClass(JCNewClass tree) { @Override public void visitApply(JCMethodInvocation tree) { - if (tree.type.isErroneous()) { + if (tree.type.isErroneous() || tree.args.stream().anyMatch(arg -> arg.type == null || arg.type.isErroneous())) { visitErroneous(null); } else { super.visitApply(tree); @@ -118,7 +120,7 @@ public void visitExec(JCExpressionStatement tree) { @Override public void visitAssign(JCAssign tree) { - if (tree.lhs.type.isErroneous()) { + if (tree.lhs.type.isErroneous() || tree.rhs == null || tree.rhs.type == null || tree.rhs.type.isErroneous()) { visitErroneous(null); } else { super.visitAssign(tree); @@ -127,7 +129,7 @@ public void visitAssign(JCAssign tree) { @Override public void visitIndexed(JCArrayAccess tree) { - if (tree.type.isErroneous() || tree.getIndex() == null) { + if (tree.type.isErroneous() || tree.getIndex() == null || tree.getIndex().type == null || tree.getIndex().type.isErroneous()) { visitErroneous(null); } else { super.visitIndexed(tree); @@ -165,4 +167,22 @@ public void visitVarDef(JCVariableDecl varDef) { super.visitVarDef(varDef); } } + + @Override + public void visitBinary(JCBinary binary) { + if (!isValid(binary.lhs) || !isValid(binary.rhs)) { + visitErroneous(null); + } else { + super.visitBinary(binary); + } + } + + @Override + public void visitParens(JCParens parens) { + if (!isValid(parens) || !isValid(parens.expr)) { + visitErroneous(null); + } else { + super.visitParens(parens); + } + } } diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorTransTypes.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorTransTypes.java index 554a64db3e6..c56c699ae82 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorTransTypes.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProceedOnErrorTransTypes.java @@ -10,12 +10,18 @@ *******************************************************************************/ package org.eclipse.jdt.internal.javac; +import java.util.function.Predicate; + 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.JCTree; +import com.sun.tools.javac.tree.TreeInfo; +import com.sun.tools.javac.tree.JCTree.JCAssign; 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.tree.JCTree.JCParens; +import com.sun.tools.javac.tree.JCTree.JCTypeCast; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context.Factory; @@ -46,27 +52,53 @@ private boolean hasErrors(JCClassDecl def) { @Override public void visitApply(JCMethodInvocation tree) { - 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; - } + if (!isValid(tree) || tree.args.stream().anyMatch(Predicate.not(this::isValid))) { + return; + } + // 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 + + 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); } + @Override + public void visitAssign(JCAssign tree) { + if (!isValid(tree.lhs) || !isValid(tree.rhs)) { + return; + } + super.visitAssign(tree); + } + + @Override + public void visitTypeCast(JCTypeCast tree) { + if (!isValid(tree) || !isValid(tree.expr)) { + return; + } + super.visitTypeCast(tree); + } + + @Override + public void visitParens(JCParens tree) { + if (!isValid(tree)) { + return; + } + super.visitParens(tree); + } + + private boolean isValid(JCTree tree) { + return tree != null && tree.type != null && !tree.type.isErroneous(); + } }