Skip to content

Commit 03ac39b

Browse files
laeubiiloveeclipse
authored andcommitted
Restore original type from class file input in background
Fixes #2245
1 parent 6b8dd2b commit 03ac39b

2 files changed

Lines changed: 72 additions & 49 deletions

File tree

org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/ClassFileDocumentProvider.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ public ClassFileDocumentProvider() {
209209
protected boolean setDocumentContent(IDocument document, IEditorInput editorInput, String encoding) throws CoreException {
210210
if (editorInput instanceof IClassFileEditorInput) {
211211
IClassFile classFile= ((IClassFileEditorInput) editorInput).getClassFile();
212-
String source= classFile.getSource();
212+
String source= getSourceIfPresent(classFile);
213213
if (source == null)
214214
source= ""; //$NON-NLS-1$
215215
document.set(source);
@@ -218,6 +218,15 @@ protected boolean setDocumentContent(IDocument document, IEditorInput editorInpu
218218
return super.setDocumentContent(document, editorInput, encoding);
219219
}
220220

221+
private String getSourceIfPresent(IClassFile classFile) {
222+
try {
223+
return classFile.getSource();
224+
} catch (JavaModelException e) {
225+
//Assume no source...
226+
return null;
227+
}
228+
}
229+
221230
/**
222231
* Creates an annotation model derived from the given class file editor input.
223232
*

org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/ClassFileEditor.java

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.eclipse.core.runtime.IPath;
4040
import org.eclipse.core.runtime.IProgressMonitor;
4141
import org.eclipse.core.runtime.IStatus;
42+
import org.eclipse.core.runtime.OperationCanceledException;
4243
import org.eclipse.core.runtime.Status;
4344
import org.eclipse.core.runtime.jobs.Job;
4445

@@ -73,10 +74,12 @@
7374
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
7475

7576
import org.eclipse.jdt.core.ClasspathContainerInitializer;
77+
import org.eclipse.jdt.core.ElementChangedEvent;
7678
import org.eclipse.jdt.core.IClassFile;
7779
import org.eclipse.jdt.core.IClasspathAttribute;
7880
import org.eclipse.jdt.core.IClasspathContainer;
7981
import org.eclipse.jdt.core.IClasspathEntry;
82+
import org.eclipse.jdt.core.IElementChangedListener;
8083
import org.eclipse.jdt.core.IJavaElement;
8184
import org.eclipse.jdt.core.IJavaModelStatusConstants;
8285
import org.eclipse.jdt.core.IJavaProject;
@@ -111,6 +114,52 @@
111114
* Java specific text editor.
112115
*/
113116
public 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

Comments
 (0)