1 2 3 package de.loskutov.bco.editors; 4 5 import java.lang.reflect.Constructor ; 6 import java.util.BitSet ; 7 8 import org.eclipse.core.resources.IFile; 9 import org.eclipse.core.runtime.CoreException; 10 import org.eclipse.core.runtime.IStatus; 11 import org.eclipse.debug.core.DebugException; 12 import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; 13 import org.eclipse.jdt.core.IBuffer; 14 import org.eclipse.jdt.core.IBufferChangedListener; 15 import org.eclipse.jdt.core.IClassFile; 16 import org.eclipse.jdt.core.IInitializer; 17 import org.eclipse.jdt.core.IJavaElement; 18 import org.eclipse.jdt.core.IJavaModelStatusConstants; 19 import org.eclipse.jdt.core.IMember; 20 import org.eclipse.jdt.core.IMethod; 21 import org.eclipse.jdt.core.ISourceRange; 22 import org.eclipse.jdt.core.ISourceReference; 23 import org.eclipse.jdt.core.IType; 24 import org.eclipse.jdt.core.JavaModelException; 25 import org.eclipse.jdt.core.dom.CompilationUnit; 26 import org.eclipse.jdt.debug.core.IJavaReferenceType; 27 import org.eclipse.jdt.internal.ui.JavaPlugin; 28 import org.eclipse.jdt.internal.ui.JavaUIStatus; 29 import org.eclipse.jdt.internal.ui.javaeditor.ClassFileDocumentProvider; 30 import org.eclipse.jdt.internal.ui.javaeditor.ExternalClassFileEditorInput; 31 import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput; 32 import org.eclipse.jdt.internal.ui.javaeditor.InternalClassFileEditorInput; 33 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; 34 import org.eclipse.jface.preference.IPreferenceStore; 35 import org.eclipse.jface.text.BadLocationException; 36 import org.eclipse.jface.text.IDocument; 37 import org.eclipse.jface.text.IRegion; 38 import org.eclipse.jface.text.ITextSelection; 39 import org.eclipse.jface.text.ITextViewerExtension5; 40 import org.eclipse.jface.text.Region; 41 import org.eclipse.jface.text.TextSelection; 42 import org.eclipse.jface.text.source.IOverviewRuler; 43 import org.eclipse.jface.text.source.ISourceViewer; 44 import org.eclipse.jface.text.source.IVerticalRuler; 45 import org.eclipse.jface.viewers.ISelection; 46 import org.eclipse.jface.viewers.ISelectionProvider; 47 import org.eclipse.jface.viewers.SelectionChangedEvent; 48 import org.eclipse.swt.SWT; 49 import org.eclipse.swt.custom.StackLayout; 50 import org.eclipse.swt.custom.StyledText; 51 import org.eclipse.swt.layout.FillLayout; 52 import org.eclipse.swt.widgets.Composite; 53 import org.eclipse.ui.IEditorInput; 54 import org.eclipse.ui.IEditorPart; 55 import org.eclipse.ui.IEditorReference; 56 import org.eclipse.ui.IEditorSite; 57 import org.eclipse.ui.IFileEditorInput; 58 import org.eclipse.ui.PartInitException; 59 import org.eclipse.ui.PlatformUI; 60 import org.eclipse.ui.part.FileEditorInput; 61 import org.eclipse.ui.texteditor.IDocumentProvider; 62 63 import de.loskutov.bco.BytecodeOutlinePlugin; 64 import de.loskutov.bco.preferences.BCOConstants; 65 import de.loskutov.bco.ui.JdtUtils; 66 67 71 public class BytecodeClassFileEditor extends JavaEditor 72 implements 73 ClassFileDocumentProvider.InputChangeListener { 74 75 private StackLayout fStackLayout; 76 private Composite fParent; 77 private Composite fViewerComposite; 78 private InputUpdater fInputUpdater; 79 public static final String ID = "de.loskutov.bco.editors.BytecodeClassFileEditor"; 80 public static final String MARK = "// class version "; 81 82 private BitSet decompilerFlags; 83 84 private static BytecodeSourceMapper sourceMapper; 85 private static BytecodeDocumentProvider fClassFileDocumentProvider; 86 private boolean hasMappedSource; 87 private boolean decompiled; 88 private boolean initDone; 89 90 93 public BytecodeClassFileEditor() { 94 super(); 95 if (sourceMapper == null) { 96 sourceMapper = new BytecodeSourceMapper(); 97 } 98 fInputUpdater = new InputUpdater(); 99 setDocumentProvider(getClassFileDocumentProvider()); 100 setEditorContextMenuId("#ClassFileEditorContext"); setRulerContextMenuId("#ClassFileRulerContext"); setOutlinerContextMenuId("#ClassFileOutlinerContext"); 105 decompilerFlags = new BitSet (); 106 decompilerFlags.set(BCOConstants.F_SHOW_LINE_INFO, true); 108 decompilerFlags.set(BCOConstants.F_SHOW_VARIABLES, true); 109 decompilerFlags.set(BCOConstants.F_SHOW_RAW_BYTECODE, false); 110 } 111 112 115 protected boolean hasMappedSource() { 116 return hasMappedSource; 117 } 118 119 122 protected void setHasMappedSource(boolean hasMappedSource) { 123 this.hasMappedSource = hasMappedSource; 124 } 125 126 private static ClassFileDocumentProvider getClassFileDocumentProvider() { 127 if (fClassFileDocumentProvider == null) { 128 fClassFileDocumentProvider = new BytecodeDocumentProvider(); 129 } 130 return fClassFileDocumentProvider; 131 } 132 133 public void setDecompilerFlag(int flag, boolean value) { 134 decompilerFlags.set(flag, value); 135 } 136 137 public boolean getDecompilerFlag(int flag) { 138 return decompilerFlags.get(flag); 139 } 140 141 144 public void init(IEditorSite site, IEditorInput input) 145 throws PartInitException { 146 input = doOpenBuffer(input, false, true); 147 super.init(site, input); 148 } 149 150 155 public void doSetInput(boolean force, boolean reuseSource) { 156 IEditorInput input = getEditorInput(); 157 input = doOpenBuffer(input, force, reuseSource); 158 if (input != null) { 159 try { 160 doSetInput(input); 161 } catch (Exception e) { 162 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 163 } 164 } 165 } 166 167 182 protected void doSetInput(IEditorInput input) throws CoreException { 183 184 input = transformEditorInput(input); 185 if (!(input instanceof IClassFileEditorInput)) 186 throw new CoreException(JavaUIStatus.createError( 187 IJavaModelStatusConstants.INVALID_RESOURCE_TYPE, 188 "invalid input", null)); 190 191 IDocumentProvider documentProvider = getDocumentProvider(); 192 if (documentProvider instanceof ClassFileDocumentProvider) { 193 ((ClassFileDocumentProvider) documentProvider) 194 .removeInputChangeListener(this); 195 } 196 197 super.doSetInput(input); 198 199 documentProvider = getDocumentProvider(); 200 if (documentProvider instanceof ClassFileDocumentProvider) { 201 ((ClassFileDocumentProvider) documentProvider) 202 .addInputChangeListener(this); 203 } 204 } 205 206 210 public boolean isDecompiled() { 211 return decompiled; 212 } 213 214 private IEditorInput doOpenBuffer(IJavaReferenceType type, 215 IClassFile parent, boolean externalClass) { 216 IClassFile classFile = null; 217 try { 218 classFile = JdtUtils.getInnerType(parent, getSourceMapper() 219 .getDecompiledClass(parent), type.getSignature()); 220 } catch (DebugException e) { 221 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 222 } 223 return doOpenBuffer(classFile, externalClass); 224 } 225 226 private IEditorInput doOpenBuffer(IClassFile classFile, boolean externalClass) { 227 IEditorInput input = null; 228 if (classFile == null) { 229 return null; 230 } 231 if (externalClass) { 232 } else { 234 input = transformEditorInput(classFile); 235 } 236 return doOpenBuffer(input, false, true); 237 } 238 239 private IEditorInput doOpenBuffer(IEditorInput input, boolean force, 240 boolean reuseSource) { 241 if (input instanceof IClassFileEditorInput) { 242 IClassFile cf = ((IClassFileEditorInput) input).getClassFile(); 243 String origSrc = getAttachedJavaSource(cf, force); 244 if (origSrc != null && !hasMappedSource) { 245 setHasMappedSource(true); 247 } 248 249 if (origSrc == null || (force && !reuseSource)) { 250 setDecompiled(true); 251 char[] src; 252 if (input instanceof ExternalClassFileEditorInput) { 253 ExternalClassFileEditorInput extInput = (ExternalClassFileEditorInput) input; 254 src = getSourceMapper().getSource( 255 extInput.getFile(), cf, decompilerFlags); 256 } else { 257 src = getSourceMapper().getSource(cf, decompilerFlags); 258 } 259 changeBufferContent(cf, src); 260 } else { 261 setDecompiled(false); 262 } 263 } else if (input instanceof FileEditorInput) { 264 FileEditorInput fileEditorInput = (FileEditorInput) input; 265 IClassFileEditorInput cfi = transformEditorInput(input); 267 input = cfi; 269 setDecompiled(true); 270 IClassFile cf = cfi.getClassFile(); 271 char[] src = getSourceMapper().getSource( 272 fileEditorInput.getFile(), cf, decompilerFlags); 273 changeBufferContent(cf, src); 274 } 275 return input; 276 } 277 278 private void setDecompiled(boolean decompiled) { 279 boolean oldDecompiled = this.decompiled; 280 this.decompiled = decompiled; 281 if(initDone && oldDecompiled != decompiled) { 282 if(decompiled) { 283 uninstallOccurrencesFinder(); 285 } else { 286 installOccurrencesFinder(true); 288 } 289 } 290 } 291 292 private String getAttachedJavaSource(IClassFile cf, boolean force) { 293 String origSrc = null; 294 if (force) { 295 IBuffer buffer = BytecodeBufferManager.getBuffer(cf); 296 if (buffer != null) { 297 BytecodeBufferManager.removeBuffer(buffer); 298 } 299 } 300 try { 301 origSrc = cf.getSource(); 302 if (origSrc != null && origSrc.startsWith(MARK)) { 303 origSrc = null; 305 } 306 } catch (JavaModelException e) { 307 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 308 } 309 return origSrc; 310 } 311 312 private void changeBufferContent(IClassFile cf, char[] src) { 313 IBuffer buffer = BytecodeBufferManager.getBuffer(cf); 314 315 boolean addBuffer = false; 320 321 buffer = BytecodeBufferManager.createBuffer(cf); 323 addBuffer = true; 324 if (src == null) { 326 src = new char[]{'\n', '/', '/', 'E', 'r', 'r', 'o', 'r'}; 327 } 328 buffer.setContents(src); 329 if (addBuffer) { 330 BytecodeBufferManager.addBuffer(buffer); 331 buffer.addBufferChangedListener((IBufferChangedListener) cf); 332 } 333 } 334 335 338 protected IJavaElement getElementAt(int offset) { 339 340 IClassFile classFile = getClassFile(); 341 if (classFile == null) { 342 return null; 343 } 344 IJavaElement result = null; 345 if (isDecompiled()) { 346 IDocument document = getDocumentProvider().getDocument( 347 getEditorInput()); 348 try { 349 int lineAtOffset = document.getLineOfOffset(offset); 350 result = getSourceMapper().findElement(classFile, lineAtOffset); 354 } catch (BadLocationException e) { 355 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 356 } 357 } else { 358 try { 359 result = classFile.getElementAt(offset); 360 } catch (JavaModelException e) { 361 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 362 } 363 } 364 365 return result; 366 } 367 368 public IClassFile getClassFile() { 369 IEditorInput editorInput = getEditorInput(); 370 if (!(editorInput instanceof IClassFileEditorInput)) { 371 return null; 372 } 373 return ((IClassFileEditorInput) editorInput).getClassFile(); 374 } 375 376 protected void setSelection(ISourceReference reference, boolean moveCursor) { 377 if (reference == null) { 378 if (moveCursor) { 379 resetHighlightRange(); 380 } 381 return; 382 } 383 try { 384 ISourceRange range = null; 385 int offset; 386 int length; 387 if (isDecompiled() && isSupportedMember(reference)) { 388 389 int decompLine = -1 391 + getSourceMapper().getDecompiledLine( 392 (IMember) reference, getClassFile()); 393 if(decompLine < 0){ 394 return; 395 } 396 IRegion region = ((BytecodeDocumentProvider) getDocumentProvider()) 397 .getDecompiledLineInfo(getEditorInput(), decompLine); 398 if (region == null) { 399 return; 400 } 401 offset = region.getOffset(); 402 length = region.getLength(); 403 } else if (!isDecompiled()) { 404 range = reference.getSourceRange(); 405 if (range == null) { 406 return; 407 } 408 offset = range.getOffset(); 409 length = range.getLength(); 410 } else { 411 return; 412 } 413 414 if (offset > -1 && length > 0) { 415 setHighlightRange(offset, length, moveCursor); 416 } 417 418 if ((reference instanceof IMember) && !isDecompiled()) { 419 IMember member = (IMember) reference; 420 range = member.getNameRange(); 421 if (range != null) { 422 offset = range.getOffset(); 423 length = range.getLength(); 424 } 425 } 426 if (moveCursor && offset > -1 && length > 0) { 427 ISourceViewer sourceViewer = getSourceViewer(); 428 if (sourceViewer != null) { 429 sourceViewer.revealRange(offset, length); 430 sourceViewer.setSelectedRange(offset, length); 431 } 432 } 433 return; 434 } catch (Exception e) { 435 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 436 } 437 438 if (moveCursor) { 439 resetHighlightRange(); 440 } 441 } 442 443 private boolean isSupportedMember(ISourceReference reference) { 444 449 return reference instanceof IMethod 451 || reference instanceof IInitializer; 452 } 453 454 public Object getAdapter(Class required) { 455 if (IToggleBreakpointsTarget.class == required) { 456 457 super.getAdapter(required); 467 } 468 469 return super.getAdapter(required); 470 } 471 472 477 protected void adjustHighlightRange(int offset, int length) { 478 try { 479 480 IJavaElement element = getElementAt(offset); 481 while (element instanceof ISourceReference) { 482 ISourceRange range = ((ISourceReference) element) 483 .getSourceRange(); 484 if (range != null 486 && (offset < range.getOffset() + range.getLength() && range 487 .getOffset() < offset + length)) { 488 489 ISourceViewer viewer = getSourceViewer(); 490 if (viewer instanceof ITextViewerExtension5) { 491 ITextViewerExtension5 extension = (ITextViewerExtension5) viewer; 492 extension.exposeModelRange(new Region( 493 range.getOffset(), range.getLength())); 494 } 495 496 setHighlightRange( 497 range.getOffset(), range.getLength(), true); 498 if (fOutlinePage != null) { 499 fOutlineSelectionChangedListener 500 .uninstall(fOutlinePage); 501 fOutlinePage.select((ISourceReference) element); 502 fOutlineSelectionChangedListener.install(fOutlinePage); 503 } 504 505 return; 506 } 507 element = element.getParent(); 508 } 509 510 } catch (JavaModelException x) { 511 JavaPlugin.log(x.getStatus()); 512 } 513 514 ISourceViewer viewer = getSourceViewer(); 515 if (viewer instanceof ITextViewerExtension5) { 516 ITextViewerExtension5 extension = (ITextViewerExtension5) viewer; 517 extension.exposeModelRange(new Region(offset, length)); 518 } else { 519 resetHighlightRange(); 520 } 521 522 } 523 524 528 protected ISourceReference computeHighlightRangeSourceReference() { 529 if (!isDecompiled()) { 530 return super.computeHighlightRangeSourceReference(); 531 } 532 533 ISourceViewer sourceViewer = getSourceViewer(); 534 if (sourceViewer == null) { 535 return null; 536 } 537 StyledText styledText = sourceViewer.getTextWidget(); 538 if (styledText == null) { 539 return null; 540 } 541 542 int caret = 0; 543 if (sourceViewer instanceof ITextViewerExtension5) { 544 ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer; 545 caret = extension.widgetOffset2ModelOffset(styledText 546 .getCaretOffset()); 547 } else { 548 int offset = sourceViewer.getVisibleRegion().getOffset(); 549 caret = offset + styledText.getCaretOffset(); 550 } 551 552 IJavaElement element = getElementAt(caret); 553 554 if (!(element instanceof ISourceReference)) { 555 return null; 556 } 557 return (ISourceReference) element; 558 } 559 560 567 protected ISourceViewer createJavaSourceViewer(Composite parent, 568 IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, 569 boolean isOverviewRulerVisible, int styles, IPreferenceStore store) { 570 571 return super.createJavaSourceViewer( 572 parent, verticalRuler, overviewRuler, isOverviewRulerVisible, 573 styles, store); 574 } 575 576 580 protected void doSelectionChanged(SelectionChangedEvent event) { 581 582 super.doSelectionChanged(event); 583 } 584 585 589 protected void doSetSelection(ISelection selection) { 590 591 super.doSetSelection(selection); 592 } 593 594 598 protected IRegion getSignedSelection(ISourceViewer sourceViewer) { 599 600 return super.getSignedSelection(sourceViewer); 601 } 602 603 608 protected void synchronizeOutlinePage(ISourceReference element, 609 boolean checkIfOutlinePageActive) { 610 611 super.synchronizeOutlinePage(element, checkIfOutlinePageActive); 612 } 613 614 618 protected void synchronizeOutlinePage(ISourceReference element) { 619 620 super.synchronizeOutlinePage(element); 621 } 622 623 627 public void synchronizeOutlinePageSelection() { 628 629 super.synchronizeOutlinePageSelection(); 630 } 631 632 636 public ISelectionProvider getSelectionProvider() { 637 638 return super.getSelectionProvider(); 639 } 640 641 646 protected void selectAndReveal(int selectionStart, int selectionLength, 647 int revealStart, int revealLength) { 648 649 super.selectAndReveal( 650 selectionStart, selectionLength, revealStart, revealLength); 651 } 652 653 657 public void selectAndReveal(int start, int length) { 658 659 super.selectAndReveal(start, length); 660 } 661 662 667 public void setHighlightRange(int offset, int length, boolean moveCursor) { 668 super.setHighlightRange(offset, length, moveCursor); 669 670 } 671 672 public void showHighlightRangeOnly(boolean showHighlightRangeOnly) { 673 } 677 678 protected void updateOccurrenceAnnotations(ITextSelection selection, 679 CompilationUnit astRoot) { 680 if(hasMappedSource()) { 682 super.updateOccurrenceAnnotations(selection, astRoot); 683 } 684 } 685 686 689 private class InputUpdater implements Runnable { 690 691 692 private boolean fPosted = false; 693 694 private IClassFileEditorInput fClassFileEditorInput; 695 696 public InputUpdater() { 697 } 699 700 703 public void run() { 704 705 IClassFileEditorInput input; 706 synchronized (this) { 707 input = fClassFileEditorInput; 708 } 709 710 try { 711 if (getSourceViewer() != null) { 712 setInput(input); 713 } 714 } finally { 715 synchronized (this) { 716 fPosted = false; 717 } 718 } 719 } 720 721 725 public void post(IClassFileEditorInput input) { 726 727 synchronized (this) { 728 if (fPosted) { 729 if (input != null && input.equals(fClassFileEditorInput)) 730 fClassFileEditorInput = input; 731 return; 732 } 733 } 734 735 if (input != null && input.equals(getEditorInput())) { 736 ISourceViewer viewer = getSourceViewer(); 737 if (viewer != null) { 738 StyledText textWidget = viewer.getTextWidget(); 739 if (textWidget != null && !textWidget.isDisposed()) { 740 synchronized (this) { 741 fPosted = true; 742 fClassFileEditorInput = input; 743 } 744 textWidget.getDisplay().asyncExec(this); 745 } 746 } 747 } 748 } 749 } 750 751 754 protected void createActions() { 755 super.createActions(); 756 757 760 774 } 775 776 779 protected IJavaElement getCorrespondingElement(IJavaElement element) { 780 IClassFile classFile = getClassFile(); 781 if (classFile == null) { 782 return null; 783 } 784 if (classFile.equals(element.getAncestor(IJavaElement.CLASS_FILE))) { 785 return element; 786 } 787 return null; 788 } 789 790 794 797 public boolean isEditable() { 798 return isDecompiled(); 799 } 800 801 805 public boolean isEditorInputReadOnly() { 806 return !isDecompiled(); 807 } 808 809 813 public boolean isEditorInputModifiable() { 814 return isDecompiled(); 815 } 816 817 public boolean isSaveAsAllowed() { 818 return isDecompiled(); 819 } 820 821 826 protected IClassFileEditorInput transformEditorInput(Object input) { 827 828 if (input instanceof IFileEditorInput) { 829 IFile file = ((IFileEditorInput) input).getFile(); 830 Constructor cons; 831 try { 832 cons = ExternalClassFileEditorInput.class 833 .getDeclaredConstructor(new Class []{IFile.class}); 834 cons.setAccessible(true); 835 IClassFileEditorInput classFileInput = (IClassFileEditorInput) cons 836 .newInstance(new Object []{file}); 837 return classFileInput; 838 } catch (Exception e) { 839 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 840 } 841 } else if (input instanceof IClassFileEditorInput) { 842 return (IClassFileEditorInput) input; 843 } else if (input instanceof IClassFile) { 844 return new InternalClassFileEditorInput((IClassFile) input); 845 } 846 847 return null; 848 } 849 850 853 public void createPartControl(Composite parent) { 854 855 fParent = new Composite(parent, SWT.NONE); 856 fStackLayout = new StackLayout(); 857 fParent.setLayout(fStackLayout); 858 859 fViewerComposite = new Composite(fParent, SWT.NONE); 860 fViewerComposite.setLayout(new FillLayout()); 861 862 super.createPartControl(fViewerComposite); 863 864 fStackLayout.topControl = fViewerComposite; 865 fParent.layout(); 866 initDone = true; 867 } 868 869 872 public void inputChanged(IClassFileEditorInput input) { 873 fInputUpdater.post(input); 874 IClassFile cf = input.getClassFile(); 875 String source; 876 try { 877 source = cf.getSource(); 878 setDecompiled(source != null && source.startsWith(MARK)); 879 } catch (JavaModelException e) { 880 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 881 } 882 883 } 884 885 888 public void dispose() { 889 IDocumentProvider documentProvider = getDocumentProvider(); 891 if (documentProvider instanceof ClassFileDocumentProvider) { 892 ((ClassFileDocumentProvider) documentProvider) 893 .removeInputChangeListener(this); 894 } 895 896 IClassFile classFile = getClassFile(); 897 BytecodeBufferManager.removeBuffer(BytecodeBufferManager 898 .getBuffer(classFile)); 899 super.dispose(); 900 } 901 902 public static BytecodeSourceMapper getSourceMapper() { 903 return sourceMapper; 904 } 905 906 919 public static IRegion checkForInnerClass(int sourceLine, IClassFile parent) { 920 IRegion region = new Region(0, 0); 921 922 BytecodeClassFileEditor editor = getBytecodeEditor(parent); 924 if (editor == null) { 925 return region; 926 } 927 928 IJavaReferenceType debugType = sourceMapper.getLastTypeInDebugger(); 930 if (debugType == null) { 931 return region; 932 } 933 934 boolean externalClass = editor.getEditorInput() instanceof ExternalClassFileEditorInput; 935 IEditorInput input = null; 936 if (!hasInnerClass(debugType, parent)) { 938 IClassFile classFile = getLocalTypeClass(debugType, parent); 941 if(classFile != null){ 942 input = editor.doOpenBuffer(classFile, externalClass); 943 } 944 } else { 945 input = editor.doOpenBuffer(debugType, parent, externalClass); 947 } 948 949 if (input == null) { 950 return region; 951 } 952 953 958 try { 959 editor.doSetInput(input); 960 } catch (CoreException e) { 961 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 962 return region; 963 } 964 965 int decompiledLine = sourceMapper.mapToDecompiled( 967 sourceLine + 1, editor.getClassFile()); 968 969 if (decompiledLine >= 0) { 970 try { 972 region = editor.getDocumentProvider().getDocument(input) 973 .getLineInformation(decompiledLine); 974 } catch (BadLocationException e) { 975 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 976 } 977 } 978 return region; 979 } 980 981 987 private static IClassFile getLocalTypeClass(IJavaReferenceType debugType, IClassFile parent) { 988 try { 989 IType type = parent.getType(); 990 if((type.isLocal()) || (type.isMember())) { 991 return null; 993 } 994 String binarySignature = debugType.getSignature(); 996 int idx = binarySignature.lastIndexOf('/'); 998 if(idx > 0 && idx < binarySignature.length() - 1){ 999 String name = binarySignature.substring(idx + 1); 1000 if(name.charAt(name.length() - 1) == ';'){ 1001 name = name.substring(0, name.length() - 1); 1002 } 1003 return type.getPackageFragment().getClassFile(name + ".class"); 1004 } 1005 } catch (Exception e) { 1006 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 1007 } 1008 return null; 1009 } 1010 1011 private static boolean hasInnerClass(IJavaReferenceType debugType, 1012 IClassFile parent) { 1013 try { 1014 String parentName = parent.getType().getFullyQualifiedName(); 1015 String childName = debugType.getName(); 1016 return childName != null && childName.startsWith(parentName + "$"); 1017 } catch (Exception e) { 1018 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 1019 } 1020 return false; 1021 } 1022 1023 private static BytecodeClassFileEditor getBytecodeEditor(IClassFile parent) { 1024 IEditorReference[] editorReferences = PlatformUI.getWorkbench() 1025 .getActiveWorkbenchWindow().getActivePage().getEditorReferences(); 1026 for (int i = 0; i < editorReferences.length; i++) { 1027 IEditorPart editor = editorReferences[i].getEditor(false); 1028 if (editor instanceof BytecodeClassFileEditor) { 1029 BytecodeClassFileEditor bytecodeEditor = (BytecodeClassFileEditor) editor; 1030 if (parent.equals((bytecodeEditor).getClassFile())) { 1031 return bytecodeEditor; 1032 } 1033 } 1034 } 1035 return null; 1036 } 1037 1038 public ITextSelection convertSelection(ITextSelection textSelection, 1039 boolean toDecompiled) { 1040 int startLine = textSelection.getStartLine(); 1041 int newLine; 1042 if (toDecompiled) { 1043 newLine = sourceMapper.mapToDecompiled( 1044 startLine + 1, getClassFile()) + 1; 1045 } else { 1046 newLine = sourceMapper.mapToSource(startLine, getClassFile()) - 1; 1047 } 1048 IDocument document = getDocumentProvider() 1049 .getDocument(getEditorInput()); 1050 try { 1051 int lineOffset = document.getLineOffset(newLine); 1052 return new TextSelection(lineOffset, 0); 1053 } catch (BadLocationException e) { 1054 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 1055 } 1056 return null; 1057 } 1058 1059 public int getSourceLine(ITextSelection bytecodeSelection) { 1060 int startLine = bytecodeSelection.getStartLine(); 1061 return sourceMapper.mapToSource(startLine, getClassFile()) - 1; 1062 } 1063 1064 public ITextSelection convertLine(int sourceLine) { 1065 int newLine = sourceMapper.mapToDecompiled( 1066 sourceLine + 1, getClassFile()) + 1; 1067 IDocument document = getDocumentProvider() 1068 .getDocument(getEditorInput()); 1069 try { 1070 int lineOffset = document.getLineOffset(newLine); 1071 return new TextSelection(lineOffset, 0); 1072 } catch (BadLocationException e) { 1073 BytecodeOutlinePlugin.log(e, IStatus.ERROR); 1074 } 1075 return null; 1076 } 1077 1078 1082 protected void installOverrideIndicator(boolean provideAST) { 1083 super.installOverrideIndicator(true); 1084 } 1085 1086} 1087 | Popular Tags |