b0f6fef057a292d5699f1296ecb204bda2c3dbe4
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / problem / ProblemHandler.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.problem;
12
13 import net.sourceforge.phpdt.core.compiler.IProblem;
14 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
15 import net.sourceforge.phpdt.internal.compiler.IErrorHandlingPolicy;
16 import net.sourceforge.phpdt.internal.compiler.IProblemFactory;
17 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
18 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
19
20
21 /*
22  * Compiler error handler, responsible to determine whether
23  * a problem is actually a warning or an error; also will
24  * decide whether the compilation task can be processed further or not.
25  *
26  * Behavior : will request its current policy if need to stop on
27  *      first error, and if should proceed (persist) with problems.
28  */
29
30 public class ProblemHandler implements ProblemSeverities {
31
32         public final static String[] NoArgument = new String[0];
33         
34         final public IErrorHandlingPolicy policy;
35         public final IProblemFactory problemFactory;
36         public final CompilerOptions options;
37 /*
38  * Problem handler can be supplied with a policy to specify
39  * its behavior in error handling. Also see static methods for
40  * built-in policies.
41  *
42  */
43 public ProblemHandler(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
44         this.policy = policy;
45         this.problemFactory = problemFactory;
46         this.options = options;
47 }
48 /*
49  * Given the current configuration, answers which category the problem
50  * falls into:
51  *              Error | Warning | Ignore
52  */
53 public int computeSeverity(int problemId){
54         return Error; // by default all problems are errors
55 }
56 public IProblem createProblem(
57         char[] fileName, 
58         int problemId, 
59         String[] problemArguments, 
60         String[] messageArguments,
61         int severity, 
62         int problemStartPosition, 
63         int problemEndPosition, 
64         int lineNumber,
65         ReferenceContext referenceContext,
66         CompilationResult unitResult) {
67
68         return problemFactory.createProblem(
69                 fileName, 
70                 problemId, 
71                 problemArguments, 
72                 messageArguments,
73                 severity, 
74                 problemStartPosition, 
75                 problemEndPosition, 
76                 lineNumber); 
77 }
78 public void handle(
79         int problemId, 
80         String[] problemArguments, 
81         String[] messageArguments,
82         int severity, 
83         int problemStartPosition, 
84         int problemEndPosition, 
85         ReferenceContext referenceContext, 
86         CompilationResult unitResult) {
87
88         if (severity == Ignore)
89                 return;
90
91         // if no reference context, we need to abort from the current compilation process
92         if (referenceContext == null) {
93                 if ((severity & Error) != 0) { // non reportable error is fatal
94                         throw new AbortCompilation(problemId, problemArguments, messageArguments);
95                 } else {
96                         return; // ignore non reportable warning
97                 }
98         }
99
100         IProblem problem = 
101                 this.createProblem(
102                         unitResult.getFileName(), 
103                         problemId, 
104                         problemArguments, 
105                         messageArguments,
106                         severity, 
107                         problemStartPosition, 
108                         problemEndPosition, 
109                         problemStartPosition >= 0
110                                 ? searchLineNumber(unitResult.lineSeparatorPositions, problemStartPosition)
111                                 : 0,
112                         referenceContext,
113                         unitResult); 
114         if (problem == null) return; // problem couldn't be created, ignore
115         
116         switch (severity & Error) {
117                 case Error :
118                         this.record(problem, unitResult, referenceContext);
119                         referenceContext.tagAsHavingErrors();
120
121                         // should abort ?
122                         int abortLevel;
123                         if ((abortLevel = 
124                                 (policy.stopOnFirstError() ? AbortCompilation : severity & Abort)) != 0) {
125
126                                 referenceContext.abort(abortLevel);
127                         }
128                         break;
129                 case Warning :
130                         this.record(problem, unitResult, referenceContext);
131                         break;
132         }
133 }
134 /**
135  * Standard problem handling API, the actual severity (warning/error/ignore) is deducted
136  * from the problem ID and the current compiler options.
137  */
138 public void handle(
139         int problemId, 
140         String[] problemArguments, 
141         String[] messageArguments,
142         int problemStartPosition, 
143         int problemEndPosition, 
144         ReferenceContext referenceContext, 
145         CompilationResult unitResult) {
146
147         this.handle(
148                 problemId,
149                 problemArguments,
150                 messageArguments,
151                 this.computeSeverity(problemId), // severity inferred using the ID
152                 problemStartPosition,
153                 problemEndPosition,
154                 referenceContext,
155                 unitResult);
156 }
157 public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) {
158         unitResult.record(problem, referenceContext);
159 }
160 /**
161  * Search the line number corresponding to a specific position
162  *
163  * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
164  */
165 public static final int searchLineNumber(int[] startLineIndexes, int position) {
166         if (startLineIndexes == null)
167                 return 1;
168         int length = startLineIndexes.length;
169         if (length == 0)
170                 return 1;
171         int g = 0, d = length - 1;
172         int m = 0;
173         while (g <= d) {
174                 m = (g + d) /2;
175                 if (position < startLineIndexes[m]) {
176                         d = m-1;
177                 } else if (position > startLineIndexes[m]) {
178                         g = m+1;
179                 } else {
180                         return m + 1;
181                 }
182         }
183         if (position < startLineIndexes[m]) {
184                 return m+1;
185         }
186         return m+2;
187 }
188 }