Take superclass into account for properties CTRL-click

See: https://github.com/spring-projects/sts4/issues/326
This commit is contained in:
Kris De Volder
2019-07-25 13:09:17 -07:00
parent ef63d13226
commit bd061a4ec3
10 changed files with 174 additions and 13 deletions

View File

@@ -72,7 +72,7 @@ public class PropertiesJavaDefinitionHandler implements DefinitionHandler, Langu
PropertyFinder propertyFinder = new PropertyFinder(index, typeUtil, doc, offset);
Node node = propertyFinder.findNode();
if (node instanceof Key) {
Collection<IMember> propertyJavaElements = PropertiesDefinitionCalculator.getPropertyJavaElements(propertyFinder, project, ((Key) node).decode());
Collection<IMember> propertyJavaElements = PropertiesDefinitionCalculator.getPropertyJavaElements(typeUtil, propertyFinder, project, ((Key) node).decode());
return PropertiesDefinitionCalculator.getLocations(javaElementLocationProvider, project, propertyJavaElements);
} else if (node instanceof Value) {
Value value = (Value) node;

View File

@@ -578,6 +578,13 @@ public class TypeUtil {
}
return false;
}
public IType getSuperType(IType type) {
if (type!=null) {
return findType(type.getSuperclassName());
}
return null;
}
private IType findType(String typeName) {
try {

View File

@@ -52,15 +52,15 @@ public class PropertiesDefinitionCalculator {
return null;
}
public static Collection<IMember> getPropertyJavaElements(PropertyFinder propertyFinder, IJavaProject project, String propertyKey) {
public static Collection<IMember> getPropertyJavaElements(TypeUtil typeUtil, PropertyFinder propertyFinder, IJavaProject project, String propertyKey) {
PropertyInfo best = propertyFinder.findBestHoverMatch(propertyKey);
if (best != null) {
return getPropertyJavaElement(project, best);
return getPropertyJavaElement(typeUtil, project, best);
}
return ImmutableList.of();
}
public static Collection<IMember> getPropertyJavaElement(IJavaProject project, PropertyInfo property) {
public static Collection<IMember> getPropertyJavaElement(TypeUtil typeUtil, IJavaProject project, PropertyInfo property) {
List<PropertySource> sources = property.getSources();
ImmutableList.Builder<IMember> elements = ImmutableList.builder();
if (sources != null) {
@@ -74,7 +74,7 @@ public class PropertiesDefinitionCalculator {
if (methodSig!=null) {
method = getMethod(type, methodSig);
} else {
method = getPropertyMethod(type, property.getName());
method = getPropertyMethod(typeUtil, type, property.getName());
}
}
if (method!=null) {
@@ -146,13 +146,16 @@ public class PropertiesDefinitionCalculator {
}
}
public static IMethod getPropertyMethod(IType type, String propName) {
public static IMethod getPropertyMethod(TypeUtil typeUtil, IType type, String propName) {
String[] accessors = { "set", "get", "is" };
for (String a : accessors) {
IMethod propertyMethod = getAccessor(type, a, propName);
if (propertyMethod != null) {
return propertyMethod;
while (type!=null && !"java.lang.Object".equals(type.getFullyQualifiedName())) {
for (String a : accessors) {
IMethod propertyMethod = getAccessor(type, a, propName);
if (propertyMethod != null) {
return propertyMethod;
}
}
type = typeUtil.getSuperType(type);
}
return null;
}

View File

@@ -406,7 +406,7 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
} else {
IType javaType = javaProject.getIndex().findType(parentType.getErasure());
if (javaType != null) {
IMethod method = PropertiesDefinitionCalculator.getPropertyMethod(javaType, propName);
IMethod method = PropertiesDefinitionCalculator.getPropertyMethod(typeUtil, javaType, propName);
if (method != null) {
Location location = javaElementLocationProvider.findLocation(javaProject, method);
if (location != null) {
@@ -555,7 +555,7 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
PropertyInfo prop = indexNav.getExactMatch();
if (prop != null) {
IJavaProject project = typeUtil.getJavaProject();
Collection<IMember> elements = PropertiesDefinitionCalculator.getPropertyJavaElement(project, prop);
Collection<IMember> elements = PropertiesDefinitionCalculator.getPropertyJavaElement(typeUtil, project, prop);
return PropertiesDefinitionCalculator.getLocations(javaElementLocationProvider, project, elements);
}
return ImmutableList.of();

View File

@@ -140,7 +140,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
);
editor.assertProblems(/*NONE*/);
}
@Test public void bug_158348104() throws Exception {
//See: https://www.pivotaltracker.com/story/show/158348104
data("spring.activemq.close-timeout", "java.time.Duration", null, null);
@@ -542,6 +542,31 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
definitionLinkAsserts.assertLinkTargets(editor, "data", project, method("demo.FooProperties", "setData", "demo.ColorData"));
definitionLinkAsserts.assertLinkTargets(editor, "wavelen", project, method("demo.ColorData", "setWavelen", "double"));
}
@Test
public void testInheritedPropertyLinkTarget() throws Exception {
//See: https://github.com/spring-projects/sts4/issues/326
MavenJavaProject project = createPredefinedMavenProject("super-property-nav-sample");
useProject(project);
Editor editor = harness.newEditor(
"initializr:\n" +
" languages:\n" +
" - name: foo\n" +
" id: yada\n" +
" default: false\n" +
" bogus: whatever\n"
);
//io.spring.initializr.metadata.DefaultMetadataElement.setDefault(boolean)
//io.spring.initializr.metadata.MetadataElement.setId(String)
//io.spring.initializr.metadata.MetadataElement.setName(String)
definitionLinkAsserts.assertLinkTargets(editor, "name", project, method("io.spring.initializr.metadata.MetadataElement", "setName", "java.lang.String"));
definitionLinkAsserts.assertLinkTargets(editor, "id", project, method("io.spring.initializr.metadata.MetadataElement", "setId", "java.lang.String"));
definitionLinkAsserts.assertLinkTargets(editor, "default", project, method("io.spring.initializr.metadata.DefaultMetadataElement", "setDefault", "boolean"));
definitionLinkAsserts.assertLinkTargets(editor, "bogus", project /*NONE*/);
}
@Test public void testHyperlinkTargets() throws Exception {
IJavaProject p = createPredefinedMavenProject("tricky-getters-boot-1.3.1-app");

View File

@@ -0,0 +1,31 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>super-property-nav-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>super-property-nav-sample</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>io.spring.initializr</groupId>
<artifactId>initializr-generator-spring</artifactId>
<version>0.8.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,13 @@
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SuperPropertyNavSampleApplication {
public static void main(String[] args) {
SpringApplication.run(SuperPropertyNavSampleApplication.class, args);
}
}

View File

@@ -0,0 +1,5 @@
initializr:
languages:
- name: ffo
id: yada
default: false

View File

@@ -0,0 +1,16 @@
package com.example.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SuperPropertyNavSampleApplicationTests {
@Test
public void contextLoads() {
}
}