From 3c2167ce64975cd9accdbdd2009753eee6b26ebc Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 9 Sep 2024 16:22:10 +0800 Subject: [PATCH] Force the DOM parser to continue with errors (#808) * Force the DOM parser to continue with compilation errors --- .../dom/JavacCompilationUnitResolver.java | 2 + .../jdt/internal/javac/JavacCompiler.java | 45 +---------- .../internal/javac/TolerantJavaCompiler.java | 76 +++++++++++++++++++ 3 files changed, 79 insertions(+), 44 deletions(-) create mode 100644 org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/TolerantJavaCompiler.java diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java index bde8c148689..825f641626b 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java @@ -70,6 +70,7 @@ import org.eclipse.jdt.internal.core.util.BindingKeyParser; import org.eclipse.jdt.internal.javac.JavacProblemConverter; import org.eclipse.jdt.internal.javac.JavacUtils; +import org.eclipse.jdt.internal.javac.TolerantJavaCompiler; import org.eclipse.jdt.internal.javac.UnusedProblemFactory; import org.eclipse.jdt.internal.javac.UnusedTreeScanner; @@ -479,6 +480,7 @@ private Map result = new HashMap<>(sourceUnits.length, 1.f); Map filesToUnits = new HashMap<>(); final UnusedProblemFactory unusedProblemFactory = new UnusedProblemFactory(new DefaultProblemFactory(), compilerOptions); diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacCompiler.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacCompiler.java index 6a1a16b738d..0ae2a89a050 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacCompiler.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacCompiler.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Queue; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -46,12 +45,9 @@ import org.eclipse.jdt.internal.core.builder.SourceFile; import com.sun.tools.javac.api.MultiTaskListener; -import com.sun.tools.javac.comp.*; import com.sun.tools.javac.comp.CompileStates.CompileState; import com.sun.tools.javac.main.JavaCompiler; -import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Pair; public class JavacCompiler extends Compiler { JavacConfig compilerConfig; @@ -117,46 +113,7 @@ public void compile(ICompilationUnit[] sourceUnits) { // Configure Javac to generate the class files in a mapped temporary location var outputDir = JavacClassFile.getMappedTempOutput(outputSourceSet.getKey()).toFile(); JavacUtils.configureJavacContext(javacContext, this.compilerConfig, javaProject, outputDir, true); - JavaCompiler javac = new JavaCompiler(javacContext) { - boolean isInGeneration = false; - - @Override - protected boolean shouldStop(CompileState cs) { - // Never stop - return false; - } - - @Override - public void generate(Queue, JCClassDecl>> queue, Queue results) { - try { - this.isInGeneration = true; - super.generate(queue, results); - } catch (Throwable ex) { - // TODO error handling - } finally { - this.isInGeneration = false; - } - } - - @Override - protected void desugar(Env env, Queue, JCClassDecl>> results) { - try { - super.desugar(env, results); - } catch (Throwable ex) { - // TODO error handling - } - } - - @Override - public int errorCount() { - // See JavaCompiler.genCode(Env env, JCClassDecl cdef), - // it stops writeClass if errorCount is not zero. - // Force it to return 0 if we are in generation phase, and keeping - // generating class files for those files without errors. - return this.isInGeneration ? 0 : super.errorCount(); - } - }; - javacContext.put(JavaCompiler.compilerKey, javac); + JavaCompiler javac = TolerantJavaCompiler.configureCompilerInstance(javacContext); javac.shouldStopPolicyIfError = CompileState.GENERATE; try { javac.compile(com.sun.tools.javac.util.List.from(outputSourceSet.getValue().stream() diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/TolerantJavaCompiler.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/TolerantJavaCompiler.java new file mode 100644 index 00000000000..970ebae9fb4 --- /dev/null +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/TolerantJavaCompiler.java @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (c) 2024 Microsoft Corporation and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License 2.0 +* which accompanies this distribution, and is available at +* https://www.eclipse.org/legal/epl-2.0/ +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Microsoft Corporation - initial API and implementation +*******************************************************************************/ + +package org.eclipse.jdt.internal.javac; + +import java.util.Queue; + +import javax.tools.JavaFileObject; + +import com.sun.tools.javac.comp.AttrContext; +import com.sun.tools.javac.comp.CompileStates.CompileState; +import com.sun.tools.javac.comp.Env; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Pair; + +public class TolerantJavaCompiler extends JavaCompiler { + boolean isInGeneration = false; + + public TolerantJavaCompiler(Context context) { + super(context); + } + + @Override + protected boolean shouldStop(CompileState cs) { + // Never stop + return false; + } + + @Override + public void generate(Queue, JCClassDecl>> queue, Queue results) { + try { + this.isInGeneration = true; + super.generate(queue, results); + } catch (Throwable ex) { + // TODO error handling + } finally { + this.isInGeneration = false; + } + } + + @Override + protected void desugar(Env env, Queue, JCClassDecl>> results) { + try { + super.desugar(env, results); + } catch (Throwable ex) { + // TODO error handling + } + } + + @Override + public int errorCount() { + // See JavaCompiler.genCode(Env env, JCClassDecl cdef), + // it stops writeClass if errorCount is not zero. + // Force it to return 0 if we are in generation phase, and keeping + // generating class files for those files without errors. + return this.isInGeneration ? 0 : super.errorCount(); + } + + public static JavaCompiler configureCompilerInstance(Context context) { + TolerantJavaCompiler javacCompiler = new TolerantJavaCompiler(context); + context.put(JavaCompiler.compilerKey, javacCompiler); + return javacCompiler; + } +}