blob: c8b2772a9010983953c392ccedff93016007b895 [file] [log] [blame]
package org.eclipse.jdt.internal.compiler.problem;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.impl.*;
/*
* 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 {
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,
int severity,
int problemStartPosition,
int problemEndPosition,
int lineNumber) {
return problemFactory.createProblem(
fileName,
problemId,
problemArguments,
severity,
problemStartPosition,
problemEndPosition,
lineNumber);
}
public void handle(
int problemId,
String[] problemArguments,
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) {
throw new AbortCompilation(problemId, problemArguments);
}
IProblem problem =
this.createProblem(
unitResult.getFileName(),
problemId,
problemArguments,
severity,
problemStartPosition,
problemEndPosition,
problemStartPosition >= 0
? searchLineNumber(unitResult.lineSeparatorPositions, problemStartPosition)
: 0);
switch (severity & Error) {
case Error :
referenceContext.tagAsHavingErrors();
this.record(problem, unitResult);
// should abort ?
int abortLevel;
if ((abortLevel =
(policy.stopOnFirstError() ? AbortCompilation : severity & Abort))
!= 0) {
referenceContext.abort(abortLevel);
}
break;
case Warning :
this.record(problem, unitResult);
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,
int problemStartPosition,
int problemEndPosition,
ReferenceContext referenceContext,
CompilationResult unitResult) {
this.handle(
problemId,
problemArguments,
this.computeSeverity(problemId), // severity inferred using the ID
problemStartPosition,
problemEndPosition,
referenceContext,
unitResult);
}
public void record(IProblem problem, CompilationResult unitResult) {
unitResult.record(problem);
}
/**
* Search the line number corresponding to a specific position
*
* @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
*/
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;
}
}