diff options
author | Sarika Sinha | 2017-02-06 06:56:09 +0000 |
---|---|---|
committer | Sarika Sinha | 2017-02-06 06:56:09 +0000 |
commit | 5145e01b37c3732d687a9339df2abffe9663d9ee (patch) | |
tree | e755bcb23dc2278f65ef732187723a5545bd57e3 | |
parent | 0fd9e4750969a3d4601de7ddaecd177b98bf6ad9 (diff) | |
download | eclipse.jdt.debug-5145e01b37c3732d687a9339df2abffe9663d9ee.tar.gz eclipse.jdt.debug-5145e01b37c3732d687a9339df2abffe9663d9ee.tar.xz eclipse.jdt.debug-5145e01b37c3732d687a9339df2abffe9663d9ee.zip |
Bug 511659 - UI freeze of 13s caused by requesting AST on the UI thread
Change-Id: Ib93f9fbf10ccac037e8cafc7b74b94339e58afb8
3 files changed, 295 insertions, 359 deletions
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java index 742a79776..2b3b7f56c 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointToggleUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 IBM Corporation and others. + * Copyright (c) 2016, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,50 +12,9 @@ package org.eclipse.jdt.internal.debug.ui.actions; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.core.IClassFile; -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.IPackageDeclaration; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.ITypeRoot; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext; -import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType; -import org.eclipse.jdt.internal.corext.template.java.JavaContextType; -import org.eclipse.jdt.internal.debug.ui.DebugWorkingCopyManager; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; -import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; -import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine; -import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal; -import org.eclipse.jdt.ui.IWorkingCopyManager; -import org.eclipse.jdt.ui.JavaUI; -import org.eclipse.jdt.ui.SharedASTProvider; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.templates.Template; -import org.eclipse.jface.text.templates.TemplateContextType; -import org.eclipse.jface.text.templates.TemplateException; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IEditorStatusLine; -import org.eclipse.ui.texteditor.ITextEditor; /** * Utility class for Java Toggle breakpoints @@ -64,7 +23,6 @@ public class BreakpointToggleUtils { private static boolean isTracepoint = false; - public static final String EMPTY_STRING = ""; //$NON-NLS-1$ public static void setUnsetTracepoints(boolean tracePoint) { isTracepoint = tracePoint; @@ -75,65 +33,6 @@ public class BreakpointToggleUtils { } /** - * Returns the package qualified name, while accounting for the fact that a source file might not have a project - * - * @param type - * the type to ensure the package qualified name is created for - * @return the package qualified name - * @since 3.3 - */ - static String createQualifiedTypeName(IType type) { - String tname = pruneAnonymous(type); - try { - String packName = null; - if (type.isBinary()) { - packName = type.getPackageFragment().getElementName(); - } else { - IPackageDeclaration[] pd = type.getCompilationUnit().getPackageDeclarations(); - if (pd.length > 0) { - packName = pd[0].getElementName(); - } - } - if (packName != null && !packName.equals(EMPTY_STRING)) { - tname = packName + "." + tname; //$NON-NLS-1$ - } - } - catch (JavaModelException e) { - } - return tname; - } - - /** - * Prunes out all naming occurrences of anonymous inner types, since these types have no names and cannot be derived visiting an AST (no positive - * type name matching while visiting ASTs) - * - * @param type - * @return the compiled type name from the given {@link IType} with all occurrences of anonymous inner types removed - * @since 3.4 - */ - private static String pruneAnonymous(IType type) { - StringBuffer buffer = new StringBuffer(); - IJavaElement parent = type; - while (parent != null) { - if (parent.getElementType() == IJavaElement.TYPE) { - IType atype = (IType) parent; - try { - if (!atype.isAnonymous()) { - if (buffer.length() > 0) { - buffer.insert(0, '$'); - } - buffer.insert(0, atype.getElementName()); - } - } - catch (JavaModelException jme) { - } - } - parent = parent.getParent(); - } - return buffer.toString(); - } - - /** * Convenience method for printing messages to the status line * * @param message @@ -157,196 +56,4 @@ public class BreakpointToggleUtils { }); } - /** - * Returns the text editor associated with the given part or <code>null</code> if none. In case of a multi-page editor, this method should be used - * to retrieve the correct editor to perform the breakpoint operation on. - * - * @param part - * workbench part - * @return text editor part or <code>null</code> - */ - protected static ITextEditor getTextEditor(IWorkbenchPart part) { - if (part instanceof ITextEditor) { - return (ITextEditor) part; - } - return part.getAdapter(ITextEditor.class); - } - - - /** - * Returns the compilation unit from the editor - * - * @param editor - * the editor to get the compilation unit from - * @return the compilation unit or <code>null</code> - */ - public static CompilationUnit parseCompilationUnit(ITextEditor editor) { - return parseCompilationUnit(getTypeRoot(editor.getEditorInput())); - } - - /** - * Parses the {@link ITypeRoot}. - * - * @param root - * the root - * @return the parsed {@link CompilationUnit} - */ - static CompilationUnit parseCompilationUnit(ITypeRoot root) { - if (root != null) { - return SharedASTProvider.getAST(root, SharedASTProvider.WAIT_YES, null); - } - return null; - } - - /** - * Returns a selection of the member in the given text selection, or the original selection if none. - * - * @param part - * @param selection - * @return a structured selection of the member in the given text selection, or the original selection if none - * @exception CoreException - * if an exception occurs - */ - protected static ISelection translateToMembers(IWorkbenchPart part, ISelection selection) throws CoreException { - ITextEditor textEditor = getTextEditor(part); - if (textEditor != null && selection instanceof ITextSelection) { - ITextSelection textSelection = (ITextSelection) selection; - IEditorInput editorInput = textEditor.getEditorInput(); - IDocumentProvider documentProvider = textEditor.getDocumentProvider(); - if (documentProvider == null) { - throw new CoreException(Status.CANCEL_STATUS); - } - IDocument document = documentProvider.getDocument(editorInput); - int offset = textSelection.getOffset(); - if (document != null) { - try { - IRegion region = document.getLineInformationOfOffset(offset); - int end = region.getOffset() + region.getLength(); - while (Character.isWhitespace(document.getChar(offset)) && offset < end) { - offset++; - } - } - catch (BadLocationException ex) { - } - } - IMember m = null; - ITypeRoot root = getTypeRoot(editorInput); - if (root instanceof ICompilationUnit) { - ICompilationUnit unit = (ICompilationUnit) root; - synchronized (unit) { - unit.reconcile(ICompilationUnit.NO_AST, false, null, null); - } - } - if (root != null) { - IJavaElement e = root.getElementAt(offset); - if (e instanceof IMember) { - m = (IMember) e; - } - } - if (m != null) { - return new StructuredSelection(m); - } - } - return selection; - } - - /** - * Returns the {@link ITypeRoot} for the given {@link IEditorInput} - * - * @param input - * @return the type root or <code>null</code> if one cannot be derived - * @since 3.4 - */ - private static ITypeRoot getTypeRoot(IEditorInput input) { - ITypeRoot root = input.getAdapter(IClassFile.class); - if (root == null) { - IWorkingCopyManager manager = JavaUI.getWorkingCopyManager(); - root = manager.getWorkingCopy(input); - } - if (root == null) { - root = DebugWorkingCopyManager.getWorkingCopy(input, false); - } - return root; - } - - /** - * Returns the {@link ITypeRoot} for the given {@link IEditorInput} - * - * @param input - * @return the type root or <code>null</code> if one cannot be derived - * @since 3.8 - */ - public static String getCodeTemplate(ITextSelection textSelection, CompilationUnitEditor part) { - TemplateContextType contextType = JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(JavaContextType.ID_STATEMENTS); - TemplateEngine fStatementEngine = new TemplateEngine(contextType); - fStatementEngine.reset(); - ITextViewer viewer = part.getViewer(); - final String[] fTemplateBuffer = new String[1]; - fTemplateBuffer[0] = null; - if (viewer != null) { - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - ITextEditor editor = BreakpointToggleUtils.getTextEditor(part); - if (editor != null) { - IJavaElement element = getJavaElement(editor.getEditorInput()); - ICompilationUnit cunit = null; - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IFile file = root.getFile(element.getPath()); - cunit = JavaCore.createCompilationUnitFrom(file); - IDocumentProvider documentProvider = editor.getDocumentProvider(); - if (documentProvider == null) { - return; - } - IDocument document = documentProvider.getDocument(editor.getEditorInput()); - try { - IRegion line = document.getLineInformation(textSelection.getStartLine() + 1); - Point selectedRange = viewer.getSelectedRange(); - viewer.setSelectedRange(selectedRange.x, 0); - fStatementEngine.complete(viewer, line.getOffset(), cunit); - viewer.setSelectedRange(selectedRange.x, selectedRange.y); - TemplateProposal[] templateProposals = fStatementEngine.getResults(); - for (TemplateProposal templateProposal : templateProposals) { - Template template = templateProposal.getTemplate(); - if (template.getName().equals("systrace")) { //$NON-NLS-1$ - CompilationUnitContextType contextType = (CompilationUnitContextType) JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(template.getContextTypeId()); - CompilationUnitContext context = contextType.createContext(document, line.getOffset(), 0, cunit); - context.setVariable("selection", EMPTY_STRING); //$NON-NLS-1$ - context.setForceEvaluation(true); - fTemplateBuffer[0] = context.evaluate(template).getString(); - return; - } - } - } - catch (BadLocationException e) { - e.printStackTrace(); - } - catch (TemplateException e1) { - e1.printStackTrace(); - } - - } - } - }); - } - return fTemplateBuffer[0]; - } - - /** - * gets the <code>IJavaElement</code> from the editor input - * - * @param input - * the current editor input - * @return the corresponding <code>IJavaElement</code> - * @since 3.3 - */ - public static IJavaElement getJavaElement(IEditorInput input) { - IJavaElement je = JavaUI.getEditorInputJavaElement(input); - if (je != null) { - return je; - } - // try to get from the working copy manager - return DebugWorkingCopyManager.getWorkingCopy(input, false); - } - } diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java index 4ea788044..1ee3d01a8 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RetargetToggleTracepointAction.java @@ -12,13 +12,7 @@ package org.eclipse.jdt.internal.debug.ui.actions; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.internal.ui.actions.breakpoints.RetargetToggleBreakpointAction; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.internal.debug.core.breakpoints.ValidBreakpointLocationLocator; -import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IWorkbenchPart; /** @@ -49,41 +43,7 @@ public class RetargetToggleTracepointAction extends RetargetToggleBreakpointActi */ @Override protected boolean canPerformAction(Object target, ISelection selection, IWorkbenchPart part) { - try { - ISelection sel = BreakpointToggleUtils.translateToMembers(part, selection); - if (sel instanceof IStructuredSelection) { - Object firstElement = ((IStructuredSelection) sel).getFirstElement(); - if (firstElement instanceof IMember) { - IMember member = (IMember) firstElement; - int mtype = member.getElementType(); - if (mtype == IJavaElement.FIELD || mtype == IJavaElement.METHOD || mtype == IJavaElement.INITIALIZER) { - // remove line breakpoint if present first - if (selection instanceof ITextSelection) { - ITextSelection ts = (ITextSelection) selection; - - CompilationUnit unit = BreakpointToggleUtils.parseCompilationUnit(BreakpointToggleUtils.getTextEditor(part)); - ValidBreakpointLocationLocator loc = new ValidBreakpointLocationLocator(unit, ts.getStartLine() + 1, true, true); - unit.accept(loc); - if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_METHOD) { - return true; - } else if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_FIELD) { - return false; - } else if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_LINE) { - return true; - } - } - } - - if (member.getElementType() == IJavaElement.TYPE) { - return false; - } - } - } - return super.canPerformAction(target, selection, part); - } - catch (CoreException e) { - return false; - } + return super.canPerformAction(target, selection, part); } /* diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java index f5e1e9c08..dc46d7b1d 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java @@ -19,6 +19,7 @@ import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -42,9 +43,12 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IPackageDeclaration; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeParameter; +import org.eclipse.jdt.core.ITypeRoot; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.SourceRange; @@ -64,22 +68,38 @@ import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint; import org.eclipse.jdt.debug.core.IJavaType; import org.eclipse.jdt.debug.core.IJavaWatchpoint; import org.eclipse.jdt.debug.core.JDIDebugModel; +import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext; +import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType; +import org.eclipse.jdt.internal.corext.template.java.JavaContextType; import org.eclipse.jdt.internal.debug.core.JavaDebugUtils; import org.eclipse.jdt.internal.debug.core.breakpoints.ValidBreakpointLocationLocator; import org.eclipse.jdt.internal.debug.ui.BreakpointUtils; +import org.eclipse.jdt.internal.debug.ui.DebugWorkingCopyManager; import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; +import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; +import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine; +import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal; +import org.eclipse.jdt.ui.IWorkingCopyManager; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jdt.ui.SharedASTProvider; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.text.templates.Template; +import org.eclipse.jface.text.templates.TemplateContextType; +import org.eclipse.jface.text.templates.TemplateException; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; @@ -98,6 +118,7 @@ import org.eclipse.ui.texteditor.ITextEditor; */ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtension2 { + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ /** @@ -215,7 +236,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio BreakpointToggleUtils.report(null, part); ISelection selection = finalSelection; if(!(selection instanceof IStructuredSelection)) { - selection = BreakpointToggleUtils.translateToMembers(part, selection); + selection = translateToMembers(part, selection); } boolean isInterface = isInterface(selection, part); if (selection instanceof IStructuredSelection) { @@ -265,7 +286,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio IJavaMethodBreakpoint methodBreakpoint = JDIDebugModel.createMethodBreakpoint(BreakpointUtils.getBreakpointResource(members[i]), getQualifiedName(type), mname, signature, true, false, false, -1, start, end, 0, true, attributes); if (BreakpointToggleUtils.isToggleTracepoints() && finalSelection instanceof ITextSelection && part instanceof CompilationUnitEditor) { - String pattern = BreakpointToggleUtils.getCodeTemplate((ITextSelection) finalSelection, (CompilationUnitEditor) part); + String pattern = getCodeTemplate((ITextSelection) finalSelection, (CompilationUnitEditor) part); if (pattern != null) { pattern.trim(); pattern = pattern.replaceAll("\\\t", ""); //$NON-NLS-1$//$NON-NLS-2$ @@ -314,7 +335,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio * @since 3.8 */ IStatus doLineBreakpointToggle(ISelection selection, IWorkbenchPart part, ValidBreakpointLocationLocator locator, boolean bestMatch, IProgressMonitor monitor) { - ITextEditor editor = BreakpointToggleUtils.getTextEditor(part); + ITextEditor editor = getTextEditor(part); if (editor != null && selection instanceof ITextSelection) { if (monitor.isCanceled()) { return Status.CANCEL_STATUS; @@ -327,7 +348,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio BreakpointToggleUtils.report(null, part); ISelection sel = selection; if(!(selection instanceof IStructuredSelection)) { - sel = BreakpointToggleUtils.translateToMembers(part, selection); + sel = translateToMembers(part, selection); } if(sel instanceof IStructuredSelection) { IMember member = (IMember) ((IStructuredSelection)sel).getFirstElement(); @@ -339,14 +360,14 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio type = member.getDeclaringType(); } if (locator == null && BreakpointToggleUtils.isToggleTracepoints()) { - CompilationUnit cUnit = BreakpointToggleUtils.parseCompilationUnit(type.getTypeRoot()); + CompilationUnit cUnit = parseCompilationUnit(type.getTypeRoot()); locator = new ValidBreakpointLocationLocator(cUnit, tsel.getStartLine() + 1, true, bestMatch); cUnit.accept(locator); } String tname = null; IJavaProject project = type.getJavaProject(); if (locator == null || (project != null && !project.isOnClasspath(type))) { - tname = BreakpointToggleUtils.createQualifiedTypeName(type); + tname = createQualifiedTypeName(type); } else { tname = locator.getFullyQualifiedTypeName(); } @@ -381,7 +402,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio BreakpointUtils.addJavaBreakpointAttributes(attributes, type); IJavaLineBreakpoint breakpoint = JDIDebugModel.createLineBreakpoint(resource, tname, lnumber, charstart, charend, 0, true, attributes); if (BreakpointToggleUtils.isToggleTracepoints() && selection instanceof ITextSelection && part instanceof CompilationUnitEditor) { - String pattern = BreakpointToggleUtils.getCodeTemplate((ITextSelection) selection, (CompilationUnitEditor) part); + String pattern = getCodeTemplate((ITextSelection) selection, (CompilationUnitEditor) part); if (pattern != null) { pattern.trim(); pattern = pattern.replaceAll("\\\t", ""); //$NON-NLS-1$//$NON-NLS-2$ @@ -393,7 +414,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio BreakpointToggleUtils.setUnsetTracepoints(false); } if (locator == null) { - new BreakpointLocationVerifierJob(document, BreakpointToggleUtils.parseCompilationUnit(type.getTypeRoot()), breakpoint, lnumber, tname, type, editor, bestMatch).schedule(); + new BreakpointLocationVerifierJob(document, parseCompilationUnit(type.getTypeRoot()), breakpoint, lnumber, tname, type, editor, bestMatch).schedule(); } if (BreakpointToggleUtils.isToggleTracepoints()) { BreakpointToggleUtils.setUnsetTracepoints(false); @@ -429,7 +450,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio BreakpointToggleUtils.report(null, part); ISelection sel = selection; if(!(selection instanceof IStructuredSelection)) { - sel = BreakpointToggleUtils.translateToMembers(part, selection); + sel = translateToMembers(part, selection); } if(isInterface(sel, part)) { BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_1, part); @@ -500,7 +521,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio String getQualifiedName(IType type) throws JavaModelException { IJavaProject project = type.getJavaProject(); if (project != null && project.isOnClasspath(type) && needsBindings(type)) { - CompilationUnit cuNode = BreakpointToggleUtils.parseCompilationUnit(type.getTypeRoot()); + CompilationUnit cuNode = parseCompilationUnit(type.getTypeRoot()); ISourceRange nameRange = type.getNameRange(); if (SourceRange.isAvailable(nameRange)) { ASTNode node = NodeFinder.perform(cuNode, nameRange); @@ -521,7 +542,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio } } } - return BreakpointToggleUtils.createQualifiedTypeName(type); + return createQualifiedTypeName(type); } /** @@ -551,6 +572,76 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio return false; } + /** + * Returns the package qualified name, while accounting for the fact that a source file might + * not have a project + * @param type the type to ensure the package qualified name is created for + * @return the package qualified name + * @since 3.3 + */ + String createQualifiedTypeName(IType type) { + String tname = pruneAnonymous(type); + try { + String packName = null; + if (type.isBinary()) { + packName = type.getPackageFragment().getElementName(); + } else { + IPackageDeclaration[] pd = type.getCompilationUnit().getPackageDeclarations(); + if(pd.length > 0) { + packName = pd[0].getElementName(); + } + } + if(packName != null && !packName.equals(EMPTY_STRING)) { + tname = packName+"."+tname; //$NON-NLS-1$ + } + } + catch (JavaModelException e) {} + return tname; + } + + /** + * Prunes out all naming occurrences of anonymous inner types, since these types have no names + * and cannot be derived visiting an AST (no positive type name matching while visiting ASTs) + * @param type + * @return the compiled type name from the given {@link IType} with all occurrences of anonymous inner types removed + * @since 3.4 + */ + private String pruneAnonymous(IType type) { + StringBuffer buffer = new StringBuffer(); + IJavaElement parent = type; + while(parent != null) { + if(parent.getElementType() == IJavaElement.TYPE){ + IType atype = (IType) parent; + try { + if(!atype.isAnonymous()) { + if(buffer.length() > 0) { + buffer.insert(0, '$'); + } + buffer.insert(0, atype.getElementName()); + } + } + catch(JavaModelException jme) {} + } + parent = parent.getParent(); + } + return buffer.toString(); + } + + /** + * gets the <code>IJavaElement</code> from the editor input + * @param input the current editor input + * @return the corresponding <code>IJavaElement</code> + * @since 3.3 + */ + private IJavaElement getJavaElement(IEditorInput input) { + IJavaElement je = JavaUI.getEditorInputJavaElement(input); + if(je != null) { + return je; + } + //try to get from the working copy manager + return DebugWorkingCopyManager.getWorkingCopy(input, false); + } + /* * (non-Javadoc) * @@ -586,7 +677,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio return !member.getJavaProject().getProject().exists(); } } - ITextEditor editor = BreakpointToggleUtils.getTextEditor(part); + ITextEditor editor = getTextEditor(part); if (editor != null) { IEditorInput input = editor.getEditorInput(); Object adapter = Platform.getAdapterManager().getAdapter(input, "org.eclipse.team.core.history.IFileRevision"); //$NON-NLS-1$ @@ -596,6 +687,21 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio } /** + * Returns the text editor associated with the given part or <code>null</code> + * if none. In case of a multi-page editor, this method should be used to retrieve + * the correct editor to perform the breakpoint operation on. + * + * @param part workbench part + * @return text editor part or <code>null</code> + */ + protected ITextEditor getTextEditor(IWorkbenchPart part) { + if (part instanceof ITextEditor) { + return (ITextEditor) part; + } + return part.getAdapter(ITextEditor.class); + } + + /** * Returns the methods from the selection, or an empty array * @param selection the selection to get the methods from * @return an array of the methods from the selection or an empty array @@ -659,9 +765,9 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio * @return true if the selection is a valid method, false otherwise */ private boolean isMethod(ITextSelection selection, IWorkbenchPart part) { - ITextEditor editor = BreakpointToggleUtils.getTextEditor(part); + ITextEditor editor = getTextEditor(part); if (editor != null) { - IJavaElement element = BreakpointToggleUtils.getJavaElement(editor.getEditorInput()); + IJavaElement element = getJavaElement(editor.getEditorInput()); if (element != null) { try { if (element instanceof ICompilationUnit) { @@ -727,7 +833,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio try { ISelection sel = selection; if(!(sel instanceof IStructuredSelection)) { - sel = BreakpointToggleUtils.translateToMembers(part, selection); + sel = translateToMembers(part, selection); } if(sel instanceof IStructuredSelection) { Object obj = ((IStructuredSelection)sel).getFirstElement(); @@ -757,9 +863,9 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio * @since 3.3 */ private boolean isField(ITextSelection selection, IWorkbenchPart part) { - ITextEditor editor = BreakpointToggleUtils.getTextEditor(part); + ITextEditor editor = getTextEditor(part); if(editor != null) { - IJavaElement element = BreakpointToggleUtils.getJavaElement(editor.getEditorInput()); + IJavaElement element = getJavaElement(editor.getEditorInput()); if(element != null) { try { if(element instanceof ICompilationUnit) { @@ -822,7 +928,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio BreakpointToggleUtils.report(null, part); ISelection selection = finalSelection; if(!(selection instanceof IStructuredSelection)) { - selection = BreakpointToggleUtils.translateToMembers(part, finalSelection); + selection = translateToMembers(part, finalSelection); } if(isInterface(selection, part)) { BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_5, part); @@ -994,8 +1100,8 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio types[1] = types[1].replace('.', '$'); String resolvedElementTypeName = Signature.toQualifiedName(types); - String resolvedElementTypeSignature = BreakpointToggleUtils.EMPTY_STRING; - if (types[0].equals(BreakpointToggleUtils.EMPTY_STRING)) { + String resolvedElementTypeSignature = EMPTY_STRING; + if (types[0].equals(EMPTY_STRING)) { resolvedElementTypeName = resolvedElementTypeName.substring(1); resolvedElementTypeSignature = Signature.createTypeSignature(resolvedElementTypeName, true); } @@ -1097,7 +1203,26 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio return null; } + /** + * Returns the compilation unit from the editor + * @param editor the editor to get the compilation unit from + * @return the compilation unit or <code>null</code> + */ + protected CompilationUnit parseCompilationUnit(ITextEditor editor) { + return parseCompilationUnit(getTypeRoot(editor.getEditorInput())); + } + /** + * Parses the {@link ITypeRoot}. + * @param root the root + * @return the parsed {@link CompilationUnit} + */ + CompilationUnit parseCompilationUnit(ITypeRoot root) { + if(root != null) { + return SharedASTProvider.getAST(root, SharedASTProvider.WAIT_YES, null); + } + return null; + } /* * (non-Javadoc) @@ -1118,6 +1243,76 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio } /** + * Returns a selection of the member in the given text selection, or the + * original selection if none. + * + * @param part + * @param selection + * @return a structured selection of the member in the given text selection, + * or the original selection if none + * @exception CoreException + * if an exception occurs + */ + protected ISelection translateToMembers(IWorkbenchPart part, ISelection selection) throws CoreException { + ITextEditor textEditor = getTextEditor(part); + if (textEditor != null && selection instanceof ITextSelection) { + ITextSelection textSelection = (ITextSelection) selection; + IEditorInput editorInput = textEditor.getEditorInput(); + IDocumentProvider documentProvider = textEditor.getDocumentProvider(); + if (documentProvider == null) { + throw new CoreException(Status.CANCEL_STATUS); + } + IDocument document = documentProvider.getDocument(editorInput); + int offset = textSelection.getOffset(); + if (document != null) { + try { + IRegion region = document.getLineInformationOfOffset(offset); + int end = region.getOffset() + region.getLength(); + while (Character.isWhitespace(document.getChar(offset)) && offset < end) { + offset++; + } + } catch (BadLocationException e) {} + } + IMember m = null; + ITypeRoot root = getTypeRoot(editorInput); + if(root instanceof ICompilationUnit) { + ICompilationUnit unit = (ICompilationUnit) root; + synchronized (unit) { + unit.reconcile(ICompilationUnit.NO_AST , false, null, null); + } + } + if(root != null){ + IJavaElement e = root.getElementAt(offset); + if (e instanceof IMember) { + m = (IMember) e; + } + } + if (m != null) { + return new StructuredSelection(m); + } + } + return selection; + } + + /** + * Returns the {@link ITypeRoot} for the given {@link IEditorInput} + * @param input + * @return the type root or <code>null</code> if one cannot be derived + * @since 3.4 + */ + private ITypeRoot getTypeRoot(IEditorInput input) { + ITypeRoot root = input.getAdapter(IClassFile.class); + if(root == null) { + IWorkingCopyManager manager = JavaUI.getWorkingCopyManager(); + root = manager.getWorkingCopy(input); + } + if(root == null) { + root = DebugWorkingCopyManager.getWorkingCopy(input, false); + } + return root; + } + + /** * Return the associated IField (Java model) for the given * IJavaFieldVariable (JDI model) */ @@ -1149,7 +1344,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio */ @Override public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { - ISelection sel = BreakpointToggleUtils.translateToMembers(part, selection); + ISelection sel = translateToMembers(part, selection); if(sel instanceof IStructuredSelection) { IMember member = (IMember) ((IStructuredSelection)sel).getFirstElement(); int mtype = member.getElementType(); @@ -1169,13 +1364,18 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio } return; } - CompilationUnit unit = BreakpointToggleUtils.parseCompilationUnit(BreakpointToggleUtils.getTextEditor(part)); + CompilationUnit unit = parseCompilationUnit(getTextEditor(part)); ValidBreakpointLocationLocator loc = new ValidBreakpointLocationLocator(unit, ts.getStartLine()+1, true, true); unit.accept(loc); if(loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_METHOD) { toggleMethodBreakpoints(part, ts); } else if(loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_FIELD) { + if (BreakpointToggleUtils.isToggleTracepoints()) { + BreakpointToggleUtils.report(ActionMessages.TracepointToggleAction_Unavailable, part); + BreakpointToggleUtils.setUnsetTracepoints(false); + return; + } toggleWatchpoints(part, ts); } else if(loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_LINE) { @@ -1184,6 +1384,11 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio } } else if(member.getElementType() == IJavaElement.TYPE) { + if (BreakpointToggleUtils.isToggleTracepoints()) { + BreakpointToggleUtils.report(ActionMessages.TracepointToggleAction_Unavailable, part); + BreakpointToggleUtils.setUnsetTracepoints(false); + return; + } toggleClassBreakpoints(part, sel); } else { @@ -1294,7 +1499,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio public void toggleBreakpointsWithEvent(IWorkbenchPart part, ISelection selection, Event event) throws CoreException { if(event != null) { if((event.stateMask & SWT.MOD2) > 0) { - ITextEditor editor = BreakpointToggleUtils.getTextEditor(part); + ITextEditor editor = getTextEditor(part); if(editor != null) { IVerticalRulerInfo info = editor.getAdapter(IVerticalRulerInfo.class); if(info != null) { @@ -1307,7 +1512,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio } } else if((event.stateMask & SWT.MOD1) > 0) { - ITextEditor editor = BreakpointToggleUtils.getTextEditor(part); + ITextEditor editor = getTextEditor(part); if(editor != null) { IVerticalRulerInfo info = editor.getAdapter(IVerticalRulerInfo.class); if(info != null) { @@ -1335,4 +1540,68 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtensio public boolean canToggleBreakpointsWithEvent(IWorkbenchPart part, ISelection selection, Event event) { return canToggleBreakpoints(part, selection); } + + /** + * Returns the {@link ITypeRoot} for the given {@link IEditorInput} + * + * @param input + * @return the type root or <code>null</code> if one cannot be derived + * @since 3.8 + */ + private String getCodeTemplate(ITextSelection textSelection, CompilationUnitEditor part) { + TemplateContextType contextType = JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(JavaContextType.ID_STATEMENTS); + TemplateEngine fStatementEngine = new TemplateEngine(contextType); + fStatementEngine.reset(); + ITextViewer viewer = part.getViewer(); + final String[] fTemplateBuffer = new String[1]; + fTemplateBuffer[0] = null; + if (viewer != null) { + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + ITextEditor editor = getTextEditor(part); + if (editor != null) { + IJavaElement element = getJavaElement(editor.getEditorInput()); + ICompilationUnit cunit = null; + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IFile file = root.getFile(element.getPath()); + cunit = JavaCore.createCompilationUnitFrom(file); + IDocumentProvider documentProvider = editor.getDocumentProvider(); + if (documentProvider == null) { + return; + } + IDocument document = documentProvider.getDocument(editor.getEditorInput()); + try { + IRegion line = document.getLineInformation(textSelection.getStartLine() + 1); + Point selectedRange = viewer.getSelectedRange(); + viewer.setSelectedRange(selectedRange.x, 0); + fStatementEngine.complete(viewer, line.getOffset(), cunit); + viewer.setSelectedRange(selectedRange.x, selectedRange.y); + TemplateProposal[] templateProposals = fStatementEngine.getResults(); + for (TemplateProposal templateProposal : templateProposals) { + Template template = templateProposal.getTemplate(); + if (template.getName().equals("systrace")) { //$NON-NLS-1$ + CompilationUnitContextType contextType = (CompilationUnitContextType) JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(template.getContextTypeId()); + CompilationUnitContext context = contextType.createContext(document, line.getOffset(), 0, cunit); + context.setVariable("selection", EMPTY_STRING); //$NON-NLS-1$ + context.setForceEvaluation(true); + fTemplateBuffer[0] = context.evaluate(template).getString(); + return; + } + } + } + catch (BadLocationException e) { + e.printStackTrace(); + } + catch (TemplateException e1) { + e1.printStackTrace(); + } + + } + } + }); + } + return fTemplateBuffer[0]; + } + } |