-
Notifications
You must be signed in to change notification settings - Fork 411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add hover for package fragments #84
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,62 +12,75 @@ | |
|
||
import java.io.IOException; | ||
import java.io.Reader; | ||
import java.util.stream.Stream; | ||
|
||
import org.eclipse.core.runtime.CoreException; | ||
import org.eclipse.jdt.core.IBuffer; | ||
import org.eclipse.jdt.core.IJavaElement; | ||
import org.eclipse.jdt.core.ILocalVariable; | ||
import org.eclipse.jdt.core.IMember; | ||
import org.eclipse.jdt.core.IPackageFragment; | ||
import org.eclipse.jdt.core.ISourceRange; | ||
import org.eclipse.jdt.core.ISourceReference; | ||
import org.eclipse.jdt.core.ITypeParameter; | ||
import org.eclipse.jdt.core.ITypeRoot; | ||
import org.eclipse.jdt.core.JavaModelException; | ||
import org.eclipse.jdt.internal.core.util.Util; | ||
import org.eclipse.jface.text.BadLocationException; | ||
import org.eclipse.jface.text.DefaultLineTracker; | ||
import org.eclipse.jface.text.Document; | ||
import org.eclipse.jface.text.IDocument; | ||
import org.eclipse.jface.text.ILineTracker; | ||
import org.eclipse.jface.text.IRegion; | ||
import org.jboss.tools.vscode.java.internal.handlers.JsonRpcHelpers; | ||
|
||
import copied.org.eclipse.jdt.ui.JavadocContentAccess; | ||
import org.jboss.tools.vscode.java.internal.javadoc.JavadocContentAccess; | ||
|
||
public class HoverInfoProvider { | ||
|
||
private final ITypeRoot unit; | ||
public HoverInfoProvider(ITypeRoot aUnit) { | ||
this.unit = aUnit; | ||
} | ||
|
||
public String computeHover(int line, int column) { | ||
try { | ||
IJavaElement[] elements = unit.codeSelect(JsonRpcHelpers.toOffset(unit.getBuffer(),line,column),0); | ||
if(elements == null || elements.length != 1) | ||
if(elements == null || elements.length == 0) { | ||
return null; | ||
IJavaElement curr= elements[0]; | ||
// return computeSourceHover(curr); | ||
} | ||
IJavaElement curr = null; | ||
if (elements.length != 1) { | ||
// they could be package fragments. | ||
// We need to select the one that matches the package fragment of the current unit | ||
IPackageFragment packageFragment = (IPackageFragment) unit.getParent(); | ||
IJavaElement found = | ||
Stream | ||
.of(elements) | ||
.filter(e -> e.equals(packageFragment)) | ||
.findFirst() | ||
.orElse(null); | ||
if (found == null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not imply test packageFragment.getKind() == IPackageFragmentRoot.K_BINARY? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because I think this is too early to check that. It can be a package from source as well if you import a type from another package. This is a case where it doesn't match the package from the current compilation unit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fair enough |
||
// this would be a binary package fragment | ||
return computeJavadocHover(elements[0]); | ||
} | ||
curr = found; | ||
} else { | ||
curr = elements[0]; | ||
} | ||
return computeJavadocHover(curr); | ||
|
||
} catch (JavaModelException e) { | ||
// TODO Auto-generated catch block | ||
} catch (CoreException e) { | ||
e.printStackTrace(); | ||
} | ||
return null; | ||
} | ||
|
||
private String computeJavadocHover(IJavaElement element) throws JavaModelException{ | ||
private String computeJavadocHover(IJavaElement element) throws CoreException { | ||
IMember member; | ||
if (element instanceof ILocalVariable) { | ||
member= ((ILocalVariable) element).getDeclaringMember(); | ||
} else if (element instanceof ITypeParameter) { | ||
member= ((ITypeParameter) element).getDeclaringMember(); | ||
} else if (element instanceof IMember) { | ||
member= (IMember) element; | ||
} else if (element instanceof IPackageFragment) { | ||
Reader r = JavadocContentAccess.getHTMLContentReader((IPackageFragment) element, true); | ||
if(r == null ) return null; | ||
return getString(r); | ||
} else { | ||
return null; | ||
} | ||
|
||
IBuffer buf= member.getOpenable().getBuffer(); | ||
if (buf == null) { | ||
return null; // no source attachment found | ||
|
@@ -79,75 +92,7 @@ private String computeJavadocHover(IJavaElement element) throws JavaModelExcepti | |
if(r == null ) return null; | ||
return getString(r); | ||
} | ||
|
||
|
||
/** | ||
* Returns source as hover | ||
* @param curr | ||
* @return | ||
*/ | ||
private String computeSourceHover(IJavaElement curr) { | ||
if ((curr instanceof IMember || curr instanceof ILocalVariable || curr instanceof ITypeParameter) && curr instanceof ISourceReference) { | ||
try { | ||
String source= ((ISourceReference) curr).getSource(); | ||
|
||
String[] sourceLines= getTrimmedSource(source, curr); | ||
if (sourceLines == null) | ||
return null; | ||
|
||
String delim= Util.getLineSeparator(source,unit.getJavaProject()); | ||
source= concatenate(sourceLines, delim); | ||
|
||
return source; | ||
} catch (JavaModelException ex) { | ||
//do nothing | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
|
||
/** | ||
* Returns the trimmed source lines. | ||
* | ||
* @param source the source string, could be <code>null</code> | ||
* @param javaElement the java element | ||
* @return the trimmed source lines or <code>null</code> | ||
*/ | ||
private String[] getTrimmedSource(String source, IJavaElement javaElement) { | ||
if (source == null) | ||
return null; | ||
source= removeLeadingComments(source); | ||
String[] sourceLines= convertIntoLines(source); | ||
// Strings.trimIndentation(sourceLines, javaElement.getJavaProject()); | ||
return sourceLines; | ||
} | ||
|
||
private String removeLeadingComments(String source) { | ||
final JavaCodeReader reader= new JavaCodeReader(); | ||
IDocument document= new Document(source); | ||
int i; | ||
try { | ||
reader.configureForwardReader(document, 0, document.getLength(), true, false); | ||
int c= reader.read(); | ||
while (c != -1 && (c == '\r' || c == '\n')) { | ||
c= reader.read(); | ||
} | ||
i= reader.getOffset(); | ||
reader.close(); | ||
} catch (IOException ex) { | ||
i= 0; | ||
} finally { | ||
try { | ||
reader.close(); | ||
} catch (IOException ex) { | ||
} | ||
} | ||
|
||
if (i < 0) | ||
return source; | ||
return source.substring(i); | ||
} | ||
/** | ||
* Gets the reader content as a String | ||
* | ||
|
@@ -166,46 +111,4 @@ private static String getString(Reader reader) { | |
} | ||
return buf.toString(); | ||
} | ||
|
||
/** | ||
* Converts the given string into an array of lines. The lines | ||
* don't contain any line delimiter characters. | ||
* | ||
* @param input the string | ||
* @return the string converted into an array of strings. Returns <code> | ||
* null</code> if the input string can't be converted in an array of lines. | ||
*/ | ||
public static String[] convertIntoLines(String input) { | ||
try { | ||
ILineTracker tracker= new DefaultLineTracker(); | ||
tracker.set(input); | ||
int size= tracker.getNumberOfLines(); | ||
String result[]= new String[size]; | ||
for (int i= 0; i < size; i++) { | ||
IRegion region= tracker.getLineInformation(i); | ||
int offset= region.getOffset(); | ||
result[i]= input.substring(offset, offset + region.getLength()); | ||
} | ||
return result; | ||
} catch (BadLocationException e) { | ||
return null; | ||
} | ||
} | ||
|
||
/** | ||
* Concatenate the given strings into one strings using the passed line delimiter as a | ||
* delimiter. No delimiter is added to the last line. | ||
* @param lines the lines | ||
* @param delimiter line delimiter | ||
* @return the concatenated lines | ||
*/ | ||
public static String concatenate(String[] lines, String delimiter) { | ||
StringBuilder buffer= new StringBuilder(); | ||
for (int i= 0; i < lines.length; i++) { | ||
if (i > 0) | ||
buffer.append(delimiter); | ||
buffer.append(lines[i]); | ||
} | ||
return buffer.toString(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
potential IIOOBE if length == 0, L54 and L58
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check that.