first scanner /parser copied from the jdt java version
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / problem / DefaultProblem.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.env.ICompilationUnit;
15 import net.sourceforge.phpdt.internal.compiler.util.Util;
16
17 public class DefaultProblem implements ProblemSeverities, IProblem {
18                 
19         private char[] fileName;
20         private int id;
21         private int startPosition, endPosition, line;
22         private int severity;
23         private String[] arguments;
24         private String message;
25         
26         public DefaultProblem(
27                 char[] originatingFileName,
28                 String message,
29                 int id,
30                 String[] stringArguments,
31                 int severity,
32                 int startPosition,
33                 int endPosition,
34                 int line) {
35
36                 this.fileName = originatingFileName;
37                 this.message = message;
38                 this.id = id;
39                 this.arguments = stringArguments;
40                 this.severity = severity;
41                 this.startPosition = startPosition;
42                 this.endPosition = endPosition;
43                 this.line = line;
44         }
45
46         public String errorReportSource(ICompilationUnit compilationUnit) {
47                 //extra from the source the innacurate     token
48                 //and "highlight" it using some underneath ^^^^^
49                 //put some context around too.
50
51                 //this code assumes that the font used in the console is fixed size
52
53                 //sanity .....
54                 if ((startPosition > endPosition)
55                         || ((startPosition <= 0) && (endPosition <= 0)))
56                         return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$
57
58                 final char SPACE = '\u0020';
59                 final char MARK = '^';
60                 final char TAB = '\t';
61                 char[] source = compilationUnit.getContents();
62                 //the next code tries to underline the token.....
63                 //it assumes (for a good display) that token source does not
64                 //contain any \r \n. This is false on statements ! 
65                 //(the code still works but the display is not optimal !)
66
67                 //compute the how-much-char we are displaying around the inaccurate token
68                 int begin = startPosition >= source.length ? source.length - 1 : startPosition;
69                 int relativeStart = 0;
70                 int end = endPosition >= source.length ? source.length - 1 : endPosition;
71                 int relativeEnd = 0;
72                 label : for (relativeStart = 0;; relativeStart++) {
73                         if (begin == 0)
74                                 break label;
75                         if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r'))
76                                 break label;
77                         begin--;
78                 }
79                 label : for (relativeEnd = 0;; relativeEnd++) {
80                         if ((end + 1) >= source.length)
81                                 break label;
82                         if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) {
83                                 break label;
84                         }
85                         end++;
86                 }
87                 //extract the message form the source
88                 char[] extract = new char[end - begin + 1];
89                 System.arraycopy(source, begin, extract, 0, extract.length);
90                 char c;
91                 //remove all SPACE and TAB that begin the error message...
92                 int trimLeftIndex = 0;
93                 while (((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) {
94                 };
95                 System.arraycopy(
96                         extract,
97                         trimLeftIndex - 1,
98                         extract = new char[extract.length - trimLeftIndex + 1],
99                         0,
100                         extract.length);
101                 relativeStart -= trimLeftIndex;
102                 //buffer spaces and tabs in order to reach the error position
103                 int pos = 0;
104                 char[] underneath = new char[extract.length]; // can't be bigger
105                 for (int i = 0; i <= relativeStart; i++) {
106                         if (extract[i] == TAB) {
107                                 underneath[pos++] = TAB;
108                         } else {
109                                 underneath[pos++] = SPACE;
110                         }
111                 }
112                 //mark the error position
113                 for (int i = startPosition;
114                         i <= (endPosition >= source.length ? source.length - 1 : endPosition);
115                         i++)
116                         underneath[pos++] = MARK;
117                 //resize underneathto remove 'null' chars
118                 System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);
119
120                 return " " + Util.bind("problem.atLine", String.valueOf(line))  //$NON-NLS-2$ //$NON-NLS-1$
121                         + "\n\t" + new String(extract) + "\n\t" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$
122         }
123
124         /**
125          * Answer back the original arguments recorded into the problem.
126          * @return java.lang.String[]
127          */
128         public String[] getArguments() {
129
130                 return arguments;
131         }
132
133         /**
134          * Answer the type of problem.
135          * @see org.eclipse.jdt.core.compiler.IProblem#getID()
136          * @return int
137          */
138         public int getID() {
139
140                 return id;
141         }
142
143         /**
144          * Answer a localized, human-readable message string which describes the problem.
145          * @return java.lang.String
146          */
147         public String getMessage() {
148
149                 return message;
150         }
151
152         /**
153          * Answer the file name in which the problem was found.
154          * @return char[]
155          */
156         public char[] getOriginatingFileName() {
157
158                 return fileName;
159         }
160
161         /**
162          * Answer the end position of the problem (inclusive), or -1 if unknown.
163          * @return int
164          */
165         public int getSourceEnd() {
166
167                 return endPosition;
168         }
169
170         /**
171          * Answer the line number in source where the problem begins.
172          * @return int
173          */
174         public int getSourceLineNumber() {
175
176                 return line;
177         }
178
179         /**
180          * Answer the start position of the problem (inclusive), or -1 if unknown.
181          * @return int
182          */
183         public int getSourceStart() {
184
185                 return startPosition;
186         }
187
188         /*
189          * Helper method: checks the severity to see if the Error bit is set.
190          * @return boolean
191          */
192         public boolean isError() {
193
194                 return (severity & ProblemSeverities.Error) != 0;
195         }
196
197         /*
198          * Helper method: checks the severity to see if the Error bit is not set.
199          * @return boolean
200          */
201         public boolean isWarning() {
202
203                 return (severity & ProblemSeverities.Error) == 0;
204         }
205
206         /**
207          * Set the end position of the problem (inclusive), or -1 if unknown.
208          *
209          * Used for shifting problem positions.
210          * @param sourceEnd the new value of the sourceEnd of the receiver
211          */
212         public void setSourceEnd(int sourceEnd) {
213
214                 endPosition = sourceEnd;
215         }
216
217         /**
218          * Set the line number in source where the problem begins.
219          * @param lineNumber the new value of the line number of the receiver
220          */
221         public void setSourceLineNumber(int lineNumber) {
222
223                 line = lineNumber;
224         }
225
226         /**
227          * Set the start position of the problem (inclusive), or -1 if unknown.
228          *
229          * Used for shifting problem positions.
230          * @param sourceStart the new value of the source start position of the receiver
231          */
232         public void setSourceStart(int sourceStart) {
233
234                 startPosition = sourceStart;
235         }
236
237         public String toString() {
238
239                 String s = "Pb(" + (id & IgnoreCategoriesMask) + ") "; //$NON-NLS-1$ //$NON-NLS-2$
240                 if (message != null) {
241                         s += message;
242                 } else {
243                         if (arguments != null)
244                                 for (int i = 0; i < arguments.length; i++)
245                                         s += " " + arguments[i]; //$NON-NLS-1$
246                 }
247                 return s;
248         }
249 }