1111 *******************************************************************************/
1212package org .eclipse .lsp4e .jdt ;
1313
14+ import java .io .BufferedReader ;
15+ import java .io .IOException ;
16+ import java .io .InputStreamReader ;
17+ import java .net .URL ;
18+
19+ import org .eclipse .core .runtime .FileLocator ;
20+ import org .eclipse .core .runtime .IProgressMonitor ;
1421import org .eclipse .jdt .annotation .Nullable ;
1522import org .eclipse .jdt .internal .codeassist .RelevanceConstants ;
23+ import org .eclipse .jdt .internal .ui .text .java .AbstractJavaCompletionProposal ;
24+ import org .eclipse .jdt .internal .ui .text .java .hover .JavadocBrowserInformationControlInput ;
25+ import org .eclipse .jdt .internal .ui .text .java .hover .JavadocHover ;
26+ import org .eclipse .jdt .ui .PreferenceConstants ;
1627import org .eclipse .jdt .ui .text .java .IJavaCompletionProposal ;
17- import org .eclipse .jface .text .IDocument ;
18- import org .eclipse .jface .text .contentassist .ICompletionProposal ;
19- import org .eclipse .jface .text .contentassist .IContextInformation ;
28+ import org .eclipse .jface .internal .text .html .BrowserInformationControl ;
29+ import org .eclipse .jface .internal .text .html .HTMLPrinter ;
30+ import org .eclipse .jface .resource .ColorRegistry ;
31+ import org .eclipse .jface .resource .JFaceResources ;
32+ import org .eclipse .jface .text .IInformationControlCreator ;
33+ import org .eclipse .lsp4e .LanguageServerPlugin ;
2034import org .eclipse .lsp4e .operations .completion .LSCompletionProposal ;
21- import org .eclipse .swt .graphics .Image ;
22- import org .eclipse .swt .graphics .Point ;
35+ import org .eclipse .lsp4e .ui .UI ;
36+ import org .eclipse .swt .graphics .FontData ;
37+ import org .eclipse .swt .graphics .RGB ;
38+ import org .eclipse .swt .widgets .Shell ;
39+ import org .eclipse .ui .IWorkbenchPart ;
40+ import org .osgi .framework .Bundle ;
41+ import org .osgi .framework .FrameworkUtil ;
2342
2443@ SuppressWarnings ("restriction" )
25- class LSJavaProposal implements IJavaCompletionProposal {
44+ class LSJavaProposal extends LSCompletionProposal implements IJavaCompletionProposal {
2645
2746 private static final int LS_DEFAULT_RELEVANCE = 18 ;
2847
@@ -33,51 +52,23 @@ class LSJavaProposal implements IJavaCompletionProposal {
3352
3453 private static final int RANGE_WITHIN_CATEGORY = Math .round ((MAX_BASE_RELEVANCE - DEFAULT_RELEVANCE ) / 4f );
3554
36- protected ICompletionProposal delegate ;
55+ private static @ Nullable String fgCSSStyles = null ;
56+
3757 private boolean relevanceComputed = false ;
3858 private int relevance = -1 ;
39-
40- public LSJavaProposal (ICompletionProposal delegate ) {
41- this .delegate = delegate ;
42- }
43-
44- @ Override
45- public void apply (IDocument document ) {
46- delegate .apply (document );
47- }
4859
49- @ Override
50- public @ Nullable String getAdditionalProposalInfo () {
51- return delegate .getAdditionalProposalInfo ();
52- }
60+ private @ Nullable IInformationControlCreator infoControlCreator = null ;
5361
54- @ Override
55- public @ Nullable IContextInformation getContextInformation () {
56- return delegate .getContextInformation ();
57- }
58-
59- @ Override
60- public String getDisplayString () {
61- return delegate .getDisplayString ();
62- }
63-
64- @ Override
65- public @ Nullable Image getImage () {
66- return delegate .getImage ();
67- }
68-
69- @ Override
70- public @ Nullable Point getSelection (IDocument document ) {
71- return delegate .getSelection (document );
62+ public LSJavaProposal (LSCompletionProposal lsProposal ) {
63+ super (lsProposal );
7264 }
7365
7466 @ Override
7567 public int getRelevance () {
7668 if (!relevanceComputed ) {
77- if (delegate instanceof LSCompletionProposal c ) {
7869 // Based on org.eclipse.jdt.internal.ui.text.java.RelevanceComputer
79- relevance = computeBaseRelevance (c );
80- switch (c . getItem ().getKind ()) {
70+ relevance = computeBaseRelevance ();
71+ switch (getItem ().getKind ()) {
8172 case Class :
8273 relevance += 3 ;
8374 break ;
@@ -94,18 +85,96 @@ public int getRelevance() {
9485 break ;
9586 default :
9687 }
97- }
9888 relevanceComputed = true ;
9989 }
10090 return relevance ;
10191 }
10292
103- private int computeBaseRelevance (LSCompletionProposal c ) {
93+ private int computeBaseRelevance () {
10494 // Incorporate LSP4E category and rank into base relevance.
105- int base = MAX_BASE_RELEVANCE - (c . getRankCategory () - 1 ) * RANGE_WITHIN_CATEGORY ;
106- int rank = c . getRankScore ();
95+ int base = MAX_BASE_RELEVANCE - (getRankCategory () - 1 ) * RANGE_WITHIN_CATEGORY ;
96+ int rank = getRankScore ();
10797 base -= (rank >= 0 && rank < RANGE_WITHIN_CATEGORY ? rank : RANGE_WITHIN_CATEGORY );
10898 return base ;
10999 }
100+
101+ /*
102+ * Copied from org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.getInformationControlCreator()
103+ */
104+ @ Override
105+ public @ Nullable IInformationControlCreator getInformationControlCreator () {
106+ Shell shell = UI .getActiveShell ();
107+ if (shell == null || !BrowserInformationControl .isAvailable (shell ))
108+ return null ;
109+
110+ if (infoControlCreator == null ) {
111+ /*
112+ * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=232024
113+ */
114+ IWorkbenchPart part = UI .getActivePart ();
115+ JavadocHover .PresenterControlCreator presenterControlCreator = new JavadocHover .PresenterControlCreator (part == null ? null : part .getSite ());
116+ infoControlCreator = new JavadocHover .HoverControlCreator (presenterControlCreator , true );
117+ }
118+ return infoControlCreator ;
119+ }
120+
121+ /*
122+ * Copied from org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.getAdditionalProposalInfo(IProgressMonitor monitor)
123+ */
124+ @ Override
125+ public Object getAdditionalProposalInfo (IProgressMonitor monitor ) {
126+ StringBuilder buffer = new StringBuilder ((String ) super .getAdditionalProposalInfo (monitor ));
127+ ColorRegistry registry = JFaceResources .getColorRegistry ();
128+ RGB fgRGB = registry .getRGB ("org.eclipse.jdt.ui.Javadoc.foregroundColor" ); //$NON-NLS-1$
129+ RGB bgRGB = registry .getRGB ("org.eclipse.jdt.ui.Javadoc.backgroundColor" ); //$NON-NLS-1$
130+ HTMLPrinter .insertPageProlog (buffer , 0 , fgRGB , bgRGB , getCSSStyles ());
131+ HTMLPrinter .addPageEpilog (buffer );
132+ return new JavadocBrowserInformationControlInput (null , null , buffer .toString (), 0 );
133+
134+ }
135+
136+ /**
137+ * Returns the style information for displaying HTML (Javadoc) content.
138+ * Copied from org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.getCSSStyles()
139+ *
140+ * @return the CSS styles
141+ */
142+ private @ Nullable String getCSSStyles () {
143+ if (fgCSSStyles == null ) {
144+ Bundle bundle = FrameworkUtil .getBundle (AbstractJavaCompletionProposal .class );
145+ URL url = bundle == null ? null : bundle .getEntry ("/JavadocHoverStyleSheet.css" ); //$NON-NLS-1$
146+ if (url != null ) {
147+ BufferedReader reader = null ;
148+ try {
149+ url = FileLocator .toFileURL (url );
150+ reader = new BufferedReader (new InputStreamReader (url .openStream ()));
151+ StringBuilder buffer = new StringBuilder (200 );
152+ String line = reader .readLine ();
153+ while (line != null ) {
154+ buffer .append (line );
155+ buffer .append ('\n' );
156+ line = reader .readLine ();
157+ }
158+ fgCSSStyles = buffer .toString ();
159+ } catch (IOException ex ) {
160+ LanguageServerPlugin .logError (ex );
161+ } finally {
162+ try {
163+ if (reader != null )
164+ reader .close ();
165+ } catch (IOException e ) {
166+ }
167+ }
168+
169+ }
170+ }
171+ String css = fgCSSStyles ;
172+ if (css != null ) {
173+ FontData fontData = JFaceResources .getFontRegistry ().getFontData (PreferenceConstants .APPEARANCE_JAVADOC_FONT )[0 ];
174+ css = HTMLPrinter .convertTopLevelFont (css , fontData );
175+ }
176+ return css ;
177+ }
178+
110179
111180}
0 commit comments