Skip to content
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

Merged
merged 4 commits into from
Oct 7, 2016
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) {
Copy link
Contributor

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

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll check that.

// 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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not imply test packageFragment.getKind() == IPackageFragmentRoot.K_BINARY?

Copy link
Author

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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
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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package copied.org.eclipse.jdt.internal.corext.javadoc;
package org.jboss.tools.vscode.java.internal.hover;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
}


}
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
Loading