diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnitHolder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnitHolder.java new file mode 100644 index 00000000000..29f978627fe --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnitHolder.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2013 Zeligsoft (2009) Limited. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.cdt.core.model; + +/** + * Represents a workbench object that is able to provide instances of ITranslationUnit. For + * example, the CEditor (in the CDT UI plugin) implements this interface in order to provide + * the IWorkingCopy of the editor's active translation unit. + * + * @since 5.6 + */ +public interface ITranslationUnitHolder { + /** + * Returns the translation unit that is provided by the receiver or null if there is no + * such translation unit. + */ + public ITranslationUnit getTranslationUnit(); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java index 209e91e9fc4..caa5742d74e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ASTProvider.java @@ -20,6 +20,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentExtension4; import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbenchPart; @@ -33,6 +34,7 @@ import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.ITranslationUnitHolder; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.model.ASTCache; @@ -41,7 +43,7 @@ import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; /** * Provides a shared AST for clients. The shared AST is * the AST of the active CEditor's input element. - * + * * @since 4.0 */ public final class ASTProvider { @@ -69,7 +71,7 @@ public final class ASTProvider { * wants to wait until an AST is ready. If the translation unit is not open no AST will * be provided. *

- * If not yet cached and if the translation unit is open, an AST will be created by + * If not yet cached and if the translation unit is open, an AST will be created by * this AST provider. *

*/ @@ -77,7 +79,7 @@ public final class ASTProvider { /** * Wait flag indicating that a client requesting an AST - * only wants to wait for the shared AST of the active editor. + * only wants to wait for the shared AST of the active editor. * If the translation unit is not open no AST will be provided. *

* No AST will be created by the AST provider. @@ -222,7 +224,17 @@ public final class ASTProvider { return false; String id= ref.getId(); - return CUIPlugin.EDITOR_ID.equals(id) || ref.getPart(false) instanceof CEditor; + if (CUIPlugin.EDITOR_ID.equals(id)) + return true; + + IWorkbenchPart part = ref.getPart(false); + if (part instanceof CEditor) + return true; + + // Other editors can behave as CEditors if they can provide a copy of their ITranslationUnit. + if (part instanceof IEditorPart) + return part.getAdapter(ITranslationUnitHolder.class) != null; + return false; } } @@ -233,7 +245,7 @@ public final class ASTProvider { /** * Returns the C plug-in's AST provider. - * + * * @return the AST provider */ public static ASTProvider getASTProvider() { @@ -264,14 +276,17 @@ public final class ASTProvider { } private void activeEditorChanged(IWorkbenchPart editor) { - ICElement cElement= null; - if (editor instanceof CEditor) { - cElement= ((CEditor) editor).getInputCElement(); + ITranslationUnit tu = null; + if (editor != null) { + ITranslationUnitHolder provider = (ITranslationUnitHolder) editor.getAdapter(ITranslationUnitHolder.class); + if (provider != null) + tu = provider.getTranslationUnit(); } + synchronized (this) { fActiveEditor= editor; fTimeStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; - fCache.setActiveElement((ITranslationUnit) cElement); + fCache.setActiveElement(tu); } } @@ -343,7 +358,7 @@ public final class ASTProvider { * Executes {@link ASTRunnable#runOnAST(ILanguage, IASTTranslationUnit)} * with the shared AST for the given translation unit. Handles acquiring * and releasing the index read-lock for the client. - * + * * @param cElement the translation unit * @param waitFlag condition for waiting for the AST to be built. * @param monitor a progress monitor, may be null @@ -368,7 +383,7 @@ public final class ASTProvider { *

* An index lock must be held by the caller when calling this method. The index lock may * not be released until the AST is released. - * + * * @param tu The translation unit to get the AST for. * @param index index with read lock held. * @param waitFlag condition for waiting for the AST to be built. @@ -396,7 +411,7 @@ public final class ASTProvider { /** * Prepares the AST cache to be used for the given translation unit. - * + * * @param tu the translation unit. * @param waitFlag condition for waiting for the AST to be built. * @return true if the AST cache can be used for the given translation unit, @@ -407,7 +422,7 @@ public final class ASTProvider { return false; // http://bugs.eclipse.org/bugs/show_bug.cgi?id=342506 explains - // benign nature of the race conditions in the code below. + // benign nature of the race conditions in the code below. final boolean isActive= fCache.isActiveElement(tu); if (waitFlag == WAIT_ACTIVE_ONLY && !isActive) { return false; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java index d3e294133a6..f8ade41240f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java @@ -184,6 +184,7 @@ import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.ITranslationUnitHolder; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.ICEditor; @@ -241,7 +242,7 @@ import org.eclipse.cdt.internal.ui.viewsupport.SelectionListenerWithASTManager; /** * C/C++ source editor. */ -public class CEditor extends TextEditor implements ICEditor, ISelectionChangedListener, ICReconcilingListener { +public class CEditor extends TextEditor implements ICEditor, ISelectionChangedListener, ICReconcilingListener, ITranslationUnitHolder { /** Marker used for synchronization from Problems View to the editor on double-click. */ private IMarker fSyncProblemsViewMarker; @@ -1514,6 +1515,11 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi return CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(getEditorInput()); } + @Override + public ITranslationUnit getTranslationUnit() { + return getInputCElement(); + } + /** * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() */ @@ -1575,7 +1581,8 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi fTemplatesPage = new CTemplatesPage(this); } return fTemplatesPage; - } + } else if (adapterClass.isAssignableFrom(ITranslationUnitHolder.class)) + return this; return super.getAdapter(adapterClass); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java index 7adfed80841..14993394eec 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java @@ -89,8 +89,8 @@ public class SelectionParseAction extends Action { clearStatusLine(); IEditorPart editor = EditorUtility.openInEditor(path, fEditor.getInputCElement()); - if (editor instanceof ITextEditor) { - ITextEditor textEditor = (ITextEditor) editor; + ITextEditor textEditor = EditorUtility.getTextEditor(editor); + if (textEditor != null) { textEditor.selectAndReveal(currentOffset, currentLength); } else { reportSourceFileOpenFailure(path); @@ -101,8 +101,8 @@ public class SelectionParseAction extends Action { clearStatusLine(); IEditorPart editor = EditorUtility.openInEditor(tu, true); - if (editor instanceof ITextEditor) { - ITextEditor textEditor = (ITextEditor) editor; + ITextEditor textEditor = EditorUtility.getTextEditor(editor); + if (textEditor != null) { textEditor.selectAndReveal(currentOffset, currentLength); } else { reportSourceFileOpenFailure(tu.getPath()); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java index d55ab6e0bc2..01213d138a2 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java @@ -338,7 +338,7 @@ public class EditorUtility { IEditorInput input= getEditorInputForLocation(location, element); return EditorUtility.openInEditor(input, getEditorID(input, element), activate); } - + public static IEditorPart openInEditor(URI locationURI, ICElement element) throws PartInitException { IEditorInput input= getEditorInputForLocation(locationURI, element); return EditorUtility.openInEditor(input, getEditorID(input, element), true); @@ -376,7 +376,7 @@ public class EditorUtility { IPath path = URIUtil.toPath(locationURI); if(path == null) path = new Path(locationURI.getPath()); - + if (includeReferences[j].isOnIncludeEntry(path)) { context = projects[i]; break outerFor; @@ -405,7 +405,7 @@ public class EditorUtility { e.printStackTrace(); return null; } - + if(fileStore != null) return new ExternalEditorInput(unit); } @@ -486,18 +486,18 @@ public class EditorUtility { IFile file= ResourceLookup.selectFileForLocation(location, project); if (file != null && file.isAccessible()) return file; - + IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); // workaround http://bugs.eclipse.org/233939 file= root.getFileForLocation(location); - if (file != null && file.isAccessible()) + if (file != null && file.isAccessible()) return file; // try workspace relative path if (location.segmentCount() >= 2) { // @see IContainer#getFile for the required number of segments file= root.getFile(location); - if (file != null && file.isAccessible()) + if (file != null && file.isAccessible()) return file; } return null; @@ -520,14 +520,14 @@ public class EditorUtility { project= cProject.getProject(); } } - + IFile file= ResourceLookup.selectFileForLocationURI(locationURI, project); if (file != null && file.isAccessible()) return file; - + return null; } - + /** * If the current active editor edits a c element return it, else * return null @@ -722,7 +722,7 @@ public class EditorUtility { String newModifierString= Action.findModifierString(modifier); if (modifierString.length() == 0) return newModifierString; - return NLS.bind(CEditorMessages.EditorUtility_concatModifierStrings, new String[] {modifierString, newModifierString}); + return NLS.bind(CEditorMessages.EditorUtility_concatModifierStrings, new String[] {modifierString, newModifierString}); } public static IStorage getStorage(IBinary bin) { @@ -869,10 +869,10 @@ public class EditorUtility { } } - if (!(ep instanceof ITextEditor)) + ITextEditor textEditor = getTextEditor(ep); + if (textEditor == null) return saveUnknownEditors; - ITextEditor textEditor= (ITextEditor) ep; IDocumentProvider documentProvider= textEditor.getDocumentProvider(); if (!(documentProvider instanceof TextFileDocumentProvider)) return saveUnknownEditors; @@ -885,7 +885,7 @@ public class EditorUtility { * last save occurred. Each region in the result spans over the size of at least one line. * If successive lines have changed a region spans over the size of all successive lines. * The regions include line delimiters. - * + * * @param buffer the buffer to compare contents from * @param monitor to report progress to * @return the regions of the changed lines @@ -896,7 +896,7 @@ public class EditorUtility { final IProgressMonitor monitor) throws CoreException { final IRegion[][] result= new IRegion[1][]; final IStatus[] errorStatus= new IStatus[] { Status.OK_STATUS }; - + try { SafeRunner.run(new ISafeRunnable() { /* @@ -912,7 +912,7 @@ public class EditorUtility { ICStatusConstants.EDITOR_CHANGED_REGION_CALCULATION, msg, exception); result[0]= null; } - + /* * @see org.eclipse.core.runtime.ISafeRunnable#run() */ @@ -920,14 +920,14 @@ public class EditorUtility { public void run() throws Exception { monitor.beginTask(Messages.EditorUtility_calculatingChangedRegions_message, 20); IFileStore fileStore= buffer.getFileStore(); - + ITextFileBufferManager fileBufferManager= FileBuffers.createTextFileBufferManager(); fileBufferManager.connectFileStore(fileStore, getSubProgressMonitor(monitor, 15)); try { IDocument currentDocument= buffer.getDocument(); - IDocument oldDocument= + IDocument oldDocument= ((ITextFileBuffer) fileBufferManager.getFileStoreFileBuffer(fileStore)).getDocument(); - + result[0]= getChangedLineRegions(oldDocument, currentDocument); } finally { fileBufferManager.disconnectFileStore(fileStore, getSubProgressMonitor(monitor, 5)); @@ -938,7 +938,7 @@ public class EditorUtility { /** * Return regions of all lines which differ comparing oldDocuments content * with currentDocuments content. Successive lines are merged into one region. - * + * * @param oldDocument a document containing the old content * @param currentDocument a document containing the current content * @return the changed regions @@ -973,7 +973,7 @@ public class EditorUtility { startLineRegion = currentDocument.getLineInformation(startLine); if (startLine >= endLine) { // startLine > endLine indicates a deletion of one or more lines. - // Deletions are ignored except at the end of the document. + // Deletions are ignored except at the end of the document. if (startLine == endLine || startLineRegion.getOffset() + startLineRegion.getLength() == currentDocument.getLength()) { regions.add(startLineRegion); @@ -997,7 +997,7 @@ public class EditorUtility { if (!errorStatus[0].isOK()) throw new CoreException(errorStatus[0]); } - + return result[0]; } @@ -1015,13 +1015,13 @@ public class EditorUtility { return new NullProgressMonitor(); } - - + + /** * Returns the project contains the resource, which is currently open in the active editor. - * If the active part is no ITextEditor or if the editorInput is no FileEditorInput, + * If the active part is no ITextEditor or if the editorInput is no FileEditorInput, * null is returned. - * + * * @return the project which the selected editor input belongs to or null */ public static IProject getProjectForActiveEditor() { @@ -1030,9 +1030,9 @@ public class EditorUtility { if(window != null) { IWorkbenchPage activePage = window.getActivePage(); if(activePage != null) { - IEditorPart activeEditor = activePage.getActiveEditor(); - if(activeEditor instanceof ITextEditor) { - IEditorInput editorInput = ((ITextEditor)activeEditor).getEditorInput(); + ITextEditor activeEditor = getTextEditor(activePage.getActiveEditor()); + if (activeEditor != null) { + IEditorInput editorInput = activeEditor.getEditorInput(); IFile file = ResourceUtil.getFile(editorInput); if(file != null) { project = file.getProject(); @@ -1042,4 +1042,14 @@ public class EditorUtility { } return project; } + + /** + * Tries to convert the given editor to an implementation of ITextEditor. Returns that implementation + * if possible and null otherwise. + * + * @param editor The editor to be converted or null if there is nothing to convert. + */ + public static ITextEditor getTextEditor(IEditorPart editor) { + return editor == null ? null : (ITextEditor) editor.getAdapter(ITextEditor.class); + } }