Merge branch 'master' of github.com:spring-projects/sts4
This commit is contained in:
@@ -7,13 +7,12 @@ import org.springframework.ide.vscode.application.properties.metadata.util.Depre
|
||||
import org.springframework.ide.vscode.commons.java.IJavaElement;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlBuffer;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlSnippet;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders;
|
||||
|
||||
/**
|
||||
* Sts version of {@link ValueHint} contains similar data, but accomoates
|
||||
@@ -29,7 +28,7 @@ public class StsValueHint {
|
||||
|
||||
|
||||
private final String value;
|
||||
private final HoverInfo description;
|
||||
private final Renderable description;
|
||||
private final Deprecation deprecation;
|
||||
|
||||
/**
|
||||
@@ -38,7 +37,7 @@ public class StsValueHint {
|
||||
* This constructor is private. Use one of the provided
|
||||
* static 'create' methods instead.
|
||||
*/
|
||||
private StsValueHint(String value, HoverInfo description, Deprecation deprecation) {
|
||||
private StsValueHint(String value, Renderable description, Deprecation deprecation) {
|
||||
this.value = value==null?"null":value.toString();
|
||||
Assert.isLegal(!this.value.startsWith("StsValueHint"));
|
||||
this.description = description;
|
||||
@@ -58,7 +57,7 @@ public class StsValueHint {
|
||||
}
|
||||
|
||||
public static StsValueHint create(String value) {
|
||||
return new StsValueHint(value, DescriptionProviders.NO_DESCRIPTION, null);
|
||||
return new StsValueHint(value, Renderables.NO_DESCRIPTION, null);
|
||||
}
|
||||
|
||||
public static StsValueHint create(ValueHint hint) {
|
||||
@@ -92,46 +91,33 @@ public class StsValueHint {
|
||||
/**
|
||||
* Create a html snippet from a text snippet.
|
||||
*/
|
||||
private static HoverInfo textSnippet(String description) {
|
||||
private static Renderable textSnippet(String description) {
|
||||
if (StringUtil.hasText(description)) {
|
||||
return DescriptionProviders.text(description);
|
||||
return Renderables.text(description);
|
||||
}
|
||||
return DescriptionProviders.NO_DESCRIPTION;
|
||||
return Renderables.NO_DESCRIPTION;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public HoverInfo getDescription() {
|
||||
public Renderable getDescription() {
|
||||
return description;
|
||||
}
|
||||
public HoverInfo getDescriptionProvider() {
|
||||
public Renderable getDescriptionProvider() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public static HoverInfo javaDocSnippet(IJavaElement je) {
|
||||
try {
|
||||
HtmlSnippet jdoc = je.getJavaDoc();
|
||||
private static Renderable javaDocSnippet(IJavaElement je) {
|
||||
return Renderables.lazy(() -> {
|
||||
IJavadoc jdoc = je.getJavaDoc();
|
||||
if (jdoc != null) {
|
||||
return new HoverInfo() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
// TODO not correct md
|
||||
buffer.append(jdoc.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsHtml(HtmlBuffer buffer) {
|
||||
buffer.raw(jdoc.toHtml());
|
||||
}
|
||||
};
|
||||
return jdoc.getRenderable();
|
||||
} else {
|
||||
return Renderables.NO_DESCRIPTION;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return DescriptionProviders.NO_DESCRIPTION;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package org.springframework.ide.vscode.application.properties.metadata.types;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.Deprecation;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders;
|
||||
|
||||
/**
|
||||
* Represents a property on a Type that can be accessed by name.
|
||||
@@ -27,15 +25,15 @@ public class TypedProperty implements YTypedProperty {
|
||||
/**
|
||||
* Provides a description for this property.
|
||||
*/
|
||||
private final HoverInfo descriptionProvider;
|
||||
private final Renderable descriptionProvider;
|
||||
|
||||
private final Deprecation deprecation;
|
||||
|
||||
public TypedProperty(String name, Type type, Deprecation deprecation) {
|
||||
this(name, type, DescriptionProviders.NO_DESCRIPTION, deprecation);
|
||||
this(name, type, Renderables.NO_DESCRIPTION, deprecation);
|
||||
}
|
||||
|
||||
public TypedProperty(String name, Type type, HoverInfo descriptionProvider, Deprecation deprecation) {
|
||||
public TypedProperty(String name, Type type, Renderable descriptionProvider, Deprecation deprecation) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.descriptionProvider = descriptionProvider;
|
||||
@@ -56,7 +54,7 @@ public class TypedProperty implements YTypedProperty {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getDescription() {
|
||||
public Renderable getDescription() {
|
||||
//TODO: real implementation that somehow gets this from somewhere (i.e. the JavaDoc)
|
||||
// Note that presently the application.yml and application.properties editor do not actually
|
||||
// use this description provider but produce hover infos in a different way (so this is only
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<!-- roatser version -->
|
||||
<roaster.version>2.19.2.Final</roaster.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
@@ -23,5 +29,27 @@
|
||||
<artifactId>jandex</artifactId>
|
||||
<version>2.0.3.Final</version>
|
||||
</dependency>
|
||||
<!-- HTML <-> Markdown conversion -->
|
||||
<dependency>
|
||||
<groupId>com.kotcrab.remark</groupId>
|
||||
<artifactId>remark</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.javaparser</groupId>
|
||||
<artifactId>javaparser-core</artifactId>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.forge.roaster</groupId>
|
||||
<artifactId>roaster-api</artifactId>
|
||||
<version>${roaster.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.forge.roaster</groupId>
|
||||
<artifactId>roaster-jdt</artifactId>
|
||||
<version>${roaster.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -5,69 +5,114 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jboss.jandex.CompositeIndex;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.IndexReader;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.jandex.JarIndexer;
|
||||
import org.springframework.ide.vscode.commons.java.IAnnotation;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
public class JandexIndex {
|
||||
|
||||
private static class Entry<K, V> {
|
||||
K key;
|
||||
V value;
|
||||
Entry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface IndexFileFinder {
|
||||
File findIndexFile(File jarFile);
|
||||
}
|
||||
|
||||
private Supplier<IndexView> index;
|
||||
|
||||
public JandexIndex(Stream<Path> classpathEntries) {
|
||||
this(classpathEntries, jarFile -> null, Optional.empty());
|
||||
@FunctionalInterface
|
||||
public static interface JavadocProviderFactory {
|
||||
IJavadocProvider createJavadocProvider(File jarContainer);
|
||||
}
|
||||
|
||||
public JandexIndex(Stream<Path> classpathEntries, IndexFileFinder indexFileFinder) {
|
||||
this(classpathEntries, indexFileFinder, Optional.empty());
|
||||
private static final IJavadocProvider ABSENT_JAVADOC_PROVIDER = new IJavadocProvider() {
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IType type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IField field) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IMethod method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IAnnotation method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private Supplier<List<Entry<File, IndexView>>> index;
|
||||
|
||||
private JavadocProviderFactory javadocProviderFactory;
|
||||
|
||||
private Cache<File, IJavadocProvider> javadocProvidersCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
private JandexIndex[] baseIndex;
|
||||
|
||||
public void setJvadocProviderFactory(JavadocProviderFactory sourceContainerProvider) {
|
||||
this.javadocProviderFactory = sourceContainerProvider;
|
||||
}
|
||||
|
||||
public JandexIndex(Stream<Path> classpathEntries, Optional<JandexIndex> baseIndex) {
|
||||
this(classpathEntries, jarFile -> null, baseIndex);
|
||||
public JavadocProviderFactory getJavadocProviderFactory() {
|
||||
return javadocProviderFactory;
|
||||
}
|
||||
|
||||
public JandexIndex(Stream<Path> classpathEntries, IndexFileFinder indexFileFinder, Optional<JandexIndex> baseIndex) {
|
||||
index = Suppliers.memoize(() -> {
|
||||
if (baseIndex.isPresent()) {
|
||||
return CompositeIndex.create(baseIndex.get().index.get(), buildIndex(classpathEntries, indexFileFinder));
|
||||
} else {
|
||||
return buildIndex(classpathEntries, indexFileFinder);
|
||||
}
|
||||
});
|
||||
public JandexIndex(Stream<Path> classpathEntries, IndexFileFinder indexFileFinder, JavadocProviderFactory javadocProviderFactory, JandexIndex... baseIndex) {
|
||||
this.baseIndex = baseIndex;
|
||||
index = Suppliers.memoize(() -> buildIndex(classpathEntries, indexFileFinder).collect(Collectors.toList()));
|
||||
this.javadocProviderFactory = javadocProviderFactory;
|
||||
}
|
||||
|
||||
private static CompositeIndex buildIndex(Stream<Path> classpathEntries, IndexFileFinder indexFileFinder) {
|
||||
return CompositeIndex.create(classpathEntries
|
||||
private Stream<Entry<File, IndexView>> buildIndex(Stream<Path> classpathEntries, IndexFileFinder indexFileFinder) {
|
||||
return classpathEntries
|
||||
.map(entry -> entry.toFile())
|
||||
.map(file -> {
|
||||
Optional<IndexView> index = Optional.empty();
|
||||
if (file.isFile() && file.getName().endsWith(".jar")) {
|
||||
return indexJar(file, indexFileFinder);
|
||||
index = indexJar(file, indexFileFinder);
|
||||
} else if (file.isDirectory()) {
|
||||
return indexFolder(file);
|
||||
} else {
|
||||
return Optional.<IndexView>empty();
|
||||
index = indexFolder(file);
|
||||
}
|
||||
return new Entry<>(file, index);
|
||||
})
|
||||
.filter(o -> o.isPresent())
|
||||
.map(o -> o.get())
|
||||
.collect(Collectors.toList()));
|
||||
.filter(e -> e.value.isPresent())
|
||||
.map(e -> new Entry<>(e.key, e.value.get()));
|
||||
}
|
||||
|
||||
private static Optional<IndexView> indexFolder(File folder) {
|
||||
@@ -134,8 +179,36 @@ public class JandexIndex {
|
||||
}
|
||||
|
||||
public IType findType(String fqName) {
|
||||
IndexView compositeIndex = index.get();
|
||||
return Wrappers.wrap(compositeIndex, compositeIndex.getClassByName(DotName.createSimple(fqName)));
|
||||
return getClassByName(DotName.createSimple(fqName));
|
||||
}
|
||||
|
||||
IType getClassByName(DotName fqName) {
|
||||
// First look for type in the base index array
|
||||
return (baseIndex == null ? Stream.<IType>empty()
|
||||
: Arrays.stream(baseIndex)
|
||||
.filter(jandexIndex -> jandexIndex != null)
|
||||
.map(jandexIndex -> jandexIndex.getClassByName(fqName)))
|
||||
.filter(type -> type != null)
|
||||
.findFirst()
|
||||
// If not found look at indices owned by this JandexIndex instance
|
||||
.orElseGet(() -> index.get().stream()
|
||||
.map(e -> new Entry<>(e.key, e.value.getClassByName(fqName)))
|
||||
.filter(e -> e.value != null)
|
||||
.map(e -> createType(e))
|
||||
.findFirst()
|
||||
.orElse(null));
|
||||
|
||||
}
|
||||
|
||||
private IType createType(Entry<File, ClassInfo> match) {
|
||||
File classpathResource = match.key;
|
||||
IJavadocProvider javadocProvider = null;
|
||||
try {
|
||||
javadocProvider = javadocProvidersCache.get(match.key, () -> javadocProviderFactory == null ? ABSENT_JAVADOC_PROVIDER : javadocProviderFactory.createJavadocProvider(classpathResource));
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return Wrappers.wrap(this, match.value, javadocProvider);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.jboss.jandex.AnnotationValue;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.FieldInfo;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.MethodInfo;
|
||||
import org.jboss.jandex.PrimitiveType;
|
||||
import org.jboss.jandex.Type;
|
||||
@@ -20,16 +19,19 @@ import org.springframework.ide.vscode.commons.java.Flags;
|
||||
import org.springframework.ide.vscode.commons.java.IAnnotation;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IMemberValuePair;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IPrimitiveType;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.java.IVoidType;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlSnippet;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
|
||||
public class Wrappers {
|
||||
|
||||
public static IType wrap(IndexView index, ClassInfo info) {
|
||||
private static final String JANDEX_CONTRUCTOR_NAME = "<init>";
|
||||
|
||||
public static IType wrap(JandexIndex index, ClassInfo info, IJavadocProvider javadocProvider) {
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -43,17 +45,17 @@ public class Wrappers {
|
||||
@Override
|
||||
public IType getDeclaringType() {
|
||||
DotName enclosingClass = info.enclosingClass();
|
||||
return enclosingClass == null ? null : wrap(index, index.getClassByName(enclosingClass));
|
||||
return enclosingClass == null ? null : index.getClassByName(enclosingClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return info.simpleName();
|
||||
return info.simpleName() == null ? info.name().local() : info.simpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlSnippet getJavaDoc() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
public IJavadoc getJavaDoc() {
|
||||
return javadocProvider == null ? null : javadocProvider.getJavadoc(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,7 +66,7 @@ public class Wrappers {
|
||||
@Override
|
||||
public Stream<IAnnotation> getAnnotations() {
|
||||
// TODO: check correctness!
|
||||
return info.annotations().get(info.name()).stream().map(Wrappers::wrap);
|
||||
return info.annotations().get(info.name()).stream().map(a -> wrap(a, javadocProvider));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,9 +81,14 @@ public class Wrappers {
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
return false;
|
||||
return Flags.isInterface(info.flags());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotation() {
|
||||
return Flags.isAnnotation(info.flags());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullyQualifiedName() {
|
||||
return info.name().toString();
|
||||
@@ -89,26 +96,26 @@ public class Wrappers {
|
||||
|
||||
@Override
|
||||
public IField getField(String name) {
|
||||
return wrap(index, info.field(name));
|
||||
return wrap(index, info.field(name), javadocProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<IField> getFields() {
|
||||
return info.fields().stream().map(f -> {
|
||||
return wrap(index, f);
|
||||
return wrap(index, f, javadocProvider);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMethod getMethod(String name, Stream<IJavaType> parameters) {
|
||||
List<Type> typeParameters = parameters.map(Wrappers::from).collect(Collectors.toList());
|
||||
return wrap(index, info.method(name, typeParameters.toArray(new Type[typeParameters.size()])));
|
||||
return wrap(index, info.method(name, typeParameters.toArray(new Type[typeParameters.size()])), javadocProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<IMethod> getMethods() {
|
||||
return info.methods().stream().map(m -> {
|
||||
return wrap(index, m);
|
||||
return wrap(index, m, javadocProvider);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -116,11 +123,11 @@ public class Wrappers {
|
||||
public String toString() {
|
||||
return info.toString();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static IField wrap(IndexView index, FieldInfo field) {
|
||||
public static IField wrap(JandexIndex index, FieldInfo field, IJavadocProvider javadocProvider) {
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -133,7 +140,7 @@ public class Wrappers {
|
||||
|
||||
@Override
|
||||
public IType getDeclaringType() {
|
||||
return wrap(index, field.declaringClass());
|
||||
return wrap(index, field.declaringClass(), javadocProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,8 +149,8 @@ public class Wrappers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlSnippet getJavaDoc() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
public IJavadoc getJavaDoc() {
|
||||
return javadocProvider == null ? null : javadocProvider.getJavadoc(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,7 +161,7 @@ public class Wrappers {
|
||||
@Override
|
||||
public Stream<IAnnotation> getAnnotations() {
|
||||
return field.annotations().stream().map(a -> {
|
||||
return wrap(a);
|
||||
return wrap(a, javadocProvider);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -170,7 +177,7 @@ public class Wrappers {
|
||||
};
|
||||
}
|
||||
|
||||
public static IMethod wrap(IndexView index, MethodInfo method) {
|
||||
public static IMethod wrap(JandexIndex index, MethodInfo method, IJavadocProvider javadocProvider) {
|
||||
isNotNull(index);
|
||||
isNotNull(method);
|
||||
return new IMethod() {
|
||||
@@ -179,20 +186,25 @@ public class Wrappers {
|
||||
public int getFlags() {
|
||||
return method.flags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstructor() {
|
||||
return method.name().equals(JANDEX_CONTRUCTOR_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType getDeclaringType() {
|
||||
return wrap(index, method.declaringClass());
|
||||
return wrap(index, method.declaringClass(), javadocProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return method.name();
|
||||
return isConstructor() ? getDeclaringType().getElementName() : method.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlSnippet getJavaDoc() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
public IJavadoc getJavaDoc() {
|
||||
return javadocProvider == null ? null : javadocProvider.getJavadoc(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -202,7 +214,7 @@ public class Wrappers {
|
||||
|
||||
@Override
|
||||
public Stream<IAnnotation> getAnnotations() {
|
||||
return method.annotations().stream().map(Wrappers::wrap);
|
||||
return method.annotations().stream().map(a -> wrap(a, javadocProvider));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -229,10 +241,11 @@ public class Wrappers {
|
||||
public Stream<IJavaType> parameters() {
|
||||
return method.parameters().stream().map(Wrappers::wrap);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static IAnnotation wrap(AnnotationInstance annotation) {
|
||||
public static IAnnotation wrap(AnnotationInstance annotation, IJavadocProvider javadocProvider) {
|
||||
isNotNull(annotation);
|
||||
return new IAnnotation() {
|
||||
|
||||
@@ -242,8 +255,8 @@ public class Wrappers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlSnippet getJavaDoc() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
public IJavadoc getJavaDoc() {
|
||||
return javadocProvider == null ? null : javadocProvider.getJavadoc(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -288,13 +301,6 @@ public class Wrappers {
|
||||
};
|
||||
}
|
||||
|
||||
public static Type createParameterTypeFromSignature(IndexView index, String signature) {
|
||||
if (signature == null) {
|
||||
return null;
|
||||
}
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
public static IPrimitiveType wrap(PrimitiveType type) {
|
||||
switch (type.primitive()) {
|
||||
case SHORT:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.HtmlSnippet;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
|
||||
public interface IJavaElement {
|
||||
String getElementName();
|
||||
HtmlSnippet getJavaDoc();
|
||||
IJavadoc getJavaDoc();
|
||||
boolean exists();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
|
||||
public interface IJavadocProvider {
|
||||
|
||||
IJavadoc getJavadoc(IType type);
|
||||
|
||||
IJavadoc getJavadoc(IField field);
|
||||
|
||||
IJavadoc getJavadoc(IMethod method);
|
||||
|
||||
IJavadoc getJavadoc(IAnnotation annotation);
|
||||
}
|
||||
@@ -51,5 +51,7 @@ public interface IMethod extends IMember {
|
||||
* @return
|
||||
*/
|
||||
Stream<IJavaType> parameters();
|
||||
|
||||
boolean isConstructor();
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ public interface IType extends IMember {
|
||||
boolean isClass();
|
||||
boolean isEnum();
|
||||
boolean isInterface();
|
||||
boolean isAnnotation();
|
||||
|
||||
/**
|
||||
* Returns the fully qualified name of this type,
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.springframework.ide.vscode.commons.java.parser;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.github.javaparser.JavaParser;
|
||||
import com.github.javaparser.ParseException;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
public interface CompilationUnitIndex {
|
||||
|
||||
static final CompilationUnitIndex DEFAULT = new CompilationUnitIndex() {
|
||||
|
||||
private LoadingCache<URL, CompilationUnit> cache = CacheBuilder.newBuilder().build(new CacheLoader<URL, CompilationUnit>() {
|
||||
|
||||
@Override
|
||||
public CompilationUnit load(URL url) throws Exception {
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return JavaParser.parse(in);
|
||||
} catch (ParseException e) {
|
||||
in.close();
|
||||
Log.log("Failed to parse java source file: " + url, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Override
|
||||
public CompilationUnit getCompilationUnit(URL url) {
|
||||
try {
|
||||
return cache.get(url);
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CompilationUnit getCompilationUnit(URL url);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package org.springframework.ide.vscode.commons.java.parser;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IAnnotation;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.javadoc.RawJavadoc;
|
||||
import org.springframework.ide.vscode.commons.javadoc.SourceUrlProvider;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.EnumConstantDeclaration;
|
||||
import com.github.javaparser.ast.body.EnumDeclaration;
|
||||
import com.github.javaparser.ast.body.FieldDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.body.VariableDeclarator;
|
||||
import com.github.javaparser.ast.visitor.GenericVisitorAdapter;
|
||||
|
||||
public class ParserJavadocProvider implements IJavadocProvider {
|
||||
|
||||
private SourceUrlProvider sourceUrlProvider;
|
||||
|
||||
public ParserJavadocProvider(SourceUrlProvider sourceUrlProvider) {
|
||||
this.sourceUrlProvider = sourceUrlProvider;
|
||||
}
|
||||
|
||||
public IJavadoc getJavadoc(IType type) {
|
||||
if (type.isEnum()) {
|
||||
EnumDeclaration declaration = getEnumDeclaration(type);
|
||||
return declaration.getJavaDoc() == null ? null : new RawJavadoc(declaration.getJavaDoc().toString());
|
||||
} else {
|
||||
ClassOrInterfaceDeclaration declaration = getClassOrInterfaceDeclaration(type);
|
||||
return declaration.getJavaDoc() == null ? null : new RawJavadoc(declaration.getJavaDoc().toString());
|
||||
}
|
||||
}
|
||||
|
||||
public IJavadoc getJavadoc(IField field) {
|
||||
IType declaringType = field.getDeclaringType();
|
||||
if (declaringType.isEnum()) {
|
||||
EnumConstantDeclaration declaration = createVisitorToFindEnumConstant(field).visit(getEnumDeclaration(declaringType), null);
|
||||
return declaration.getJavaDoc() == null ? null : new RawJavadoc(declaration.getJavaDoc().toString());
|
||||
} else {
|
||||
FieldDeclaration declaration = createVisitorToFindField(field).visit(getClassOrInterfaceDeclaration(declaringType), null);
|
||||
return declaration.getJavaDoc() == null ? null : new RawJavadoc(declaration.getJavaDoc().toString());
|
||||
}
|
||||
}
|
||||
|
||||
public IJavadoc getJavadoc(IMethod method) {
|
||||
if (method.parameters().findFirst().isPresent()) {
|
||||
throw new UnsupportedOperationException("Only methods with no parameters are supported");
|
||||
}
|
||||
IType declaringType = method.getDeclaringType();
|
||||
if (declaringType.isEnum()) {
|
||||
MethodDeclaration declaration = createVisitorToFindMethod(method).visit(getEnumDeclaration(declaringType), null);
|
||||
return declaration.getJavaDoc() == null ? null : new RawJavadoc(declaration.getJavaDoc().toString());
|
||||
} else {
|
||||
MethodDeclaration declaration = createVisitorToFindMethod(method).visit(getClassOrInterfaceDeclaration(declaringType), null);
|
||||
return declaration.getJavaDoc() == null ? null : new RawJavadoc(declaration.getJavaDoc().toString());
|
||||
}
|
||||
}
|
||||
|
||||
public IJavadoc getJavadoc(IAnnotation annotation) {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
private CompilationUnit getCompilationUnit(IType type) {
|
||||
try {
|
||||
URL sourceUrl = sourceUrlProvider.sourceUrl(type);
|
||||
return CompilationUnitIndex.DEFAULT.getCompilationUnit(sourceUrl);
|
||||
} catch (Exception e) {
|
||||
Log.log("Invalid source URL for type " + type, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private EnumDeclaration getEnumDeclaration(IType type) {
|
||||
IType parent = type.getDeclaringType();
|
||||
if (parent == null) {
|
||||
CompilationUnit cu = getCompilationUnit(type);
|
||||
return createVisitorToFindEnum(type).visit(cu, null);
|
||||
} else {
|
||||
if (parent.isEnum()) {
|
||||
EnumDeclaration declaration = getEnumDeclaration(parent);
|
||||
return createVisitorToFindEnum(type).visit(declaration, null);
|
||||
} else {
|
||||
ClassOrInterfaceDeclaration declaration = getClassOrInterfaceDeclaration(parent);
|
||||
return createVisitorToFindEnum(type).visit(declaration, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ClassOrInterfaceDeclaration getClassOrInterfaceDeclaration(IType type) {
|
||||
IType parent = type.getDeclaringType();
|
||||
if (parent == null) {
|
||||
CompilationUnit cu = getCompilationUnit(type);
|
||||
return createVisitorToFindClassOrInterface(type).visit(cu, null);
|
||||
} else {
|
||||
if (parent.isEnum()) {
|
||||
EnumDeclaration declaration = getEnumDeclaration(parent);
|
||||
return createVisitorToFindClassOrInterface(type).visit(declaration, null);
|
||||
} else {
|
||||
ClassOrInterfaceDeclaration declaration = getClassOrInterfaceDeclaration(parent);
|
||||
return createVisitorToFindClassOrInterface(type).visit(declaration, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GenericVisitorAdapter<ClassOrInterfaceDeclaration, Object> createVisitorToFindClassOrInterface(IType type) {
|
||||
return new GenericVisitorAdapter<ClassOrInterfaceDeclaration, Object>() {
|
||||
|
||||
@Override
|
||||
public ClassOrInterfaceDeclaration visit(ClassOrInterfaceDeclaration n, Object arg) {
|
||||
if (n.getName().equals(type.getElementName())) {
|
||||
return n;
|
||||
} else {
|
||||
return super.visit(n, arg);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private GenericVisitorAdapter<EnumDeclaration, Object> createVisitorToFindEnum(IType type) {
|
||||
return new GenericVisitorAdapter<EnumDeclaration, Object>() {
|
||||
|
||||
@Override
|
||||
public EnumDeclaration visit(EnumDeclaration n, Object arg) {
|
||||
if (n.getName().equals(type.getElementName())) {
|
||||
return n;
|
||||
} else {
|
||||
return super.visit(n, arg);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private GenericVisitorAdapter<MethodDeclaration, Object> createVisitorToFindMethod(IMethod method) {
|
||||
return new GenericVisitorAdapter<MethodDeclaration, Object>() {
|
||||
@Override
|
||||
public MethodDeclaration visit(MethodDeclaration n, Object arg) {
|
||||
if (n.getParameters().isEmpty() && n.getName().equals(method.getElementName())) {
|
||||
return n;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private GenericVisitorAdapter<FieldDeclaration, Object> createVisitorToFindField(IField field) {
|
||||
return new GenericVisitorAdapter<FieldDeclaration, Object>() {
|
||||
@Override
|
||||
public FieldDeclaration visit(FieldDeclaration n, Object arg) {
|
||||
Optional<VariableDeclarator> variable = n.getVariables().stream().filter(v -> v.getId().getName().equals(field.getElementName())).findFirst();
|
||||
return variable.isPresent() ? n : null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private GenericVisitorAdapter<EnumConstantDeclaration, Object> createVisitorToFindEnumConstant(IField field) {
|
||||
return new GenericVisitorAdapter<EnumConstantDeclaration, Object>() {
|
||||
@Override
|
||||
public EnumConstantDeclaration visit(EnumConstantDeclaration n, Object arg) {
|
||||
if (n.getName().equals(field.getElementName())) {
|
||||
return n;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.ide.vscode.commons.java.roaster;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.jboss.forge.roaster.Roaster;
|
||||
import org.jboss.forge.roaster.model.JavaUnit;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
public interface JavaUnitIndex {
|
||||
|
||||
static final JavaUnitIndex DEFAULT = new JavaUnitIndex() {
|
||||
|
||||
private LoadingCache<URL, JavaUnit> cache = CacheBuilder.newBuilder().build(new CacheLoader<URL, JavaUnit>() {
|
||||
|
||||
@Override
|
||||
public JavaUnit load(URL url) throws Exception {
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return Roaster.parseUnit(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Override
|
||||
public JavaUnit getJavaUnit(URL url) {
|
||||
try {
|
||||
return cache.get(url);
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
JavaUnit getJavaUnit(URL url);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.springframework.ide.vscode.commons.java.roaster;
|
||||
|
||||
import org.jboss.forge.roaster.model.JavaDoc;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
|
||||
public class RoasterJavadoc implements IJavadoc {
|
||||
|
||||
private JavaDoc<?> javadoc;
|
||||
|
||||
public RoasterJavadoc(JavaDoc<?> javadoc) {
|
||||
this.javadoc = javadoc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String raw() {
|
||||
return javadoc.getFullText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getRenderable() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package org.springframework.ide.vscode.commons.java.roaster;
|
||||
|
||||
import org.jboss.forge.roaster.model.Field;
|
||||
import org.jboss.forge.roaster.model.FieldHolder;
|
||||
import org.jboss.forge.roaster.model.JavaDocCapable;
|
||||
import org.jboss.forge.roaster.model.JavaType;
|
||||
import org.jboss.forge.roaster.model.JavaUnit;
|
||||
import org.jboss.forge.roaster.model.Method;
|
||||
import org.jboss.forge.roaster.model.MethodHolder;
|
||||
import org.jboss.forge.roaster.model.TypeHolder;
|
||||
import org.jboss.forge.roaster.model.source.JavaClassSource;
|
||||
import org.springframework.ide.vscode.commons.java.IAnnotation;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.javadoc.SourceUrlProvider;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
public class RoasterJavadocProvider implements IJavadocProvider {
|
||||
|
||||
private SourceUrlProvider sourceUrlProvider;
|
||||
|
||||
public RoasterJavadocProvider(SourceUrlProvider sourceUrlProvider) {
|
||||
this.sourceUrlProvider = sourceUrlProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IType type) {
|
||||
try {
|
||||
JavaClassSource declaration = (JavaClassSource) getDeclaration(type);
|
||||
return new RoasterJavadoc(declaration.getJavaDoc());
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IField field) {
|
||||
try {
|
||||
JavaType<?> typeDeclaration = getDeclaration(field.getDeclaringType());
|
||||
if (typeDeclaration instanceof FieldHolder) {
|
||||
Field<?> fieldDeclaration = ((FieldHolder<?>)typeDeclaration).getField(field.getElementName());
|
||||
if (fieldDeclaration instanceof JavaDocCapable) {
|
||||
return new RoasterJavadoc(((JavaDocCapable<?>)fieldDeclaration).getJavaDoc());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IMethod method) {
|
||||
if (method.parameters().findFirst().isPresent()) {
|
||||
throw new UnsupportedOperationException("Only methods with no parameters are supported");
|
||||
}
|
||||
try {
|
||||
JavaType<?> typeDeclaration = getDeclaration(method.getDeclaringType());
|
||||
if (typeDeclaration instanceof MethodHolder) {
|
||||
Method<?, ?> methodDeclaration = ((MethodHolder<?>)typeDeclaration).getMethod(method.getElementName());
|
||||
if (methodDeclaration instanceof JavaDocCapable) {
|
||||
return new RoasterJavadoc(((JavaDocCapable<?>)methodDeclaration).getJavaDoc());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IAnnotation annotation) {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
private JavaUnit getJavaUnit(IType type) throws Exception {
|
||||
return JavaUnitIndex.DEFAULT.getJavaUnit(sourceUrlProvider.sourceUrl(type));
|
||||
}
|
||||
|
||||
private JavaType<?> getDeclaration(IType type) throws Exception {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
IType declaringType = type.getDeclaringType();
|
||||
if (declaringType == null) {
|
||||
JavaUnit ju = getJavaUnit(type);
|
||||
return ju.getTopLevelTypes().stream().filter(jt -> jt.getName().equals(type.getElementName())).findFirst().orElse(null);
|
||||
} else {
|
||||
JavaType<?> declaringTypeDeclaration = getDeclaration(declaringType);
|
||||
if (declaringTypeDeclaration instanceof TypeHolder) {
|
||||
return ((TypeHolder<?>)declaringTypeDeclaration).getNestedType(type.getElementName());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
|
||||
public class HtmlJavadoc implements IJavadoc {
|
||||
|
||||
private String html;
|
||||
|
||||
public HtmlJavadoc(String html) {
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String raw() {
|
||||
throw new UnsupportedOperationException("Not yet implemnted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getRenderable() {
|
||||
return Renderables.htmlBlob(html);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.ide.vscode.commons.javadoc.internal.JavadocContents;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
|
||||
public interface HtmlJavadocIndex {
|
||||
|
||||
static JavadocContents NO_HTML_CONTENT = new JavadocContents(null);
|
||||
|
||||
public static final HtmlJavadocIndex DEFAULT = new HtmlJavadocIndex() {
|
||||
|
||||
private Cache<URL, JavadocContents> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
|
||||
@Override
|
||||
public JavadocContents getHtmlJavadoc(URL url) {
|
||||
try {
|
||||
JavadocContents content = cache.get(url, () -> {
|
||||
InputStream stream = null;
|
||||
try {
|
||||
stream = url.openStream();
|
||||
BufferedReader buffer = new BufferedReader(new InputStreamReader(stream));
|
||||
return new JavadocContents(buffer.lines().collect(Collectors.joining("\n")));
|
||||
} catch (IOException e) {
|
||||
Log.log("Cannot load javadoc content from " + url, e);
|
||||
return NO_HTML_CONTENT;
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
return content == NO_HTML_CONTENT ? null : content;
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JavadocContents getHtmlJavadoc(URL url);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IAnnotation;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.internal.JavadocContents;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
public class HtmlJavadocProvider implements IJavadocProvider {
|
||||
|
||||
private SourceUrlProvider htmlUrlProvider;
|
||||
|
||||
public HtmlJavadocProvider(SourceUrlProvider htmlUrlProvider) {
|
||||
this.htmlUrlProvider = htmlUrlProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IType type) {
|
||||
try {
|
||||
JavadocContents javadocContents = findHtml(type);
|
||||
String html = javadocContents == null ? null : javadocContents.getTypeDoc(type);
|
||||
return html == null ? null : new HtmlJavadoc(html);
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IField field) {
|
||||
try {
|
||||
IType declaringType = field.getDeclaringType();
|
||||
JavadocContents javadocContents = findHtml(declaringType);
|
||||
String html = javadocContents == null ? null : javadocContents.getFieldDoc(field);
|
||||
return html == null ? null : new HtmlJavadoc(html);
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IMethod method) {
|
||||
try {
|
||||
IType declaringType = method.getDeclaringType();
|
||||
JavadocContents javadocContents = findHtml(declaringType);
|
||||
String html = javadocContents == null ? null : javadocContents.getMethodDoc(method);
|
||||
return html == null ? null : new HtmlJavadoc(html);
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IAnnotation annotation) {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
private JavadocContents findHtml(IType type) throws Exception {
|
||||
URL url = htmlUrlProvider.sourceUrl(type);
|
||||
return HtmlJavadocIndex.DEFAULT.getHtmlJavadoc(url);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
|
||||
public interface IJavadoc {
|
||||
|
||||
String raw();
|
||||
|
||||
Renderable getRenderable();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
|
||||
public class RawJavadoc implements IJavadoc {
|
||||
|
||||
private String rawContent;
|
||||
|
||||
public RawJavadoc(String rawContent) {
|
||||
this.rawContent = rawContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String raw() {
|
||||
return rawContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getRenderable() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SourceUrlProvider {
|
||||
|
||||
URL sourceUrl(IType type) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SourceUrlProviderFromSourceContainer {
|
||||
|
||||
public static final SourceUrlProviderFromSourceContainer JAR_SOURCE_URL_PROVIDER = (sourceContainerUrl, type) -> {
|
||||
StringBuilder sourceUrlStr = new StringBuilder();
|
||||
sourceUrlStr.append("jar:");
|
||||
sourceUrlStr.append(sourceContainerUrl);
|
||||
sourceUrlStr.append("!");
|
||||
sourceUrlStr.append('/');
|
||||
sourceUrlStr.append(type.getFullyQualifiedName().replaceAll("\\.", "/"));
|
||||
sourceUrlStr.append(".java");
|
||||
return new URL(sourceUrlStr.toString());
|
||||
|
||||
};
|
||||
|
||||
public static final SourceUrlProviderFromSourceContainer SOURCE_FOLDER_URL_SUPPLIER = (sourceContainerUrl, type) -> {
|
||||
return Paths.get(sourceContainerUrl.toURI()).resolve(type.getFullyQualifiedName().replaceAll("\\.", "/") + ".java").toUri().toURL();
|
||||
};
|
||||
|
||||
public static final SourceUrlProviderFromSourceContainer JAR_JAVADOC_URL_PROVIDER = (javadocContainerUrl, type) -> {
|
||||
StringBuilder sourceUrlStr = new StringBuilder();
|
||||
sourceUrlStr.append("jar:");
|
||||
sourceUrlStr.append(javadocContainerUrl);
|
||||
sourceUrlStr.append("!");
|
||||
sourceUrlStr.append('/');
|
||||
// Inner classes are in separate Top.Nesting1.Nesting2.Nesting3.MyType.html files
|
||||
sourceUrlStr.append(type.getFullyQualifiedName().replaceAll("\\.", "/").replaceAll("\\$", "."));
|
||||
sourceUrlStr.append(".html");
|
||||
return new URL(sourceUrlStr.toString());
|
||||
|
||||
};
|
||||
|
||||
public static final SourceUrlProviderFromSourceContainer JAVADOC_FOLDER_URL_SUPPLIER = (sourceContainerUrl, type) -> {
|
||||
String urlStr = sourceContainerUrl.toString();
|
||||
StringBuilder sb = new StringBuilder(urlStr);
|
||||
if (!urlStr.endsWith("/")) {
|
||||
sb.append('/');
|
||||
}
|
||||
// Inner classes are in separate Top.Nesting1.Nesting2.Nesting3.MyType.html files
|
||||
sb.append(type.getFullyQualifiedName().replaceAll("\\.", "/").replaceAll("\\$", ".") + ".html");
|
||||
return new URL(sb.toString());
|
||||
};
|
||||
|
||||
URL sourceUrl(URL sourceContainerUrl, IType type) throws Exception;
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc.internal;
|
||||
|
||||
/**
|
||||
* Hashtable of {Object --> int[] }
|
||||
*/
|
||||
public final class HashtableOfObjectToIntArray implements Cloneable {
|
||||
|
||||
// to avoid using Enumerations, walk the individual tables skipping nulls
|
||||
public Object[] keyTable;
|
||||
public int[][] valueTable;
|
||||
|
||||
public int elementSize; // number of elements in the table
|
||||
int threshold;
|
||||
|
||||
public HashtableOfObjectToIntArray() {
|
||||
this(13);
|
||||
}
|
||||
|
||||
public HashtableOfObjectToIntArray(int size) {
|
||||
|
||||
this.elementSize = 0;
|
||||
this.threshold = size; // size represents the expected number of elements
|
||||
int extraRoom = (int) (size * 1.75f);
|
||||
if (this.threshold == extraRoom)
|
||||
extraRoom++;
|
||||
this.keyTable = new Object[extraRoom];
|
||||
this.valueTable = new int[extraRoom][];
|
||||
}
|
||||
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
HashtableOfObjectToIntArray result = (HashtableOfObjectToIntArray) super.clone();
|
||||
result.elementSize = this.elementSize;
|
||||
result.threshold = this.threshold;
|
||||
|
||||
int length = this.keyTable.length;
|
||||
result.keyTable = new Object[length];
|
||||
System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
|
||||
|
||||
length = this.valueTable.length;
|
||||
result.valueTable = new int[length][];
|
||||
System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
int length = this.keyTable.length,
|
||||
index = (key.hashCode()& 0x7FFFFFFF) % length;
|
||||
Object currentKey;
|
||||
while ((currentKey = this.keyTable[index]) != null) {
|
||||
if (currentKey.equals(key))
|
||||
return true;
|
||||
if (++index == length) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int[] get(Object key) {
|
||||
int length = this.keyTable.length,
|
||||
index = (key.hashCode()& 0x7FFFFFFF) % length;
|
||||
Object currentKey;
|
||||
while ((currentKey = this.keyTable[index]) != null) {
|
||||
if (currentKey.equals(key))
|
||||
return this.valueTable[index];
|
||||
if (++index == length) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void keysToArray(Object[] array) {
|
||||
int index = 0;
|
||||
for (int i=0, length=this.keyTable.length; i<length; i++) {
|
||||
if (this.keyTable[i] != null)
|
||||
array[index++] = this.keyTable[i];
|
||||
}
|
||||
}
|
||||
|
||||
public int[] put(Object key, int[] value) {
|
||||
int length = this.keyTable.length,
|
||||
index = (key.hashCode()& 0x7FFFFFFF) % length;
|
||||
Object currentKey;
|
||||
while ((currentKey = this.keyTable[index]) != null) {
|
||||
if (currentKey.equals(key))
|
||||
return this.valueTable[index] = value;
|
||||
if (++index == length) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
this.keyTable[index] = key;
|
||||
this.valueTable[index] = value;
|
||||
|
||||
// assumes the threshold is never equal to the size of the table
|
||||
if (++this.elementSize > this.threshold)
|
||||
rehash();
|
||||
return value;
|
||||
}
|
||||
|
||||
public int[] removeKey(Object key) {
|
||||
int length = this.keyTable.length,
|
||||
index = (key.hashCode()& 0x7FFFFFFF) % length;
|
||||
Object currentKey;
|
||||
while ((currentKey = this.keyTable[index]) != null) {
|
||||
if (currentKey.equals(key)) {
|
||||
int[] value = this.valueTable[index];
|
||||
this.elementSize--;
|
||||
this.keyTable[index] = null;
|
||||
rehash();
|
||||
return value;
|
||||
}
|
||||
if (++index == length) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void rehash() {
|
||||
|
||||
HashtableOfObjectToIntArray newHashtable = new HashtableOfObjectToIntArray(this.elementSize * 2); // double the number of expected elements
|
||||
Object currentKey;
|
||||
for (int i = this.keyTable.length; --i >= 0;)
|
||||
if ((currentKey = this.keyTable[i]) != null)
|
||||
newHashtable.put(currentKey, this.valueTable[i]);
|
||||
|
||||
this.keyTable = newHashtable.keyTable;
|
||||
this.valueTable = newHashtable.valueTable;
|
||||
this.threshold = newHashtable.threshold;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.elementSize;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
Object key;
|
||||
for (int i = 0, length = this.keyTable.length; i < length; i++) {
|
||||
if ((key = this.keyTable[i]) != null) {
|
||||
buffer.append(key).append(" -> "); //$NON-NLS-1$
|
||||
int[] ints = this.valueTable[i];
|
||||
buffer.append('[');
|
||||
if (ints != null) {
|
||||
for (int j = 0, max = ints.length; j < max; j++) {
|
||||
if (j > 0) {
|
||||
buffer.append(',');
|
||||
}
|
||||
buffer.append(ints[j]);
|
||||
}
|
||||
}
|
||||
buffer.append("]\n"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
return String.valueOf(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc.internal;
|
||||
|
||||
public interface JavadocConstants {
|
||||
|
||||
String ANCHOR_PREFIX_END = "\""; //$NON-NLS-1$
|
||||
char[] ANCHOR_PREFIX_START = "<A NAME=\"".toCharArray(); //$NON-NLS-1$
|
||||
int ANCHOR_PREFIX_START_LENGHT = ANCHOR_PREFIX_START.length;
|
||||
char[] ANCHOR_SUFFIX = "</A>".toCharArray(); //$NON-NLS-1$
|
||||
int ANCHOR_SUFFIX_LENGTH = JavadocConstants.ANCHOR_SUFFIX.length;
|
||||
char[] CONSTRUCTOR_DETAIL = "<!-- ========= CONSTRUCTOR DETAIL ======== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] CONSTRUCTOR_SUMMARY = "<!-- ======== CONSTRUCTOR SUMMARY ======== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] FIELD_DETAIL= "<!-- ============ FIELD DETAIL =========== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] FIELD_SUMMARY = "<!-- =========== FIELD SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] ENUM_CONSTANT_SUMMARY = "<!-- =========== ENUM CONSTANT SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] ANNOTATION_TYPE_REQUIRED_MEMBER_SUMMARY = "<!-- =========== ANNOTATION TYPE REQUIRED MEMBER SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] ANNOTATION_TYPE_OPTIONAL_MEMBER_SUMMARY = "<!-- =========== ANNOTATION TYPE OPTIONAL MEMBER SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] END_OF_CLASS_DATA = "<!-- ========= END OF CLASS DATA ========= -->".toCharArray(); //$NON-NLS-1$
|
||||
String HTML_EXTENSION = ".html"; //$NON-NLS-1$
|
||||
String INDEX_FILE_NAME = "index.html"; //$NON-NLS-1$
|
||||
char[] METHOD_DETAIL = "<!-- ============ METHOD DETAIL ========== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] METHOD_SUMMARY = "<!-- ========== METHOD SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] NESTED_CLASS_SUMMARY = "<!-- ======== NESTED CLASS SUMMARY ======== -->".toCharArray(); //$NON-NLS-1$
|
||||
String PACKAGE_FILE_NAME = "package-summary.html"; //$NON-NLS-1$
|
||||
char[] PACKAGE_DESCRIPTION_START = "name=\"package_description\"".toCharArray(); //$NON-NLS-1$
|
||||
char[] PACKAGE_DESCRIPTION_START2 = "name=\"package.description\"".toCharArray(); //$NON-NLS-1$
|
||||
char[] H2_PREFIX = "<H2".toCharArray(); //$NON-NLS-1$
|
||||
char[] H2_SUFFIX = "</H2>".toCharArray(); //$NON-NLS-1$
|
||||
int H2_SUFFIX_LENGTH = H2_SUFFIX.length;
|
||||
char[] BOTTOM_NAVBAR = "<!-- ======= START OF BOTTOM NAVBAR ====== -->".toCharArray(); //$NON-NLS-1$
|
||||
char[] SEPARATOR_START = "<!-- =".toCharArray(); //$NON-NLS-1$
|
||||
char[] START_OF_CLASS_DATA = "<!-- ======== START OF CLASS DATA ======== -->".toCharArray(); //$NON-NLS-1$
|
||||
int START_OF_CLASS_DATA_LENGTH = JavadocConstants.START_OF_CLASS_DATA.length;
|
||||
String P = "<P>"; //$NON-NLS-1$
|
||||
String DIV_CLASS_BLOCK = "<DIV CLASS=\"BLOCK\">"; //$NON-NLS-1$
|
||||
}
|
||||
@@ -0,0 +1,627 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
|
||||
public class JavadocContents {
|
||||
private static final int[] UNKNOWN_FORMAT = new int[0];
|
||||
|
||||
// private IType type;
|
||||
private char[] content;
|
||||
|
||||
private int childrenStart;
|
||||
|
||||
private boolean hasComputedChildrenSections = false;
|
||||
private int indexOfFieldDetails;
|
||||
private int indexOfConstructorDetails;
|
||||
private int indexOfMethodDetails;
|
||||
private int indexOfEndOfClassData;
|
||||
|
||||
private int indexOfFieldsBottom;
|
||||
private int indexOfAllMethodsTop;
|
||||
private int indexOfAllMethodsBottom;
|
||||
|
||||
private int[] typeDocRange;
|
||||
private HashtableOfObjectToIntArray fieldDocRanges;
|
||||
private HashtableOfObjectToIntArray methodDocRanges;
|
||||
|
||||
private int[] fieldAnchorIndexes;
|
||||
private int fieldAnchorIndexesCount;
|
||||
private int fieldLastAnchorFoundIndex;
|
||||
private int[] methodAnchorIndexes;
|
||||
private int methodAnchorIndexesCount;
|
||||
private int methodLastAnchorFoundIndex;
|
||||
private int[] unknownFormatAnchorIndexes;
|
||||
private int unknownFormatAnchorIndexesCount;
|
||||
private int unknownFormatLastAnchorFoundIndex;
|
||||
private int[] tempAnchorIndexes;
|
||||
private int tempAnchorIndexesCount;
|
||||
private int tempLastAnchorFoundIndex;
|
||||
|
||||
// public JavadocContents(IType type, String content) {
|
||||
// this(content);
|
||||
// this.type = type;
|
||||
// }
|
||||
|
||||
public JavadocContents(String content) {
|
||||
this.content = content != null ? content.toCharArray() : null;
|
||||
}
|
||||
/*
|
||||
* Returns the part of the javadoc that describe the type
|
||||
*/
|
||||
public String getTypeDoc(IType type) throws Exception {
|
||||
if (this.content == null) return null;
|
||||
|
||||
synchronized (this) {
|
||||
if (this.typeDocRange == null) {
|
||||
computeTypeRange(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.typeDocRange != null) {
|
||||
if (this.typeDocRange == UNKNOWN_FORMAT) throw new Exception("Unknown javadoc format " + type);
|
||||
return String.valueOf(CharOperation.subarray(this.content, this.typeDocRange[0], this.typeDocRange[1]));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// public String getPackageDoc() throws JavaModelException {
|
||||
// if (this.content == null) return null;
|
||||
// int[] range = null;
|
||||
// int index = CharOperation.indexOf(JavadocConstants.PACKAGE_DESCRIPTION_START2, this.content, false, 0);
|
||||
// if (index == -1) {
|
||||
// index = CharOperation.indexOf(JavadocConstants.PACKAGE_DESCRIPTION_START, this.content, false, 0);
|
||||
// }
|
||||
// if (index == -1) return null;
|
||||
// index = CharOperation.indexOf(JavadocConstants.ANCHOR_SUFFIX, this.content, false, index);
|
||||
// if (index == -1) return null;
|
||||
//
|
||||
// int start = CharOperation.indexOf(JavadocConstants.H2_PREFIX, this.content, false, index);
|
||||
// if (start != -1) {
|
||||
// start = CharOperation.indexOf(JavadocConstants.H2_SUFFIX, this.content, false, start);
|
||||
// if (start != -1) index = start + JavadocConstants.H2_SUFFIX_LENGTH;
|
||||
// }
|
||||
// if (index != -1) {
|
||||
// int end = CharOperation.indexOf(JavadocConstants.BOTTOM_NAVBAR, this.content, false, index);
|
||||
// if (end == -1) end = this.content.length -1;
|
||||
// range = new int[]{index, end};
|
||||
// return String.valueOf(CharOperation.subarray(this.content, range[0], range[1]));
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
/*
|
||||
* Returns the part of the javadoc that describe a field of the type
|
||||
*/
|
||||
public String getFieldDoc(IField child) throws Exception {
|
||||
if (this.content == null) return null;
|
||||
|
||||
int[] range = null;
|
||||
synchronized (this) {
|
||||
if (this.fieldDocRanges == null) {
|
||||
this.fieldDocRanges = new HashtableOfObjectToIntArray();
|
||||
} else {
|
||||
range = this.fieldDocRanges.get(child);
|
||||
}
|
||||
|
||||
if (range == null) {
|
||||
range = computeFieldRange(child);
|
||||
this.fieldDocRanges.put(child, range);
|
||||
}
|
||||
}
|
||||
|
||||
if (range != null) {
|
||||
if (range == UNKNOWN_FORMAT) throw new Exception("Unknown javadoc format " + child);
|
||||
return String.valueOf(CharOperation.subarray(this.content, range[0], range[1]));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the part of the javadoc that describe a method of the type
|
||||
*/
|
||||
public String getMethodDoc(IMethod method) throws Exception {
|
||||
if (this.content == null) return null;
|
||||
|
||||
int[] range = null;
|
||||
synchronized (this) {
|
||||
if (this.methodDocRanges == null) {
|
||||
this.methodDocRanges = new HashtableOfObjectToIntArray();
|
||||
} else {
|
||||
range = this.methodDocRanges.get(method);
|
||||
}
|
||||
|
||||
if (range == null) {
|
||||
range = computeMethodRange(method);
|
||||
this.methodDocRanges.put(method, range);
|
||||
}
|
||||
}
|
||||
|
||||
if (range != null) {
|
||||
if (range == UNKNOWN_FORMAT) {
|
||||
throw new Exception("Unknown javadoc format " + method);
|
||||
}
|
||||
return String.valueOf(CharOperation.subarray(this.content, range[0], range[1]));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the ranges of the parts of the javadoc that describe each method of the type
|
||||
*/
|
||||
private int[] computeChildRange(char[] anchor, int indexOfSectionBottom) throws Exception {
|
||||
|
||||
// checks each known anchor locations
|
||||
if (this.tempAnchorIndexesCount > 0) {
|
||||
for (int i = 0; i < this.tempAnchorIndexesCount; i++) {
|
||||
int anchorEndStart = this.tempAnchorIndexes[i];
|
||||
|
||||
if (anchorEndStart != -1 && CharOperation.prefixEquals(anchor, this.content, false, anchorEndStart)) {
|
||||
|
||||
this.tempAnchorIndexes[i] = -1;
|
||||
|
||||
return computeChildRange(anchorEndStart, anchor, indexOfSectionBottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fromIndex = this.tempLastAnchorFoundIndex;
|
||||
int index;
|
||||
|
||||
// check each next unknown anchor locations
|
||||
while ((index = CharOperation.indexOf(JavadocConstants.ANCHOR_PREFIX_START, this.content, false, fromIndex)) != -1 && (index < indexOfSectionBottom || indexOfSectionBottom == -1)) {
|
||||
fromIndex = index + 1;
|
||||
|
||||
int anchorEndStart = index + JavadocConstants.ANCHOR_PREFIX_START_LENGHT;
|
||||
|
||||
this.tempLastAnchorFoundIndex = anchorEndStart;
|
||||
|
||||
if (CharOperation.prefixEquals(anchor, this.content, false, anchorEndStart)) {
|
||||
return computeChildRange(anchorEndStart, anchor, indexOfSectionBottom);
|
||||
} else {
|
||||
if (this.tempAnchorIndexes.length == this.tempAnchorIndexesCount) {
|
||||
System.arraycopy(this.tempAnchorIndexes, 0, this.tempAnchorIndexes = new int[this.tempAnchorIndexesCount + 20], 0, this.tempAnchorIndexesCount);
|
||||
}
|
||||
|
||||
this.tempAnchorIndexes[this.tempAnchorIndexesCount++] = anchorEndStart;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int[] computeChildRange(int anchorEndStart, char[] anchor, int indexOfBottom) {
|
||||
int[] range = null;
|
||||
|
||||
// try to find the bottom of the section
|
||||
if (indexOfBottom != -1) {
|
||||
// try to find the end of the anchor
|
||||
int indexOfEndLink = CharOperation.indexOf(JavadocConstants.ANCHOR_SUFFIX, this.content, false, anchorEndStart + anchor.length);
|
||||
if (indexOfEndLink != -1) {
|
||||
// try to find the next anchor
|
||||
int indexOfNextElement = CharOperation.indexOf(JavadocConstants.ANCHOR_PREFIX_START, this.content, false, indexOfEndLink);
|
||||
|
||||
int javadocStart = indexOfEndLink + JavadocConstants.ANCHOR_SUFFIX_LENGTH;
|
||||
int javadocEnd = indexOfNextElement == -1 ? indexOfBottom : Math.min(indexOfNextElement, indexOfBottom);
|
||||
range = sanitizeRange(new int[]{javadocStart, javadocEnd}, "ul", "li");
|
||||
} else {
|
||||
// the anchor has no suffix
|
||||
range = UNKNOWN_FORMAT;
|
||||
}
|
||||
} else {
|
||||
// the detail section has no bottom
|
||||
range = UNKNOWN_FORMAT;
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
private void computeChildrenSections() {
|
||||
// try to find the next separator part
|
||||
int lastIndex = CharOperation.indexOf(JavadocConstants.SEPARATOR_START, this.content, false, this.childrenStart);
|
||||
lastIndex = lastIndex == -1 ? this.childrenStart : lastIndex;
|
||||
|
||||
// try to find field detail start
|
||||
this.indexOfFieldDetails = CharOperation.indexOf(JavadocConstants.FIELD_DETAIL, this.content, false, lastIndex);
|
||||
lastIndex = this.indexOfFieldDetails == -1 ? lastIndex : this.indexOfFieldDetails;
|
||||
|
||||
// try to find constructor detail start
|
||||
this.indexOfConstructorDetails = CharOperation.indexOf(JavadocConstants.CONSTRUCTOR_DETAIL, this.content, false, lastIndex);
|
||||
lastIndex = this.indexOfConstructorDetails == -1 ? lastIndex : this.indexOfConstructorDetails;
|
||||
|
||||
// try to find method detail start
|
||||
this.indexOfMethodDetails = CharOperation.indexOf(JavadocConstants.METHOD_DETAIL, this.content, false, lastIndex);
|
||||
lastIndex = this.indexOfMethodDetails == -1 ? lastIndex : this.indexOfMethodDetails;
|
||||
|
||||
// we take the end of class data
|
||||
final int indexOfStartOfClassData = CharOperation.indexOf(JavadocConstants.START_OF_CLASS_DATA, this.content, false);
|
||||
this.indexOfEndOfClassData = CharOperation.indexOf(JavadocConstants.END_OF_CLASS_DATA, this.content, false, lastIndex);
|
||||
int[] classDataRange = sanitizeRange(new int[] { indexOfStartOfClassData + JavadocConstants.START_OF_CLASS_DATA.length, indexOfEndOfClassData}, "ul", "li", "div");
|
||||
this.indexOfEndOfClassData = classDataRange[1];
|
||||
|
||||
// try to find the field detail end
|
||||
this.indexOfFieldsBottom =
|
||||
this.indexOfConstructorDetails != -1 ? this.indexOfConstructorDetails :
|
||||
this.indexOfMethodDetails != -1 ? this.indexOfMethodDetails:
|
||||
this.indexOfEndOfClassData;
|
||||
|
||||
this.indexOfAllMethodsTop =
|
||||
this.indexOfConstructorDetails != -1 ?
|
||||
this.indexOfConstructorDetails :
|
||||
this.indexOfMethodDetails;
|
||||
|
||||
this.indexOfAllMethodsBottom = this.indexOfEndOfClassData;
|
||||
|
||||
// Get rid of possible <ul><li> tag wrappers
|
||||
int[] fieldsRange = sanitizeRange(new int[] {indexOfFieldDetails + JavadocConstants.FIELD_DETAIL.length, indexOfFieldsBottom}, "ul", "li", "div");
|
||||
indexOfFieldDetails = fieldsRange[0];
|
||||
indexOfFieldsBottom = fieldsRange[1];
|
||||
|
||||
int[] methodsRange = sanitizeRange(new int[] {
|
||||
indexOfAllMethodsTop + (indexOfAllMethodsTop == indexOfConstructorDetails
|
||||
? JavadocConstants.CONSTRUCTOR_DETAIL.length : JavadocConstants.METHOD_DETAIL.length),
|
||||
indexOfAllMethodsBottom }, "ul", "li", "div");
|
||||
indexOfAllMethodsTop = methodsRange[0];
|
||||
indexOfAllMethodsBottom = methodsRange[1];
|
||||
|
||||
// Remove trailing extra tag closings
|
||||
String badEnding = "</li>\n</ul>\n</li>\n</ul>";
|
||||
indexOfAllMethodsBottom = trimBadEnding(badEnding, indexOfAllMethodsBottom, badEnding.length() / 2);
|
||||
|
||||
this.hasComputedChildrenSections = true;
|
||||
|
||||
}
|
||||
|
||||
private int trimBadEnding(String badEnding, int end) {
|
||||
return trimBadEnding(badEnding, end, badEnding.length());
|
||||
}
|
||||
|
||||
private int trimBadEnding(String badEnding, int end, int numberOfCharsToTrim) {
|
||||
if (Arrays.equals(CharOperation.subarray(content, end - badEnding.length(), end), badEnding.toCharArray())) {
|
||||
return end - numberOfCharsToTrim;
|
||||
} else {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the ranges of the parts of the javadoc that describe each child of the type (fields, methods)
|
||||
*/
|
||||
private int[] computeFieldRange(IField field) throws Exception {
|
||||
IType type = field.getDeclaringType();
|
||||
|
||||
if (!this.hasComputedChildrenSections) {
|
||||
computeChildrenSections();
|
||||
}
|
||||
|
||||
StringBuffer buffer = new StringBuffer(field.getElementName());
|
||||
buffer.append(JavadocConstants.ANCHOR_PREFIX_END);
|
||||
char[] anchor = String.valueOf(buffer).toCharArray();
|
||||
|
||||
int[] range = null;
|
||||
|
||||
if (this.indexOfFieldDetails == -1 || this.indexOfFieldsBottom == -1) {
|
||||
// the detail section has no top or bottom, so the doc has an unknown format
|
||||
if (this.unknownFormatAnchorIndexes == null) {
|
||||
this.unknownFormatAnchorIndexes = new int[(int)type.getFields().count()];
|
||||
this.unknownFormatAnchorIndexesCount = 0;
|
||||
this.unknownFormatLastAnchorFoundIndex = this.childrenStart;
|
||||
}
|
||||
|
||||
this.tempAnchorIndexes = this.unknownFormatAnchorIndexes;
|
||||
this.tempAnchorIndexesCount = this.unknownFormatAnchorIndexesCount;
|
||||
this.tempLastAnchorFoundIndex = this.unknownFormatLastAnchorFoundIndex;
|
||||
|
||||
range = computeChildRange(anchor, this.indexOfFieldsBottom);
|
||||
|
||||
this.unknownFormatLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
|
||||
this.unknownFormatAnchorIndexesCount = this.tempAnchorIndexesCount;
|
||||
this.unknownFormatAnchorIndexes = this.tempAnchorIndexes;
|
||||
} else {
|
||||
if (this.fieldAnchorIndexes == null) {
|
||||
this.fieldAnchorIndexes = new int[(int)type.getFields().count()];
|
||||
this.fieldAnchorIndexesCount = 0;
|
||||
this.fieldLastAnchorFoundIndex = this.indexOfFieldDetails;
|
||||
}
|
||||
|
||||
this.tempAnchorIndexes = this.fieldAnchorIndexes;
|
||||
this.tempAnchorIndexesCount = this.fieldAnchorIndexesCount;
|
||||
this.tempLastAnchorFoundIndex = this.fieldLastAnchorFoundIndex;
|
||||
|
||||
range = computeChildRange(anchor, this.indexOfFieldsBottom);
|
||||
|
||||
this.fieldLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
|
||||
this.fieldAnchorIndexesCount = this.tempAnchorIndexesCount;
|
||||
this.fieldAnchorIndexes = this.tempAnchorIndexes;
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the ranges of the parts of the javadoc that describe each method of the type
|
||||
*/
|
||||
private int[] computeMethodRange(IMethod method) throws Exception {
|
||||
IType type = method.getDeclaringType();
|
||||
|
||||
if (!this.hasComputedChildrenSections) {
|
||||
computeChildrenSections();
|
||||
}
|
||||
|
||||
char[] anchor = computeMethodAnchorPrefixEnd(method).toCharArray();
|
||||
|
||||
int[] range = null;
|
||||
|
||||
|
||||
if (this.indexOfAllMethodsTop == -1 || this.indexOfAllMethodsBottom == -1) {
|
||||
// the detail section has no top or bottom, so the doc has an unknown format
|
||||
if (this.unknownFormatAnchorIndexes == null) {
|
||||
int childernCount = (int)(type.getMethods().count() + type.getFields().count());
|
||||
this.unknownFormatAnchorIndexes = new int[childernCount];
|
||||
this.unknownFormatAnchorIndexesCount = 0;
|
||||
this.unknownFormatLastAnchorFoundIndex = this.childrenStart;
|
||||
}
|
||||
|
||||
this.tempAnchorIndexes = this.unknownFormatAnchorIndexes;
|
||||
this.tempAnchorIndexesCount = this.unknownFormatAnchorIndexesCount;
|
||||
this.tempLastAnchorFoundIndex = this.unknownFormatLastAnchorFoundIndex;
|
||||
|
||||
range = computeChildRange(anchor, this.indexOfFieldsBottom);
|
||||
if (range == null) {
|
||||
range = computeChildRange(getJavadoc8Anchor(anchor), this.indexOfAllMethodsBottom);
|
||||
}
|
||||
|
||||
this.unknownFormatLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
|
||||
this.unknownFormatAnchorIndexesCount = this.tempAnchorIndexesCount;
|
||||
this.unknownFormatAnchorIndexes = this.tempAnchorIndexes;
|
||||
} else {
|
||||
if (this.methodAnchorIndexes == null) {
|
||||
this.methodAnchorIndexes = new int[(int)type.getMethods().count()];
|
||||
this.methodAnchorIndexesCount = 0;
|
||||
this.methodLastAnchorFoundIndex = this.indexOfAllMethodsTop;
|
||||
}
|
||||
|
||||
this.tempAnchorIndexes = this.methodAnchorIndexes;
|
||||
this.tempAnchorIndexesCount = this.methodAnchorIndexesCount;
|
||||
this.tempLastAnchorFoundIndex = this.methodLastAnchorFoundIndex;
|
||||
|
||||
range = computeChildRange(anchor, this.indexOfAllMethodsBottom);
|
||||
if (range == null) {
|
||||
range = computeChildRange(getJavadoc8Anchor(anchor), this.indexOfAllMethodsBottom);
|
||||
}
|
||||
|
||||
this.methodLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
|
||||
this.methodAnchorIndexesCount = this.tempAnchorIndexesCount;
|
||||
this.methodAnchorIndexes = this.tempAnchorIndexes;
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
private static char[] getJavadoc8Anchor(char[] anchor) {
|
||||
// fix for bug 432284: [1.8] Javadoc-8-style anchors not found by IMethod#getAttachedJavadoc(..)
|
||||
char[] anchor8 = new char[anchor.length];
|
||||
int i8 = 0;
|
||||
for (int i = 0; i < anchor.length; i++) {
|
||||
char ch = anchor[i];
|
||||
switch (ch) {
|
||||
case '(':
|
||||
case ')':
|
||||
case ',':
|
||||
anchor8[i8++] = '-';
|
||||
break;
|
||||
case '[':
|
||||
anchor8[i8++] = ':';
|
||||
anchor8[i8++] = 'A';
|
||||
break;
|
||||
case ' ': // handled by preceding ','
|
||||
case ']': // handled by preceding '['
|
||||
break;
|
||||
default:
|
||||
anchor8[i8++] = ch;
|
||||
}
|
||||
}
|
||||
if (i8 != anchor.length) {
|
||||
anchor8 = CharOperation.subarray(anchor8, 0, i8);
|
||||
}
|
||||
return anchor8;
|
||||
}
|
||||
|
||||
private String computeMethodAnchorPrefixEnd(IMethod method) throws Exception {
|
||||
// String typeQualifiedName = null;
|
||||
// if (this.type.isMember()) {
|
||||
// IType currentType = this.type;
|
||||
// StringBuffer buffer = new StringBuffer();
|
||||
// while (currentType != null) {
|
||||
// buffer.insert(0, currentType.getElementName());
|
||||
// currentType = currentType.getDeclaringType();
|
||||
// if (currentType != null) {
|
||||
// buffer.insert(0, '.');
|
||||
// }
|
||||
// }
|
||||
// typeQualifiedName = new String(buffer.toString());
|
||||
// } else {
|
||||
// typeQualifiedName = this.type.getElementName();
|
||||
// }
|
||||
|
||||
// String methodName = method.getElementName();
|
||||
// if (method.getElementName().equals(method.getDeclaringType().getElementName())) {
|
||||
// methodName = typeQualifiedName;
|
||||
// }
|
||||
|
||||
String anchor = createMethodAnchor(method);
|
||||
|
||||
// char[] genericSignature = info.getGenericSignature();
|
||||
// if (genericSignature != null) {
|
||||
// genericSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
|
||||
// anchor = Util.toAnchor(0, genericSignature, methodName, Flags.isVarargs(method.getFlags()));
|
||||
// if (anchor == null) throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.UNKNOWN_JAVADOC_FORMAT, method));
|
||||
// } else {
|
||||
// anchor = Signature.toString(method.getSignature().replace('/', '.'), methodName, null, true, false, Flags.isVarargs(method.getFlags()));
|
||||
// }
|
||||
|
||||
// IType declaringType = /*this.type*/method.getDeclaringType();
|
||||
// if (declaringType.isMember()) {
|
||||
// // might need to remove a part of the signature corresponding to the synthetic argument (only for constructor)
|
||||
// if (method.getElementName().equals(method.getDeclaringType().getElementName()) && !Flags.isStatic(declaringType.getFlags())) {
|
||||
// int indexOfOpeningParen = anchor.indexOf('(');
|
||||
// if (indexOfOpeningParen == -1) {
|
||||
// // should not happen as this is a method signature
|
||||
// return null;
|
||||
// }
|
||||
// int index = indexOfOpeningParen;
|
||||
// indexOfOpeningParen++;
|
||||
// int indexOfComma = anchor.indexOf(',', index);
|
||||
// if (indexOfComma != -1) {
|
||||
// index = indexOfComma + 2;
|
||||
// } else {
|
||||
// // no argument, but a synthetic argument
|
||||
// index = anchor.indexOf(')', index);
|
||||
// }
|
||||
// anchor = anchor.substring(0, indexOfOpeningParen) + anchor.substring(index);
|
||||
// }
|
||||
// }
|
||||
return anchor + JavadocConstants.ANCHOR_PREFIX_END;
|
||||
}
|
||||
|
||||
private String createMethodAnchor(IMethod method) {
|
||||
StringBuilder sb = new StringBuilder(method.getElementName());
|
||||
sb.append('(');
|
||||
sb.append(String.join(",", method.parameters().map(p -> p.toString()).collect(Collectors.toList())));
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the range of the part of the javadoc that describe the type
|
||||
*/
|
||||
private void computeTypeRange(IType type) throws Exception {
|
||||
final int indexOfStartOfClassData = CharOperation.indexOf(JavadocConstants.START_OF_CLASS_DATA, this.content, false);
|
||||
if (indexOfStartOfClassData == -1) {
|
||||
this.typeDocRange = UNKNOWN_FORMAT;
|
||||
return;
|
||||
}
|
||||
int indexOfNextSeparator = CharOperation.indexOf(JavadocConstants.SEPARATOR_START, this.content, false, indexOfStartOfClassData);
|
||||
if (indexOfNextSeparator == -1) {
|
||||
this.typeDocRange = UNKNOWN_FORMAT;
|
||||
return;
|
||||
}
|
||||
int indexOfNextSummary = CharOperation.indexOf(JavadocConstants.NESTED_CLASS_SUMMARY, this.content, false, indexOfNextSeparator);
|
||||
if (indexOfNextSummary == -1 && type.isEnum()) {
|
||||
// try to find enum constant summary start
|
||||
indexOfNextSummary = CharOperation.indexOf(JavadocConstants.ENUM_CONSTANT_SUMMARY, this.content, false, indexOfNextSeparator);
|
||||
}
|
||||
if (indexOfNextSummary == -1 && type.isAnnotation()) {
|
||||
// try to find required enum constant summary start
|
||||
indexOfNextSummary = CharOperation.indexOf(JavadocConstants.ANNOTATION_TYPE_REQUIRED_MEMBER_SUMMARY, this.content, false, indexOfNextSeparator);
|
||||
if (indexOfNextSummary == -1) {
|
||||
// try to find optional enum constant summary start
|
||||
indexOfNextSummary = CharOperation.indexOf(JavadocConstants.ANNOTATION_TYPE_OPTIONAL_MEMBER_SUMMARY, this.content, false, indexOfNextSeparator);
|
||||
}
|
||||
}
|
||||
if (indexOfNextSummary == -1) {
|
||||
// try to find field summary start
|
||||
indexOfNextSummary = CharOperation.indexOf(JavadocConstants.FIELD_SUMMARY, this.content, false, indexOfNextSeparator);
|
||||
}
|
||||
if (indexOfNextSummary == -1) {
|
||||
// try to find constructor summary start
|
||||
indexOfNextSummary = CharOperation.indexOf(JavadocConstants.CONSTRUCTOR_SUMMARY, this.content, false, indexOfNextSeparator);
|
||||
}
|
||||
if (indexOfNextSummary == -1) {
|
||||
// try to find method summary start
|
||||
indexOfNextSummary = CharOperation.indexOf(JavadocConstants.METHOD_SUMMARY, this.content, false, indexOfNextSeparator);
|
||||
}
|
||||
|
||||
if (indexOfNextSummary == -1) {
|
||||
// we take the end of class data
|
||||
indexOfNextSummary = CharOperation.indexOf(JavadocConstants.END_OF_CLASS_DATA, this.content, false, indexOfNextSeparator);
|
||||
} else {
|
||||
// improve performance of computation of children ranges
|
||||
this.childrenStart = indexOfNextSummary + 1;
|
||||
}
|
||||
|
||||
if (indexOfNextSummary == -1) {
|
||||
this.typeDocRange = UNKNOWN_FORMAT;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Cut off the type hierarchy, see bug 119844.
|
||||
* We remove the contents between the start of class data and where
|
||||
* we guess the actual class comment starts.
|
||||
*/
|
||||
int start = indexOfStartOfClassData + JavadocConstants.START_OF_CLASS_DATA_LENGTH;
|
||||
int indexOfFirstParagraph = CharOperation.indexOf(JavadocConstants.P.toCharArray(), this.content, false, start, indexOfNextSummary);
|
||||
int indexOfFirstDiv = CharOperation.indexOf(JavadocConstants.DIV_CLASS_BLOCK.toCharArray(), this.content, false, start, indexOfNextSummary);
|
||||
int afterHierarchy = indexOfNextSummary;
|
||||
if (indexOfFirstParagraph != -1 && indexOfFirstParagraph < afterHierarchy) {
|
||||
afterHierarchy = indexOfFirstParagraph;
|
||||
}
|
||||
if (indexOfFirstDiv != -1 && indexOfFirstDiv < afterHierarchy) {
|
||||
afterHierarchy = indexOfFirstDiv;
|
||||
}
|
||||
if (afterHierarchy != indexOfNextSummary) {
|
||||
start = afterHierarchy;
|
||||
|
||||
int indexOfClassDescriptionEnd = trimBadEnding("<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n", indexOfNextSummary);
|
||||
indexOfClassDescriptionEnd = trimBadEnding("</li>\n</ul>\n</div>\n", indexOfClassDescriptionEnd);
|
||||
this.typeDocRange = new int[]{start, indexOfClassDescriptionEnd};
|
||||
this.typeDocRange = sanitizeRange(typeDocRange, "ul", "li");
|
||||
} else {
|
||||
// No room left for class comment;
|
||||
this.typeDocRange = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private int[] trimRange(int[] range) {
|
||||
int start = range[0];
|
||||
int end = range[1];
|
||||
|
||||
while (start < content.length && start < end && Character.isWhitespace(content[start])) {
|
||||
start++;
|
||||
}
|
||||
|
||||
while (end > 0 && start < end && Character.isWhitespace(content[end-1])) {
|
||||
end--;
|
||||
}
|
||||
|
||||
return new int[] { start, end };
|
||||
}
|
||||
|
||||
private int[] trimTag(int[] range, CharSequence tag) {
|
||||
int start = range[0];
|
||||
int end = range[1];
|
||||
|
||||
char[] startingTag = ("<" + tag).toCharArray();
|
||||
char[] closingTag = ("</" + tag + ">").toCharArray();
|
||||
char[] ending = CharOperation.subarray(content, end - closingTag.length, end);
|
||||
char[] starting = CharOperation.subarray(content, start, start + startingTag.length);
|
||||
if (Arrays.equals(closingTag, ending) && Arrays.equals(startingTag, starting)) {
|
||||
return new int[] { CharOperation.indexOf('>', content, start, end) + 1, end - closingTag.length};
|
||||
} else {
|
||||
return range;
|
||||
}
|
||||
}
|
||||
|
||||
private int[] sanitizeRange(int[] range, CharSequence... removeWrapperTags) {
|
||||
boolean changed = false;
|
||||
do {
|
||||
int[] newRange = trimRange(range);
|
||||
for (CharSequence tag : removeWrapperTags) {
|
||||
newRange = trimTag(newRange, tag);
|
||||
}
|
||||
// newRange = trimTag(newRange, "div");
|
||||
// newRange = trimTag(newRange, "ul");
|
||||
// newRange = trimTag(newRange, "li");
|
||||
changed = !Arrays.equals(newRange, range);
|
||||
range = newRange;
|
||||
} while (changed);
|
||||
return range;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
package org.springframework.ide.vscode.commons.javadoc.internal;
|
||||
|
||||
public class ScannerHelper {
|
||||
|
||||
// storage for internal flags (32 bits) BIT USAGE
|
||||
public final static int Bit1 = 0x1; // return type (operator) | name reference kind (name ref) | add assertion (type decl) | useful empty statement (empty statement)
|
||||
public final static int Bit2 = 0x2; // return type (operator) | name reference kind (name ref) | has local type (type, method, field decl) | if type elided (local)
|
||||
public final static int Bit3 = 0x4; // return type (operator) | name reference kind (name ref) | implicit this (this ref) | is argument(local)
|
||||
public final static int Bit4 = 0x8; // return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl)
|
||||
public final static int Bit5 = 0x10; // value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl)
|
||||
public final static int Bit6 = 0x20; // depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer) | is recovered (annotation reference)
|
||||
public final static int Bit7 = 0x40; // depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) | needFreeReturn (AbstractMethodDeclaration)
|
||||
public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration) | isElseStatementUnreachable (if statement)
|
||||
public final static int Bit9 = 0x100; // depth (name ref, msg) | operator (operator) | is local type (type decl) | isThenStatementUnreachable (if statement) | can be static
|
||||
public final static int Bit10= 0x200; // depth (name ref, msg) | operator (operator) | is anonymous type (type decl)
|
||||
public final static int Bit11 = 0x400; // depth (name ref, msg) | operator (operator) | is member type (type decl)
|
||||
public final static int Bit12 = 0x800; // depth (name ref, msg) | operator (operator) | has abstract methods (type decl)
|
||||
public final static int Bit13 = 0x1000; // depth (name ref, msg) | is secondary type (type decl)
|
||||
public final static int Bit14 = 0x2000; // strictly assigned (reference lhs) | discard enclosing instance (explicit constr call) | hasBeenGenerated (type decl)
|
||||
public final static int Bit15 = 0x4000; // is unnecessary cast (expression) | is varargs (type ref) | isSubRoutineEscaping (try statement) | superAccess (javadoc allocation expression/javadoc message send/javadoc return statement)
|
||||
public final static int Bit16 = 0x8000; // in javadoc comment (name ref, type ref, msg)
|
||||
public final static int Bit17 = 0x10000; // compound assigned (reference lhs) | unchecked (msg, alloc, explicit constr call)
|
||||
public final static int Bit18 = 0x20000; // non null (expression) | onDemand (import reference)
|
||||
public final static int Bit19 = 0x40000; // didResolve (parameterized qualified type ref/parameterized single type ref) | empty (javadoc return statement) | needReceiverGenericCast (msg/fieldref)
|
||||
public final static int Bit20 = 0x80000; // contains syntax errors (method declaration, type declaration, field declarations, initializer), typeref: <> name ref: lambda capture)
|
||||
public final static int Bit21 = 0x100000;
|
||||
public final static int Bit22 = 0x200000; // parenthesis count (expression) | used (import reference) shadows outer local (local declarations)
|
||||
public final static int Bit23 = 0x400000; // parenthesis count (expression)
|
||||
public final static int Bit24 = 0x800000; // parenthesis count (expression)
|
||||
public final static int Bit25 = 0x1000000; // parenthesis count (expression)
|
||||
public final static int Bit26 = 0x2000000; // parenthesis count (expression)
|
||||
public final static int Bit27 = 0x4000000; // parenthesis count (expression)
|
||||
public final static int Bit28 = 0x8000000; // parenthesis count (expression)
|
||||
public final static int Bit29 = 0x10000000; // parenthesis count (expression)
|
||||
public final static int Bit30 = 0x20000000; // elseif (if statement) | try block exit (try statement) | fall-through (case statement) | ignore no effect assign (expression ref) | needScope (for statement) | isAnySubRoutineEscaping (return statement) | blockExit (synchronized statement)
|
||||
public final static int Bit31 = 0x40000000; // local declaration reachable (local decl) | ignore raw type check (type ref) | discard entire assignment (assignment) | isSynchronized (return statement) | thenExit (if statement)
|
||||
public final static int Bit32 = 0x80000000; // reachable (statement)
|
||||
|
||||
// public final static long[] Bits = {
|
||||
// ASTNode.Bit1, ASTNode.Bit2, ASTNode.Bit3, ASTNode.Bit4, ASTNode.Bit5, ASTNode.Bit6,
|
||||
// ASTNode.Bit7, ASTNode.Bit8, ASTNode.Bit9, ASTNode.Bit10, ASTNode.Bit11, ASTNode.Bit12,
|
||||
// ASTNode.Bit13, ASTNode.Bit14, ASTNode.Bit15, ASTNode.Bit16, ASTNode.Bit17, ASTNode.Bit18,
|
||||
// ASTNode.Bit19, ASTNode.Bit20, ASTNode.Bit21, ASTNode.Bit22, ASTNode.Bit23, ASTNode.Bit24,
|
||||
// ASTNode.Bit25, ASTNode.Bit26, ASTNode.Bit27, ASTNode.Bit28, ASTNode.Bit29, ASTNode.Bit30,
|
||||
// ASTNode.Bit31, ASTNode.Bit32L, ASTNode.Bit33L, ASTNode.Bit34L, ASTNode.Bit35L, ASTNode.Bit36L,
|
||||
// ASTNode.Bit37L, ASTNode.Bit38L, ASTNode.Bit39L, ASTNode.Bit40L, ASTNode.Bit41L, ASTNode.Bit42L,
|
||||
// ASTNode.Bit43L, ASTNode.Bit44L, ASTNode.Bit45L, ASTNode.Bit46L, ASTNode.Bit47L, ASTNode.Bit48L,
|
||||
// ASTNode.Bit49L, ASTNode.Bit50L, ASTNode.Bit51L, ASTNode.Bit52L, ASTNode.Bit53L, ASTNode.Bit54L,
|
||||
// ASTNode.Bit55L, ASTNode.Bit56L, ASTNode.Bit57L, ASTNode.Bit58L, ASTNode.Bit59L, ASTNode.Bit60L,
|
||||
// ASTNode.Bit61L, ASTNode.Bit62L, ASTNode.Bit63L, ASTNode.Bit64L,
|
||||
// };
|
||||
//
|
||||
// private static final int START_INDEX = 0;
|
||||
// private static final int PART_INDEX = 1;
|
||||
//
|
||||
// private static long[][][] Tables;
|
||||
// private static long[][][] Tables7;
|
||||
// private static long[][][] Tables8;
|
||||
|
||||
public final static int MAX_OBVIOUS = 128;
|
||||
public final static int[] OBVIOUS_IDENT_CHAR_NATURES = new int[MAX_OBVIOUS];
|
||||
|
||||
public final static int C_JLS_SPACE = Bit9;
|
||||
public final static int C_SPECIAL = Bit8;
|
||||
public final static int C_IDENT_START = Bit7;
|
||||
public final static int C_UPPER_LETTER = Bit6;
|
||||
public final static int C_LOWER_LETTER = Bit5;
|
||||
public final static int C_IDENT_PART = Bit4;
|
||||
public final static int C_DIGIT = Bit3;
|
||||
public final static int C_SEPARATOR = Bit2;
|
||||
public final static int C_SPACE = Bit1;
|
||||
|
||||
static {
|
||||
OBVIOUS_IDENT_CHAR_NATURES[0] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[1] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[2] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[3] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[4] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[5] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[6] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[7] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[8] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[14] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[15] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[16] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[17] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[18] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[19] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[20] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[21] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[22] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[23] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[24] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[25] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[26] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[27] = C_IDENT_PART;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[127] = C_IDENT_PART;
|
||||
|
||||
for (int i = '0'; i <= '9'; i++)
|
||||
OBVIOUS_IDENT_CHAR_NATURES[i] = C_DIGIT | C_IDENT_PART;
|
||||
|
||||
for (int i = 'a'; i <= 'z'; i++)
|
||||
OBVIOUS_IDENT_CHAR_NATURES[i] = C_LOWER_LETTER | C_IDENT_PART | C_IDENT_START;
|
||||
for (int i = 'A'; i <= 'Z'; i++)
|
||||
OBVIOUS_IDENT_CHAR_NATURES[i] = C_UPPER_LETTER | C_IDENT_PART | C_IDENT_START;
|
||||
|
||||
OBVIOUS_IDENT_CHAR_NATURES['_'] = C_SPECIAL | C_IDENT_PART | C_IDENT_START;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['$'] = C_SPECIAL | C_IDENT_PART | C_IDENT_START;
|
||||
|
||||
OBVIOUS_IDENT_CHAR_NATURES[9] = C_SPACE | C_JLS_SPACE; // \ u0009: HORIZONTAL TABULATION
|
||||
OBVIOUS_IDENT_CHAR_NATURES[10] = C_SPACE | C_JLS_SPACE; // \ u000a: LINE FEED
|
||||
OBVIOUS_IDENT_CHAR_NATURES[11] = C_SPACE;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[12] = C_SPACE | C_JLS_SPACE; // \ u000c: FORM FEED
|
||||
OBVIOUS_IDENT_CHAR_NATURES[13] = C_SPACE | C_JLS_SPACE; // \ u000d: CARRIAGE RETURN
|
||||
OBVIOUS_IDENT_CHAR_NATURES[28] = C_SPACE;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[29] = C_SPACE;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[30] = C_SPACE;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[31] = C_SPACE;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[32] = C_SPACE | C_JLS_SPACE; // \ u0020: SPACE
|
||||
|
||||
OBVIOUS_IDENT_CHAR_NATURES['.'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[':'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[';'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[','] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['['] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[']'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['('] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES[')'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['{'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['}'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['+'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['-'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['*'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['/'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['='] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['&'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['|'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['?'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['<'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['>'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['!'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['%'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['^'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['~'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['"'] = C_SEPARATOR;
|
||||
OBVIOUS_IDENT_CHAR_NATURES['\''] = C_SEPARATOR;
|
||||
}
|
||||
//static void initializeTable() {
|
||||
// Tables = initializeTables("unicode"); //$NON-NLS-1$
|
||||
//}
|
||||
//static void initializeTable17() {
|
||||
// Tables7 = initializeTables("unicode6"); //$NON-NLS-1$
|
||||
//}
|
||||
//static void initializeTable18() {
|
||||
// Tables8 = initializeTables("unicode6_2"); //$NON-NLS-1$
|
||||
//}
|
||||
//static long[][][] initializeTables(String unicode_path) {
|
||||
// long[][][] tempTable = new long[2][][];
|
||||
// tempTable[START_INDEX] = new long[3][];
|
||||
// tempTable[PART_INDEX] = new long[4][];
|
||||
// try {
|
||||
// DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream(unicode_path + "/start0.rsc"))); //$NON-NLS-1$
|
||||
// long[] readValues = new long[1024];
|
||||
// for (int i = 0; i < 1024; i++) {
|
||||
// readValues[i] = inputStream.readLong();
|
||||
// }
|
||||
// inputStream.close();
|
||||
// tempTable[START_INDEX][0] = readValues;
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// try {
|
||||
// DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream(unicode_path + "/start1.rsc"))); //$NON-NLS-1$
|
||||
// long[] readValues = new long[1024];
|
||||
// for (int i = 0; i < 1024; i++) {
|
||||
// readValues[i] = inputStream.readLong();
|
||||
// }
|
||||
// inputStream.close();
|
||||
// tempTable[START_INDEX][1] = readValues;
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// try {
|
||||
// DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream(unicode_path + "/start2.rsc"))); //$NON-NLS-1$
|
||||
// long[] readValues = new long[1024];
|
||||
// for (int i = 0; i < 1024; i++) {
|
||||
// readValues[i] = inputStream.readLong();
|
||||
// }
|
||||
// inputStream.close();
|
||||
// tempTable[START_INDEX][2] = readValues;
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// try {
|
||||
// DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream(unicode_path + "/part0.rsc"))); //$NON-NLS-1$
|
||||
// long[] readValues = new long[1024];
|
||||
// for (int i = 0; i < 1024; i++) {
|
||||
// readValues[i] = inputStream.readLong();
|
||||
// }
|
||||
// inputStream.close();
|
||||
// tempTable[PART_INDEX][0] = readValues;
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// try {
|
||||
// DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream(unicode_path + "/part1.rsc"))); //$NON-NLS-1$
|
||||
// long[] readValues = new long[1024];
|
||||
// for (int i = 0; i < 1024; i++) {
|
||||
// readValues[i] = inputStream.readLong();
|
||||
// }
|
||||
// inputStream.close();
|
||||
// tempTable[PART_INDEX][1] = readValues;
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// try {
|
||||
// DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream(unicode_path + "/part2.rsc"))); //$NON-NLS-1$
|
||||
// long[] readValues = new long[1024];
|
||||
// for (int i = 0; i < 1024; i++) {
|
||||
// readValues[i] = inputStream.readLong();
|
||||
// }
|
||||
// inputStream.close();
|
||||
// tempTable[PART_INDEX][2] = readValues;
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// try {
|
||||
// DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream(unicode_path + "/part14.rsc"))); //$NON-NLS-1$
|
||||
// long[] readValues = new long[1024];
|
||||
// for (int i = 0; i < 1024; i++) {
|
||||
// readValues[i] = inputStream.readLong();
|
||||
// }
|
||||
// inputStream.close();
|
||||
// tempTable[PART_INDEX][3] = readValues;
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return tempTable;
|
||||
//}
|
||||
//private final static boolean isBitSet(long[] values, int i) {
|
||||
// try {
|
||||
// return (values[i / 64] & Bits[i % 64]) != 0;
|
||||
// } catch (NullPointerException e) {
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
//public static boolean isJavaIdentifierPart(char c) {
|
||||
// if (c < MAX_OBVIOUS) {
|
||||
// return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_PART) != 0;
|
||||
// }
|
||||
// return Character.isJavaIdentifierPart(c);
|
||||
//}
|
||||
///**
|
||||
// * @param complianceLevel
|
||||
// * @param c
|
||||
// * @return
|
||||
// */
|
||||
//public static boolean isJavaIdentifierPart(long complianceLevel, char c) {
|
||||
// if (c < MAX_OBVIOUS) {
|
||||
// return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_PART) != 0;
|
||||
// }
|
||||
// return isJavaIdentifierPart(complianceLevel, (int) c);
|
||||
//}
|
||||
///**
|
||||
// * @param complianceLevel
|
||||
// * @param codePoint
|
||||
// * @return
|
||||
// */
|
||||
//public static boolean isJavaIdentifierPart(long complianceLevel, int codePoint) {
|
||||
// if (complianceLevel <= ClassFileConstants.JDK1_6) {
|
||||
// if (Tables == null) {
|
||||
// initializeTable();
|
||||
// }
|
||||
// switch((codePoint & 0x1F0000) >> 16) {
|
||||
// case 0 :
|
||||
// return isBitSet(Tables[PART_INDEX][0], codePoint & 0xFFFF);
|
||||
// case 1 :
|
||||
// return isBitSet(Tables[PART_INDEX][1], codePoint & 0xFFFF);
|
||||
// case 2 :
|
||||
// return isBitSet(Tables[PART_INDEX][2], codePoint & 0xFFFF);
|
||||
// case 14 :
|
||||
// return isBitSet(Tables[PART_INDEX][3], codePoint & 0xFFFF);
|
||||
// }
|
||||
// } else if (complianceLevel <= ClassFileConstants.JDK1_7) {
|
||||
// // java 7 supports Unicode 6
|
||||
// if (Tables7 == null) {
|
||||
// initializeTable17();
|
||||
// }
|
||||
// switch((codePoint & 0x1F0000) >> 16) {
|
||||
// case 0 :
|
||||
// return isBitSet(Tables7[PART_INDEX][0], codePoint & 0xFFFF);
|
||||
// case 1 :
|
||||
// return isBitSet(Tables7[PART_INDEX][1], codePoint & 0xFFFF);
|
||||
// case 2 :
|
||||
// return isBitSet(Tables7[PART_INDEX][2], codePoint & 0xFFFF);
|
||||
// case 14 :
|
||||
// return isBitSet(Tables7[PART_INDEX][3], codePoint & 0xFFFF);
|
||||
// }
|
||||
// } else {
|
||||
// // java 7 supports Unicode 6.2
|
||||
// if (Tables8 == null) {
|
||||
// initializeTable18();
|
||||
// }
|
||||
// switch((codePoint & 0x1F0000) >> 16) {
|
||||
// case 0 :
|
||||
// return isBitSet(Tables8[PART_INDEX][0], codePoint & 0xFFFF);
|
||||
// case 1 :
|
||||
// return isBitSet(Tables8[PART_INDEX][1], codePoint & 0xFFFF);
|
||||
// case 2 :
|
||||
// return isBitSet(Tables8[PART_INDEX][2], codePoint & 0xFFFF);
|
||||
// case 14 :
|
||||
// return isBitSet(Tables8[PART_INDEX][3], codePoint & 0xFFFF);
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
///**
|
||||
// * @param complianceLevel
|
||||
// * @param high
|
||||
// * @param low
|
||||
// * @return
|
||||
// */
|
||||
//public static boolean isJavaIdentifierPart(long complianceLevel, char high, char low) {
|
||||
// return isJavaIdentifierPart(complianceLevel, toCodePoint(high, low));
|
||||
//}
|
||||
///**
|
||||
// * @param c
|
||||
// * @return
|
||||
// */
|
||||
//public static boolean isJavaIdentifierStart(char c) {
|
||||
// if (c < MAX_OBVIOUS) {
|
||||
// return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0;
|
||||
// }
|
||||
// return Character.isJavaIdentifierStart(c);
|
||||
//}
|
||||
///**
|
||||
// * @param complianceLevel
|
||||
// * @param c
|
||||
// * @return
|
||||
// */
|
||||
//public static boolean isJavaIdentifierStart(long complianceLevel, char c) {
|
||||
// if (c < MAX_OBVIOUS) {
|
||||
// return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0;
|
||||
// }
|
||||
// return ScannerHelper.isJavaIdentifierStart(complianceLevel, (int) c);
|
||||
//}
|
||||
///**
|
||||
// * @param complianceLevel
|
||||
// * @param high
|
||||
// * @param low
|
||||
// * @return
|
||||
// */
|
||||
//public static boolean isJavaIdentifierStart(long complianceLevel, char high, char low) {
|
||||
// return isJavaIdentifierStart(complianceLevel, toCodePoint(high, low));
|
||||
//}
|
||||
///**
|
||||
// * @param complianceLevel
|
||||
// * @param codePoint
|
||||
// * @return
|
||||
// */
|
||||
//public static boolean isJavaIdentifierStart(long complianceLevel, int codePoint) {
|
||||
// if (complianceLevel <= ClassFileConstants.JDK1_6) {
|
||||
// if (Tables == null) {
|
||||
// initializeTable();
|
||||
// }
|
||||
// switch((codePoint & 0x1F0000) >> 16) {
|
||||
// case 0 :
|
||||
// return isBitSet(Tables[START_INDEX][0], codePoint & 0xFFFF);
|
||||
// case 1 :
|
||||
// return isBitSet(Tables[START_INDEX][1], codePoint & 0xFFFF);
|
||||
// case 2 :
|
||||
// return isBitSet(Tables[START_INDEX][2], codePoint & 0xFFFF);
|
||||
// }
|
||||
// } else if (complianceLevel <= ClassFileConstants.JDK1_7) {
|
||||
// // java 7 supports Unicode 6
|
||||
// if (Tables7 == null) {
|
||||
// initializeTable17();
|
||||
// }
|
||||
// switch((codePoint & 0x1F0000) >> 16) {
|
||||
// case 0 :
|
||||
// return isBitSet(Tables7[START_INDEX][0], codePoint & 0xFFFF);
|
||||
// case 1 :
|
||||
// return isBitSet(Tables7[START_INDEX][1], codePoint & 0xFFFF);
|
||||
// case 2 :
|
||||
// return isBitSet(Tables7[START_INDEX][2], codePoint & 0xFFFF);
|
||||
// }
|
||||
// } else {
|
||||
// // java 7 supports Unicode 6
|
||||
// if (Tables8 == null) {
|
||||
// initializeTable18();
|
||||
// }
|
||||
// switch((codePoint & 0x1F0000) >> 16) {
|
||||
// case 0 :
|
||||
// return isBitSet(Tables8[START_INDEX][0], codePoint & 0xFFFF);
|
||||
// case 1 :
|
||||
// return isBitSet(Tables8[START_INDEX][1], codePoint & 0xFFFF);
|
||||
// case 2 :
|
||||
// return isBitSet(Tables8[START_INDEX][2], codePoint & 0xFFFF);
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
//private static int toCodePoint(char high, char low) {
|
||||
// return (high - Scanner.HIGH_SURROGATE_MIN_VALUE) * 0x400 + (low - Scanner.LOW_SURROGATE_MIN_VALUE) + 0x10000;
|
||||
//}
|
||||
//public static boolean isDigit(char c) throws InvalidInputException {
|
||||
// if(c < ScannerHelper.MAX_OBVIOUS) {
|
||||
// return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0;
|
||||
// }
|
||||
// if (Character.isDigit(c)) {
|
||||
// throw new InvalidStateException(Scanner.INVALID_DIGIT);
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
public static int digit(char c, int radix) {
|
||||
if (c < ScannerHelper.MAX_OBVIOUS) {
|
||||
switch(radix) {
|
||||
case 8 :
|
||||
if (c >= 48 && c <= 55) {
|
||||
return c - 48;
|
||||
}
|
||||
return -1;
|
||||
case 10 :
|
||||
if (c >= 48 && c <= 57) {
|
||||
return c - 48;
|
||||
}
|
||||
return -1;
|
||||
case 16 :
|
||||
if (c >= 48 && c <= 57) {
|
||||
return c - 48;
|
||||
}
|
||||
if (c >= 65 && c <= 70) {
|
||||
return c - 65 + 10;
|
||||
}
|
||||
if (c >= 97 && c <= 102) {
|
||||
return c - 97 + 10;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return Character.digit(c, radix);
|
||||
}
|
||||
public static int getNumericValue(char c) {
|
||||
if (c < ScannerHelper.MAX_OBVIOUS) {
|
||||
switch(ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c]) {
|
||||
case C_DIGIT :
|
||||
return c - '0';
|
||||
case C_LOWER_LETTER :
|
||||
return 10 + c - 'a';
|
||||
case C_UPPER_LETTER :
|
||||
return 10 + c - 'A';
|
||||
}
|
||||
}
|
||||
return Character.getNumericValue(c);
|
||||
}
|
||||
public static int getHexadecimalValue(char c) {
|
||||
switch(c) {
|
||||
case '0' :
|
||||
return 0;
|
||||
case '1' :
|
||||
return 1;
|
||||
case '2' :
|
||||
return 2;
|
||||
case '3' :
|
||||
return 3;
|
||||
case '4' :
|
||||
return 4;
|
||||
case '5' :
|
||||
return 5;
|
||||
case '6' :
|
||||
return 6;
|
||||
case '7' :
|
||||
return 7;
|
||||
case '8' :
|
||||
return 8;
|
||||
case '9' :
|
||||
return 9;
|
||||
case 'A' :
|
||||
case 'a' :
|
||||
return 10;
|
||||
case 'B' :
|
||||
case 'b' :
|
||||
return 11;
|
||||
case 'C' :
|
||||
case 'c' :
|
||||
return 12;
|
||||
case 'D' :
|
||||
case 'd' :
|
||||
return 13;
|
||||
case 'E' :
|
||||
case 'e' :
|
||||
return 14;
|
||||
case 'F' :
|
||||
case 'f' :
|
||||
return 15;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
public static char toUpperCase(char c) {
|
||||
if (c < MAX_OBVIOUS) {
|
||||
if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_UPPER_LETTER) != 0) {
|
||||
return c;
|
||||
} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_LOWER_LETTER) != 0) {
|
||||
return (char) (c - 32);
|
||||
}
|
||||
}
|
||||
return Character.toUpperCase(c);
|
||||
}
|
||||
public static char toLowerCase(char c) {
|
||||
if (c < MAX_OBVIOUS) {
|
||||
if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_LOWER_LETTER) != 0) {
|
||||
return c;
|
||||
} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_UPPER_LETTER) != 0) {
|
||||
return (char) (32 + c);
|
||||
}
|
||||
}
|
||||
return Character.toLowerCase(c);
|
||||
}
|
||||
public static boolean isLowerCase(char c) {
|
||||
if (c < MAX_OBVIOUS) {
|
||||
return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_LOWER_LETTER) != 0;
|
||||
}
|
||||
return Character.isLowerCase(c);
|
||||
}
|
||||
public static boolean isUpperCase(char c) {
|
||||
if (c < MAX_OBVIOUS) {
|
||||
return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_UPPER_LETTER) != 0;
|
||||
}
|
||||
return Character.isUpperCase(c);
|
||||
}
|
||||
/**
|
||||
* Include also non JLS whitespaces.
|
||||
*
|
||||
* return true if Character.isWhitespace(c) would return true
|
||||
*/
|
||||
public static boolean isWhitespace(char c) {
|
||||
if (c < MAX_OBVIOUS) {
|
||||
return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_SPACE) != 0;
|
||||
}
|
||||
return Character.isWhitespace(c);
|
||||
}
|
||||
public static boolean isLetter(char c) {
|
||||
if (c < MAX_OBVIOUS) {
|
||||
return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER)) != 0;
|
||||
}
|
||||
return Character.isLetter(c);
|
||||
}
|
||||
public static boolean isLetterOrDigit(char c) {
|
||||
if (c < MAX_OBVIOUS) {
|
||||
return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_DIGIT)) != 0;
|
||||
}
|
||||
return Character.isLetterOrDigit(c);
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,12 @@ package org.springframework.ide.vscode.commons.languageserver.hover;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
public interface HoverInfoProvider {
|
||||
|
||||
Tuple2<HoverInfo, IRegion> getHoverInfo(IDocument document, int offset) throws Exception;
|
||||
Tuple2<Renderable, IRegion> getHoverInfo(IDocument document, int offset) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguage
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.util.Futures;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
@@ -49,9 +50,9 @@ public class VscodeHoverEngineAdapter implements VscodeHoverEngine {
|
||||
if (doc!=null) {
|
||||
int offset = doc.toOffset(params.getPosition());
|
||||
|
||||
Tuple2<HoverInfo, IRegion> hoverTuple = hoverInfoProvider.getHoverInfo(doc, offset);
|
||||
Tuple2<Renderable, IRegion> hoverTuple = hoverInfoProvider.getHoverInfo(doc, offset);
|
||||
if (hoverTuple != null) {
|
||||
HoverInfo hoverInfo = hoverTuple.getT1();
|
||||
Renderable hoverInfo = hoverTuple.getT1();
|
||||
IRegion region = hoverTuple.getT2();
|
||||
Range range = doc.toRange(region.getOffset(), region.getLength());
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.springframework.ide.vscode.commons.maven;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalProcess;
|
||||
|
||||
public class MavenBuilder {
|
||||
|
||||
|
||||
private Path projectPath;
|
||||
|
||||
private List<String> targets;
|
||||
|
||||
private List<String> properties;
|
||||
|
||||
public void execute() throws IOException, InterruptedException {
|
||||
Path mvnwPath = System.getProperty("os.name").toLowerCase().startsWith("win") ? projectPath.resolve("mvnw.cmd")
|
||||
: projectPath.resolve("mvnw");
|
||||
mvnwPath.toFile().setExecutable(true);
|
||||
List<String> all = new ArrayList<>(1 + targets.size() + properties.size());
|
||||
all.add(mvnwPath.toAbsolutePath().toString());
|
||||
all.addAll(targets);
|
||||
all.addAll(properties);
|
||||
ExternalProcess process = new ExternalProcess(projectPath.toFile(),
|
||||
new ExternalCommand(all.toArray(new String[all.size()])), true);
|
||||
if (process.getExitValue() != 0) {
|
||||
throw new RuntimeException("Failed to build test project");
|
||||
}
|
||||
}
|
||||
|
||||
public static MavenBuilder newBuilder(Path projectPath) {
|
||||
return new MavenBuilder(projectPath);
|
||||
}
|
||||
|
||||
public MavenBuilder clean() {
|
||||
targets.add("clean");
|
||||
return this;
|
||||
}
|
||||
|
||||
public MavenBuilder pack() {
|
||||
targets.add("package");
|
||||
return this;
|
||||
}
|
||||
|
||||
public MavenBuilder skipTests() {
|
||||
properties.add("-DskipTests");
|
||||
return this;
|
||||
}
|
||||
|
||||
public MavenBuilder javadoc() {
|
||||
properties.add("javadoc:javadoc");
|
||||
return this;
|
||||
}
|
||||
|
||||
private MavenBuilder(Path projectPath) {
|
||||
this.projectPath = projectPath;
|
||||
this.targets = new ArrayList<>();
|
||||
this.properties = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -23,7 +25,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -50,8 +51,8 @@ import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
|
||||
import org.eclipse.aether.util.graph.visitor.CloningDependencyVisitor;
|
||||
import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexIndex;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalProcess;
|
||||
import org.springframework.ide.vscode.commons.javadoc.HtmlJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.SourceUrlProviderFromSourceContainer;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
@@ -81,11 +82,26 @@ public class MavenCore {
|
||||
|
||||
private MavenBridge maven = new MavenBridge();
|
||||
|
||||
private Supplier<Optional<JandexIndex>> javaCoreIndex = Suppliers.memoize(() -> {
|
||||
private Supplier<JandexIndex> javaCoreIndex = Suppliers.memoize(() -> {
|
||||
try {
|
||||
return Optional.of(new JandexIndex(getJreLibs(), jarFile -> findIndexFile(jarFile)));
|
||||
return new JandexIndex(getJreLibs(), jarFile -> findIndexFile(jarFile), (classpathResource) -> {
|
||||
try {
|
||||
String javaVersion = "8";
|
||||
try {
|
||||
String fullVersion = getJavaRuntimeVersion();
|
||||
javaVersion = fullVersion.substring(fullVersion.indexOf('.') + 1, fullVersion.lastIndexOf('.'));
|
||||
} catch (MavenException e) {
|
||||
Log.log("Cannot determine Java runtime version. Defaulting to version 8", e);
|
||||
}
|
||||
URL javadocUrl = new URL("http://docs.oracle.com/javase/" + javaVersion + "/docs/api/");
|
||||
return new HtmlJavadocProvider((type) -> SourceUrlProviderFromSourceContainer.JAVADOC_FOLDER_URL_SUPPLIER.sourceUrl(javadocUrl, type));
|
||||
} catch (MalformedURLException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (MavenException e) {
|
||||
return Optional.empty();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -110,23 +126,6 @@ public class MavenCore {
|
||||
return Arrays.stream(text.split(File.pathSeparator)).map(dir::resolve);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds maven project
|
||||
*
|
||||
* @param Path of the project
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void buildMavenProject(Path testProjectPath) throws Exception {
|
||||
Path mvnwPath = System.getProperty("os.name").toLowerCase().startsWith("win")
|
||||
? testProjectPath.resolve("mvnw.cmd") : testProjectPath.resolve("mvnw");
|
||||
mvnwPath.toFile().setExecutable(true);
|
||||
ExternalProcess process = new ExternalProcess(testProjectPath.toFile(),
|
||||
new ExternalCommand(mvnwPath.toAbsolutePath().toString(), "clean", "package", "-DskipTests"), true);
|
||||
if (process.getExitValue() != 0) {
|
||||
throw new RuntimeException("Failed to build test project");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Maven Project descriptor based on the pom file.
|
||||
*
|
||||
@@ -281,7 +280,7 @@ public class MavenCore {
|
||||
return new File(getIndexFolder().toString(), jarFile.getName() + "-" + suffix + ".jdx");
|
||||
}
|
||||
|
||||
public Optional<JandexIndex> getJavaIndexForJreLibs() {
|
||||
public JandexIndex getJavaIndexForJreLibs() {
|
||||
return javaCoreIndex.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ import org.apache.maven.project.MavenProject;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlSnippet;
|
||||
|
||||
/**
|
||||
* Wrapper for Maven Core project
|
||||
@@ -45,7 +45,7 @@ public class MavenJavaProject implements IJavaProject {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlSnippet getJavaDoc() {
|
||||
public IJavadoc getJavaDoc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,17 +11,26 @@
|
||||
package org.springframework.ide.vscode.commons.maven.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.codehaus.plexus.util.DirectoryScanner;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexIndex;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.java.parser.ParserJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.roaster.RoasterJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.HtmlJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.SourceUrlProviderFromSourceContainer;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
@@ -34,11 +43,19 @@ import com.google.common.base.Suppliers;
|
||||
*
|
||||
*/
|
||||
public class MavenProjectClasspath implements IClasspath {
|
||||
|
||||
|
||||
public static JavadocProviderTypes providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
public enum JavadocProviderTypes {
|
||||
JAVA_PARSER,
|
||||
ROASTER,
|
||||
HTML
|
||||
}
|
||||
|
||||
private MavenCore maven;
|
||||
private MavenProject project;
|
||||
private Supplier<JandexIndex> javaIndex;
|
||||
|
||||
|
||||
public MavenProjectClasspath(MavenProject project) {
|
||||
this(project, MavenCore.getInstance());
|
||||
}
|
||||
@@ -53,16 +70,25 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return new JandexIndex(classpathEntries, jarFile -> findIndexFile(jarFile), maven.getJavaIndexForJreLibs());
|
||||
return new JandexIndex(classpathEntries, jarFile -> findIndexFile(jarFile), classpathResource -> {
|
||||
switch (providerType) {
|
||||
case JAVA_PARSER:
|
||||
return createParserJavadocProvider(classpathResource);
|
||||
case ROASTER:
|
||||
return createRoasterJavadocProvider(classpathResource);
|
||||
default:
|
||||
return createHtmlJavdocProvider(classpathResource);
|
||||
}
|
||||
}, maven.getJavaIndexForJreLibs());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Path> getClasspathEntries() throws Exception {
|
||||
return Stream.concat(maven.resolveDependencies(project, null).stream().map(artifact -> {
|
||||
return Paths.get(artifact.getFile().toURI());
|
||||
}), Stream.of(Paths.get(new File(project.getBuild().getOutputDirectory()).toURI()),
|
||||
Paths.get(new File(project.getBuild().getTestOutputDirectory()).toURI())));
|
||||
return artifact.getFile().toPath();
|
||||
}), Stream.of(new File(project.getBuild().getOutputDirectory()).toPath(),
|
||||
new File(project.getBuild().getTestOutputDirectory()).toPath()));
|
||||
}
|
||||
|
||||
public IType findType(String fqName) {
|
||||
@@ -72,7 +98,11 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
private File findIndexFile(File jarFile) {
|
||||
return new File(maven.getIndexFolder().toString(), jarFile.getName() + "-" + jarFile.lastModified() + ".jdx");
|
||||
}
|
||||
|
||||
|
||||
private Optional<Artifact> getArtifactFromJarFile(File file) throws MavenException {
|
||||
return maven.resolveDependencies(project, null).stream().filter(a -> file.equals(a.getFile())).findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getClasspathResources() {
|
||||
return project.getBuild().getResources().stream().flatMap(resource -> {
|
||||
@@ -89,5 +119,105 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
return Arrays.stream(scanner.getIncludedFiles());
|
||||
});
|
||||
}
|
||||
|
||||
private IJavadocProvider createRoasterJavadocProvider(File classpathResource) {
|
||||
if (classpathResource.isDirectory()) {
|
||||
if (classpathResource.toString().startsWith(project.getBuild().getOutputDirectory())) {
|
||||
return new RoasterJavadocProvider(type -> {
|
||||
return SourceUrlProviderFromSourceContainer.SOURCE_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(new File(project.getBuild().getSourceDirectory()).toURI().toURL(), type);
|
||||
});
|
||||
} else if (classpathResource.toString().startsWith(project.getBuild().getTestOutputDirectory())) {
|
||||
return new RoasterJavadocProvider(type -> {
|
||||
return SourceUrlProviderFromSourceContainer.SOURCE_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(new File(project.getBuild().getTestSourceDirectory()).toURI().toURL(), type);
|
||||
});
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot find source folder for " + classpathResource);
|
||||
}
|
||||
} else {
|
||||
// Assume it's a JAR file
|
||||
return new RoasterJavadocProvider(type -> {
|
||||
try {
|
||||
Artifact artifact = getArtifactFromJarFile(classpathResource).get();
|
||||
URL sourceContainer = maven.getSources(artifact).getFile().toURI().toURL();
|
||||
return SourceUrlProviderFromSourceContainer.JAR_SOURCE_URL_PROVIDER.sourceUrl(sourceContainer,
|
||||
type);
|
||||
} catch (MavenException e) {
|
||||
Log.log("Failed to find sources JAR for " + classpathResource, e);
|
||||
} catch (MalformedURLException e) {
|
||||
Log.log("Invalid URL for sources JAR for " + classpathResource, e);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private IJavadocProvider createParserJavadocProvider(File classpathResource) {
|
||||
if (classpathResource.isDirectory()) {
|
||||
if (classpathResource.toString().startsWith(project.getBuild().getOutputDirectory())) {
|
||||
return new ParserJavadocProvider(type -> {
|
||||
return SourceUrlProviderFromSourceContainer.SOURCE_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(new File(project.getBuild().getSourceDirectory()).toURI().toURL(), type);
|
||||
});
|
||||
} else if (classpathResource.toString().startsWith(project.getBuild().getTestOutputDirectory())) {
|
||||
return new ParserJavadocProvider(type -> {
|
||||
return SourceUrlProviderFromSourceContainer.SOURCE_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(new File(project.getBuild().getTestSourceDirectory()).toURI().toURL(), type);
|
||||
});
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot find source folder for " + classpathResource);
|
||||
}
|
||||
} else {
|
||||
// Assume it's a JAR file
|
||||
return new ParserJavadocProvider(type -> {
|
||||
try {
|
||||
Artifact artifact = getArtifactFromJarFile(classpathResource).get();
|
||||
URL sourceContainer = maven.getSources(artifact).getFile().toURI().toURL();
|
||||
return SourceUrlProviderFromSourceContainer.JAR_SOURCE_URL_PROVIDER.sourceUrl(sourceContainer,
|
||||
type);
|
||||
} catch (MavenException e) {
|
||||
Log.log("Failed to find sources JAR for " + classpathResource, e);
|
||||
} catch (MalformedURLException e) {
|
||||
Log.log("Invalid URL for sources JAR for " + classpathResource, e);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private IJavadocProvider createHtmlJavdocProvider(File classpathResource) {
|
||||
if (classpathResource.isDirectory()) {
|
||||
if (classpathResource.toString().startsWith(project.getBuild().getOutputDirectory())) {
|
||||
return new HtmlJavadocProvider(type -> {
|
||||
return SourceUrlProviderFromSourceContainer.JAVADOC_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(new File(project.getModel().getReporting().getOutputDirectory(), "apidocs").toURI().toURL(), type);
|
||||
});
|
||||
} else if (classpathResource.toString().startsWith(project.getBuild().getTestOutputDirectory())) {
|
||||
return new ParserJavadocProvider(type -> {
|
||||
return SourceUrlProviderFromSourceContainer.JAVADOC_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(new File(project.getModel().getReporting().getOutputDirectory(), "apidocs").toURI().toURL(), type);
|
||||
});
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot find source folder for " + classpathResource);
|
||||
}
|
||||
} else {
|
||||
// Assume it's a JAR file
|
||||
return new HtmlJavadocProvider(type -> {
|
||||
try {
|
||||
Artifact artifact = getArtifactFromJarFile(classpathResource).get();
|
||||
URL sourceContainer = maven.getJavadoc(artifact).getFile().toURI().toURL();
|
||||
return SourceUrlProviderFromSourceContainer.JAR_JAVADOC_URL_PROVIDER.sourceUrl(sourceContainer,
|
||||
type);
|
||||
} catch (MavenException e) {
|
||||
Log.log("Failed to find sources JAR for " + classpathResource, e);
|
||||
} catch (MalformedURLException e) {
|
||||
Log.log("Invalid URL for sources JAR for " + classpathResource, e);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,94 +1,94 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java.classpathfile;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlSnippet;
|
||||
|
||||
/**
|
||||
* Java project that contains classpath text file
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class JavaProjectWithClasspathFile implements IJavaProject {
|
||||
|
||||
private File cpFile;
|
||||
private FileClasspath classpath;
|
||||
|
||||
public JavaProjectWithClasspathFile(File cpFile) {
|
||||
this.cpFile = cpFile;
|
||||
this.classpath = new FileClasspath(Paths.get(cpFile.toURI()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return cpFile.getParentFile().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlSnippet getJavaDoc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return cpFile.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
//TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClasspath getClasspath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JavaProjectWithClasspathFile("+cpFile+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cpFile == null) ? 0 : cpFile.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
JavaProjectWithClasspathFile other = (JavaProjectWithClasspathFile) obj;
|
||||
if (cpFile == null) {
|
||||
if (other.cpFile != null)
|
||||
return false;
|
||||
} else if (!cpFile.equals(other.cpFile))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java.classpathfile;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
|
||||
/**
|
||||
* Java project that contains classpath text file
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class JavaProjectWithClasspathFile implements IJavaProject {
|
||||
|
||||
private File cpFile;
|
||||
private FileClasspath classpath;
|
||||
|
||||
public JavaProjectWithClasspathFile(File cpFile) {
|
||||
this.cpFile = cpFile;
|
||||
this.classpath = new FileClasspath(Paths.get(cpFile.toURI()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return cpFile.getParentFile().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavaDoc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return cpFile.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
//TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClasspath getClasspath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JavaProjectWithClasspathFile("+cpFile+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cpFile == null) ? 0 : cpFile.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
JavaProjectWithClasspathFile other = (JavaProjectWithClasspathFile) obj;
|
||||
if (cpFile == null) {
|
||||
if (other.cpFile != null)
|
||||
return false;
|
||||
} else if (!cpFile.equals(other.cpFile))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public class DependencyTreeTest {
|
||||
|
||||
private void testMavenClasspath(String projectName) throws Exception {
|
||||
Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/" + projectName).toURI());
|
||||
MavenCore.buildMavenProject(testProjectPath);
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().skipTests().execute();
|
||||
|
||||
MavenProject project = MavenCore.getInstance().readProject(testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
Set<Path> calculatedClassPath = MavenCore.getInstance().resolveDependencies(project, null).stream().map(artifact -> {
|
||||
|
||||
@@ -11,11 +11,15 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IPrimitiveType;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.java.IVoidType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectClasspath;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectClasspath.JavadocProviderTypes;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
@@ -23,41 +27,55 @@ import com.google.common.cache.LoadingCache;
|
||||
|
||||
public class JavaIndexTest {
|
||||
|
||||
private static LoadingCache<String, MavenJavaProject> projectsCache = CacheBuilder.newBuilder().build(new CacheLoader<String, MavenJavaProject>() {
|
||||
private static LoadingCache<String, Path> projectsCache = CacheBuilder.newBuilder().build(new CacheLoader<String, Path>() {
|
||||
|
||||
@Override
|
||||
public MavenJavaProject load(String projectName) throws Exception {
|
||||
public Path load(String projectName) throws Exception {
|
||||
Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/" + projectName).toURI());
|
||||
MavenCore.buildMavenProject(testProjectPath);
|
||||
return new MavenJavaProject(testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().javadoc().skipTests().execute();
|
||||
return testProjectPath;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
private static LoadingCache<String, MavenJavaProject> mavenProjectsCache = CacheBuilder.newBuilder().build(new CacheLoader<String, MavenJavaProject>() {
|
||||
|
||||
@Override
|
||||
public MavenJavaProject load(String projectName) throws Exception {
|
||||
Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/" + projectName).toURI());
|
||||
return createMavenProject(testProjectPath);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
private static MavenJavaProject createMavenProject(Path projectPath) throws Exception {
|
||||
return new MavenJavaProject(projectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findClassInJar() throws Exception {
|
||||
MavenJavaProject project = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("org.springframework.test.web.client.ExpectedCount");
|
||||
assertNotNull(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findClassInOutputFolder() throws Exception {
|
||||
MavenJavaProject project = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("hello.Greeting");
|
||||
assertNotNull(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classNotFound() throws Exception {
|
||||
MavenJavaProject project = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("hello.NonExistentClass");
|
||||
assertNull(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void voidMethodNoParams() throws Exception {
|
||||
MavenJavaProject project = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod m = type.getMethod("clear", Stream.empty());
|
||||
@@ -68,24 +86,480 @@ public class JavaIndexTest {
|
||||
|
||||
@Test
|
||||
public void voidConstructor() throws Exception {
|
||||
MavenJavaProject project = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod m = type.getMethod("<init>", Stream.empty());
|
||||
assertEquals("<init>", m.getElementName());
|
||||
assertEquals(type.getElementName(), m.getElementName());
|
||||
assertEquals(IVoidType.DEFAULT, m.getReturnType());
|
||||
assertEquals(0, m.parameters().count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorMethodWithParams() throws Exception {
|
||||
MavenJavaProject project = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod m = type.getMethod("<init>", Stream.of(IPrimitiveType.INT));
|
||||
assertEquals("<init>", m.getElementName());
|
||||
assertEquals(m.getDeclaringType().getElementName(), m.getElementName());
|
||||
assertEquals(IVoidType.DEFAULT, m.getReturnType());
|
||||
assertEquals(Collections.singletonList(IPrimitiveType.INT), m.parameters().collect(Collectors.toList()));
|
||||
assertEquals(Collections.singletonList(IPrimitiveType.INT), m.parameters().collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parser_testClassJavadocForOutputFolder() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.JAVA_PARSER;
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
IType type = project.findType("hello.Greeting");
|
||||
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
"/**",
|
||||
" * Comment for Greeting class ",
|
||||
" */"
|
||||
);
|
||||
assertEquals(expected, type.getJavaDoc().raw().trim());
|
||||
|
||||
IField field = type.getField("id");
|
||||
assertNotNull(field);
|
||||
expected = String.join("\n",
|
||||
"/**",
|
||||
" * Comment for id field",
|
||||
" */"
|
||||
);
|
||||
assertEquals(expected, field.getJavaDoc().raw().trim());
|
||||
|
||||
IMethod method = type.getMethod("getId", Stream.empty());
|
||||
assertNotNull(method);
|
||||
expected = String.join("\n",
|
||||
"/**",
|
||||
" * Comment for getId()",
|
||||
" */"
|
||||
);
|
||||
assertEquals(expected, method.getJavaDoc().raw().trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parser_testInnerClassJavadocForOutputFolder() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.JAVA_PARSER;
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
IType type = project.findType("hello.Greeting$TestInnerClass");
|
||||
assertNotNull(type);
|
||||
assertEquals("/**\n * Comment for inner class\n */", type.getJavaDoc().raw().trim());
|
||||
|
||||
IField field = type.getField("innerField");
|
||||
assertNotNull(field);
|
||||
assertEquals("/**\n \t * Comment for inner field\n \t */", field.getJavaDoc().raw().trim());
|
||||
|
||||
IMethod method = type.getMethod("getInnerField", Stream.empty());
|
||||
assertNotNull(method);
|
||||
assertEquals("/**\n \t * Comment for method inside nested class\n \t */", method.getJavaDoc().raw().trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parser_testClassJavadocForJar() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.JAVA_PARSER;
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener");
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
"/**",
|
||||
" * {@link ApplicationListener} that replaces the liquibase {@link ServiceLocator} with a"
|
||||
);
|
||||
assertEquals(expected, type.getJavaDoc().raw().trim().substring(0, expected.length()));
|
||||
|
||||
type = project.findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener$LiquibasePresent");
|
||||
assertNotNull(type);
|
||||
expected = String.join("\n",
|
||||
"/**",
|
||||
" * Inner class to prevent class not found issues.",
|
||||
" */"
|
||||
);
|
||||
assertEquals(expected, type.getJavaDoc().raw().trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parser_testFieldAndMethodJavadocForJar() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.JAVA_PARSER;
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("org.springframework.boot.SpringApplication");
|
||||
assertNotNull(type);
|
||||
|
||||
IField field = type.getField("BANNER_LOCATION_PROPERTY_VALUE");
|
||||
assertNotNull(field);
|
||||
String expected = String.join("\n",
|
||||
"/**",
|
||||
" * Default banner location.",
|
||||
" */"
|
||||
);
|
||||
assertEquals(expected, field.getJavaDoc().raw().trim());
|
||||
|
||||
IMethod method = type.getMethod("getListeners", Stream.empty());
|
||||
assertNotNull(method);
|
||||
expected = String.join("\n",
|
||||
"/**",
|
||||
" * Returns read-only ordered Set of the {@link ApplicationListener}s that will be"
|
||||
);
|
||||
assertEquals(expected, method.getJavaDoc().raw().trim().substring(0, expected.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roaster_testClassJavadocForOutputFolder() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.ROASTER;
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
IType type = project.findType("hello.Greeting");
|
||||
|
||||
assertNotNull(type);
|
||||
assertEquals("Comment for Greeting class", type.getJavaDoc().raw());
|
||||
|
||||
IField field = type.getField("id");
|
||||
assertNotNull(field);
|
||||
assertEquals("Comment for id field", field.getJavaDoc().raw());
|
||||
|
||||
IMethod method = type.getMethod("getId", Stream.empty());
|
||||
assertNotNull(method);
|
||||
assertEquals("Comment for getId()", method.getJavaDoc().raw());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roaster_testInnerClassJavadocForOutputFolder() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.ROASTER;
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
IType type = project.findType("hello.Greeting$TestInnerClass");
|
||||
assertNotNull(type);
|
||||
assertEquals("Comment for inner class", type.getJavaDoc().raw());
|
||||
|
||||
IField field = type.getField("innerField");
|
||||
assertNotNull(field);
|
||||
assertEquals("Comment for inner field", field.getJavaDoc().raw());
|
||||
|
||||
IMethod method = type.getMethod("getInnerField", Stream.empty());
|
||||
assertNotNull(method);
|
||||
assertEquals("Comment for method inside nested class", method.getJavaDoc().raw());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roaster_testClassJavadocForJar() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.ROASTER;
|
||||
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener");
|
||||
assertNotNull(type);
|
||||
String expected = "{@link ApplicationListener} that replaces the liquibase {@link ServiceLocator} with a";
|
||||
assertEquals(expected, type.getJavaDoc().raw().substring(0, expected.length()));
|
||||
|
||||
type = project.findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener$LiquibasePresent");
|
||||
assertNotNull(type);
|
||||
assertEquals("Inner class to prevent class not found issues.", type.getJavaDoc().raw());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roaster_testFieldAndMethodJavadocForJar() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.ROASTER;
|
||||
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("org.springframework.boot.SpringApplication");
|
||||
assertNotNull(type);
|
||||
|
||||
IField field = type.getField("BANNER_LOCATION_PROPERTY_VALUE");
|
||||
assertNotNull(field);
|
||||
assertEquals("Default banner location.", field.getJavaDoc().raw());
|
||||
|
||||
IMethod method = type.getMethod("getListeners", Stream.empty());
|
||||
assertNotNull(method);
|
||||
String expected = "Returns read-only ordered Set of the {@link ApplicationListener} s that will be";
|
||||
assertEquals(expected, method.getJavaDoc().raw().substring(0, expected.length()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void html_testClassJavadoc() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("java.util.Map");
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
"<div class=\"block\">An object that maps keys to values. A map cannot contain duplicate keys;",
|
||||
" each key can map to at most one value."
|
||||
);
|
||||
IJavadoc javaDoc = type.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml().substring(0, expected.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testNestedClassJavadoc() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("java.util.Map$Entry");
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
"<div class=\"block\">A map entry (key-value pair). The <tt>Map.entrySet</tt> method returns",
|
||||
" a collection-view of the map, whose elements are of this class. The");
|
||||
IJavadoc javaDoc = type.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml().substring(0, expected.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testMethodJavadoc() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod method = type.getMethod("size", Stream.empty());
|
||||
assertNotNull(method);
|
||||
|
||||
String expected = String.join("\n",
|
||||
"<h4>size</h4>",
|
||||
"<pre>public int size()</pre>",
|
||||
"<div class=\"block\">Returns the number of elements in this list.</div>"
|
||||
);
|
||||
IJavadoc javaDoc = method.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml().substring(0, expected.length()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testConstructorJavadoc() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod method = type.getMethod("<init>", Stream.empty());
|
||||
assertNotNull(method);
|
||||
|
||||
String expected = String.join("\n",
|
||||
"<h4>ArrayList</h4>"
|
||||
);
|
||||
IJavadoc javaDoc = method.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml().substring(0, expected.length()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testFieldAndMethodJavadocForJar() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
MavenJavaProject project = createMavenProject(projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"));
|
||||
|
||||
IType type = project.findType("org.springframework.boot.SpringApplication");
|
||||
assertNotNull(type);
|
||||
|
||||
IField field = type.getField("BANNER_LOCATION_PROPERTY_VALUE");
|
||||
assertNotNull(field);
|
||||
String expected = String.join("\n",
|
||||
"<h4>BANNER_LOCATION_PROPERTY_VALUE</h4>",
|
||||
"<pre>public static final <a href=\"http://docs.oracle.com/javase/6/docs/api/java/lang/String.html?is-external=true\" title=\"class or interface in java.lang\">String</a> BANNER_LOCATION_PROPERTY_VALUE</pre>",
|
||||
"<div class=\"block\">Default banner location.</div>",
|
||||
"<dl>",
|
||||
"<dt><span class=\"seeLabel\">See Also:</span></dt>",
|
||||
"<dd><a href=\"../../../constant-values.html#org.springframework.boot.SpringApplication.BANNER_LOCATION_PROPERTY_VALUE\">Constant Field Values</a></dd>",
|
||||
"</dl>"
|
||||
);
|
||||
IJavadoc javaDoc = field.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
|
||||
IMethod method = type.getMethod("getListeners", Stream.empty());
|
||||
assertNotNull(method);
|
||||
expected = String.join("\n",
|
||||
"<h4>getListeners</h4>",
|
||||
"<pre>public <a href=\"http://docs.oracle.com/javase/6/docs/api/java/util/Set.html?is-external=true\" title=\"class or interface in java.util\">Set</a><org.springframework.context.ApplicationListener<?>> getListeners()</pre>",
|
||||
"<div class=\"block\">Returns read-only ordered Set of the <code>ApplicationListener</code>s that will be",
|
||||
" applied to the SpringApplication and registered with the <code>ApplicationContext</code>",
|
||||
" .</div>",
|
||||
"<dl>",
|
||||
"<dt><span class=\"returnLabel\">Returns:</span></dt>",
|
||||
"<dd>the listeners</dd>",
|
||||
"</dl>"
|
||||
);
|
||||
javaDoc = method.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testJavadocOutputFolder() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
Path projectPath = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = createMavenProject(projectPath);
|
||||
IType type = project.findType("hello.Greeting");
|
||||
|
||||
assertNotNull(type);
|
||||
String expected = "<div class=\"block\">Comment for Greeting class</div>";
|
||||
IJavadoc javaDoc = type.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
|
||||
IField field = type.getField("id");
|
||||
assertNotNull(field);
|
||||
expected = String.join("\n",
|
||||
"<h4>id</h4>",
|
||||
"<pre>protected final long id</pre>",
|
||||
"<div class=\"block\">Comment for id field</div>"
|
||||
);
|
||||
javaDoc = field.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
|
||||
IMethod method = type.getMethod("getId", Stream.empty());
|
||||
assertNotNull(method);
|
||||
expected = String.join("\n",
|
||||
"<h4>getId</h4>",
|
||||
"<pre>public long getId()</pre>",
|
||||
"<div class=\"block\">Comment for getId()</div>"
|
||||
);
|
||||
javaDoc = method.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testInnerClassJavadocForOutputFolder() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
Path projectPath = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = createMavenProject(projectPath);
|
||||
|
||||
IType type = project.findType("hello.Greeting$TestInnerClass");
|
||||
assertNotNull(type);
|
||||
IJavadoc javaDoc = type.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals("<div class=\"block\">Comment for inner class</div>", javaDoc.getRenderable().toHtml());
|
||||
|
||||
IField field = type.getField("innerField");
|
||||
assertNotNull(field);
|
||||
String expected = String.join("\n",
|
||||
"<h4>innerField</h4>",
|
||||
"<pre>protected int innerField</pre>",
|
||||
"<div class=\"block\">Comment for inner field</div>"
|
||||
);
|
||||
javaDoc = field.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
|
||||
IMethod method = type.getMethod("getInnerField", Stream.empty());
|
||||
assertNotNull(method);
|
||||
expected = String.join("\n",
|
||||
"<h4>getInnerField</h4>",
|
||||
"<pre>public int getInnerField()</pre>",
|
||||
"<div class=\"block\">Comment for method inside nested class</div>"
|
||||
);
|
||||
javaDoc = method.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testInnerClassLevel2_JavadocForOutputFolder() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
Path projectPath = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = createMavenProject(projectPath);
|
||||
|
||||
IType type = project.findType("hello.Greeting$TestInnerClass$TestInnerClassLevel2");
|
||||
assertNotNull(type);
|
||||
IJavadoc javaDoc = type.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals("<div class=\"block\">Comment for level 2 nested class</div>", javaDoc.getRenderable().toHtml());
|
||||
|
||||
IField field = type.getField("innerLevel2Field");
|
||||
assertNotNull(field);
|
||||
String expected = String.join("\n",
|
||||
"<h4>innerLevel2Field</h4>",
|
||||
"<pre>protected int innerLevel2Field</pre>",
|
||||
"<div class=\"block\">Comment for level 2 inner field</div>"
|
||||
);
|
||||
javaDoc = field.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
|
||||
IMethod method = type.getMethod("getInnerLevel2Field", Stream.empty());
|
||||
assertNotNull(method);
|
||||
expected = String.join("\n",
|
||||
"<h4>getInnerLevel2Field</h4>",
|
||||
"<pre>public int getInnerLevel2Field()</pre>",
|
||||
"<div class=\"block\">Comment for method inside level 2 nested class</div>"
|
||||
);
|
||||
javaDoc = method.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testNoJavadocClass() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
Path projectPath = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = createMavenProject(projectPath);
|
||||
|
||||
IType type = project.findType("hello.GreetingController");
|
||||
assertNotNull(type);
|
||||
assertNull(type.getJavaDoc());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testEmptyJavadocClass() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
Path projectPath = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = createMavenProject(projectPath);
|
||||
|
||||
IType type = project.findType("hello.Application");
|
||||
assertNotNull(type);
|
||||
assertNull(type.getJavaDoc());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testNoJavadocMethod() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
Path projectPath = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = createMavenProject(projectPath);
|
||||
|
||||
IType type = project.findType("hello.Application");
|
||||
assertNotNull(type);
|
||||
IMethod method = type.getMethod("corsConfigurer", Stream.empty());
|
||||
assertNotNull(method);
|
||||
String expected = String.join("\n",
|
||||
"<h4>corsConfigurer</h4>",
|
||||
"<pre>@Bean",
|
||||
"public org.springframework.web.servlet.config.annotation.WebMvcConfigurer corsConfigurer()</pre>"
|
||||
);
|
||||
IJavadoc javaDoc = method.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void html_testNoJavadocField() throws Exception {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
Path projectPath = projectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
MavenJavaProject project = createMavenProject(projectPath);
|
||||
|
||||
IType type = project.findType("hello.GreetingController");
|
||||
assertNotNull(type);
|
||||
IField field = type.getField("template");
|
||||
assertNotNull(field);
|
||||
String expected = String.join("\n",
|
||||
"<h4>template</h4>",
|
||||
"<pre>public static final <a href=\"http://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true\" title=\"class or interface in java.lang\">String</a> template</pre>",
|
||||
"<dl>",
|
||||
"<dt><span class=\"seeLabel\">See Also:</span></dt>",
|
||||
"<dd><a href=\"../constant-values.html#hello.GreetingController.template\">Constant Field Values</a></dd>",
|
||||
"</dl>"
|
||||
);
|
||||
IJavadoc javaDoc = field.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
assertEquals(expected, javaDoc.getRenderable().toHtml());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,4 +61,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -8,6 +8,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
@SpringBootApplication
|
||||
/**
|
||||
*/
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
package hello;
|
||||
|
||||
/**
|
||||
* Comment for Greeting class
|
||||
*/
|
||||
public class Greeting {
|
||||
|
||||
private final long id;
|
||||
/**
|
||||
* Comment for id field
|
||||
*/
|
||||
protected final long id;
|
||||
private final String content;
|
||||
|
||||
public Greeting() {
|
||||
@@ -15,6 +21,9 @@ public class Greeting {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment for getId()
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -22,4 +31,41 @@ public class Greeting {
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment for inner class
|
||||
*/
|
||||
public class TestInnerClass {
|
||||
|
||||
/**
|
||||
* Comment for inner field
|
||||
*/
|
||||
protected int innerField;
|
||||
|
||||
/**
|
||||
* Comment for method inside nested class
|
||||
*/
|
||||
public int getInnerField() {
|
||||
return innerField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment for level 2 nested class
|
||||
*/
|
||||
public class TestInnerClassLevel2 {
|
||||
|
||||
/**
|
||||
* Comment for level 2 inner field
|
||||
*/
|
||||
protected int innerLevel2Field;
|
||||
|
||||
/**
|
||||
* Comment for method inside level 2 nested class
|
||||
*/
|
||||
public int getInnerLevel2Field() {
|
||||
return innerField;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RestController
|
||||
public class GreetingController {
|
||||
|
||||
private static final String template = "Hello, %s!";
|
||||
public static final String template = "Hello, %s!";
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
|
||||
@CrossOrigin(origins = "http://localhost:9000")
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
<!-- HTM -> Markdown converter -->
|
||||
<dependency>
|
||||
<groupId>com.kotcrab.remark</groupId>
|
||||
<artifactId>remark</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -113,10 +113,6 @@ public class HtmlBuffer {
|
||||
raw("</p>");
|
||||
}
|
||||
|
||||
public void snippet(HtmlSnippet snippet) {
|
||||
snippet.render(this);
|
||||
}
|
||||
|
||||
public void bold(String string) {
|
||||
raw("<b>");
|
||||
text(string);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Pivotal Software, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.util;
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -8,15 +8,13 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.hover;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.HtmlBuffer;
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
/**
|
||||
* Placeholder. Still need to figure out what exactly we should do with this in
|
||||
* vscode. TODO: rename to Renderable
|
||||
*/
|
||||
public interface HoverInfo {
|
||||
public interface Renderable {
|
||||
|
||||
void renderAsHtml(HtmlBuffer buffer);
|
||||
|
||||
@@ -8,20 +8,17 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.util;
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlBuffer;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlSnippet;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.overzealous.remark.Remark;
|
||||
|
||||
/**
|
||||
* Static methods and convenience constants for creating some 'description
|
||||
@@ -29,44 +26,50 @@ import com.google.common.collect.ImmutableList;
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class DescriptionProviders {
|
||||
public class Renderables {
|
||||
|
||||
private static final String NO_DESCRIPTION_TEXT = "no description";
|
||||
|
||||
final static Logger logger = LoggerFactory.getLogger(DescriptionProviders.class);
|
||||
final static Logger logger = LoggerFactory.getLogger(Renderables.class);
|
||||
|
||||
public static final HoverInfo NO_DESCRIPTION = italic(text(NO_DESCRIPTION_TEXT));
|
||||
|
||||
public static Provider<HtmlSnippet> snippet(final HtmlSnippet snippet) {
|
||||
return new Provider<HtmlSnippet>() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return snippet.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlSnippet get() {
|
||||
return snippet;
|
||||
}
|
||||
};
|
||||
public static final Renderable NO_DESCRIPTION = italic(text(NO_DESCRIPTION_TEXT));
|
||||
|
||||
private static Remark getHtmlToMarkdownConverter() {
|
||||
return new Remark();
|
||||
}
|
||||
|
||||
public static HoverInfo concat(HoverInfo... pieces) {
|
||||
public static Renderable htmlBlob(String html) {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsHtml(HtmlBuffer buffer) {
|
||||
buffer.raw(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
buffer.append(getHtmlToMarkdownConverter().convert(html));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static Renderable concat(Renderable... pieces) {
|
||||
return concat(ImmutableList.copyOf(pieces));
|
||||
}
|
||||
|
||||
public static HoverInfo concat(List<HoverInfo> pieces) {
|
||||
public static Renderable concat(List<Renderable> pieces) {
|
||||
if (pieces == null || pieces.size() == 0) {
|
||||
throw new IllegalArgumentException("At least one hover information is required for concat");
|
||||
} else if (pieces.size() == 1) {
|
||||
return pieces.get(0);
|
||||
} else {
|
||||
return new ConcatHoverInfo(pieces);
|
||||
return new ConcatRenderables(pieces);
|
||||
}
|
||||
}
|
||||
|
||||
public static HoverInfo italic(HoverInfo text) {
|
||||
return new HoverInfo() {
|
||||
public static Renderable italic(Renderable text) {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
@@ -84,8 +87,8 @@ public class DescriptionProviders {
|
||||
};
|
||||
}
|
||||
|
||||
public static HoverInfo link(String text, String url) {
|
||||
return new HoverInfo() {
|
||||
public static Renderable link(String text, String url) {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
@@ -110,8 +113,8 @@ public class DescriptionProviders {
|
||||
};
|
||||
}
|
||||
|
||||
public static HoverInfo lineBreak() {
|
||||
return new HoverInfo() {
|
||||
public static Renderable lineBreak() {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
@@ -125,9 +128,9 @@ public class DescriptionProviders {
|
||||
};
|
||||
}
|
||||
|
||||
public static HoverInfo bold(HoverInfo text) {
|
||||
public static Renderable bold(Renderable text) {
|
||||
|
||||
return new HoverInfo() {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
@@ -145,8 +148,8 @@ public class DescriptionProviders {
|
||||
};
|
||||
}
|
||||
|
||||
public static HoverInfo text(String text) {
|
||||
return new HoverInfo() {
|
||||
public static Renderable text(String text) {
|
||||
return new Renderable() {
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
// TODO: handle escaping
|
||||
@@ -159,9 +162,24 @@ public class DescriptionProviders {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Renderable lazy(Supplier<Renderable> supplier) {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
supplier.get().renderAsMarkdown(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsHtml(HtmlBuffer buffer) {
|
||||
supplier.get().renderAsHtml(buffer);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static HoverInfo fromClasspath(final Class<?> klass, final String resourcePath) {
|
||||
return new HoverInfo() {
|
||||
public static Renderable fromClasspath(final Class<?> klass, final String resourcePath) {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
@@ -199,28 +217,28 @@ public class DescriptionProviders {
|
||||
};
|
||||
}
|
||||
|
||||
private static class ConcatHoverInfo implements HoverInfo {
|
||||
private static class ConcatRenderables implements Renderable {
|
||||
|
||||
private HoverInfo[] pieces;
|
||||
private Renderable[] pieces;
|
||||
|
||||
ConcatHoverInfo(HoverInfo[] pieces) {
|
||||
ConcatRenderables(Renderable[] pieces) {
|
||||
this.pieces = pieces;
|
||||
}
|
||||
|
||||
public ConcatHoverInfo(List<HoverInfo> pieces) {
|
||||
this(pieces.toArray(new HoverInfo[pieces.size()]));
|
||||
public ConcatRenderables(List<Renderable> pieces) {
|
||||
this(pieces.toArray(new Renderable[pieces.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsHtml(HtmlBuffer buffer) {
|
||||
for (HoverInfo hoverInfo : pieces) {
|
||||
for (Renderable hoverInfo : pieces) {
|
||||
hoverInfo.renderAsHtml(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
for (HoverInfo hoverInfo : pieces) {
|
||||
for (Renderable hoverInfo : pieces) {
|
||||
hoverInfo.renderAsMarkdown(buffer);
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode;
|
||||
@@ -52,17 +52,17 @@ public abstract class TopLevelAssistContext implements YamlAssistContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo() {
|
||||
public Renderable getHoverInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo(YamlPathSegment lastSegment) {
|
||||
public Renderable getHoverInfo(YamlPathSegment lastSegment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.CollectionUtil;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.yaml.hover.YPropertyHoverInfo;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
@@ -219,7 +219,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
|
||||
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo() {
|
||||
public Renderable getHoverInfo() {
|
||||
if (parent!=null) {
|
||||
return parent.getHoverInfo(contextPath.getLastSegment());
|
||||
}
|
||||
@@ -231,7 +231,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo(YamlPathSegment lastSegment) {
|
||||
public Renderable getHoverInfo(YamlPathSegment lastSegment) {
|
||||
//Hoverinfo is only attached to YTypedProperties so...
|
||||
switch (lastSegment.getType()) {
|
||||
case VAL_AT_KEY:
|
||||
@@ -247,7 +247,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
//By default we don't provide value-specific hover, so just show the same hover
|
||||
// as the assistContext the value is in. This is likely more interesting than showing nothing at all.
|
||||
return getHoverInfo();
|
||||
|
||||
@@ -13,8 +13,8 @@ package org.springframework.ide.vscode.commons.yaml.completion;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlNavigable;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument;
|
||||
@@ -28,8 +28,8 @@ public interface YamlAssistContext extends YamlNavigable<YamlAssistContext> {
|
||||
|
||||
//TODO: conceptually... the right thing would be to only implement the second of these
|
||||
// two methods and get rid of the first one.
|
||||
HoverInfo getHoverInfo();
|
||||
HoverInfo getHoverInfo(YamlPathSegment lastSegment);
|
||||
Renderable getHoverInfo();
|
||||
Renderable getHoverInfo(YamlPathSegment lastSegment);
|
||||
|
||||
HoverInfo getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion);
|
||||
Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion);
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.hover;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders.bold;
|
||||
import static org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders.concat;
|
||||
import static org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders.lineBreak;
|
||||
import static org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders.link;
|
||||
import static org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders.text;
|
||||
import static org.springframework.ide.vscode.commons.util.Renderables.bold;
|
||||
import static org.springframework.ide.vscode.commons.util.Renderables.concat;
|
||||
import static org.springframework.ide.vscode.commons.util.Renderables.lineBreak;
|
||||
import static org.springframework.ide.vscode.commons.util.Renderables.link;
|
||||
import static org.springframework.ide.vscode.commons.util.Renderables.text;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
|
||||
@@ -31,9 +31,9 @@ import com.google.common.collect.ImmutableList.Builder;
|
||||
*/
|
||||
public class YPropertyHoverInfo {
|
||||
|
||||
public static HoverInfo create(String contextProperty, YType contextType, YTypedProperty prop) {
|
||||
public static Renderable create(String contextProperty, YType contextType, YTypedProperty prop) {
|
||||
|
||||
Builder<HoverInfo> html = ImmutableList.builder();
|
||||
Builder<Renderable> html = ImmutableList.builder();
|
||||
if (StringUtil.hasText(contextProperty)) {
|
||||
html.add(text(contextProperty));
|
||||
html.add(text("."));
|
||||
@@ -48,7 +48,7 @@ public class YPropertyHoverInfo {
|
||||
html.add(link(type.toString(), /* no URL */ null));
|
||||
}
|
||||
|
||||
HoverInfo description = prop.getDescription();
|
||||
Renderable description = prop.getDescription();
|
||||
if (description != null) {
|
||||
html.add(lineBreak());
|
||||
html.add(description);
|
||||
|
||||
@@ -12,13 +12,13 @@ package org.springframework.ide.vscode.commons.yaml.hover;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.Region;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeRef;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlASTProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
@@ -59,7 +59,7 @@ public class YamlHoverInfoProvider implements HoverInfoProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tuple2<HoverInfo, IRegion> getHoverInfo(IDocument doc, int offset) throws Exception {
|
||||
public Tuple2<Renderable, IRegion> getHoverInfo(IDocument doc, int offset) throws Exception {
|
||||
YamlFileAST ast = getAst(doc);
|
||||
if (ast != null) {
|
||||
IRegion region = getHoverRegion(ast, offset);
|
||||
@@ -82,10 +82,10 @@ public class YamlHoverInfoProvider implements HoverInfoProvider {
|
||||
assistContext = assistPath.traverse(assistContext);
|
||||
if (assistContext != null) {
|
||||
if (path.pointsAtValue()) {
|
||||
HoverInfo info = assistContext.getValueHoverInfo(ymlDoc, new DocumentRegion(doc, region));
|
||||
Renderable info = assistContext.getValueHoverInfo(ymlDoc, new DocumentRegion(doc, region));
|
||||
return Tuples.of(info, region);
|
||||
}
|
||||
HoverInfo info = assistContext.getHoverInfo();
|
||||
Renderable info = assistContext.getHoverInfo();
|
||||
return Tuples.of(info, region);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ import java.util.Set;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.util.EnumValueParser;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders;
|
||||
|
||||
/**
|
||||
* Static utility method for creating YType objects representing either
|
||||
@@ -193,7 +193,7 @@ public class YTypeFactory {
|
||||
propertyList.add(p);
|
||||
}
|
||||
|
||||
public void addProperty(String name, YType type, HoverInfo description) {
|
||||
public void addProperty(String name, YType type, Renderable description) {
|
||||
YTypedPropertyImpl prop;
|
||||
addProperty(prop = new YTypedPropertyImpl(name, type));
|
||||
prop.setDescriptionProvider(description);
|
||||
@@ -314,7 +314,7 @@ public class YTypeFactory {
|
||||
|
||||
final private String name;
|
||||
final private YType type;
|
||||
private HoverInfo description = DescriptionProviders.NO_DESCRIPTION;
|
||||
private Renderable description = Renderables.NO_DESCRIPTION;
|
||||
|
||||
private YTypedPropertyImpl(String name, YType type) {
|
||||
this.name = name;
|
||||
@@ -337,11 +337,11 @@ public class YTypeFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getDescription() {
|
||||
public Renderable getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescriptionProvider(HoverInfo description) {
|
||||
public void setDescriptionProvider(Renderable description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.schema;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
|
||||
/**
|
||||
* @author Kris De Volder
|
||||
@@ -18,5 +18,5 @@ import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
public interface YTypedProperty {
|
||||
String getName();
|
||||
YType getType();
|
||||
HoverInfo getDescription();
|
||||
Renderable getDescription();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenBuilder;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.maven.java.classpathfile.JavaProjectWithClasspathFile;
|
||||
@@ -59,10 +60,10 @@ public class ProjectsHarness {
|
||||
Path testProjectPath = getProjectPath(name);
|
||||
switch (type) {
|
||||
case MAVEN:
|
||||
MavenCore.buildMavenProject(testProjectPath);
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack()./*javadoc().*/skipTests().execute();
|
||||
return new MavenJavaProject(testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
case CLASSPATH_TXT:
|
||||
MavenCore.buildMavenProject(testProjectPath);
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().skipTests().execute();
|
||||
return new JavaProjectWithClasspathFile(testProjectPath.resolve(MavenCore.CLASSPATH_TXT).toFile());
|
||||
default:
|
||||
throw new IllegalStateException("Bug!!! Missing case");
|
||||
|
||||
@@ -63,4 +63,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -86,5 +86,14 @@
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -98,4 +98,14 @@
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -54,5 +54,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -54,5 +54,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -72,5 +72,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -49,5 +49,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -53,5 +53,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -52,4 +52,14 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -50,5 +50,15 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
<artifactId>tricky-getters-boot-1.3.1-app</artifactId>
|
||||
</project>
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ApplicationPropertiesLanguageServer extends SimpleLanguageServer {
|
||||
javaProjectFinder
|
||||
);
|
||||
completionEngine = new VscodeCompletionEngineAdapter(this, propertiesCompletionEngine);
|
||||
completionEngine.setMaxCompletionsNumber(-1);
|
||||
completionEngine.setMaxCompletionsNumber(40);
|
||||
documents.onCompletion(completionEngine::getCompletions);
|
||||
documents.onCompletionResolve(completionEngine::resolveCompletion);
|
||||
|
||||
|
||||
@@ -38,11 +38,11 @@ import org.springframework.ide.vscode.commons.languageserver.completion.IComplet
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.LazyProposalApplier;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ProposalApplier;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.CollectionUtil;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.AbstractYamlAssistContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.TopLevelAssistContext;
|
||||
@@ -376,19 +376,19 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo(YamlPathSegment lastSegment) {
|
||||
public Renderable getHoverInfo(YamlPathSegment lastSegment) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo() {
|
||||
public Renderable getHoverInfo() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@@ -504,19 +504,19 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo() {
|
||||
public Renderable getHoverInfo() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getHoverInfo(YamlPathSegment lastSegment) {
|
||||
public Renderable getHoverInfo(YamlPathSegment lastSegment) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverInfo getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ import java.util.Set;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YAtomicType;
|
||||
@@ -24,7 +25,6 @@ import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YTypedPro
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@@ -109,11 +109,11 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
}
|
||||
}
|
||||
|
||||
private HoverInfo descriptionFor(String propName) {
|
||||
return DescriptionProviders.fromClasspath(this.getClass(), "/description-by-prop-name/"+propName);
|
||||
private Renderable descriptionFor(String propName) {
|
||||
return Renderables.fromClasspath(this.getClass(), "/description-by-prop-name/"+propName);
|
||||
}
|
||||
|
||||
private HoverInfo descriptionFor(YTypedPropertyImpl prop) {
|
||||
private Renderable descriptionFor(YTypedPropertyImpl prop) {
|
||||
return descriptionFor(prop.getName());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YBeanType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YSeqType;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.DescriptionProviders;
|
||||
import org.springframework.ide.vscode.manifest.yaml.ManifestYmlSchema;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -115,14 +115,14 @@ public class ManifestYmlSchemaTest {
|
||||
|
||||
private void assertHasRealDescription(YTypedProperty p) {
|
||||
{
|
||||
String noDescriptionText = DescriptionProviders.NO_DESCRIPTION.toHtml();
|
||||
String noDescriptionText = Renderables.NO_DESCRIPTION.toHtml();
|
||||
String actual = p.getDescription().toHtml();
|
||||
String msg = "Description missing for '"+p.getName()+"'";
|
||||
assertTrue(msg, StringUtil.hasText(actual));
|
||||
assertFalse(msg, noDescriptionText.equals(actual));
|
||||
}
|
||||
{
|
||||
String noDescriptionText = DescriptionProviders.NO_DESCRIPTION.toMarkdown();
|
||||
String noDescriptionText = Renderables.NO_DESCRIPTION.toMarkdown();
|
||||
String actual = p.getDescription().toMarkdown();
|
||||
String msg = "Description missing for '"+p.getName()+"'";
|
||||
assertTrue(msg, StringUtil.hasText(actual));
|
||||
|
||||
Reference in New Issue
Block a user