1 11 package org.eclipse.jdt.internal.debug.ui.display; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 18 import org.eclipse.core.resources.IResource; 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IAdaptable; 21 import org.eclipse.core.runtime.IPath; 22 import org.eclipse.core.runtime.Path; 23 import org.eclipse.debug.core.DebugException; 24 import org.eclipse.debug.core.ILaunch; 25 import org.eclipse.debug.core.model.ISourceLocator; 26 import org.eclipse.debug.core.model.IStackFrame; 27 import org.eclipse.debug.core.model.IVariable; 28 import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; 29 import org.eclipse.debug.ui.DebugUITools; 30 import org.eclipse.jdt.core.IClassFile; 31 import org.eclipse.jdt.core.ICompilationUnit; 32 import org.eclipse.jdt.core.IJavaElement; 33 import org.eclipse.jdt.core.IJavaProject; 34 import org.eclipse.jdt.core.IType; 35 import org.eclipse.jdt.core.JavaCore; 36 import org.eclipse.jdt.core.JavaModelException; 37 import org.eclipse.jdt.debug.core.IJavaStackFrame; 38 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; 39 import org.eclipse.jdt.internal.ui.JavaPlugin; 40 import org.eclipse.jdt.internal.ui.text.java.JavaParameterListValidator; 41 import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine; 42 import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal; 43 import org.eclipse.jdt.ui.text.java.CompletionProposalCollector; 44 import org.eclipse.jdt.ui.text.java.CompletionProposalComparator; 45 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; 46 import org.eclipse.jface.dialogs.ErrorDialog; 47 import org.eclipse.jface.text.BadLocationException; 48 import org.eclipse.jface.text.Document; 49 import org.eclipse.jface.text.IDocument; 50 import org.eclipse.jface.text.ITextSelection; 51 import org.eclipse.jface.text.ITextViewer; 52 import org.eclipse.jface.text.contentassist.ICompletionProposal; 53 import org.eclipse.jface.text.contentassist.IContentAssistProcessor; 54 import org.eclipse.jface.text.contentassist.IContextInformation; 55 import org.eclipse.jface.text.contentassist.IContextInformationValidator; 56 import org.eclipse.jface.text.templates.TemplateContextType; 57 import org.eclipse.swt.widgets.Shell; 58 59 import com.sun.jdi.ClassNotLoadedException; 60 61 64 public class DisplayCompletionProcessor implements IContentAssistProcessor { 65 66 private CompletionProposalCollector fCollector; 67 private IContextInformationValidator fValidator; 68 private TemplateEngine fTemplateEngine; 69 private String fErrorMessage = null; 70 71 private char[] fProposalAutoActivationSet; 72 private CompletionProposalComparator fComparator; 73 74 public DisplayCompletionProcessor() { 75 TemplateContextType contextType= JavaPlugin.getDefault().getTemplateContextRegistry().getContextType("java"); if (contextType != null) { 77 fTemplateEngine= new TemplateEngine(contextType); 78 } 79 fComparator= new CompletionProposalComparator(); 80 } 81 82 85 public String getErrorMessage() { 86 if (fErrorMessage != null) { 87 return fErrorMessage; 88 } 89 if (fCollector != null) { 90 return fCollector.getErrorMessage(); 91 } 92 return null; 93 } 94 95 101 protected void setErrorMessage(String string) { 102 if (string != null && string.length() == 0) { 103 string = null; 104 } 105 fErrorMessage = string; 106 } 107 108 111 public IContextInformationValidator getContextInformationValidator() { 112 if (fValidator == null) { 113 fValidator= new JavaParameterListValidator(); 114 } 115 return fValidator; 116 } 117 118 121 public char[] getContextInformationAutoActivationCharacters() { 122 return null; 123 } 124 125 128 public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { 129 return null; 130 } 131 132 135 public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { 136 try { 137 setErrorMessage(DisplayMessages.DisplayCompletionProcessor_0); IAdaptable context = DebugUITools.getDebugContext(); 139 if (context == null) { 140 return new ICompletionProposal[0]; 141 } 142 143 IJavaStackFrame stackFrame= (IJavaStackFrame)context.getAdapter(IJavaStackFrame.class); 144 if (stackFrame == null) { 145 return new ICompletionProposal[0]; 146 } 147 setErrorMessage(null); 148 return computeCompletionProposals(stackFrame, viewer, documentOffset); 149 } finally { 150 releaseCollector(); 151 } 152 } 153 154 protected ICompletionProposal[] computeCompletionProposals(IJavaStackFrame stackFrame, ITextViewer viewer, int documentOffset) { 155 setErrorMessage(null); 156 try { 157 IType receivingType = resolveType(stackFrame.getLaunch(), stackFrame.getReceivingTypeName(), getReceivingSourcePath(stackFrame)); 158 if (receivingType == null) { 159 setErrorMessage(DisplayMessages.DisplayCompletionProcessor_1); return new ICompletionProposal[0]; 161 } 162 IJavaProject project = receivingType.getJavaProject(); 163 164 IVariable[] variables= stackFrame.getLocalVariables(); 165 char[][][] res= resolveLocalVariables(variables); 166 char[][] localVariableNames= res[0]; 167 char[][] localVariableTypeNames= res[1]; 168 169 ITextSelection selection= (ITextSelection)viewer.getSelectionProvider().getSelection(); 170 configureResultCollector(project, selection); 171 172 int[] localModifiers= new int[localVariableNames.length]; 173 Arrays.fill(localModifiers, 0); 174 175 int insertionPosition = computeInsertionPosition(receivingType, stackFrame); 176 177 receivingType.codeComplete(viewer.getDocument().get().toCharArray(), insertionPosition, documentOffset, 178 localVariableTypeNames, localVariableNames, 179 localModifiers, stackFrame.isStatic(), fCollector); 180 181 IJavaCompletionProposal[] results= fCollector.getJavaCompletionProposals(); 182 183 if (fTemplateEngine != null) { 184 fTemplateEngine.reset(); 185 fTemplateEngine.complete(viewer, documentOffset, null); 186 TemplateProposal[] templateResults= fTemplateEngine.getResults(); 187 188 IJavaCompletionProposal[] total= new IJavaCompletionProposal[results.length + templateResults.length]; 190 System.arraycopy(templateResults, 0, total, 0, templateResults.length); 191 System.arraycopy(results, 0, total, templateResults.length, results.length); 192 results= total; 193 } 194 return order(results); 197 } catch (JavaModelException x) { 198 handle(viewer, x); 199 } catch (DebugException de) { 200 handle(viewer, de); 201 } 202 203 return null; 204 } 205 206 protected int computeInsertionPosition(IType receivingType, IJavaStackFrame stackFrame) throws JavaModelException, DebugException { 207 int insertion = -1; 208 if (!receivingType.isBinary() && receivingType.getDeclaringType() == null) { 209 ICompilationUnit stackCU= getCompilationUnit(stackFrame); 210 ICompilationUnit typeCU= receivingType.getCompilationUnit(); 211 if (typeCU != null && typeCU.equals(stackCU)) { 212 if (stackCU != null) { 213 IDocument doc = new Document(stackCU.getSource()); 214 try { 215 insertion = doc.getLineOffset(stackFrame.getLineNumber() - 1); 216 } catch(BadLocationException e) { 217 JDIDebugUIPlugin.log(e); 218 } 219 } 220 } 221 } 222 return insertion; 223 } 224 225 230 protected ICompilationUnit getCompilationUnit(IJavaStackFrame stackFrame) { 231 ILaunch launch = stackFrame.getLaunch(); 233 if (launch == null) { 234 return null; 235 } 236 ISourceLocator locator= launch.getSourceLocator(); 237 if (locator == null) { 238 return null; 239 } 240 Object sourceElement= locator.getSourceElement(stackFrame); 241 if (sourceElement instanceof IType) { 242 return ((IType)sourceElement).getCompilationUnit(); 243 } 244 if (sourceElement instanceof ICompilationUnit) { 245 return (ICompilationUnit)sourceElement; 246 } 247 return null; 248 } 249 250 protected void handle(ITextViewer viewer, CoreException x) { 251 Shell shell= viewer.getTextWidget().getShell(); 252 ErrorDialog.openError(shell, 253 DisplayMessages.DisplayCompletionProcessor_Problems_during_completion_1, DisplayMessages.DisplayCompletionProcessor_An_exception_occurred_during_code_completion_2, x.getStatus()); 256 JDIDebugUIPlugin.log(x); 257 } 258 259 protected char[][][] resolveLocalVariables(IVariable[] variables) throws DebugException { 260 List localVariableNames= new ArrayList (); 261 List localVariableTypeNames= new ArrayList (); 262 for (int i = 0; i < variables.length; i++) { 263 IVariable variable = variables[i]; 264 try { 265 localVariableTypeNames.add(getTranslatedTypeName(variable.getReferenceTypeName()).toCharArray()); 266 localVariableNames.add(variable.getName().toCharArray()); 267 } catch (DebugException e) { 268 if (!(e.getStatus().getException() instanceof ClassNotLoadedException)) { 271 throw e; 272 } 273 } 274 } 275 char[][] names= new char[localVariableNames.size()][]; 276 int i= 0; 277 for (Iterator iter= localVariableNames.iterator(); iter.hasNext();) { 278 names[i++]= (char[]) iter.next(); 279 } 280 char[][] typeNames= new char[localVariableNames.size()][]; 281 i= 0; 282 for (Iterator iter= localVariableTypeNames.iterator(); iter.hasNext();) { 283 typeNames[i++]= (char[]) iter.next(); 284 } 285 return new char[][][] {names, typeNames}; 286 } 287 288 292 protected IJavaProject getJavaProject(IStackFrame stackFrame) { 293 294 ILaunch launch = stackFrame.getLaunch(); 296 if (launch == null) { 297 return null; 298 } 299 ISourceLocator locator= launch.getSourceLocator(); 300 if (locator == null) 301 return null; 302 303 Object sourceElement = locator.getSourceElement(stackFrame); 304 if (sourceElement instanceof IJavaElement) { 305 return ((IJavaElement) sourceElement).getJavaProject(); 306 } 307 if (sourceElement instanceof IResource) { 308 IJavaProject project = JavaCore.create(((IResource)sourceElement).getProject()); 309 if (project.exists()) { 310 return project; 311 } 312 } 313 return null; 314 } 315 316 319 protected IJavaCompletionProposal[] order(IJavaCompletionProposal[] proposals) { 320 Arrays.sort(proposals, fComparator); 321 return proposals; 322 } 323 324 327 protected void configureResultCollector(IJavaProject project, ITextSelection selection) { 328 fCollector = new CompletionProposalCollector(project); 329 if (selection.getLength() != 0) { 330 fCollector.setReplacementLength(selection.getLength()); 331 } 332 } 333 334 343 protected String [] getNestedTypeNames(String typeName) { 344 int index = typeName.lastIndexOf('.'); 345 if (index >= 0) { 346 typeName= typeName.substring(index + 1); 347 } 348 index = typeName.indexOf('$'); 349 List list = new ArrayList (1); 350 while (index >= 0) { 351 list.add(typeName.substring(0, index)); 352 typeName = typeName.substring(index + 1); 353 index = typeName.indexOf('$'); 354 } 355 list.add(typeName); 356 return (String [])list.toArray(new String [list.size()]); 357 } 358 359 369 protected String getTranslatedTypeName(String typeName) { 370 int index = typeName.lastIndexOf('$'); 371 if (index == -1) { 372 return typeName; 373 } 374 if (index + 1 > typeName.length()) { 375 return typeName; 377 } 378 String last = typeName.substring(index + 1); 379 try { 380 Integer.parseInt(last); 381 return null; 382 } catch (NumberFormatException e) { 383 return typeName.replace('$', '.'); 384 } 385 } 386 387 388 399 protected String getReceivingSourcePath(IJavaStackFrame frame) throws DebugException { 400 String typeName= frame.getReceivingTypeName(); 401 String sourceName= frame.getSourceName(); 402 if (sourceName == null || !typeName.equals(frame.getDeclaringTypeName())) { 403 int dollarIndex= typeName.indexOf('$'); 407 if (dollarIndex >= 0) { 408 typeName= typeName.substring(0, dollarIndex); 409 } 410 typeName = typeName.replace('.', IPath.SEPARATOR); 411 typeName+= ".java"; } else { 413 int index = typeName.lastIndexOf('.'); 414 if (index >= 0) { 415 typeName = typeName.substring(0, index + 1); 416 typeName = typeName.replace('.', IPath.SEPARATOR); 417 } else { 418 typeName = ""; } 420 typeName+=sourceName; 421 } 422 return typeName; 423 } 424 425 430 public void orderProposalsAlphabetically(boolean order) { 431 fComparator.setOrderAlphabetically(order); 432 } 433 434 437 public char[] getCompletionProposalAutoActivationCharacters() { 438 return fProposalAutoActivationSet; 439 } 440 441 447 public void setCompletionProposalAutoActivationCharacters(char[] activationSet) { 448 fProposalAutoActivationSet= activationSet; 449 } 450 451 protected CompletionProposalCollector getCollector() { 452 return fCollector; 453 } 454 455 458 protected void releaseCollector() { 459 if (fCollector != null && fCollector.getErrorMessage().length() > 0 && fErrorMessage != null) { 460 setErrorMessage(fCollector.getErrorMessage()); 461 } 462 fCollector = null; 463 } 464 465 protected void setCollector(CompletionProposalCollector collector) { 466 fCollector = collector; 467 } 468 469 protected IType getType(IJavaProject project, String originalTypeName, String typeName) throws DebugException { 470 471 int dollarIndex= typeName.indexOf('$'); 472 if (dollarIndex > 0) { 473 typeName= typeName.substring(0, dollarIndex); 474 } 475 IPath sourcePath = new Path(typeName); 476 IType type = null; 477 try { 478 IJavaElement result= project.findElement(sourcePath); 479 String [] typeNames = getNestedTypeNames(originalTypeName); 480 if (result != null) { 481 if (result instanceof IClassFile) { 482 type = ((IClassFile)result).getType(); 483 } else if (result instanceof ICompilationUnit) { 484 type = ((ICompilationUnit)result).getType(typeNames[0]); 485 } else if (result instanceof IType) { 486 type = (IType)result; 487 } 488 } 489 for (int i = 1; i < typeNames.length; i++) { 490 String innerTypeName= typeNames[i]; 491 try { 492 Integer.parseInt(innerTypeName); 493 return type; 494 } catch (NumberFormatException e) { 495 } 496 type = type.getType(innerTypeName); 497 } 498 } catch (JavaModelException e) { 499 throw new DebugException(e.getStatus()); 500 } 501 502 return type; 503 } 504 508 public TemplateEngine getTemplateEngine() { 509 return fTemplateEngine; 510 } 511 512 513 523 protected IType resolveType(ILaunch launch, String typeName, String sourceName) throws DebugException { 524 ISourceLocator sourceLocator = launch.getSourceLocator(); 525 if (sourceLocator != null) { 526 if (sourceLocator instanceof ISourceLookupDirector) { 527 ISourceLookupDirector director = (ISourceLookupDirector) sourceLocator; 528 try { 529 Object [] objects = director.findSourceElements(sourceName); 530 if (objects.length > 0) { 531 Object element = objects[0]; 532 if (element instanceof IAdaptable) { 533 IAdaptable adaptable = (IAdaptable) element; 534 IJavaElement javaElement = (IJavaElement) adaptable.getAdapter(IJavaElement.class); 535 if (javaElement != null) { 536 IType type = null; 537 String [] typeNames = getNestedTypeNames(typeName); 538 if (javaElement instanceof IClassFile) { 539 type = ((IClassFile)javaElement).getType(); 540 } else if (javaElement instanceof ICompilationUnit) { 541 type = ((ICompilationUnit)javaElement).getType(typeNames[0]); 542 } else if (javaElement instanceof IType) { 543 type = (IType)javaElement; 544 } 545 if (type != null) { 546 for (int i = 1; i < typeNames.length; i++) { 547 String innerTypeName= typeNames[i]; 548 try { 549 Integer.parseInt(innerTypeName); 550 return type; 551 } catch (NumberFormatException e) { 552 } 553 type = type.getType(innerTypeName); 554 } 555 } 556 return type; 557 } 558 } 559 } 560 } catch (CoreException e) { 561 throw new DebugException(e.getStatus()); 562 } 563 } 564 } 565 return null; 566 } 567 } 568 | Popular Tags |