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