KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > java > JavaParameterListValidator


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.text.java;
12
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.custom.StyleRange;
21
22 import org.eclipse.jface.text.BadLocationException;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.IRegion;
25 import org.eclipse.jface.text.ITextViewer;
26 import org.eclipse.jface.text.TextPresentation;
27 import org.eclipse.jface.text.contentassist.IContextInformation;
28 import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
29 import org.eclipse.jface.text.contentassist.IContextInformationValidator;
30
31 import org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner;
32
33
34
35 public class JavaParameterListValidator implements IContextInformationValidator, IContextInformationPresenter {
36
37     private int fPosition;
38     private ITextViewer fViewer;
39     private IContextInformation fInformation;
40
41     private int fCurrentParameter;
42
43
44
45     public JavaParameterListValidator() {
46     }
47
48     /**
49      * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
50      * @see IContextInformationPresenter#install(IContextInformation, ITextViewer, int)
51      */

52     public void install(IContextInformation info, ITextViewer viewer, int documentPosition) {
53         fPosition= documentPosition;
54         fViewer= viewer;
55         fInformation= info;
56
57         fCurrentParameter= -1;
58     }
59
60     private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
61         while (pos < end) {
62             char curr= d.getChar(pos);
63             pos++;
64             if (curr == '*') {
65                 if (pos < end && d.getChar(pos) == '/') {
66                     return pos + 1;
67                 }
68             }
69         }
70         return end;
71     }
72
73     private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
74         while (pos < end) {
75             char curr= d.getChar(pos);
76             pos++;
77             if (curr == '\\') {
78                 // ignore escaped characters
79
pos++;
80             } else if (curr == ch) {
81                 return pos;
82             }
83         }
84         return end;
85     }
86
87     private int getCharCount(IDocument document, final int start, final int end, String JavaDoc increments, String JavaDoc decrements, boolean considerNesting) throws BadLocationException {
88
89         Assert.isTrue((increments.length() != 0 || decrements.length() != 0) && !increments.equals(decrements));
90         
91         final int NONE= 0;
92         final int BRACKET= 1;
93         final int BRACE= 2;
94         final int PAREN= 3;
95         final int ANGLE= 4;
96
97         int nestingMode= NONE;
98         int nestingLevel= 0;
99
100         int charCount= 0;
101         int offset= start;
102         while (offset < end) {
103             char curr= document.getChar(offset++);
104             switch (curr) {
105                 case '/':
106                     if (offset < end) {
107                         char next= document.getChar(offset);
108                         if (next == '*') {
109                             // a comment starts, advance to the comment end
110
offset= getCommentEnd(document, offset + 1, end);
111                         } else if (next == '/') {
112                             // '//'-comment: nothing to do anymore on this line
113
offset= end;
114                         }
115                     }
116                     break;
117                 case '*':
118                     if (offset < end) {
119                         char next= document.getChar(offset);
120                         if (next == '/') {
121                             // we have been in a comment: forget what we read before
122
charCount= 0;
123                             ++ offset;
124                         }
125                     }
126                     break;
127                 case '"':
128                 case '\'':
129                     offset= getStringEnd(document, offset, end, curr);
130                     break;
131                 case '[':
132                     if (considerNesting) {
133                         if (nestingMode == BRACKET || nestingMode == NONE) {
134                             nestingMode= BRACKET;
135                             nestingLevel++;
136                         }
137                         break;
138                     }
139                 case ']':
140                     if (considerNesting) {
141                         if (nestingMode == BRACKET)
142                             if (--nestingLevel == 0)
143                                 nestingMode= NONE;
144                         break;
145                     }
146                 case '(':
147                     if (considerNesting) {
148                         if (nestingMode == ANGLE) {
149                             // generics heuristic failed
150
nestingMode=PAREN;
151                             nestingLevel= 1;
152                         }
153                         if (nestingMode == PAREN || nestingMode == NONE) {
154                             nestingMode= PAREN;
155                             nestingLevel++;
156                         }
157                         break;
158                     }
159                 case ')':
160                     if (considerNesting) {
161                         if (nestingMode == PAREN)
162                             if (--nestingLevel == 0)
163                                 nestingMode= NONE;
164                         break;
165                     }
166                 case '{':
167                     if (considerNesting) {
168                         if (nestingMode == ANGLE) {
169                             // generics heuristic failed
170
nestingMode=BRACE;
171                             nestingLevel= 1;
172                         }
173                         if (nestingMode == BRACE || nestingMode == NONE) {
174                             nestingMode= BRACE;
175                             nestingLevel++;
176                         }
177                         break;
178                     }
179                 case '}':
180                     if (considerNesting) {
181                         if (nestingMode == BRACE)
182                             if (--nestingLevel == 0)
183                                 nestingMode= NONE;
184                         break;
185                     }
186                 case '<':
187                     if (considerNesting) {
188                         if (nestingMode == ANGLE || nestingMode == NONE && checkGenericsHeuristic(document, offset - 1, start - 1)) {
189                             nestingMode= ANGLE;
190                             nestingLevel++;
191                         }
192                         break;
193                     }
194                 case '>':
195                     if (considerNesting) {
196                         if (nestingMode == ANGLE)
197                             if (--nestingLevel == 0)
198                                 nestingMode= NONE;
199                         break;
200                     }
201
202                 default:
203                     if (nestingLevel != 0)
204                         continue;
205
206                     if (increments.indexOf(curr) >= 0) {
207                         ++ charCount;
208                     }
209
210                     if (decrements.indexOf(curr) >= 0) {
211                         -- charCount;
212                     }
213             }
214         }
215
216         return charCount;
217     }
218
219     private boolean checkGenericsHeuristic(IDocument document, int end, int bound) throws BadLocationException {
220         JavaHeuristicScanner scanner= new JavaHeuristicScanner(document);
221         return scanner.looksLikeClassInstanceCreationBackward(end, bound);
222     }
223
224     /**
225      * @see IContextInformationValidator#isContextInformationValid(int)
226      */

