3939import org .eclipse .core .runtime .IPath ;
4040import org .eclipse .core .runtime .IProgressMonitor ;
4141import org .eclipse .core .runtime .IStatus ;
42+ import org .eclipse .core .runtime .OperationCanceledException ;
4243import org .eclipse .core .runtime .Status ;
4344import org .eclipse .core .runtime .jobs .Job ;
4445
7374import org .eclipse .ui .texteditor .ITextEditorActionConstants ;
7475
7576import org .eclipse .jdt .core .ClasspathContainerInitializer ;
77+ import org .eclipse .jdt .core .ElementChangedEvent ;
7678import org .eclipse .jdt .core .IClassFile ;
7779import org .eclipse .jdt .core .IClasspathAttribute ;
7880import org .eclipse .jdt .core .IClasspathContainer ;
7981import org .eclipse .jdt .core .IClasspathEntry ;
82+ import org .eclipse .jdt .core .IElementChangedListener ;
8083import org .eclipse .jdt .core .IJavaElement ;
8184import org .eclipse .jdt .core .IJavaModelStatusConstants ;
8285import org .eclipse .jdt .core .IJavaProject ;
111114 * Java specific text editor.
112115 */
113116public class ClassFileEditor extends JavaEditor implements ClassFileDocumentProvider .InputChangeListener {
117+ private final class LoadJob extends Job implements IElementChangedListener {
118+ private final IJavaElement fElement ;
119+
120+ private LoadJob (IJavaElement element ) {
121+ super ("Check the element in the background" ); //$NON-NLS-1$
122+ fElement = element ;
123+ }
124+
125+ @ Override
126+ protected IStatus run (IProgressMonitor monitor ) {
127+ try {
128+ Job .getJobManager ().join (ClasspathContainerInitializer .class , null );
129+ } catch (OperationCanceledException | InterruptedException e ) {
130+ // Ignore
131+ }
132+ try {
133+ if (!fElement .exists () && fElement instanceof IOrdinaryClassFile ) {
134+ /*
135+ * Let's try to find the class file,
136+ * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=83221
137+ */
138+ IOrdinaryClassFile cf = (IOrdinaryClassFile )fElement ;
139+ IType type = cf .getType ();
140+ IJavaProject project = fElement .getJavaProject ();
141+ if (project != null ) {
142+ type = project .findType (type .getFullyQualifiedName ());
143+ if (type == null ) {
144+ } else {
145+ JavaCore .removeElementChangedListener (this );
146+ IEditorInput editorInput = EditorUtility .getEditorInput (type .getParent ());
147+ Display .getDefault ().asyncExec (()->setInput (editorInput ));
148+ }
149+ }
150+ }
151+ } catch (CoreException e ) {
152+ return e .getStatus ();
153+ }
154+ return Status .OK_STATUS ;
155+ }
156+
157+ @ Override
158+ public void elementChanged (ElementChangedEvent event ) {
159+ schedule ();
160+ }
161+ }
162+
114163 /**
115164 * A form to attach source to a class file.
116165 */
@@ -644,21 +693,9 @@ public boolean isEditorInputReadOnly() {
644693 protected IEditorInput transformEditorInput (IEditorInput input ) throws CoreException {
645694 if (input instanceof HandleEditorInput handle ) {
646695 IJavaElement element = handle .getElement ();
647- if (!element .exists () && element instanceof IOrdinaryClassFile ) {
648- /*
649- * Let's try to find the class file,
650- * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=83221
651- */
652- IOrdinaryClassFile cf = (IOrdinaryClassFile )element ;
653- IType type = cf .getType ();
654- IJavaProject project = element .getJavaProject ();
655- if (project != null ) {
656- type = project .findType (type .getFullyQualifiedName ());
657- if (type == null )
658- return null ;
659- element = type .getParent ();
660- }
661- }
696+ LoadJob job = new LoadJob (element );
697+ JavaCore .addElementChangedListener (job );
698+ job .schedule ();
662699 input = EditorUtility .getEditorInput (element );
663700 }
664701 if (input instanceof IFileEditorInput ) {
@@ -694,21 +731,6 @@ private void doSetInputCached(IEditorInput input) throws CoreException {
694731 message ,
695732 null ));
696733 }
697-
698- JavaModelException e = probeInputForSource (input );
699- if (e != null ) {
700- IClassFileEditorInput classFileEditorInput = (IClassFileEditorInput ) input ;
701- IClassFile file = classFileEditorInput .getClassFile ();
702- IJavaProject javaProject = file .getJavaProject ();
703- if (!javaProject .exists () || !javaProject .isOnClasspath (file )) {
704- throw new CoreException (JavaUIStatus .createError (
705- IJavaModelStatusConstants .INVALID_RESOURCE ,
706- JavaEditorMessages .ClassFileEditor_error_classfile_not_on_classpath ,
707- null ));
708- }
709- throw e ;
710- }
711-
712734 IDocumentProvider documentProvider = getDocumentProvider ();
713735 if (documentProvider instanceof ClassFileDocumentProvider ) {
714736 ((ClassFileDocumentProvider ) documentProvider ).removeInputChangeListener (this );
@@ -799,23 +821,6 @@ private void createPartControlCached(Composite parent) {
799821 }
800822 }
801823
802- private JavaModelException probeInputForSource (IEditorInput input ) {
803- if (input == null ) {
804- return null ;
805- }
806-
807- IClassFileEditorInput classFileEditorInput = (IClassFileEditorInput ) input ;
808- IClassFile file = classFileEditorInput .getClassFile ();
809-
810- try {
811- file .getSourceRange ();
812- } catch (JavaModelException e ) {
813- return e ;
814- }
815-
816- return null ;
817- }
818-
819824 /**
820825 * Checks if the class file input has no source attached. If so, a source attachment form is shown.
821826 *
@@ -836,7 +841,7 @@ private void verifyInput(IEditorInput input) throws JavaModelException {
836841 boolean wasUsingSourceCopyAction = fSourceCopyAction == getAction (ITextEditorActionConstants .COPY );
837842
838843 // show source attachment form if no source found
839- if (file . getSourceRange () == null ) {
844+ if (! hasSource ( file ) ) {
840845 // dispose old source attachment form
841846 if (fSourceAttachmentForm != null ) {
842847 fSourceAttachmentForm .dispose ();
@@ -925,6 +930,15 @@ public void run() {
925930 }
926931 }
927932
933+ private static boolean hasSource (IClassFile file ) {
934+ try {
935+ return file .getSourceRange () != null ;
936+ } catch (JavaModelException e ) {
937+ //assume no source then...
938+ return false ;
939+ }
940+ }
941+
928942 /*
929943 * @see ClassFileDocumentProvider.InputChangeListener#inputChanged(IClassFileEditorInput)
930944 */
0 commit comments