Copyright (c) 2000, 2016 IBM Corporation and others. 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: IBM Corporation - initial API and implementation Stephan Herrmann - Contribution for Bug 458396 - NPE in CodeStream.invoke()
/******************************************************************************* * Copyright (c) 2000, 2016 IBM Corporation and others. * * 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: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for * Bug 458396 - NPE in CodeStream.invoke() *******************************************************************************/
package org.eclipse.jdt.internal.compiler.problem; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; import org.eclipse.jdt.internal.compiler.IProblemFactory; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.util.Util; /* * Compiler error handler, responsible to determine whether * a problem is actually a warning or an error; also will * decide whether the compilation task can be processed further or not. * * Behavior : will request its current policy if need to stop on * first error, and if should proceed (persist) with problems. */ public class ProblemHandler { public final static String[] NoArgument = CharOperation.NO_STRINGS; public IErrorHandlingPolicy policy; public final IProblemFactory problemFactory; public final CompilerOptions options; /* When temporarily switching policies, store here the original root policy (for temporary resume). */ private IErrorHandlingPolicy rootPolicy; protected boolean suppressTagging = false; /* * Problem handler can be supplied with a policy to specify * its behavior in error handling. Also see static methods for * built-in policies. * */ public ProblemHandler(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) { this.policy = policy; this.problemFactory = problemFactory; this.options = options; } /* * Given the current configuration, answers which category the problem * falls into: * Error | Warning | Ignore */ public int computeSeverity(int problemId){ return ProblemSeverities.Error; // by default all problems are errors } public CategorizedProblem createProblem( char[] fileName, int problemId, String[] problemArguments, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition, int lineNumber, int columnNumber) { return this.problemFactory.createProblem( fileName, problemId, problemArguments, messageArguments, severity, problemStartPosition, problemEndPosition, lineNumber, columnNumber); } public CategorizedProblem createProblem( char[] fileName, int problemId, String[] problemArguments, int elaborationId, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition, int lineNumber, int columnNumber) { return this.problemFactory.createProblem( fileName, problemId, problemArguments, elaborationId, messageArguments, severity, problemStartPosition, problemEndPosition, lineNumber, columnNumber); } public void handle( int problemId, String[] problemArguments, int elaborationId, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition, ReferenceContext referenceContext, CompilationResult unitResult) { if (severity == ProblemSeverities.Ignore) return; boolean mandatory = (severity & (ProblemSeverities.Error | ProblemSeverities.Optional)) == ProblemSeverities.Error; if ((severity & ProblemSeverities.InternalError) == 0 && this.policy.ignoreAllErrors()) { // Error is not to be exposed, but clients may need still notification as to whether there are silently-ignored-errors. // if no reference context, we need to abort from the current compilation process if (referenceContext == null) { if ((severity & ProblemSeverities.Error) != 0) { // non reportable error is fatal CategorizedProblem problem = this.createProblem(null, problemId, problemArguments, elaborationId, messageArguments, severity, 0, 0, 0, 0); throw new AbortCompilation(null, problem); } else { return; // ignore non reportable warning } } if (mandatory) referenceContext.tagAsHavingIgnoredMandatoryErrors(problemId); return; } if ((severity & ProblemSeverities.Optional) != 0 && problemId != IProblem.Task && !this.options.ignoreSourceFolderWarningOption) { ICompilationUnit cu = unitResult.getCompilationUnit(); try{ if (cu != null && cu.ignoreOptionalProblems()) return; // workaround for illegal implementation of ICompilationUnit, see https://bugs.eclipse.org/372351 } catch (AbstractMethodError ex) { // continue } } // if no reference context, we need to abort from the current compilation process if (referenceContext == null) { if ((severity & ProblemSeverities.Error) != 0) { // non reportable error is fatal CategorizedProblem problem = this.createProblem(null, problemId, problemArguments, elaborationId, messageArguments, severity, 0, 0, 0, 0); throw new AbortCompilation(null, problem); } else { return; // ignore non reportable warning } } int[] lineEnds; int lineNumber = problemStartPosition >= 0 ? Util.getLineNumber(problemStartPosition, lineEnds = unitResult.getLineSeparatorPositions(), 0, lineEnds.length-1) : 0; int columnNumber = problemStartPosition >= 0 ? Util.searchColumnNumber(unitResult.getLineSeparatorPositions(), lineNumber, problemStartPosition) : 0; CategorizedProblem problem = this.createProblem( unitResult.getFileName(), problemId, problemArguments, elaborationId, messageArguments, severity, problemStartPosition, problemEndPosition, lineNumber, columnNumber); if (problem == null) return; // problem couldn't be created, ignore switch (severity & ProblemSeverities.Error) { case ProblemSeverities.Error : record(problem, unitResult, referenceContext, mandatory); if ((severity & ProblemSeverities.Fatal) != 0) { // don't abort or tag as error if the error is suppressed if (!referenceContext.hasErrors() && !mandatory && this.options.suppressOptionalErrors) { CompilationUnitDeclaration unitDecl = referenceContext.getCompilationUnitDeclaration(); if (unitDecl != null && unitDecl.isSuppressed(problem)) { return; } } if (!this.suppressTagging || this.options.treatOptionalErrorAsFatal) { referenceContext.tagAsHavingErrors(); } // should abort ? int abortLevel; if ((abortLevel = this.policy.stopOnFirstError() ? ProblemSeverities.AbortCompilation : severity & ProblemSeverities.Abort) != 0) { referenceContext.abort(abortLevel, problem); } } break; case ProblemSeverities.Warning : record(problem, unitResult, referenceContext, false); break; } }
Standard problem handling API, the actual severity (warning/error/ignore) is deducted from the problem ID and the current compiler options.
/** * Standard problem handling API, the actual severity (warning/error/ignore) is deducted * from the problem ID and the current compiler options. */
public void handle( int problemId, String[] problemArguments, String[] messageArguments, int problemStartPosition, int problemEndPosition, ReferenceContext referenceContext, CompilationResult unitResult) { this.handle( problemId, problemArguments, 0, // no message elaboration messageArguments, computeSeverity(problemId), // severity inferred using the ID problemStartPosition, problemEndPosition, referenceContext, unitResult); } public void record(CategorizedProblem problem, CompilationResult unitResult, ReferenceContext referenceContext, boolean mandatoryError) { unitResult.record(problem, referenceContext, mandatoryError); }
Returns:old policy.
/** @return old policy. */
public IErrorHandlingPolicy switchErrorHandlingPolicy(IErrorHandlingPolicy newPolicy) { if (this.rootPolicy == null) this.rootPolicy = this.policy; IErrorHandlingPolicy presentPolicy = this.policy; this.policy = newPolicy; return presentPolicy; }
Temporarily suspend a temporary error handling policy.
Returns:old policy.
/** * Temporarily suspend a temporary error handling policy. * @return old policy. */
public IErrorHandlingPolicy suspendTempErrorHandlingPolicy() { IErrorHandlingPolicy presentPolicy = this.policy; if (this.rootPolicy != null) this.policy = this.rootPolicy; return presentPolicy; }
Resume from a corresponding suspendTempErrorHandlingPolicy().
Params:
  • previousPolicy – the result value of the matching suspend call
/** * Resume from a corresponding {@link #suspendTempErrorHandlingPolicy()}. * @param previousPolicy the result value of the matching suspend call */
public void resumeTempErrorHandlingPolicy(IErrorHandlingPolicy previousPolicy) { this.policy = previousPolicy; } }