227     public boolean isContextInformationValid(int position) {
228
229         try {
230             if (position < fPosition)
231                 return false;
232
233             IDocument document= fViewer.getDocument();
234             IRegion line= document.getLineInformationOfOffset(fPosition);
235
236             if (position < line.getOffset() || position >= document.getLength())
237                 return false;
238
239             return getCharCount(document, fPosition, position, "(<", ")>", false) >= 0; //$NON-NLS-1$ //$NON-NLS-2$
240

241         } catch (BadLocationException x) {
242             return false;
243         }
244     }
245
246     /**
247      * @see IContextInformationPresenter#updatePresentation(int, TextPresentation)
248      */

249     public boolean updatePresentation(int position, TextPresentation presentation) {
250
251         int currentParameter= -1;
252
253         try {
254             currentParameter= getCharCount(fViewer.getDocument(), fPosition, position, ",", "", true); //$NON-NLS-1$//$NON-NLS-2$
255
} catch (BadLocationException x) {
256             return false;
257         }
258
259         if (fCurrentParameter != -1) {
260             if (currentParameter == fCurrentParameter)
261                 return false;
262         }
263
264         presentation.clear();
265         fCurrentParameter= currentParameter;
266
267         String JavaDoc s= fInformation.getInformationDisplayString();
268         int[] commas= computeCommaPositions(s);
269
270         if (commas.length - 2 < fCurrentParameter) {
271             presentation.addStyleRange(new StyleRange(0, s.length(), null, null, SWT.NORMAL));
272             return true;
273         }
274         
275         int start= commas[fCurrentParameter] + 1;
276         int end= commas[fCurrentParameter + 1];
277         if (start > 0)
278             presentation.addStyleRange(new StyleRange(0, start, null, null, SWT.NORMAL));
279
280         if (end > start)
281             presentation.addStyleRange(new StyleRange(start, end - start, null, null, SWT.BOLD));
282
283         if (end < s.length())
284             presentation.addStyleRange(new StyleRange(end, s.length() - end, null, null, SWT.NORMAL));
285
286         return true;
287     }
288     
289     private int[] computeCommaPositions(String JavaDoc code) {
290         final int length= code.length();
291         int pos= 0;
292         List JavaDoc positions= new ArrayList JavaDoc();
293         positions.add(new Integer JavaDoc(-1));
294         while (pos < length && pos != -1) {
295             char ch= code.charAt(pos);
296             switch (ch) {
297                 case ',':
298                     positions.add(new Integer JavaDoc(pos));
299                     break;
300                 case '<':
301                     pos= code.indexOf('>', pos);
302                     break;
303                 case '[':
304                     pos= code.indexOf(']', pos);
305                     break;
306                 default:
307                     break;
308             }
309             if (pos != -1)
310                 pos++;
311         }
312         positions.add(new Integer JavaDoc(length));
313         
314         int[] fields= new int[positions.size()];
315         for (int i= 0; i < fields.length; i++)
316             fields[i]= ((Integer JavaDoc) positions.get(i)).intValue();
317         return fields;
318     }
319
320 }
321
322
Popular Tags