More fancy implementation active profiles live hovers

This commit is contained in:
Kris De Volder
2017-10-24 16:16:01 -07:00
parent 4a0fde19f9
commit f0ffb29458
2 changed files with 112 additions and 18 deletions

View File

@@ -12,22 +12,26 @@ package org.springframework.ide.vscode.boot.java.profiles;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.springframework.ide.vscode.boot.java.handlers.HoverProvider;
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
import org.springframework.ide.vscode.commons.util.BadLocationException;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableSet;
/**
* @author Kris De Volder
@@ -74,14 +78,65 @@ public class ActiveProfilesProvider implements HoverProvider {
@Override
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
try {
if (runningApps.length > 0) {
Name node = annotation.getTypeName();
return ImmutableList.of(doc.toRange(node.getStartPosition(), node.getLength()));
}
} catch (BadLocationException e) {
Log.log(e);
if (runningApps.length > 0) {
Builder<Range> ranges = ImmutableList.builder();
nameRange(doc, annotation).ifPresent(ranges::add);
Set<String> allActiveProfiles = getAllActiveProfiles(runningApps);
annotation.accept(new ASTVisitor() {
@Override
public boolean visit(StringLiteral node) {
String value = node.getLiteralValue();
if (value!=null && allActiveProfiles.contains(value)) {
rangeOf(doc, node).ifPresent(ranges::add);
}
return true;
}
});
return ranges.build();
}
return ImmutableList.of();
}
private static Set<String> getAllActiveProfiles(SpringBootApp[] runningApps) {
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
for (SpringBootApp app : runningApps) {
List<String> profiles = app.getActiveProfiles();
if (profiles!=null) {
builder.addAll(app.getActiveProfiles());
}
}
return builder.build();
}
private static Optional<Range> nameRange(TextDocument doc, Annotation annotation) {
try {
int start = annotation.getTypeName().getStartPosition();
int len = annotation.getTypeName().getLength();
if (doc.getSafeChar(start-1)=='@') {
start--; len++;
}
return Optional.of(doc.toRange(start, len));
} catch (Exception e) {
Log.log(e);
return Optional.empty();
}
}
private static Optional<Range> rangeOf(TextDocument doc, StringLiteral node) {
try {
int start = node.getStartPosition();
int end = start + node.getLength();
if (doc.getSafeChar(start)=='"') {
start++;
}
if (doc.getSafeChar(end-1)=='"') {
end--;
}
return Optional.of(doc.toRange(start, end-start));
} catch (Exception e) {
Log.log(e);
return Optional.empty();
}
}
}

View File

@@ -60,18 +60,21 @@ public class ActiveProfilesHoverTest {
"public class LocalConfig {\n" +
"}"
);
editor.assertHoverContains("@Profile", "testing-profile");
editor.assertHoverContains("@Profile", "local-profile");
editor.assertHoverContains("@Profile", "foo.bar.RunningApp");
editor.assertHoverContains("@Profile", "22022");
//TODO:
// editor.assertHighlights(
// "@Profile", "local-profile", "testing-profile"
// );
String[] hoverSites = {
"@Profile", "local-profile", "testing-profile"
};
editor.assertHighlights(
hoverSites
);
for (String hoverOver : hoverSites) {
editor.assertHoverContains(hoverOver, "testing-profile");
editor.assertHoverContains(hoverOver, "local-profile");
editor.assertHoverContains(hoverOver, "foo.bar.RunningApp");
editor.assertHoverContains(hoverOver, "22022");
}
}
@Test
public void testActiveProfileHover_Unknown() throws Exception {
//Sometimes its not possible to determine active profiles for an app (e.g. no actuator dependency).
@@ -97,6 +100,41 @@ public class ActiveProfilesHoverTest {
"}"
);
editor.assertHoverContains("@Profile", "Process [PID=22022, name=`foo.bar.RunningApp`] : _Unknown_");
editor.assertHighlights("@Profile");
}
@Test
public void testActiveProfileHoverMixedKnownAndUnknown() throws Exception {
mockAppProvider.builder()
.isSpringBootApp(true)
.processId("22022")
.processName("foo.bar.NoActuatorApp")
.profilesUnknown()
.build();
mockAppProvider.builder()
.isSpringBootApp(true)
.processId("3456")
.processName("foo.bar.NormalApp")
.profiles("fancy")
.build();
Editor editor = harness.newEditor(LanguageId.JAVA,
"package hello;\n" +
"\n" +
"import org.springframework.context.annotation.Configuration;\n" +
"import org.springframework.context.annotation.Profile;\n" +
"\n" +
"@Configuration\n" +
"@Profile({\"unknown\", \"inactive\", \"fancy\"})\n" +
"public class LocalConfig {\n" +
"\n" +
"}"
);
editor.assertHighlights("@Profile", "fancy");
editor.assertHoverContains("@Profile", "Unknown");
editor.assertHoverContains("@Profile", "fancy");
}
@Test
@@ -114,5 +152,6 @@ public class ActiveProfilesHoverTest {
"}"
);
editor.assertNoHover("@Profile");
editor.assertHighlights(/*NONE*/);
}
}