1 11 package org.eclipse.jdt.internal.ui.text.java; 12 13 14 import java.util.ArrayList ; 15 import java.util.List ; 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 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 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 increments, String 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 offset= getCommentEnd(document, offset + 1, end); 111 } else if (next == '/') { 112 offset= end; 114 } 115 } 116 break; 117 case '*': 118 if (offset < end) { 119 char next= document.getChar(offset); 120 if (next == '/') { 121 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 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 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 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; 241 } catch (BadLocationException x) { 242 return false; 243 } 244 } 245 246 249 public boolean updatePresentation(int position, TextPresentation presentation) { 250 251 int currentParameter= -1; 252 253 try { 254 currentParameter= getCharCount(fViewer.getDocument(), fPosition, position, ",", "", true); } 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 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 code) { 290 final int length= code.length(); 291 int pos= 0; 292 List positions= new ArrayList (); 293 positions.add(new Integer (-1)); 294 while (pos < length && pos != -1) { 295 char ch= code.charAt(pos); 296 switch (ch) { 297 case ',': 298 positions.add(new Integer (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 (length)); 313 314 int[] fields= new int[positions.size()]; 315 for (int i= 0; i < fields.length; i++) 316 fields[i]= ((Integer ) positions.get(i)).intValue(); 317 return fields; 318 } 319 320 } 321 322 | Popular Tags |