Modified: 1216132 - Error when debugging eval()'d code
[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  * Compiler error handler, responsible to determine whether a problem is
22  * actually a warning or an error; also will decide whether the compilation task
23  * can be processed further or not.
24  * 
25  * Behavior : will request its current policy if need to stop on first error,
26  * and if should proceed (persist) with problems.
27  */
28
29 public class ProblemHandler implements ProblemSeverities {
30
31         public final static String[] NoArgument = new String[0];
32
33         final public IErrorHandlingPolicy policy;
34
35         public final IProblemFactory problemFactory;
36
37         public final CompilerOptions options;
38
39         /*
40          * Problem handler can be supplied with a policy to specify its behavior in
41          * error handling. Also see static methods for built-in policies.
42          * 
43          */
44         public ProblemHandler(IErrorHandlingPolicy policy, CompilerOptions options,
45                         IProblemFactory problemFactory) {
46                 this.policy = policy;
47                 this.problemFactory = problemFactory;
48                 this.options = options;
49         }
50
51         /*
52          * Given the current configuration, answers which category the problem falls
53          * into: Error | Warning | Ignore
54          */
55         public int computeSeverity(int problemId) {
56                 return Error; // by default all problems are errors
57         }
58
59         public IProblem createProblem(char[] fileName, int problemId,
60                         String[] problemArguments, String[] messageArguments, int severity,
61                         int problemStartPosition, int problemEndPosition, int lineNumber,
62                         ReferenceContext referenceContext, CompilationResult unitResult) {
63
64                 return problemFactory.createProblem(fileName, problemId,
65                                 problemArguments, messageArguments, severity,
66                                 problemStartPosition, problemEndPosition, lineNumber);
67         }
68
69         public void handle(int problemId, String[] problemArguments,
70                         String[] messageArguments, int severity, int problemStartPosition,
71                         int problemEndPosition, ReferenceContext referenceContext,
72                         CompilationResult unitResult) {
73
74                 if (severity == Ignore)
75                         return;
76
77                 // if no reference context, we need to abort from the current
78                 // compilation process
79                 if (referenceContext == null) {
80                         if ((severity & Error) != 0) { // non reportable error is fatal
81                                 throw new AbortCompilation(problemId, problemArguments,
82                                                 messageArguments);
83                         } else {
84                                 return; // ignore non reportable warning
85                         }
86                 }
87
88                 IProblem problem = this
89                                 .createProblem(unitResult.getFileName(), problemId,
90                                                 problemArguments, messageArguments, severity,
91                                                 problemStartPosition, problemEndPosition,
92                                                 problemStartPosition >= 0 ? searchLineNumber(
93                                                                 unitResult.lineSeparatorPositions,
94                                                                 problemStartPosition) : 0, referenceContext,
95                                                 unitResult);
96                 if (problem == null)
97                         return; // problem couldn't be created, ignore
98
99                 switch (severity & Error) {
100                 case Error:
101                         this.record(problem, unitResult, referenceContext);
102                         referenceContext.tagAsHavingErrors();
103
104                         // should abort ?
105                         int abortLevel;
106                         if ((abortLevel = (policy.stopOnFirstError() ? AbortCompilation
107                                         : severity & Abort)) != 0) {
108
109                                 referenceContext.abort(abortLevel);
110                         }
111                         break;
112                 case Warning:
113                         this.record(problem, unitResult, referenceContext);
114                         break;
115                 }
116         }
117
118         /**
119          * Standard problem handling API, the actual severity (warning/error/ignore)
120          * is deducted from the problem ID and the current compiler options.
121          */
122         public void handle(int problemId, String[] problemArguments,
123                         String[] messageArguments, int problemStartPosition,
124                         int problemEndPosition, ReferenceContext referenceContext,
125                         CompilationResult unitResult) {
126
127                 this.handle(problemId, problemArguments, messageArguments,
128                                 this.computeSeverity(problemId), // severity inferred using
129                                                                                                         // the ID
130                                 problemStartPosition, problemEndPosition, referenceContext,
131                                 unitResult);
132         }
133
134         public void record(IProblem problem, CompilationResult unitResult,
135                         ReferenceContext referenceContext) {
136                 unitResult.record(problem, referenceContext);
137         }
138
139         /**
140          * Search the line number corresponding to a specific position
141          * 
142          * @param methodBinding
143          *            net.sourceforge.phpdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
144          */
145         public static final int searchLineNumber(int[] startLineIndexes,
146                         int position) {
147                 if (startLineIndexes == null)
148                         return 1;
149                 int length = startLineIndexes.length;
150                 if (length == 0)
151                         return 1;
152                 int g = 0, d = length - 1;
153                 int m = 0;
154                 while (g <= d) {
155                         m = (g + d) / 2;
156                         if (position < startLineIndexes[m]) {
157                                 d = m - 1;
158                         } else if (position > startLineIndexes[m]) {
159                                 g = m + 1;
160                         } else {
161                                 return m + 1;
162                         }
163                 }
164                 if (position < startLineIndexes[m]) {
165                         return m + 1;
166                 }
167                 return m + 2;
168         }
169 }