Skip to content

Commit ddca7a0

Browse files
danthe1sttrancexpress
authored andcommitted
Allow highlighting instructions in ClassFileEditor
1 parent 85e6c77 commit ddca7a0

4 files changed

Lines changed: 322 additions & 2 deletions

File tree

org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/AutomatedSuite.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2025 IBM Corporation and others.
2+
* Copyright (c) 2000, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -34,6 +34,7 @@
3434
import org.eclipse.jdt.ui.tests.core.CoreTestSuite;
3535
import org.eclipse.jdt.ui.tests.core.CoreTests;
3636
import org.eclipse.jdt.ui.tests.dialogs.FilteredTypesSelectionDialogTests;
37+
import org.eclipse.jdt.ui.tests.editor.ClassFileEditorTests;
3738
import org.eclipse.jdt.ui.tests.editor.ClassFileInputTests;
3839
import org.eclipse.jdt.ui.tests.editor.MarkdownTypingTest;
3940
import org.eclipse.jdt.ui.tests.hover.JavadocHoverTests;
@@ -92,6 +93,7 @@
9293
MarkdownCommentTests.class,
9394
SmokeViewsTest.class,
9495
ClassFileInputTests.class,
96+
ClassFileEditorTests.class,
9597
FilteredTypesSelectionDialogTests.class,
9698
MarkdownTypingTest.class
9799
})
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026, Daniel Schmid and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Daniel Schmid - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.jdt.ui.tests.editor;
15+
16+
import static org.junit.jupiter.api.Assertions.assertEquals;
17+
import static org.junit.jupiter.api.Assertions.assertFalse;
18+
19+
import org.junit.jupiter.api.AfterEach;
20+
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.Test;
22+
23+
import org.eclipse.jdt.testplugin.JavaProjectHelper;
24+
25+
import org.eclipse.swt.custom.StyleRange;
26+
import org.eclipse.swt.custom.StyledText;
27+
import org.eclipse.swt.custom.StyledTextContent;
28+
29+
import org.eclipse.core.runtime.CoreException;
30+
import org.eclipse.core.runtime.NullProgressMonitor;
31+
32+
import org.eclipse.core.resources.IncrementalProjectBuilder;
33+
34+
import org.eclipse.jdt.core.IJavaProject;
35+
import org.eclipse.jdt.core.IPackageFragment;
36+
37+
import org.eclipse.jdt.internal.ui.JavaPlugin;
38+
import org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor;
39+
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
40+
import org.eclipse.jdt.internal.ui.util.CoreUtility;
41+
42+
public class ClassFileEditorTests {
43+
private static final String TYPE_NAME= "HelloWorld";
44+
45+
private IJavaProject javaProject;
46+
private boolean wasAutoBuilding;
47+
48+
@BeforeEach
49+
void setUp() throws Exception {
50+
javaProject = setUpProject();
51+
52+
wasAutoBuilding = CoreUtility.setAutoBuilding(false);
53+
}
54+
55+
@AfterEach
56+
void tearDown() throws Exception {
57+
JavaPlugin.getActivePage().closeAllEditors(false);
58+
if (javaProject != null) {
59+
JavaProjectHelper.delete(javaProject);
60+
}
61+
CoreUtility.setAutoBuilding(wasAutoBuilding);
62+
}
63+
64+
private IJavaProject setUpProject() throws Exception {
65+
javaProject= JavaProjectHelper.createJavaProject(ClassFileEditorTests.class.getSimpleName(), "bin");
66+
JavaProjectHelper.addSourceContainer(javaProject, "src");
67+
JavaProjectHelper.addRTJar(javaProject);
68+
return javaProject;
69+
}
70+
71+
@Test
72+
void testHighlightRange() throws CoreException {
73+
createHelloWorldClass();
74+
ClassFileEditor classEditor= createClassFileEditor(TYPE_NAME);
75+
classEditor.highlightInstruction("main", "([Ljava/lang/String;)V", 5);
76+
assertEquals(" 5 invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]", getSingleHighlightedRange(classEditor));
77+
}
78+
79+
@Test
80+
void testHighlightInConstructor() throws CoreException {
81+
createHelloWorldClass();
82+
ClassFileEditor classEditor= createClassFileEditor(TYPE_NAME);
83+
classEditor.highlightInstruction(TYPE_NAME, "()V", 1);
84+
assertEquals(" 1 invokespecial java.lang.Object() [8]", getSingleHighlightedRange(classEditor));
85+
}
86+
87+
@Test
88+
void testChangeHighlightRange() throws CoreException {
89+
createHelloWorldClass();
90+
ClassFileEditor classEditor= createClassFileEditor(TYPE_NAME);
91+
classEditor.highlightInstruction("main", "([Ljava/lang/String;)V", 5);
92+
classEditor.highlightInstruction("main", "([Ljava/lang/String;)V", 0);
93+
assertEquals(" 0 getstatic java.lang.System.out : java.io.PrintStream [16]", getSingleHighlightedRange(classEditor));
94+
}
95+
96+
@Test
97+
void testUnhighlight() throws CoreException {
98+
createHelloWorldClass();
99+
ClassFileEditor classEditor= createClassFileEditor(TYPE_NAME);
100+
classEditor.highlightInstruction("main", "([Ljava/lang/String;)V", 5);
101+
StyledText noSourceTextWidget= classEditor.getNoSourceTextWidget();
102+
assertEquals(1, noSourceTextWidget.getStyleRanges().length);
103+
classEditor.unhighlight();
104+
assertEquals(0, noSourceTextWidget.getStyleRanges().length);
105+
}
106+
107+
@Test
108+
void testHighlightNonexistentCodeIndex() throws CoreException {
109+
createHelloWorldClass();
110+
ClassFileEditor classEditor= createClassFileEditor(TYPE_NAME);
111+
classEditor.highlightInstruction("main", "([Ljava/lang/String;)V", 100);
112+
StyledText noSourceTextWidget= classEditor.getNoSourceTextWidget();
113+
assertEquals(0, noSourceTextWidget.getStyleRanges().length);
114+
}
115+
116+
@Test
117+
void testHighlightNonexistentMethod() throws CoreException {
118+
createHelloWorldClass();
119+
ClassFileEditor classEditor= createClassFileEditor(TYPE_NAME);
120+
classEditor.highlightInstruction("main", "a", 5);
121+
assertEquals(0, classEditor.getNoSourceTextWidget().getStyleRanges().length);
122+
}
123+
124+
@Test
125+
void testHighlightMultipleCompilationUnits() throws CoreException {
126+
createClassFromSource("A.java", """
127+
public class A {
128+
void a() {
129+
System.out.println("a");
130+
}
131+
}
132+
class B {
133+
void b() {
134+
System.out.println("b");
135+
}
136+
}
137+
""");
138+
ClassFileEditor classEditor= createClassFileEditor("A");
139+
classEditor.highlightInstruction("a", "()V", 3);
140+
assertEquals(" 3 ldc <String \"a\"> [21]", getSingleHighlightedRange(classEditor));
141+
142+
classEditor= createClassFileEditor("B");
143+
classEditor.highlightInstruction("b", "()V", 3);
144+
assertEquals(" 3 ldc <String \"b\"> [21]", getSingleHighlightedRange(classEditor));
145+
146+
}
147+
148+
private String getSingleHighlightedRange(ClassFileEditor classEditor) {
149+
StyledText noSourceTextWidget= classEditor.getNoSourceTextWidget();
150+
StyleRange[] ranges= noSourceTextWidget.getStyleRanges();
151+
assertEquals(1, ranges.length);
152+
StyledTextContent content= noSourceTextWidget.getContent();
153+
StyleRange range= ranges[0];
154+
return content.getTextRange(range.start, range.length);
155+
}
156+
157+
private void createHelloWorldClass() throws CoreException {
158+
createClassFromSource(TYPE_NAME + ".java", """
159+
public class HelloWorld {
160+
public static void main(String[] args) {
161+
System.out.println("Hello World");
162+
}
163+
}
164+
""");
165+
}
166+
167+
private void createClassFromSource(String fileName, String content) throws CoreException {
168+
IPackageFragment fragment= javaProject.findPackageFragment(javaProject.getProject().getFullPath().append("src"));
169+
fragment.createCompilationUnit(fileName, content, true, new NullProgressMonitor());
170+
javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
171+
javaProject.getProject().getFile("src/" + fileName).delete(true,new NullProgressMonitor());
172+
}
173+
174+
private ClassFileEditor createClassFileEditor(String typeName) throws CoreException {
175+
ClassFileEditor editor= (ClassFileEditor) EditorUtility.openInEditor(javaProject.getProject().getFile("bin/" + typeName + ".class"));
176+
assertFalse(editor.isEditable());
177+
return editor;
178+
}
179+
}

org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/IUIConstants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ public interface IUIConstants {
3030

3131
String DIALOGSTORE_TYPECOMMENT_DEPRECATED= JavaUI.ID_PLUGIN + ".typecomment.deprecated"; //$NON-NLS-1$
3232

33+
// The preference is defined in the org.eclipse.debug.ui plugin.xml file
34+
String INSTRUCTION_POINTER_COLOR_PREFERENCE_KEY= "currentIPColor"; //$NON-NLS-1$
35+
3336
}

0 commit comments

Comments
 (0)