/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.compiler.problem; 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.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; /* * 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 implements ProblemSeverities { public final static String[] NoArgument = new String[0]; final public IErrorHandlingPolicy policy; public final IProblemFactory problemFactory; public final CompilerOptions options; /* * 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 Error; // by default all problems are errors } public IProblem createProblem( char[] fileName, int problemId, String[] problemArguments, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition, int lineNumber) { return this.problemFactory.createProblem( fileName, problemId, problemArguments, messageArguments, severity, problemStartPosition, problemEndPosition, lineNumber); } public void handle( int problemId, String[] problemArguments, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition, ReferenceContext referenceContext, CompilationResult unitResult) { if (severity == Ignore) return; // if no reference context, we need to abort from the current compilation process if (referenceContext == null) { if ((severity & Error) != 0) { // non reportable error is fatal IProblem problem = this.createProblem(null, problemId, problemArguments, messageArguments, severity, 0, 0, 0); throw new AbortCompilation(null, problem); } else { return; // ignore non reportable warning } } IProblem problem = this.createProblem( unitResult.getFileName(), problemId, problemArguments, messageArguments, severity, problemStartPosition, problemEndPosition, problemStartPosition >= 0 ? searchLineNumber(unitResult.lineSeparatorPositions, problemStartPosition) : 0); if (problem == null) return; // problem couldn't be created, ignore switch (severity & Error) { case Error : this.record(problem, unitResult, referenceContext); referenceContext.tagAsHavingErrors(); // should abort ? int abortLevel; if ((abortLevel = (this.policy.stopOnFirstError() ? AbortCompilation : severity & Abort)) != 0) { referenceContext.abort(abortLevel, problem); } break; case Warning : this.record(problem, unitResult, referenceContext); break; } } /** * 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, messageArguments, this.computeSeverity(problemId), // severity inferred using the ID problemStartPosition, problemEndPosition, referenceContext, unitResult); } public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) { unitResult.record(problem, referenceContext); } /** * Search the line number corresponding to a specific position */ public static final int searchLineNumber(int[] startLineIndexes, int position) { if (startLineIndexes == null) return 1; int length = startLineIndexes.length; if (length == 0) return 1; int g = 0, d = length - 1; int m = 0; while (g <= d) { m = (g + d) /2; if (position < startLineIndexes[m]) { d = m-1; } else if (position > startLineIndexes[m]) { g = m+1; } else { return m + 1; } } if (position < startLineIndexes[m]) { return m+1; } return m+2; } }