Skip to content

Commit

Permalink
Add hover for package fragments (#84)
Browse files Browse the repository at this point in the history
Signed-off-by: Olivier Thomann <[email protected]>
  • Loading branch information
othomann authored and fbricon committed Oct 7, 2016
1 parent 5a405c2 commit 41a327c
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
// 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
Expand All @@ -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
*
Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
import org.jboss.tools.vscode.java.internal.JDTUtils;
import org.jboss.tools.vscode.java.internal.JavaLanguageServerPlugin;
import org.jboss.tools.vscode.java.internal.SignatureUtil;

import copied.org.eclipse.jdt.ui.JavadocContentAccess;
import org.jboss.tools.vscode.java.internal.javadoc.JavadocContentAccess;

public class CompletionResolveHandler implements RequestHandler<CompletionItem, CompletionItem> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.jboss.tools.vscode.java.internal;
package org.jboss.tools.vscode.java.internal.javadoc;


import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package copied.org.eclipse.jdt.internal.corext.javadoc;
package org.jboss.tools.vscode.java.internal.javadoc;

import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.formatter.IndentManipulation;
Expand All @@ -23,6 +23,8 @@ public class JavaDocCommentReader extends SingleCharReader {

private IBuffer fBuffer;

private String fSource;

private int fCurrPos;

private int fStartPos;
Expand All @@ -39,21 +41,29 @@ public JavaDocCommentReader(IBuffer buf, int start, int end) {
reset();
}

public JavaDocCommentReader(String source, int start, int end) {
fSource= source;
fStartPos= start + 3;
fEndPos= end - 2;

reset();
}

/**
* @see java.io.Reader#read()
*/
@Override
public int read() {
if (fCurrPos < fEndPos) {
char ch= fBuffer.getChar(fCurrPos++);
char ch= getChar(fCurrPos++);
if (fWasNewLine && !IndentManipulation.isLineDelimiterChar(ch)) {
while (fCurrPos < fEndPos && Character.isWhitespace(ch)) {
ch= fBuffer.getChar(fCurrPos++);
ch= getChar(fCurrPos++);
}
if (ch == '*') {
if (fCurrPos < fEndPos) {
do {
ch= fBuffer.getChar(fCurrPos++);
ch= getChar(fCurrPos++);
} while (ch == '*');
} else {
return -1;
Expand All @@ -72,6 +82,7 @@ public int read() {
*/
@Override
public void close() {
fSource = null;
fBuffer= null;
}

Expand All @@ -83,23 +94,27 @@ public void reset() {
fCurrPos= fStartPos;
fWasNewLine= true;
// skip first line delimiter:
if (fCurrPos < fEndPos && '\r' == fBuffer.getChar(fCurrPos)) {
if (fCurrPos < fEndPos && '\r' == getChar(fCurrPos)) {
fCurrPos++;
}
if (fCurrPos < fEndPos && '\n' == fBuffer.getChar(fCurrPos)) {
if (fCurrPos < fEndPos && '\n' == getChar(fCurrPos)) {
fCurrPos++;
}
}

private char getChar(int pos) {
if (fBuffer != null) {
return fBuffer.getChar(fCurrPos);
}
return fSource.charAt(pos);
}

/**
* Returns the offset of the last read character in the passed buffer.
*
*
* @return the offset
*/
public int getOffset() {
return fCurrPos;
}


}
Loading

0 comments on commit 41a327c

Please sign in to comment.