Merge branch 'master' of github.com:spring-projects/sts4

This commit is contained in:
Kris De Volder
2018-02-21 11:04:16 -08:00
4 changed files with 135 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017 Pivotal, Inc.
* Copyright (c) 2017, 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
@@ -14,6 +14,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.core.dom.Annotation;
@@ -60,7 +61,7 @@ public abstract class AnnotationHierarchies {
public static Set<String> getTransitiveSuperAnnotations(ITypeBinding typeBinding) {
Set<String> seen = new HashSet<>();
findTransitiveSupers(typeBinding, seen);
findTransitiveSupers(typeBinding, seen).collect(Collectors.toList());
return seen;
}

View File

@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.java.livehover;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -27,21 +28,18 @@ import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.springframework.ide.vscode.boot.java.Annotations;
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
import org.springframework.ide.vscode.boot.java.utils.FunctionUtils;
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBean;
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBeansModel;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.StringUtil;
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.common.collect.ImmutableList;
import reactor.util.function.Tuple3;
public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverProvider {
public ComponentInjectionsHoverProvider(BootJavaLanguageServerComponents server) {
@@ -135,8 +133,7 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
@Override
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc,
SpringBootApp[] runningApps) {
Tuple3<String, String, DocumentRegion> functionBean = FunctionUtils.getFunctionBean(typeDeclaration, doc);
if (functionBean != null && runningApps.length > 0) {
if (runningApps.length > 0 && !isComponentAnnotatedType(typeDeclaration)) {
try {
LiveBean definedBean = getDefinedBeanForType(typeDeclaration, null);
if (definedBean != null) {
@@ -157,8 +154,8 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
@Override
public Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset,
TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
Tuple3<String, String, DocumentRegion> functionBean = FunctionUtils.getFunctionBean(typeDeclaration, doc);
if (functionBean != null && runningApps.length > 0) {
if (runningApps.length > 0 && !isComponentAnnotatedType(typeDeclaration)) {
LiveBean definedBean = getDefinedBeanForType(typeDeclaration, null);
if (definedBean != null) {
@@ -191,4 +188,26 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
return null;
}
private boolean isComponentAnnotatedType(TypeDeclaration typeDeclaration) {
List<?> modifiers = typeDeclaration.modifiers();
for (Object modifier : modifiers) {
if (modifier instanceof Annotation) {
ITypeBinding typeBinding = ((Annotation) modifier).resolveTypeBinding();
return isComponentAnnotation(typeBinding);
}
}
return false;
}
private boolean isComponentAnnotation(ITypeBinding type) {
Set<String> transitiveSuperAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(type);
for (String annotationType : transitiveSuperAnnotations) {
if (Annotations.COMPONENT.equals(annotationType)) {
return true;
}
}
return false;
}
}

View File

@@ -23,7 +23,7 @@ import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarn
import org.springframework.ide.vscode.project.harness.MockRunningAppProvider;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
public class FunctionInjectionsHoverProviderTest {
public class BeansByTypeHoverProviderTest {
private BootJavaLanguageServerHarness harness;
private ProjectsHarness projects = ProjectsHarness.INSTANCE;
@@ -45,7 +45,53 @@ public class FunctionInjectionsHoverProviderTest {
}
@Test
public void typeButNotAFunction() throws Exception {
public void typeButNotABean() throws Exception {
LiveBeansModel beans = LiveBeansModel.builder()
.add(LiveBean.builder()
.id("scannedRandomClass")
.type("com.example.ScannedRandomClass")
.build()
)
.add(LiveBean.builder()
.id("randomOtherBean")
.type("randomOtherBeanType")
.dependencies("scannedRandomClass")
.build()
)
.add(LiveBean.builder()
.id("irrelevantBean")
.type("com.example.IrrelevantBean")
.dependencies("myController")
.build()
)
.build();
mockAppProvider.builder()
.isSpringBootApp(true)
.processId("111")
.processName("the-app")
.beans(beans)
.build();
Editor editor = harness.newEditor(LanguageId.JAVA,
"package com.example;\n" +
"\n" +
"import java.io.Serializable;\n" +
"\n" +
"public class ClassNoBean implements Serializable {\n" +
"\n" +
" public String apply(String t) {\n" +
" return t.toUpperCase();\n" +
" }\n" +
"\n" +
"}\n" +
""
);
editor.assertHighlights();
editor.assertNoHover("ClassNoBean");
}
@Test
public void typeWithGeneralBean() throws Exception {
LiveBeansModel beans = LiveBeansModel.builder()
.add(LiveBean.builder()
.id("scannedRandomClass")
@@ -86,8 +132,17 @@ public class FunctionInjectionsHoverProviderTest {
"}\n" +
""
);
editor.assertHighlights();
editor.assertNoHover("ScannedRandomClass");
editor.assertHighlights("ScannedRandomClass");
editor.assertTrimmedHover("ScannedRandomClass",
"**Injection report for Bean [id: scannedRandomClass, type: `com.example.ScannedRandomClass`]**\n" +
"\n" +
"Process [PID=111, name=`the-app`]:\n" +
"\n" +
"Bean [id: scannedRandomClass, type: `com.example.ScannedRandomClass`] injected into:\n" +
"\n" +
"- Bean: randomOtherBean \n" +
" Type: `randomOtherBeanType`"
);
}
@Test
@@ -145,4 +200,46 @@ public class FunctionInjectionsHoverProviderTest {
" Type: `org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration`"
);
}
@Test
public void generalBeanLiveHoverAvoidOverlapWithAnnotation() throws Exception {
LiveBeansModel beans = LiveBeansModel.builder()
.add(LiveBean.builder()
.id("fooImplementation")
.type("com.example.FooImplementation")
.build()
)
.build();
mockAppProvider.builder()
.isSpringBootApp(true)
.processId("111")
.processName("the-app")
.beans(beans)
.build();
Editor editor = harness.newEditor(LanguageId.JAVA,
"package com.example;\n" +
"\n" +
"import org.springframework.stereotype.Component;\n" +
"\n" +
"@Component\n" +
"public class FooImplementation implements Foo {\n" +
"\n" +
" @Override\n" +
" public void doSomeFoo() {\n" +
" System.out.println(\"Foo do do do!\");\n" +
" }\n" +
"}\n"
);
editor.assertHighlights("@Component");
editor.assertTrimmedHover("@Component",
"**Injection report for Bean [id: fooImplementation, type: `com.example.FooImplementation`]**\n" +
"\n" +
"Process [PID=111, name=`the-app`]:\n" +
"\n" +
"Bean [id: fooImplementation, type: `com.example.FooImplementation`] exists but is **Not injected anywhere**\n"
);
}
}

View File

@@ -14,6 +14,10 @@ To install it in vscode follow these steps:
- Press `CTRL-SHIFT-P` and type 'vsix' in the search box
- Select the `Extensions: Install from vsix file` command
- Install the `.vsix` you downloaded earlier.
**IMPORTANT**: Take care not to install multiple versions of the extension at once.
Vscode will not complain but it leads to unpredictable outcomes. So if you have
a prior version already installed make sure to uninstall it first!
## Bulding and Running