From 1203b899dd8d5ef5e3480f4d304719d2087bbb8b Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Wed, 6 Jun 2018 21:42:28 -0400 Subject: [PATCH] PT #156686000: Make enum value description look closer to javadoc --- .../ide/vscode/commons/jandex/FieldImpl.java | 26 ++++++++++++- .../ide/vscode/commons/jandex/MethodImpl.java | 18 ++++----- .../ide/vscode/commons/jandex/TypeImpl.java | 5 +++ .../ide/vscode/commons/jandex/Wrappers.java | 7 ++++ .../ide/vscode/commons/java/IField.java | 2 + .../ide/vscode/commons/java/IMember.java | 4 +- .../commons/jandex/JandexClasspathTest.java | 36 ++++++++++++++++++ .../simple-java-project/bin/demo/Hello.class | Bin 250 -> 550 bytes .../simple-java-project/src/demo/Hello.java | 9 +++++ .../ide/vscode/commons/util/Renderables.java | 2 +- .../boot/metadata/hints/StsValueHint.java | 8 ++-- .../boot/metadata/util/PropertyDocUtils.java | 29 +++++++++++--- 12 files changed, 124 insertions(+), 22 deletions(-) diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/FieldImpl.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/FieldImpl.java index 64dfca9c4..b09bea94c 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/FieldImpl.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/FieldImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2017 Pivotal, Inc. + * Copyright (c) 2016-2018 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 @@ -11,12 +11,14 @@ package org.springframework.ide.vscode.commons.jandex; +import java.util.regex.Pattern; import java.util.stream.Stream; import org.jboss.jandex.FieldInfo; 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.IType; import org.springframework.ide.vscode.commons.javadoc.IJavadoc; @@ -93,4 +95,26 @@ class FieldImpl implements IField { return BindingKeyUtils.getBindingKey(field); } + @Override + public IJavaType type() { + return Wrappers.wrap(field.type()); + } + + @Override + public String signature() { + String jandexSignature = field.toString(); + int typeEndIdx = jandexSignature.indexOf(' '); + if (typeEndIdx < 0) { + return jandexSignature; + } else { + if (isEnumConstant()) { + // Chop off field type completely for enum constant + return jandexSignature.substring(typeEndIdx + 1); + } else { + // Chop off prefix of the FQ name of the field type + return Pattern.compile(field.type().name().toString(), Pattern.LITERAL).matcher(jandexSignature).replaceFirst(Wrappers.simpleName(field.type().name())); + } + } + } + } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/MethodImpl.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/MethodImpl.java index f2adcf14f..e48d444cc 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/MethodImpl.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/MethodImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2017 Pivotal, Inc. + * Copyright (c) 2016-2018 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 @@ -75,16 +75,6 @@ public class MethodImpl implements IMethod { return Wrappers.wrap(method.returnType()); } -// @Override -// public String getSignature() { -// StringBuilder sb = new StringBuilder(); -// sb.append('('); -// method.parameters().forEach(p -> sb.append(signature(p))); -// sb.append(')'); -// sb.append(getReturnType()); -// return sb.toString(); -// } - @Override public String toString() { return method.toString(); @@ -113,4 +103,10 @@ public class MethodImpl implements IMethod { return BindingKeyUtils.getBindingKey(method); } + @Override + public String signature() { + //Return Jandex signature for now + return method.toString(); + } + } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java index 18e89a815..33c194a31 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java @@ -154,4 +154,9 @@ class TypeImpl implements IType { return classpathContainer; } + @Override + public String signature() { + return info.toString(); + } + } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java index 09c2280e4..3942e0469 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java @@ -18,6 +18,7 @@ import java.io.File; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; import org.jboss.jandex.FieldInfo; import org.jboss.jandex.MethodInfo; import org.jboss.jandex.PrimitiveType; @@ -153,4 +154,10 @@ public class Wrappers { throw new IllegalArgumentException("Invalid Java Type " + type.toString()); } + public static String simpleName(DotName dotName) { + String fqName = dotName.toString(); + int idx = fqName.lastIndexOf('.'); + return idx < 0 ? fqName : fqName.substring(idx + 1); + } + } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java index 5581d7796..a1abfa2af 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java @@ -15,6 +15,8 @@ import java.io.File; public interface IField extends IMember { boolean isEnumConstant(); + IJavaType type(); + @Override default File classpathContainer() { return getDeclaringType().classpathContainer(); diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java index 6f4d200de..c8032b99a 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2013, 2018 IBM Corporation and others. * 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 @@ -47,4 +47,6 @@ public interface IMember extends IJavaElement, IAnnotatable { File classpathContainer(); + String signature(); + } diff --git a/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java b/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java index db122d08c..b56d2e4f4 100644 --- a/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java +++ b/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java @@ -10,16 +10,21 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.jandex; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.io.File; import java.util.function.BiConsumer; +import java.util.stream.Stream; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.springframework.ide.vscode.commons.java.ClasspathData; +import org.springframework.ide.vscode.commons.java.IField; +import org.springframework.ide.vscode.commons.java.IMethod; +import org.springframework.ide.vscode.commons.java.IType; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.util.BasicFileObserver; @@ -99,4 +104,35 @@ public class JandexClasspathTest { assertNull(subject.findType("demo.Hello")); assertNull(subject.findType("demo.Goodbye")); } + + + @Test public void fieldSignature() throws Exception { + TestProject project = new TestProject("simple-java-project"); + project.createClass("demo.Hello"); + + JandexClasspath subject = project.getJandexClasspath(); + + IType type = subject.findType("demo.Hello"); + assertNotNull(type); + + IField field = type.getField("message"); + assertNotNull(field); + + assertEquals("String demo.Hello.message", field.signature()); + } + + @Test public void methodSignature() throws Exception { + TestProject project = new TestProject("simple-java-project"); + project.createClass("demo.Hello"); + + JandexClasspath subject = project.getJandexClasspath(); + + IType type = subject.findType("demo.Hello"); + assertNotNull(type); + + IMethod method = type.getMethod("getMessage", Stream.of()); + assertNotNull(method); + + assertEquals("java.util.List getMessage()", method.signature()); + } } diff --git a/headless-services/commons/commons-java/src/test/resources/simple-java-project/bin/demo/Hello.class b/headless-services/commons/commons-java/src/test/resources/simple-java-project/bin/demo/Hello.class index 74d4b2d38019cfce49be4e71d50edb7b91764c39..2151d34d3e21ac585f5b158987906ef60ec67313 100644 GIT binary patch literal 550 zcmZvZT}uK%6o%hXb9G&_?E4df2=$_c=uYuQh%UCeFuWgi*ha=3*q!Zn6$C{W{eXT{ zbao6C>|)N$`QSP4IrIJV`32w_rw(!q?pRE%h^|{ z;IYj7zhJ>U$%MfR7J>-whQi#<+c%ms0jZJ74`gDfqTH8Z#7!C#_+q7?v#Pk;E`wpm z!y1Y%_Hf`}pL{!+1^2X4G`Q4J;^7cS4Aq22Rl?{fYszrmSi;WM)c!}B+t+D45;rm% z+O<2r%-Z0L1mx)x7#&hUHb-yT7TGd+KHWCgdWZXJ(;nHP4Hi+Qw>K-mI%?$6zhRRg hbz8e-Ay*X5Af?tDwm-1@Vsi^lWrk_XIY1=74g9wP%EkYr-u2LK1S3=#kU diff --git a/headless-services/commons/commons-java/src/test/resources/simple-java-project/src/demo/Hello.java b/headless-services/commons/commons-java/src/test/resources/simple-java-project/src/demo/Hello.java index 11c2c424f..4e506abab 100644 --- a/headless-services/commons/commons-java/src/test/resources/simple-java-project/src/demo/Hello.java +++ b/headless-services/commons/commons-java/src/test/resources/simple-java-project/src/demo/Hello.java @@ -1,5 +1,14 @@ package demo; +import java.util.Collections; +import java.util.List; + public class Hello { + + String message; + + public List getMessage() { + return Collections.singletonList(message); + } } diff --git a/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Renderables.java b/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Renderables.java index 4b6ede123..19eed5258 100644 --- a/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Renderables.java +++ b/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Renderables.java @@ -206,7 +206,7 @@ public class Renderables { @Override public void renderAsMarkdown(StringBuilder buffer) { - if (buffer.charAt(buffer.length() - 1) != '\n') { + if (buffer.length() > 0 && buffer.charAt(buffer.length() - 1) != '\n') { // 2 spaces and then new line would create a line break in text buffer.append(" "); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java index fda693c63..fc16269c7 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java @@ -11,6 +11,8 @@ package org.springframework.ide.vscode.boot.metadata.hints; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.configurationmetadata.Deprecation; import org.springframework.ide.vscode.boot.configurationmetadata.ValueHint; import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory; @@ -22,7 +24,6 @@ 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.util.Assert; -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; @@ -39,6 +40,7 @@ import org.springframework.ide.vscode.commons.util.StringUtil; */ public class StsValueHint { + private static final Logger log = LoggerFactory.getLogger(StsValueHint.class); private final String value; private final Renderable description; @@ -87,7 +89,7 @@ public class StsValueHint { } } } catch (Exception e) { - Log.log(e); + log.error("", e); } return null; } @@ -122,7 +124,7 @@ public class StsValueHint { private static Renderable javaDocSnippet(IJavaProject project, IJavaElement je) { return Renderables.lazy(() -> { SourceLinks sourceLinks = SourceLinkFactory.createSourceLinks(null); - return PropertyDocUtils.documentation(sourceLinks, project, je); + return PropertyDocUtils.documentJavaValue(sourceLinks, project, je); }); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/util/PropertyDocUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/util/PropertyDocUtils.java index 17dca288a..5e65fbde3 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/util/PropertyDocUtils.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/util/PropertyDocUtils.java @@ -42,16 +42,32 @@ public class PropertyDocUtils { * @return */ public static Renderable documentation(SourceLinks sourceLinks, IJavaProject project, IJavaElement je) { - IJavadoc javadoc = je.getJavaDoc(); Builder renderableBuilder = ImmutableList.builder(); - renderableBuilder.add(javadoc == null ? Renderables.NO_DESCRIPTION: javadoc.getRenderable()); + IJavadoc javadoc = je.getJavaDoc(); + renderableBuilder.add(Renderables.lineBreak()); + renderableBuilder.add(Renderables.paragraph(javadoc == null ? Renderables.NO_DESCRIPTION: javadoc.getRenderable())); + return Renderables.concat(renderableBuilder.build()); + } + + /** + * Generates documentation for the value of some Java type. Includes signature, javadoc, link to container type. + * + * @param sourceLinks + * @param project + * @param je + * @return + */ + public static Renderable documentJavaValue(SourceLinks sourceLinks, IJavaProject project, IJavaElement je) { + Builder renderableBuilder = ImmutableList.builder(); if (je instanceof IMember) { - IType containingType = je instanceof IType ? (IType) je : ((IMember)je).getDeclaringType(); + IMember member = (IMember) je; + renderableBuilder.add(Renderables.lineBreak()); + renderableBuilder.add(Renderables.inlineSnippet(Renderables.text(member.signature()))); + IType containingType = je instanceof IType ? (IType) je : ((IMember)je).getDeclaringType(); if (je != null) { - renderableBuilder.add(Renderables.lineBreak()); - renderableBuilder.add(Renderables.text("Type: ")); String type = containingType.getFullyQualifiedName(); Optional url = SourceLinkFactory.createSourceLinks(null).sourceLinkUrlForFQName(project, type); + renderableBuilder.add(Renderables.lineBreak()); if (url.isPresent()) { renderableBuilder.add(Renderables.link(type, url.get())); } else { @@ -59,6 +75,9 @@ public class PropertyDocUtils { } } } + IJavadoc javadoc = je.getJavaDoc(); + renderableBuilder.add(Renderables.lineBreak()); + renderableBuilder.add(Renderables.paragraph(javadoc == null ? Renderables.NO_DESCRIPTION: javadoc.getRenderable())); return Renderables.concat(renderableBuilder.build()); }