blob: fdf9f35337f4681ef6aef969ef11a712fccc8baa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.manipulation.CoreASTProvider;
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.internal.ui.JavaPlugin;
/**
* Provides a shared AST for clients. The shared AST is
* the AST of the active Java editor's input element.
*
* @since 3.0
*/
public final class ASTProvider implements IASTSharedValues {
private static final CoreASTProvider INSTANCE= CoreASTProvider.getInstance();
/**
* Internal activation listener.
*
* @since 3.0
*/
private class ActivationListener implements IPartListener2, IWindowListener {
/*
* @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partActivated(IWorkbenchPartReference ref) {
if (isJavaEditor(ref) && !isActiveEditor(ref))
activeJavaEditorChanged(ref.getPart(true));
}
/*
* @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partBroughtToTop(IWorkbenchPartReference ref) {
if (isJavaEditor(ref) && !isActiveEditor(ref))
activeJavaEditorChanged(ref.getPart(true));
}
/*
* @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partClosed(IWorkbenchPartReference ref) {
if (isActiveEditor(ref)) {
if (JavaPlugin.DEBUG_AST_PROVIDER)
System.out.println(CoreASTProvider.getThreadName() + " - " + CoreASTProvider.DEBUG_PREFIX + "closed active editor: " + ref.getTitle()); //$NON-NLS-1$ //$NON-NLS-2$
activeJavaEditorChanged(null);
}
}
/*
* @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partDeactivated(IWorkbenchPartReference ref) {
}
/*
* @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partOpened(IWorkbenchPartReference ref) {
if (isJavaEditor(ref) && !isActiveEditor(ref))
activeJavaEditorChanged(ref.getPart(true));
}
/*
* @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partHidden(IWorkbenchPartReference ref) {
}
/*
* @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partVisible(IWorkbenchPartReference ref) {
if (isJavaEditor(ref) && !isActiveEditor(ref))
activeJavaEditorChanged(ref.getPart(true));
}
/*
* @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partInputChanged(IWorkbenchPartReference ref) {
if (isJavaEditor(ref) && isActiveEditor(ref))
activeJavaEditorChanged(ref.getPart(true));
}
/*
* @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
*/
@Override
public void windowActivated(IWorkbenchWindow window) {
IWorkbenchPartReference ref= window.getPartService().getActivePartReference();
if (isJavaEditor(ref) && !isActiveEditor(ref))
activeJavaEditorChanged(ref.getPart(true));
}
/*
* @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
*/
@Override
public void windowDeactivated(IWorkbenchWindow window) {
}
/*
* @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
*/
@Override
public void windowClosed(IWorkbenchWindow window) {
if (fActiveEditor != null && fActiveEditor.getSite() != null && window == fActiveEditor.getSite().getWorkbenchWindow()) {
if (JavaPlugin.DEBUG_AST_PROVIDER)
System.out.println(CoreASTProvider.getThreadName() + " - " + CoreASTProvider.DEBUG_PREFIX + "closed active editor: " + fActiveEditor.getTitle()); //$NON-NLS-1$ //$NON-NLS-2$
activeJavaEditorChanged(null);
}
window.getPartService().removePartListener(this);
}
/*
* @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
*/
@Override
public void windowOpened(IWorkbenchWindow window) {
window.getPartService().addPartListener(this);
}
private boolean isActiveEditor(IWorkbenchPartReference ref) {
return ref != null && isActiveEditor(ref.getPart(false));
}
private boolean isActiveEditor(IWorkbenchPart part) {
return part != null && (part == fActiveEditor);
}
private boolean isJavaEditor(IWorkbenchPartReference ref) {
if (ref == null)
return false;
String id= ref.getId();
// The instanceof check is not need but helps clients, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84862
return JavaUI.ID_CF_EDITOR.equals(id) || JavaUI.ID_CU_EDITOR.equals(id) || ref.getPart(false) instanceof JavaEditor;
}
}
private ActivationListener fActivationListener;
private IWorkbenchPart fActiveEditor;
/**
* Returns the Java plug-in's AST provider.
*
* @return the AST provider
* @since 3.2
*/
public static ASTProvider getASTProvider() {
return JavaPlugin.getDefault().getASTProvider();
}
/**
* Creates a new AST provider.
*/
public ASTProvider() {
install();
}
/**
* Installs this AST provider.
*/
void install() {
// Create and register activation listener
fActivationListener= new ActivationListener();
PlatformUI.getWorkbench().addWindowListener(fActivationListener);
// Ensure existing windows get connected
IWorkbenchWindow[] windows= PlatformUI.getWorkbench().getWorkbenchWindows();
for (IWorkbenchWindow window : windows)
window.getPartService().addPartListener(fActivationListener);
}
void activeJavaEditorChanged(IWorkbenchPart editor) {
ITypeRoot javaElement= null;
if (editor instanceof JavaEditor)
javaElement= ((JavaEditor)editor).getInputJavaElement();
synchronized (this) {
fActiveEditor= editor;
INSTANCE.setActiveJavaElement(javaElement);
INSTANCE.cache(null, javaElement);
}
if (JavaPlugin.DEBUG_AST_PROVIDER)
System.out.println(CoreASTProvider.getThreadName() + " - " + CoreASTProvider.DEBUG_PREFIX + "active editor is: " + INSTANCE.toString(javaElement)); //$NON-NLS-1$ //$NON-NLS-2$
if ((INSTANCE.isReconciling() && (INSTANCE.getReconcilingJavaElement() == null || !INSTANCE.getReconcilingJavaElement().equals(javaElement)))
|| (javaElement == null)) {
INSTANCE.clearReconciliation();
}
}
/**
* Returns whether the given compilation unit AST is
* cached by this AST provided.
*
* @param ast the compilation unit AST
* @return <code>true</code> if the given AST is the cached one
*/
public boolean isCached(CompilationUnit ast) {
return ast != null && INSTANCE.getCachedAST() == ast;
}
/**
* Returns whether this AST provider is active on the given
* compilation unit.
*
* @param cu the compilation unit
* @return <code>true</code> if the given compilation unit is the active one
* @since 3.1
*/
public synchronized boolean isActive(ICompilationUnit cu) {
return cu != null && cu.equals(INSTANCE.getActiveJavaElement());
}
/**
* Disposes this AST provider.
*/
public void dispose() {
// Dispose activation listener
PlatformUI.getWorkbench().removeWindowListener(fActivationListener);
fActivationListener= null;
INSTANCE.disposeAST();
INSTANCE.waitLockNotifyAll();
}
}