diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryCompletionProcessor.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryCompletionProcessor.java index 142bb1aaf..387656106 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryCompletionProcessor.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryCompletionProcessor.java @@ -11,27 +11,38 @@ package org.springframework.ide.vscode.boot.java.data; import java.util.Collection; -import java.util.Optional; +import java.util.List; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.lsp4j.CompletionItemKind; +import org.springframework.ide.vscode.boot.java.data.providers.DataRepositoryCompletionProvider; +import org.springframework.ide.vscode.boot.java.data.providers.DataRepositoryQueryStartCompletionProvider; +import org.springframework.ide.vscode.boot.java.data.providers.DataRepositoryStandardCompletionProvider; +import org.springframework.ide.vscode.boot.java.data.providers.prefixsensitive.DataRepositoryPrefixSensitiveCompletionProvider; import org.springframework.ide.vscode.boot.java.handlers.CompletionProvider; import org.springframework.ide.vscode.boot.java.utils.ASTUtils; -import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.text.IDocument; import org.springframework.ide.vscode.commons.util.text.IRegion; -import org.springframework.util.StringUtils; /** * @author Martin Lippert */ public class DataRepositoryCompletionProcessor implements CompletionProvider { + private List completionProviders; + + public DataRepositoryCompletionProcessor() { + this.completionProviders = List.of( + new DataRepositoryStandardCompletionProvider(), + new DataRepositoryQueryStartCompletionProvider(), + new DataRepositoryPrefixSensitiveCompletionProvider() + ); + } + @Override public void provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type, int offset, IDocument doc, Collection completions) { @@ -41,72 +52,20 @@ public class DataRepositoryCompletionProcessor implements CompletionProvider { public void provideCompletions(ASTNode node, int offset, IDocument doc, Collection completions) { TypeDeclaration type = ASTUtils.findDeclaringType(node); DataRepositoryDefinition repo = getDataRepositoryDefinition(type); - if (repo != null) { - DomainType domainType = repo.getDomainType(); - if (domainType != null) { - - String prefix = ""; - try { - IRegion line = doc.getLineInformationOfOffset(offset); - prefix = doc.get(line.getOffset(), offset - line.getOffset()).trim(); - } catch (BadLocationException e) { - // ignore if there is a problem computing the prefix, continue without prefix - } - - DomainProperty[] properties = domainType.getProperties(); - for (DomainProperty property : properties) { - completions.add(generateCompletionProposal(offset, prefix, repo, property)); - } - DataRepositoryPrefixSensitiveCompletionProvider.addPrefixSensitiveProposals(completions, doc, offset, prefix, repo); + if(repo != null && repo.getDomainType() != null){ + String prefix = ""; + try { + IRegion line = doc.getLineInformationOfOffset(offset); + prefix = doc.get(line.getOffset(), offset - line.getOffset()).trim(); + } catch (BadLocationException e) { + // ignore if there is a problem computing the prefix, continue without prefix + } + for(DataRepositoryCompletionProvider provider : completionProviders){ + provider.addProposals(completions, doc, offset, prefix, repo); } } } - - - protected ICompletionProposal generateCompletionProposal(int offset, String prefix, DataRepositoryDefinition repoDef, DomainProperty domainProperty) { - StringBuilder label = new StringBuilder(); - label.append("findBy"); - label.append(StringUtils.capitalize(domainProperty.getName())); - label.append("("); - label.append(domainProperty.getType().getSimpleName()); - label.append(" "); - label.append(StringUtils.uncapitalize(domainProperty.getName())); - label.append(");"); - - - StringBuilder completion = new StringBuilder(); - completion.append("List<"); - completion.append(repoDef.getDomainType().getSimpleName()); - completion.append("> findBy"); - completion.append(StringUtils.capitalize(domainProperty.getName())); - completion.append("("); - completion.append(domainProperty.getType().getSimpleName()); - completion.append(" "); - completion.append(StringUtils.uncapitalize(domainProperty.getName())); - completion.append(");"); - - return createProposal(offset, CompletionItemKind.Method, prefix, label.toString(), completion.toString()); - } - - static ICompletionProposal createProposal(int offset, CompletionItemKind completionItemKind, String prefix, String label, String completion) { - DocumentEdits edits = new DocumentEdits(null, false); - String filter = label; - if (prefix != null && label.startsWith(prefix)) { - edits.replace(offset - prefix.length(), offset, completion); - } - else if (prefix != null && completion.startsWith(prefix)) { - edits.replace(offset - prefix.length(), offset, completion); - filter = completion; - } - else { - edits.insert(offset, completion); - } - - DocumentEdits additionalEdits = new DocumentEdits(null, false); - return new FindByCompletionProposal(label, completionItemKind, edits, null, null, Optional.of(additionalEdits), filter); - } - private DataRepositoryDefinition getDataRepositoryDefinition(TypeDeclaration type) { if (type != null) { ITypeBinding resolvedType = type.resolveBinding(); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/FindByCompletionProposal.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/FindByCompletionProposal.java index c283db92c..880b175a6 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/FindByCompletionProposal.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/FindByCompletionProposal.java @@ -39,6 +39,24 @@ public class FindByCompletionProposal implements ICompletionProposal { this.filter = filter; } + public static ICompletionProposal createProposal(int offset, CompletionItemKind completionItemKind, String prefix, String label, String completion) { + DocumentEdits edits = new DocumentEdits(null, false); + String filter = label; + if (prefix != null && label.startsWith(prefix)) { + edits.replace(offset - prefix.length(), offset, completion); + } + else if (prefix != null && completion.startsWith(prefix)) { + edits.replace(offset - prefix.length(), offset, completion); + filter = completion; + } + else { + edits.insert(offset, completion); + } + + DocumentEdits additionalEdits = new DocumentEdits(null, false); + return new FindByCompletionProposal(label, completionItemKind, edits, null, null, Optional.of(additionalEdits), filter); + } + @Override public String getLabel() { return label; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryCompletionProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryCompletionProvider.java new file mode 100644 index 000000000..9a0af9feb --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryCompletionProvider.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2023 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 + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.data.providers; + +import java.util.Collection; + +import org.springframework.ide.vscode.boot.java.data.DataRepositoryDefinition; +import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; +import org.springframework.ide.vscode.commons.util.text.IDocument; + +/** + * Responsible for creating proposals related to Spring Data repositories. + * @author danthe1st + */ +public interface DataRepositoryCompletionProvider { + + void addProposals(Collection completions, IDocument doc, int offset, String prefix, DataRepositoryDefinition repo); + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryQueryStartCompletionProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryQueryStartCompletionProvider.java new file mode 100644 index 000000000..b2aa17f46 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryQueryStartCompletionProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2023 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 + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.data.providers; + +import java.util.Collection; + +import org.eclipse.lsp4j.CompletionItemKind; +import org.springframework.ide.vscode.boot.java.data.DataRepositoryDefinition; +import org.springframework.ide.vscode.boot.java.data.FindByCompletionProposal; +import org.springframework.ide.vscode.boot.java.data.providers.prefixsensitive.DataRepositoryPrefixSensitiveCompletionProvider; +import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; +import org.springframework.ide.vscode.commons.util.BadLocationException; +import org.springframework.ide.vscode.commons.util.text.IDocument; + +/** + * This class creates text roposals for query method subjects, e.g. {@code countBy}. + * @author danthe1st + */ +public class DataRepositoryQueryStartCompletionProvider implements DataRepositoryCompletionProvider{ + + @Override + public void addProposals(Collection completions, IDocument doc, int offset, String prefix, DataRepositoryDefinition repo) { + String localPrefix = DataRepositoryPrefixSensitiveCompletionProvider.findLastJavaIdentifierPart(prefix); + for(QueryMethodSubject queryMethodSubject : QueryMethodSubject.QUERY_METHOD_SUBJECTS){ + String toInsert = queryMethodSubject.key() + "By"; + if(prefix == null || toInsert.startsWith(localPrefix)||isOffsetAfterWhitespace(doc, offset)) { + completions.add(FindByCompletionProposal.createProposal(offset, CompletionItemKind.Text, prefix, toInsert, toInsert)); + } + } + } + + private boolean isOffsetAfterWhitespace(IDocument doc, int offset) { + try { + return offset > 0 && Character.isWhitespace(doc.getChar(offset-1)); + }catch (BadLocationException e) { + return false; + } + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryStandardCompletionProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryStandardCompletionProvider.java new file mode 100644 index 000000000..81e2a7c4c --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/DataRepositoryStandardCompletionProvider.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2023 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 + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.data.providers; + +import java.util.Collection; + +import org.eclipse.lsp4j.CompletionItemKind; +import org.springframework.ide.vscode.boot.java.data.DataRepositoryDefinition; +import org.springframework.ide.vscode.boot.java.data.DomainProperty; +import org.springframework.ide.vscode.boot.java.data.DomainType; +import org.springframework.ide.vscode.boot.java.data.FindByCompletionProposal; +import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; +import org.springframework.ide.vscode.commons.util.text.IDocument; +import org.springframework.util.StringUtils; + +/** + * Provides content assist proposals for querying by a single attribute in Spring Data repositories. + * @author Martin Lippert + */ +public class DataRepositoryStandardCompletionProvider implements DataRepositoryCompletionProvider { + + public void addProposals(Collection completions, IDocument doc, int offset, String prefix, DataRepositoryDefinition repo) { + DomainType domainType = repo.getDomainType(); + DomainProperty[] properties = domainType.getProperties(); + for (DomainProperty property : properties) { + completions.add(generateCompletionProposal(offset, prefix, repo, property)); + } + } + + private ICompletionProposal generateCompletionProposal(int offset, String prefix, DataRepositoryDefinition repoDef, DomainProperty domainProperty) { + StringBuilder label = new StringBuilder(); + label.append("findBy"); + label.append(StringUtils.capitalize(domainProperty.getName())); + label.append("("); + label.append(domainProperty.getType().getSimpleName()); + label.append(" "); + label.append(StringUtils.uncapitalize(domainProperty.getName())); + label.append(");"); + + StringBuilder completion = new StringBuilder(); + completion.append("List<"); + completion.append(repoDef.getDomainType().getSimpleName()); + completion.append("> findBy"); + completion.append(StringUtils.capitalize(domainProperty.getName())); + completion.append("("); + completion.append(domainProperty.getType().getSimpleName()); + completion.append(" "); + completion.append(StringUtils.uncapitalize(domainProperty.getName())); + completion.append(");"); + + return FindByCompletionProposal.createProposal(offset, CompletionItemKind.Method, prefix, label.toString(), completion.toString()); + } +} \ No newline at end of file diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/QueryMethodSubject.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/QueryMethodSubject.java similarity index 90% rename from headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/QueryMethodSubject.java rename to headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/QueryMethodSubject.java index 786d5e7b9..445065480 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/QueryMethodSubject.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/QueryMethodSubject.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.boot.java.data; +package org.springframework.ide.vscode.boot.java.data.providers; import java.util.List; @@ -18,10 +18,10 @@ import java.util.List; * See https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#appendix.query.method.subject * @author danthe1st */ -record QueryMethodSubject( +public record QueryMethodSubject( String key, String returnType, boolean isTyped) { - static final List QUERY_METHOD_SUBJECTS = List.of( + public static final List QUERY_METHOD_SUBJECTS = List.of( QueryMethodSubject.createCollectionSubject("find", "List"), QueryMethodSubject.createCollectionSubject("read", "List"), QueryMethodSubject.createCollectionSubject("get", "List"), diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodKeywordType.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodKeywordType.java similarity index 94% rename from headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodKeywordType.java rename to headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodKeywordType.java index 4a89bb0dc..02b0dddcd 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodKeywordType.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodKeywordType.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.boot.java.data; +package org.springframework.ide.vscode.boot.java.data.providers.prefixsensitive; /** * Types of predicate keywords Spring JPA repository method names diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodNameParseResult.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodNameParseResult.java similarity index 84% rename from headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodNameParseResult.java rename to headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodNameParseResult.java index 574ac365b..3048c4daf 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodNameParseResult.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodNameParseResult.java @@ -8,13 +8,15 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.boot.java.data; +package org.springframework.ide.vscode.boot.java.data.providers.prefixsensitive; import java.util.List; import java.util.Set; +import org.springframework.ide.vscode.boot.java.data.providers.QueryMethodSubject; + /** - * Represents the result of parsing a Spring JPA repository query method + * Represents the result of parsing a Spring Data repository query method * @author danthe1st */ record DataRepositoryMethodNameParseResult( diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodParser.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodParser.java similarity index 95% rename from headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodParser.java rename to headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodParser.java index 106af4540..c4c55ddc1 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryMethodParser.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryMethodParser.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.boot.java.data; +package org.springframework.ide.vscode.boot.java.data.providers.prefixsensitive; import java.util.ArrayList; import java.util.EnumSet; @@ -18,6 +18,10 @@ import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; +import org.springframework.ide.vscode.boot.java.data.DataRepositoryDefinition; +import org.springframework.ide.vscode.boot.java.data.DomainProperty; +import org.springframework.ide.vscode.boot.java.data.providers.QueryMethodSubject; + /** * Class responsible for parsing Spring JPA Repository query methods. * @author danthe1st diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryPrefixSensitiveCompletionProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryPrefixSensitiveCompletionProvider.java similarity index 70% rename from headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryPrefixSensitiveCompletionProvider.java rename to headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryPrefixSensitiveCompletionProvider.java index 5bfc2038b..95d4d0de5 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositoryPrefixSensitiveCompletionProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/DataRepositoryPrefixSensitiveCompletionProvider.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.boot.java.data; +package org.springframework.ide.vscode.boot.java.data.providers.prefixsensitive; import java.util.Collection; import java.util.HashMap; @@ -17,23 +17,24 @@ import java.util.Map; import java.util.Optional; import org.eclipse.lsp4j.CompletionItemKind; +import org.springframework.ide.vscode.boot.java.data.DataRepositoryDefinition; +import org.springframework.ide.vscode.boot.java.data.DomainProperty; +import org.springframework.ide.vscode.boot.java.data.DomainType; +import org.springframework.ide.vscode.boot.java.data.FindByCompletionProposal; +import org.springframework.ide.vscode.boot.java.data.providers.DataRepositoryCompletionProvider; import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; -import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.text.IDocument; import org.springframework.util.StringUtils; /** - * This utility class provides content assist proposals for Spring JPA query methods. + * This class provides content assist proposals for Spring Data repository query methods. * @author danthe1st */ -class DataRepositoryPrefixSensitiveCompletionProvider { +public class DataRepositoryPrefixSensitiveCompletionProvider implements DataRepositoryCompletionProvider { - private DataRepositoryPrefixSensitiveCompletionProvider() { - //prevent instantiation - } - - static void addPrefixSensitiveProposals(Collection completions, IDocument doc, int offset, String prefix, DataRepositoryDefinition repoDef) { + @Override + public void addProposals(Collection completions, IDocument doc, int offset, String prefix, DataRepositoryDefinition repoDef) { String localPrefix = findLastJavaIdentifierPart(prefix); if (localPrefix == null) { return; @@ -47,27 +48,9 @@ class DataRepositoryPrefixSensitiveCompletionProvider { addPropertyProposals(completions, offset, repoDef, parseResult); } } - addQueryStartProposals(completions, localPrefix, doc, offset); } - private static void addQueryStartProposals(Collection completions, String prefix, IDocument doc, int offset) { - for(QueryMethodSubject queryMethodSubject : QueryMethodSubject.QUERY_METHOD_SUBJECTS){ - String toInsert = queryMethodSubject.key() + "By"; - if(toInsert.startsWith(prefix)||isOffsetAfterWhitespace(doc, offset)) { - completions.add(DataRepositoryCompletionProcessor.createProposal(offset, CompletionItemKind.Text, prefix, toInsert, toInsert)); - } - } - } - - private static boolean isOffsetAfterWhitespace(IDocument doc, int offset) { - try { - return offset > 0 && Character.isWhitespace(doc.getChar(offset-1)); - }catch (BadLocationException e) { - return false; - } - } - - private static void addPropertyProposals(Collection completions, int offset, DataRepositoryDefinition repoDef, DataRepositoryMethodNameParseResult parseResult) { + private void addPropertyProposals(Collection completions, int offset, DataRepositoryDefinition repoDef, DataRepositoryMethodNameParseResult parseResult) { for(DomainProperty property : repoDef.getDomainType().getProperties()){ String lastWord = parseResult.lastWord(); if (lastWord == null) { @@ -83,7 +66,7 @@ class DataRepositoryPrefixSensitiveCompletionProvider { } } - private static void addMethodCompletionProposal(Collection completions, int offset, DataRepositoryDefinition repoDef, String localPrefix, String fullPrefix, DataRepositoryMethodNameParseResult parseResult, Map propertiesByName) { + private void addMethodCompletionProposal(Collection completions, int offset, DataRepositoryDefinition repoDef, String localPrefix, String fullPrefix, DataRepositoryMethodNameParseResult parseResult, Map propertiesByName) { String methodName = localPrefix; DocumentEdits edits = new DocumentEdits(null, false); String signature = buildSignature(methodName, propertiesByName, parseResult); @@ -105,7 +88,7 @@ class DataRepositoryPrefixSensitiveCompletionProvider { completions.add(proposal); } - private static int calculateReplaceOffset(int offset, String localPrefix, String fullPrefix, String returnType) { + private int calculateReplaceOffset(int offset, String localPrefix, String fullPrefix, String returnType) { int replaceStart = offset - localPrefix.length(); String beforeLocalPrefix = fullPrefix.substring(0, fullPrefix.length()-localPrefix.length()); String trimmed = beforeLocalPrefix.trim(); @@ -115,7 +98,7 @@ class DataRepositoryPrefixSensitiveCompletionProvider { return replaceStart; } - private static Map getPropertiesByName(DomainProperty[] properties) { + private Map getPropertiesByName(DomainProperty[] properties) { Map propertiesByName = new HashMap<>(); for(DomainProperty prop : properties){ propertiesByName.put(prop.getName(), prop); @@ -123,7 +106,7 @@ class DataRepositoryPrefixSensitiveCompletionProvider { return propertiesByName; } - private static String buildSignature(String methodName, Map properties, DataRepositoryMethodNameParseResult parseResult) { + private String buildSignature(String methodName, Map properties, DataRepositoryMethodNameParseResult parseResult) { StringBuilder signatureBuilder = new StringBuilder(); signatureBuilder.append(methodName); signatureBuilder.append("("); @@ -146,7 +129,7 @@ class DataRepositoryPrefixSensitiveCompletionProvider { return signatureBuilder.toString(); } - private static DomainType findExpressionType(Map properties, String param) { + private DomainType findExpressionType(Map properties, String param) { String[] splitByUnderscore = param.split("_"); if(properties.containsKey(splitByUnderscore[0])) { DomainType type = properties.get(splitByUnderscore[0]).getType(); @@ -158,7 +141,7 @@ class DataRepositoryPrefixSensitiveCompletionProvider { return null; } - private static DomainType findMatchingParameter(String name, DomainType type) { + private DomainType findMatchingParameter(String name, DomainType type) { for(DomainProperty prop : type.getProperties()){ if (prop.getName().equals(name)) { return prop.getType(); @@ -167,7 +150,7 @@ class DataRepositoryPrefixSensitiveCompletionProvider { return null; } - private static String findLastJavaIdentifierPart(String prefix) { + public static String findLastJavaIdentifierPart(String prefix) { if (prefix == null) { return null; } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/QueryPredicateKeywordInfo.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/QueryPredicateKeywordInfo.java similarity index 98% rename from headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/QueryPredicateKeywordInfo.java rename to headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/QueryPredicateKeywordInfo.java index daf4ed85b..e3fbc8f11 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/QueryPredicateKeywordInfo.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/providers/prefixsensitive/QueryPredicateKeywordInfo.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.boot.java.data; +package org.springframework.ide.vscode.boot.java.data.providers.prefixsensitive; import java.util.List;