GH-1299: added special handling for spaces around content-assist and annotation attribute values
This commit is contained in:
@@ -141,7 +141,15 @@ public class AnnotationAttributeCompletionProcessor implements CompletionProvide
|
||||
String prefix = identifyPropertyPrefix(node.toString(), offset - node.getStartPosition());
|
||||
|
||||
int startOffset = node.getStartPosition();
|
||||
int endOffset = node.getStartPosition() + node.getLength();
|
||||
|
||||
// special adjustment for the case of a $missing$ SimpleName node, e.g. @DependsOn(value = <*>)
|
||||
// where the node starts right after the "=", not at the offset
|
||||
if (node instanceof SimpleName && "$missing$".equals(((SimpleName)node).getIdentifier())) {
|
||||
startOffset = offset;
|
||||
prefix = "";
|
||||
}
|
||||
|
||||
int endOffset = startOffset + node.getLength();
|
||||
|
||||
String proposalPrefix = "\"";
|
||||
String proposalPostfix = "\"";
|
||||
|
||||
@@ -17,13 +17,16 @@ import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.NodeFinder;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.springframework.ide.vscode.boot.java.snippets.JavaSnippetManager;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.LanguageSpecific;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -48,7 +51,7 @@ public class BootJavaCompletionEngine implements ICompletionEngine, LanguageSpec
|
||||
public Collection<ICompletionProposal> getCompletions(TextDocument document, int offset) throws Exception {
|
||||
return cuCache.withCompilationUnit(document, cu -> {
|
||||
if (cu != null) {
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
ASTNode node = findNode(document, offset, cu);
|
||||
|
||||
if (node != null) {
|
||||
Collection<ICompletionProposal> completions = new ArrayList<ICompletionProposal>();
|
||||
@@ -63,6 +66,36 @@ public class BootJavaCompletionEngine implements ICompletionEngine, LanguageSpec
|
||||
});
|
||||
}
|
||||
|
||||
private ASTNode findNode(TextDocument document, int offset, CompilationUnit cu) {
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
|
||||
// take special case into account, e.g. @DependsOn(value = <*>)
|
||||
// in this case the NodeFinder returns the outer AST node (the one where the annotation belongs to
|
||||
// (e.g. the type declaration). This happens because the $missing$ SimpleName node is inserted right after
|
||||
// the "=". Therefore, the NodeFinder doesn't find the SimpleName at the position behind the space
|
||||
// and the information about the surrounding annotation is lost.
|
||||
//
|
||||
// For that case, we look for spaces before the offset and a $missing$ SimpleName to identify this
|
||||
// exact situation and pass on the ASTNode for the SimpleName.
|
||||
try {
|
||||
int numberOfSpaces = 0;
|
||||
while (Character.isSpaceChar(document.getChar(offset - numberOfSpaces - 1))) {
|
||||
numberOfSpaces++;
|
||||
}
|
||||
|
||||
if (numberOfSpaces > 0) {
|
||||
ASTNode leftNode = NodeFinder.perform(cu, offset - numberOfSpaces, 0);
|
||||
if (leftNode instanceof SimpleName && "$missing$".equals(((SimpleName)leftNode).getIdentifier())) {
|
||||
node = leftNode;
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
// ignore, keep the original node
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private void collectCompletionsForAnnotations(ASTNode node, int offset, TextDocument doc, Collection<ICompletionProposal> completions) {
|
||||
Annotation annotation = null;
|
||||
ASTNode exactNode = node;
|
||||
|
||||
@@ -108,11 +108,15 @@ public class DependsOnCompletionProviderTest {
|
||||
assertCompletions("@DependsOn(value=<*>)", 2, "@DependsOn(value=\"bean1\"<*>)");
|
||||
}
|
||||
|
||||
// TODO: not yet working, needs more groundwork due to the parser skipping these non-valid parts of the AST
|
||||
// @Test
|
||||
// public void testDependsOnCompletionWithoutQuotesWithAttributeNameAndDefaultSpaces() throws Exception {
|
||||
// assertCompletions("@DependsOn(value = <*>)", 2, "@DependsOn(value = \"bean1\"<*>)");
|
||||
// }
|
||||
@Test
|
||||
public void testDependsOnCompletionWithoutQuotesWithAttributeNameAndDefaultSpaces() throws Exception {
|
||||
assertCompletions("@DependsOn(value = <*>)", 2, "@DependsOn(value = \"bean1\"<*>)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDependsOnCompletionWithoutQuotesWithAttributeNameAndManySpaces() throws Exception {
|
||||
assertCompletions("@DependsOn(value = <*> )", 2, "@DependsOn(value = \"bean1\"<*> )");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDependsOnCompletionInsideOfQuotesWithoutPrefix() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user