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

[NETBEANS-1396] Missing code completion and Javadocs in maven projects with classifier #1548

Merged
merged 3 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -77,6 +77,8 @@
import org.netbeans.api.java.queries.SourceForBinaryQuery;
import org.netbeans.api.java.source.SourceUtils;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.modules.classfile.ClassFile;
import org.netbeans.modules.classfile.Module;
import org.netbeans.modules.java.source.base.Bundle;
import org.netbeans.modules.java.source.indexing.JavaIndex;
import org.netbeans.modules.java.source.parsing.CachingArchiveProvider;
Expand Down Expand Up @@ -768,7 +770,31 @@ private static List<TextStream> findJavadoc(
LOG.log(Level.FINE, "assumed valid Javadoc stream at {0}", url);
} else if (!speculative || !isRemote) {
try {
is = openStream(url, Bundle.LBL_HTTPJavadocDownload());
try {
is = openStream(url, Bundle.LBL_HTTPJavadocDownload());
} catch (InterruptedIOException iioe) {
throw iioe;
} catch (IOException x) {
// Some libraries like OpenJFX prefix their
// javadoc by module, similar to the JDK.
// Only search there when the default fails
// to avoid additional I/O.
// NOTE: No multi-release jar support for now.
URL moduleInfo = new URL(binary, "module-info.class");
try (InputStream classData = moduleInfo.openStream()) {
ClassFile clazz = new ClassFile(classData, false);
Module module = clazz.getModule();
if (module == null) {
throw x;
}
String moduleName = module.getName();
if (moduleName == null) {
throw x;
}
url = new URL(root, moduleName + "/" + pkgName + "/" + pageName + ".html");
is = openStream(url, Bundle.LBL_HTTPJavadocDownload());
}
}
if (useKnownGoodRoots) {
knownGoodRoots.add(rootS);
LOG.log(Level.FINE, "found valid Javadoc stream at {0}", url);
Expand Down Expand Up @@ -827,10 +853,10 @@ private static List<TextStream> findJavadoc(

@NonNull
private static Collection<? extends CharSequence> getFragment(Element e) {
final FragmentBuilder fb = new FragmentBuilder();
final FragmentBuilder fb = new FragmentBuilder(e.getKind());
if (!e.getKind().isClass() && !e.getKind().isInterface()) {
if (e.getKind() == ElementKind.CONSTRUCTOR) {
fb.append(e.getEnclosingElement().getSimpleName());
fb.constructor(e.getEnclosingElement().getSimpleName());
} else {
fb.append(e.getSimpleName());
}
Expand Down Expand Up @@ -870,21 +896,43 @@ private static final class FragmentBuilder {
final List<Convertor<CharSequence,CharSequence>> tmp = new ArrayList<>();
tmp.add(Convertors.<CharSequence>identity());
tmp.add(new JDoc8025633());
tmp.add(new JDoc8046068());
FILTERS = Collections.unmodifiableList(tmp);
};
private final StringBuilder[] sbs;

FragmentBuilder() {
this.sbs = new StringBuilder[FILTERS.size()];
FragmentBuilder(@NonNull ElementKind kind) {
int size = FILTERS.size();
// JDK-8046068 changed the constructor format from "Name" to "<init>"
if (kind == ElementKind.CONSTRUCTOR) {
size *= 2;
}
this.sbs = new StringBuilder[size];
for (int i = 0; i < sbs.length; i++) {
sbs[i] = new StringBuilder();
}
}

@NonNull
FragmentBuilder constructor(@NonNull final CharSequence text) {
CharSequence constructor = text;
for (int i = 0; i < sbs.length;) {
for (int j = 0; j < FILTERS.size(); j++) {
sbs[i].append(FILTERS.get(j).convert(constructor));
i++;
}
constructor = "<init>";
}
return this;
}

@NonNull
FragmentBuilder append(@NonNull final CharSequence text) {
for (int i = 0; i < sbs.length; i++) {
sbs[i].append(FILTERS.get(i).convert(text));
for (int i = 0; i < sbs.length;) {
for (int j = 0; j < FILTERS.size(); j++) {
sbs[i].append(FILTERS.get(j).convert(text));
i++;
}
}
return this;
}
Expand Down Expand Up @@ -938,6 +986,14 @@ public CharSequence convert(@NonNull final CharSequence text) {
return sb.toString();
}
}

private static final class JDoc8046068 implements Convertor<CharSequence,CharSequence> {
@Override
@NonNull
public CharSequence convert(@NonNull final CharSequence text) {
return text.toString().replace(" ", "");
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,12 @@ public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
if (t == HTML.Tag.A) {
String attrName = (String)a.getAttribute(HTML.Attribute.NAME);
if (names.contains(attrName)){
String attrId = (String)a.getAttribute(HTML.Attribute.ID);
if (names.contains(attrName) || names.contains(attrId)){
// we have found desired javadoc member info anchor
state[0] = A_OPEN;
} else {
if ((state[0] == PRE_CLOSE) && attrName!=null && hrPos != -1){
if ((state[0] == PRE_CLOSE) && (attrName != null || attrId != null) && hrPos != -1){
// reach the end of retrieved javadoc info
state[0] = INIT;
offset[1] = hrPos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
package org.netbeans.api.java.source.ui;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import junit.framework.TestCase;

/**
Expand Down Expand Up @@ -68,7 +70,87 @@ public void testGetAndroidJavadocText() throws MalformedURLException {
assertTrue(result.contains("See Also"));

}


/**
* Test of getJavadocText method used with class output from javadoc 11.
*/
public void testJavadoc11Class() throws Exception {
URL root = HTMLJavadocParserTest.class.getResource("Javadoc11Class.html");
String result = HTMLJavadocParser.getJavadocText(root, false);
assertNotNull(result);
assertTrue(result.contains("This is an example class."));

URL url = appendFragment(root, "<init>(java.lang.String)");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("This is a constructor taking a single String parameter."));

url = appendFragment(root, "<init>(java.lang.String,java.lang.String)");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("This is a constructor taking two String parameters."));

url = appendFragment(root, "hi()");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("A method."));
}

/**
* Test of getJavadocText method used with enum output from javadoc 11.
*/
public void testJavadoc11Enum() throws Exception {
URL root = HTMLJavadocParserTest.class.getResource("Javadoc11Enum.html");
String result = HTMLJavadocParser.getJavadocText(root, false);
assertNotNull(result);
assertTrue(result.contains("This is an example enum."));

URL url = appendFragment(root, "FIRST");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("The first value."));

url = appendFragment(root, "hi()");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("A method."));
}

/**
* Test of getJavadocText method used with class output from javadoc 8.
*/
public void testJavadoc8Class() throws Exception {
URL root = HTMLJavadocParserTest.class.getResource("Javadoc8Class.html");
String result = HTMLJavadocParser.getJavadocText(root, false);
assertNotNull(result);
assertTrue(result.contains("This is an example class."));

URL url = appendFragment(root, "Javadoc8Class-java.lang.String-");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("This is a constructor taking a single String parameter."));

url = appendFragment(root, "Javadoc8Class-java.lang.String-java.lang.String-");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("This is a constructor taking two String parameters."));

url = appendFragment(root, "hi--");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("A method."));
}

/**
* Test of getJavadocText method used with enum output from javadoc 8.
*/
public void testJavadoc8Enum() throws Exception {
URL root = HTMLJavadocParserTest.class.getResource("Javadoc8Enum.html");
String result = HTMLJavadocParser.getJavadocText(root, false);
assertNotNull(result);
assertTrue(result.contains("This is an example enum."));

URL url = appendFragment(root, "FIRST");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("The first value."));

url = appendFragment(root, "hi--");
result = HTMLJavadocParser.getJavadocText(url, false);
assertTrue(result.contains("A method."));
}

public void test199194() throws MalformedURLException {
URL url = HTMLJavadocParserTest.class.getResource("JavaApplication1.html");
String result = HTMLJavadocParser.getJavadocText(url, false);
Expand All @@ -91,4 +173,11 @@ public void test209707() throws MalformedURLException {
assertNotNull(result);
assertTrue(result.contains("the selected file or"));
}

private static URL appendFragment(URL root, String unencodedFragment) throws Exception {
StringBuilder uri = new StringBuilder(root.toExternalForm());
uri.append("#");
uri.append(URLEncoder.encode(unencodedFragment, "UTF-8").replace("+", "%20"));
return new URI(uri.toString()).toURL();
}
}
Loading