Added "Task Tags" functionality (TODO,...)
[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         if (problemId==IProblem.PHPParsingWarning ||
55             problemId==IProblem.PHPVarDeprecatedWarning) {
56           return Warning;
57         }
58         return Error; // by default all problems are errors
59 }
60 public IProblem createProblem(
61         char[] fileName, 
62         int problemId, 
63         String[] problemArguments, 
64         String[] messageArguments,
65         int severity, 
66         int problemStartPosition, 
67         int problemEndPosition, 
68         int lineNumber,
69         ReferenceContext referenceContext,
70         CompilationResult unitResult) {
71
72         return problemFactory.createProblem(
73                 fileName, 
74                 problemId, 
75                 problemArguments, 
76                 messageArguments,
77                 severity, 
78                 problemStartPosition, 
79                 problemEndPosition, 
80                 lineNumber); 
81 }
82 public void handle(
83         int problemId, 
84         String[] problemArguments, 
85         String[] messageArguments,
86         int severity, 
87         int problemStartPosition, 
88         int problemEndPosition, 
89         ReferenceContext referenceContext, 
90         CompilationResult unitResult) {
91
92         if (severity == Ignore)
93                 return;
94
95         // if no reference context, we need to abort from the current compilation process
96         if (referenceContext == null) {
97                 if ((severity & Error) != 0) { // non reportable error is fatal
98                         throw new AbortCompilation(problemId, problemArguments, messageArguments);
99                 } else {
100                         return; // ignore non reportable warning
101                 }
102         }
103
104         IProblem problem = 
105                 this.createProblem(
106                         unitResult.getFileName(), 
107                         problemId, 
108                         problemArguments, 
109                         messageArguments,
110                         severity, 
111                         problemStartPosition, 
112                         problemEndPosition, 
113                         problemStartPosition >= 0
114                                 ? searchLineNumber(unitResult.lineSeparatorPositions, problemStartPosition)
115                                 : 0,
116                         referenceContext,
117                         unitResult); 
118         if (problem == null) return; // problem couldn't be created, ignore
119         
120         switch (severity & Error) {
121                 case Error :
122                         this.record(problem, unitResult, referenceContext);
123                         referenceContext.tagAsHavingErrors();
124
125                         // should abort ?
126                         int abortLevel;
127                         if ((abortLevel = 
128                                 (policy.stopOnFirstError() ? AbortCompilation : severity & Abort)) != 0) {
129
130                                 referenceContext.abort(abortLevel);
131                         }
132                         break;
133                 case Warning :
134                         this.record(problem, unitResult, referenceContext);
135                         break;
136         }
137 }
138 /**
139  * Standard problem handling API, the actual severity (warning/error/ignore) is deducted
140  * from the problem ID and the current compiler options.
141  */
142 public void handle(
143         int problemId, 
144         String[] problemArguments, 
145         String[] messageArguments,
146         int problemStartPosition, 
147         int problemEndPosition, 
148         ReferenceContext referenceContext, 
149         CompilationResult unitResult) {
150
151         this.handle(
152                 problemId,
153                 problemArguments,
154                 messageArguments,
155                 this.computeSeverity(problemId), // severity inferred using the ID
156                 problemStartPosition,
157                 problemEndPosition,
158                 referenceContext,
159                 unitResult);
160 }
161 public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) {
162         unitResult.record(problem, referenceContext);
163 }
164 /**
165  * Search the line number corresponding to a specific position
166  *
167  * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
168  */
169 public static final int searchLineNumber(int[] startLineIndexes, int position) {
170         if (startLineIndexes == null)
171                 return 1;
172         int length = startLineIndexes.length;
173         if (length == 0)
174                 return 1;
175         int g = 0, d = length - 1;
176         int m = 0;
177         while (g <= d) {
178                 m = (g + d) /2;
179                 if (position < startLineIndexes[m]) {
180                         d = m-1;
181                 } else if (position > startLineIndexes[m]) {
182                         g = m+1;
183                 } else {
184                         return m + 1;
185                 }
186         }
187         if (position < startLineIndexes[m]) {
188                 return m+1;
189         }
190         return m+2;
191 }
192 }