1 11 package org.eclipse.jdt.core; 12 13 import java.util.Hashtable ; 14 import java.util.Map ; 15 16 import org.eclipse.core.resources.*; 17 import org.eclipse.jdt.core.compiler.*; 18 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 19 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; 20 import org.eclipse.jdt.internal.compiler.parser.*; 21 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 22 import org.eclipse.jdt.internal.core.util.Messages; 23 import org.eclipse.jdt.internal.core.util.Util; 24 25 32 public class CorrectionEngine implements ProblemReasons { 33 34 37 protected int correctionStart; 38 41 protected int correctionEnd; 42 45 protected int prefixLength; 46 49 protected ICompilationUnit compilationUnit; 50 53 protected ICorrectionRequestor correctionRequestor; 54 57 protected static final int CLASSES = 0x00000001; 58 61 protected static final int INTERFACES = 0x00000002; 62 65 protected static final int IMPORT = 0x00000004; 66 69 protected static final int METHOD = 0x00000008; 70 73 protected static final int FIELD = 0x00000010; 74 77 protected static final int LOCAL = 0x00000020; 78 81 protected int filter; 82 83 90 public CorrectionEngine(Map setting) { 91 } 93 94 113 public void computeCorrections(IMarker marker, ICompilationUnit targetUnit, int positionOffset, ICorrectionRequestor requestor) throws JavaModelException { 114 115 IJavaElement element = targetUnit == null ? JavaCore.create(marker.getResource()) : targetUnit; 116 117 if(!(element instanceof ICompilationUnit)) 118 return; 119 120 ICompilationUnit unit = (ICompilationUnit) element; 121 122 int id = marker.getAttribute(IJavaModelMarker.ID, -1); 123 String [] args = Util.getProblemArgumentsFromMarker(marker.getAttribute(IJavaModelMarker.ARGUMENTS, "")); int start = marker.getAttribute(IMarker.CHAR_START, -1); 125 int end = marker.getAttribute(IMarker.CHAR_END, -1); 126 127 computeCorrections(unit, id, start + positionOffset, end + positionOffset, args, requestor); 128 } 129 130 147 public void computeCorrections(IProblem problem, ICompilationUnit targetUnit, ICorrectionRequestor requestor) throws JavaModelException { 148 if (requestor == null) { 149 throw new IllegalArgumentException (Messages.correction_nullUnit); 150 } 151 this.computeCorrections( 152 targetUnit, problem.getID(), 153 problem.getSourceStart(), 154 problem.getSourceEnd(), 155 problem.getArguments(), 156 requestor); 157 } 158 159 184 private void computeCorrections(ICompilationUnit unit, int id, int start, int end, String [] arguments, ICorrectionRequestor requestor) { 185 186 if(id == -1 || arguments == null || start == -1 || end == -1) 187 return; 188 if (requestor == null) { 189 throw new IllegalArgumentException (Messages.correction_nullRequestor); 190 } 191 192 this.correctionRequestor = requestor; 193 this.correctionStart = start; 194 this.correctionEnd = end; 195 this.compilationUnit = unit; 196 197 String argument = null; 198 try { 199 switch (id) { 200 case IProblem.ImportNotFound : 202 this.filter = IMPORT; 203 argument = arguments[0]; 204 break; 205 case IProblem.UndefinedType : 206 this.filter = CLASSES | INTERFACES; 207 argument = arguments[0]; 208 break; 209 210 case IProblem.UndefinedMethod : 212 this.filter = METHOD; 213 argument = arguments[1]; 214 break; 215 216 case IProblem.UndefinedField : 218 this.filter = FIELD; 219 argument = arguments[0]; 220 break; 221 case IProblem.UndefinedName : 222 this.filter = FIELD | LOCAL; 223 argument = arguments[0]; 224 break; 225 } 226 } catch (ArrayIndexOutOfBoundsException e) { 227 return; 228 } 229 if(argument != null) { 230 correct(argument.toCharArray()); 231 } 232 } 233 234 private void correct(char[] argument) { 235 try { 236 String source = this.compilationUnit.getSource(); 237 Scanner scanner = new Scanner(); 238 scanner.setSource(source.toCharArray()); 239 240 scanner.resetTo(this.correctionStart, this.correctionEnd); 241 int token = 0; 242 char[] argumentSource = CharOperation.NO_CHAR; 243 244 while(true) { 246 token = scanner.getNextToken(); 247 if (token == TerminalTokens.TokenNameEOF) return; 248 249 char[] tokenSource = scanner.getCurrentTokenSource(); 250 251 argumentSource = CharOperation.concat(argumentSource, tokenSource); 252 if(!CharOperation.prefixEquals(argumentSource, argument)) 253 return; 254 255 if(CharOperation.equals(argument, argumentSource)) { 256 this.correctionStart = scanner.startPosition; 257 this.correctionEnd = scanner.currentPosition; 258 this.prefixLength = CharOperation.lastIndexOf('.', argument) + 1; 259 break; 260 } 261 262 } 263 264 int completionPosition = this.correctionStart; 266 scanner.resetTo(completionPosition, this.correctionEnd); 267 int position = completionPosition; 268 269 for (int i = 0; i < 4; i++) { 270 if(scanner.getNextCharAsJavaIdentifierPart()) { 271 completionPosition = position; 272 position = scanner.currentPosition; 273 } else { 274 break; 275 } 276 } 277 Hashtable oldOptions = JavaCore.getOptions(); 278 try { 279 Hashtable options = new Hashtable (oldOptions); 280 options.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.DISABLED); 281 JavaCore.setOptions(options); 282 283 this.compilationUnit.codeComplete( 284 completionPosition, 285 this.completionRequestor 286 ); 287 } finally { 288 JavaCore.setOptions(oldOptions); 289 } 290 } catch (JavaModelException e) { 291 return; 292 } catch (InvalidInputException e) { 293 return; 294 } 295 } 296 297 300 protected CompletionRequestor completionRequestor = new CompletionRequestor() { 301 public void accept(CompletionProposal proposal) { 302 switch (proposal.getKind()) { 303 case CompletionProposal.TYPE_REF: 304 int flags = proposal.getFlags(); 305 if (!(Flags.isEnum(flags) || Flags.isAnnotation(flags))) { 306 if((CorrectionEngine.this.filter & (CLASSES | INTERFACES)) != 0) { 307 char[] completionName = proposal.getCompletion(); 308 CorrectionEngine.this.correctionRequestor.acceptClass( 309 proposal.getDeclarationSignature(), 310 Signature.getSignatureSimpleName(proposal.getSignature()), 311 CharOperation.subarray(completionName, CorrectionEngine.this.prefixLength, completionName.length), 312 proposal.getFlags(), 313 CorrectionEngine.this.correctionStart, 314 CorrectionEngine.this.correctionEnd); 315 } else if((CorrectionEngine.this.filter & IMPORT) != 0) { 316 char[] packageName = proposal.getDeclarationSignature(); 317 char[] className = Signature.getSignatureSimpleName(proposal.getSignature()); 318 char[] fullName = CharOperation.concat(packageName, className, '.'); 319 CorrectionEngine.this.correctionRequestor.acceptClass( 320 packageName, 321 className, 322 CharOperation.subarray(fullName, CorrectionEngine.this.prefixLength, fullName.length), 323 proposal.getFlags(), 324 CorrectionEngine.this.correctionStart, 325 CorrectionEngine.this.correctionEnd); 326 } 327 } 328 break; 329 case CompletionProposal.FIELD_REF: 330 if((CorrectionEngine.this.filter & FIELD) != 0) { 331 char[] declaringSignature = proposal.getDeclarationSignature(); 332 char[] signature = proposal.getSignature(); 333 CorrectionEngine.this.correctionRequestor.acceptField( 334 Signature.getSignatureQualifier(declaringSignature), 335 Signature.getSignatureSimpleName(declaringSignature), 336 proposal.getName(), 337 Signature.getSignatureQualifier(signature), 338 Signature.getSignatureSimpleName(signature), 339 proposal.getName(), 340 proposal.getFlags(), 341 CorrectionEngine.this.correctionStart, 342 CorrectionEngine.this.correctionEnd); 343 } 344 break; 345 case CompletionProposal.LOCAL_VARIABLE_REF: 346 if((CorrectionEngine.this.filter & LOCAL) != 0) { 347 char[] signature = proposal.getSignature(); 348 CorrectionEngine.this.correctionRequestor.acceptLocalVariable( 349 proposal.getName(), 350 Signature.getSignatureQualifier(signature), 351 Signature.getSignatureSimpleName(signature), 352 proposal.getFlags(), 353 CorrectionEngine.this.correctionStart, 354 CorrectionEngine.this.correctionEnd); 355 } 356 break; 357 case CompletionProposal.METHOD_REF: 358 if((CorrectionEngine.this.filter & METHOD) != 0) { 359 char[] declaringSignature = proposal.getDeclarationSignature(); 360 char[] signature = proposal.getSignature(); 361 char[][] parameterTypeSignatures = Signature.getParameterTypes(signature); 362 int length = parameterTypeSignatures.length; 363 char[][] parameterPackageNames = new char[length][]; 364 char[][] parameterTypeNames = new char[length][]; 365 for (int i = 0; i < length; i++) { 366 parameterPackageNames[i] = Signature.getSignatureQualifier(parameterTypeSignatures[i]); 367 parameterTypeNames[i] = Signature.getSignatureSimpleName(parameterTypeSignatures[i]); 368 } 369 char[] returnTypeSignature = Signature.getReturnType(signature); 370 CorrectionEngine.this.correctionRequestor.acceptMethod( 371 Signature.getSignatureQualifier(declaringSignature), 372 Signature.getSignatureSimpleName(declaringSignature), 373 proposal.getName(), 374 parameterPackageNames, 375 parameterTypeNames, 376 proposal.findParameterNames(null), 377 Signature.getSignatureQualifier(returnTypeSignature), 378 Signature.getSignatureSimpleName(returnTypeSignature), 379 proposal.getName(), 380 proposal.getFlags(), 381 CorrectionEngine.this.correctionStart, 382 CorrectionEngine.this.correctionEnd); 383 } 384 break; 385 case CompletionProposal.PACKAGE_REF: 386 if((CorrectionEngine.this.filter & (CLASSES | INTERFACES | IMPORT)) != 0) { 387 char[] packageName = proposal.getDeclarationSignature(); 388 CorrectionEngine.this.correctionRequestor.acceptPackage( 389 packageName, 390 CharOperation.subarray(packageName, CorrectionEngine.this.prefixLength, packageName.length), 391 CorrectionEngine.this.correctionStart, 392 CorrectionEngine.this.correctionEnd); 393 } 394 break; 395 } 396 } 397 }; 398 399 400 415 public static String [] getAllWarningTokens() { 416 return CompilerOptions.warningTokens; 417 } 418 419 429 public static String [] getProblemArguments(IMarker problemMarker){ 430 String argumentsString = problemMarker.getAttribute(IJavaModelMarker.ARGUMENTS, null); 431 return Util.getProblemArgumentsFromMarker(argumentsString); 432 } 433 434 461 public static String getWarningToken(int problemID){ 462 long irritant = ProblemReporter.getIrritant(problemID); 463 if (irritant != 0) { 464 return CompilerOptions.warningTokenFromIrritant(irritant); 465 } 466 return null; 467 } 468 } 469 | Popular Tags |